<rss version="2.0">
<channel>
<title>alanwsmith.com</title>
<link>https://www.alanwsmith.com/</link><item>
<title><![CDATA[Open Videos - March 30, 2026]]></title>
<link>https://www.alanwsmith.com/en/3b/fg/fx/oe/</link>
<pubDate>Mon, 30 Mar 2026 08:13:37 -0400</pubDate>
<guid>ec57e003-dce0-5937-beeb-23a720d86922</guid>
<description><![CDATA[<div class="flow body-block">


<section class="title-section default-flow">


<p>The current set of video tabs I have open right now. Archiving them here and closing them in the browser.</p></section>


<section class="youtube-section default-flow"><youtube-player 
:video="S_D9WqWGhHw"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/S_D9WqWGhHw" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="9Dg8w6gk4cE"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/9Dg8w6gk4cE" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="5UMygviK2tA"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/5UMygviK2tA" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="YxgsxaFWWHQ"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/YxgsxaFWWHQ" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="BpeqUCazpzY"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/BpeqUCazpzY" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="ldxFjLJ3rVY"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/ldxFjLJ3rVY" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="1svFCGywpSs"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/1svFCGywpSs" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="M47YdERx11s"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/M47YdERx11s" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="gz9BRl7DVSM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/gz9BRl7DVSM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="pUhXi9C5N2k"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/pUhXi9C5N2k" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="wXT-22qSxEU"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/wXT-22qSxEU" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="RQYuyHNLPTQ"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/RQYuyHNLPTQ" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="9szhjhO9epA"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/9szhjhO9epA" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="h4X3rAg6lhY"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/h4X3rAg6lhY" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="JAmw-TTG2Ds"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/JAmw-TTG2Ds" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="qxuADBE4Zoc"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/qxuADBE4Zoc" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="2A4bs40scSo"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/2A4bs40scSo" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="G5SeUf2anO8"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/G5SeUf2anO8" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="kILYJ0qFhHM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/kILYJ0qFhHM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="KLHRjaUBb3o"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/KLHRjaUBb3o" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="S34wuJKVB0g"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/S34wuJKVB0g" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="5u604lTkGAY"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/5u604lTkGAY" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="g8yLNIMwWuc"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/g8yLNIMwWuc" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="t7OIc-DBRXM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/t7OIc-DBRXM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="jndlbCWs1Tg"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/jndlbCWs1Tg" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="BjPNPuHpX7w"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/BjPNPuHpX7w" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="zkOEdhfwXok"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/zkOEdhfwXok" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="73iTHJQaxcY"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/73iTHJQaxcY" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="shrIyQ2GLj4"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/shrIyQ2GLj4" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="XAtPa28baak"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/XAtPa28baak" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="iV12kgWEgG0"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/iV12kgWEgG0" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="TtO88CoW5Pg"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/TtO88CoW5Pg" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="ibNvyTD4Icg"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/ibNvyTD4Icg" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="8XR2RvfZ-68"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/8XR2RvfZ-68" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="FEcoxUZnsMc"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/FEcoxUZnsMc" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="PvSMiHFAjzo"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/PvSMiHFAjzo" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="N8QkFFe4zMA"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/N8QkFFe4zMA" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="tHQ5fOJkI-g"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/tHQ5fOJkI-g" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="K71XefOlJh0"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/K71XefOlJh0" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="1yE-TKQpl_Y"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/1yE-TKQpl_Y" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="XfOWX--CzNg"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/XfOWX--CzNg" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="1xZxxVlu7BM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/1xZxxVlu7BM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="H1j1KgKlyZU"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/H1j1KgKlyZU" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="9BjCxh5jRgQ"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/9BjCxh5jRgQ" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="PfZgOV4UHBU"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/PfZgOV4UHBU" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="_zkRjrGmTl4"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/_zkRjrGmTl4" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="uDqE8ImgdsM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/uDqE8ImgdsM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="BkpL42aLEAg"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/BkpL42aLEAg" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="nhbYveaV0pk"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/nhbYveaV0pk" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="Sx9zG7wa4FA"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/Sx9zG7wa4FA" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="mZFN_YxpDpU"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/mZFN_YxpDpU" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="53s-5RKAdGE"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/53s-5RKAdGE" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="kT4p1GXq4HY"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/kT4p1GXq4HY" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="-6lBfwiXnZ4"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/-6lBfwiXnZ4" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="mRT31iYaWOw"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/mRT31iYaWOw" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="-cVx8zOL4gc"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/-cVx8zOL4gc" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="36mEaTK9Fu4"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/36mEaTK9Fu4" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="X1tyybVuSBU"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/X1tyybVuSBU" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="OSNV6224cHg"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/OSNV6224cHg" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="fWiXZAfIH2Y"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/fWiXZAfIH2Y" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="RWNauvVJr6s"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/RWNauvVJr6s" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="uYMpMcmpfkI"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/uYMpMcmpfkI" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="_nk6rtLXyaQ"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/_nk6rtLXyaQ" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="IYnvxc_Kp9Q"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/IYnvxc_Kp9Q" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="Lsi1ZhmbNDc"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/Lsi1ZhmbNDc" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="hnq2bX3EYxM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/hnq2bX3EYxM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="Hvfa6p10H6c"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/Hvfa6p10H6c" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="_TrZdA3rRUo"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/_TrZdA3rRUo" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="ZDPyzUCwhxo"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/ZDPyzUCwhxo" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="I6lNQU7pchM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/I6lNQU7pchM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="hckwxq8rnr0"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/hckwxq8rnr0" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><youtube-player 
:video="MiUHjLxm3V0"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/MiUHjLxm3V0" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


</div>
  <div class="end-block"></div>
]]></description> 
</item><item>
<title><![CDATA[Pulling Magic Commander Rankings from EDHREC]]></title>
<link>https://www.alanwsmith.com/en/3b/e9/v6/zj/</link>
<pubDate>Sun, 29 Mar 2026 22:44:49 -0400</pubDate>
<guid>1cd6dad0-989a-5917-bee6-b4d30d8d4a4f</guid>
<description><![CDATA[<div class="flow body-block">


<section class="title-section default-flow">


<p>I'm working on a tool to help me build Magic Decks<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-mdb-text"
    id="footnote-mdb-link"
    >mdb</a></sup>. It'll let me search and assemble cards from data via Scryfall<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-sf-text"
    id="footnote-sf-link"
    >sf</a></sup>. I also want to see other folks are doing. For example, which are the most used commanders. I'm grabbing data from EDHREC<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-edh-text"
    id="footnote-edh-link"
    >edh</a></sup> for that.</p>


<p>This is the script I'm using to pull in the raw data.</p></section>


<section class="code-section default-flow"><pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python">#</span>!/usr/bin/env python3
<span class="aws-code-block-marker"></span></span>
<span class="aws-code-block-marker"></span><span class="meta statement import python"><span class="keyword control import python">import</span> <span class="meta qualified-name python"><span class="meta generic-name python">json</span></span></span>
<span class="aws-code-block-marker"></span><span class="meta statement import python"><span class="keyword control import python">import</span> <span class="meta qualified-name python"><span class="meta generic-name python">urllib</span><span class="punctuation accessor dot python">.</span><span class="meta generic-name python">request</span></span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta qualified-name python"><span class="meta generic-name python">url</span></span> <span class="keyword operator assignment python">=</span> <span class="meta string python"><span class="string quoted double python"><span class="punctuation definition string begin python">&quot;</span></span></span><span class="meta string python"><span class="string quoted double python">https://edhrec.com/commanders<span class="punctuation definition string end python">&quot;</span></span></span>
<span class="aws-code-block-marker"></span><span class="meta qualified-name python"><span class="meta generic-name python">output_path</span></span> <span class="keyword operator assignment python">=</span> <span class="meta string python"><span class="string quoted double python"><span class="punctuation definition string begin python">&quot;</span></span></span><span class="meta string python"><span class="string quoted double python">commanders.json<span class="punctuation definition string end python">&quot;</span></span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta function python"><span class="storage type function python">def</span> <span class="entity name function python"><span class="meta generic-name python">get_json</span></span></span><span class="meta function parameters python"><span class="punctuation section parameters begin python">(</span></span><span class="meta function parameters python"><span class="punctuation section parameters end python">)</span></span><span class="meta function python"><span class="punctuation section function begin python">:</span></span>
<span class="aws-code-block-marker"></span>    <span class="meta qualified-name python"><span class="meta generic-name python">response</span></span> <span class="keyword operator assignment python">=</span> <span class="meta function-call python"><span class="meta qualified-name python"><span class="meta generic-name python">urllib</span><span class="punctuation accessor dot python">.</span><span class="meta generic-name python">request</span><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">urlopen</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta qualified-name python"><span class="meta generic-name python">url</span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span>    <span class="meta qualified-name python"><span class="meta generic-name python">html</span></span> <span class="keyword operator assignment python">=</span> <span class="meta function-call python"><span class="meta qualified-name python"><span class="meta generic-name python">response</span><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">read</span></span><span class="punctuation section arguments begin python">(</span><span class="punctuation section arguments end python">)</span></span><span class="meta function-call python"><span class="meta qualified-name python"><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">decode</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta string python"><span class="string quoted single python"><span class="punctuation definition string begin python">&#39;</span></span></span><span class="meta string python"><span class="string quoted single python">utf-8<span class="punctuation definition string end python">&#39;</span></span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span>    <span class="meta qualified-name python"><span class="meta generic-name python">parts</span></span> <span class="keyword operator assignment python">=</span> <span class="meta function-call python"><span class="meta qualified-name python"><span class="meta generic-name python">html</span><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">split</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta string python"><span class="string quoted single python"><span class="punctuation definition string begin python">&#39;</span></span></span><span class="meta string python"><span class="string quoted single python">&lt;script id=&quot;__NEXT_DATA__&quot; type=&quot;application/json&quot;&gt;<span class="punctuation definition string end python">&#39;</span></span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span>    <span class="meta qualified-name python"><span class="meta generic-name python">content</span></span> <span class="keyword operator assignment python">=</span> <span class="meta item-access python"><span class="meta qualified-name python"><span class="meta generic-name python">parts</span></span></span><span class="meta item-access python"><span class="punctuation section brackets begin python">[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python">1</span></span><span class="meta item-access python"><span class="punctuation section brackets end python">]</span></span><span class="meta function-call python"><span class="meta qualified-name python"><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">split</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta string python"><span class="string quoted single python"><span class="punctuation definition string begin python">&#39;</span></span></span><span class="meta string python"><span class="string quoted single python">&lt;/script&gt;<span class="punctuation definition string end python">&#39;</span></span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span>    <span class="meta qualified-name python"><span class="meta generic-name python">data</span></span> <span class="keyword operator assignment python">=</span> <span class="meta function-call python"><span class="meta qualified-name python"><span class="meta generic-name python">json</span><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">loads</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta item-access python"><span class="meta qualified-name python"><span class="meta generic-name python">content</span></span></span><span class="meta item-access python"><span class="punctuation section brackets begin python">[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python">0</span></span><span class="meta item-access python"><span class="punctuation section brackets end python">]</span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span>    <span class="meta statement with python"><span class="keyword control flow with python">with</span> <span class="meta function-call python"><span class="meta qualified-name python"><span class="support function builtin python">open</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta qualified-name python"><span class="meta generic-name python">output_path</span></span><span class="punctuation separator arguments python">,</span> <span class="meta string python"><span class="string quoted double python"><span class="punctuation definition string begin python">&quot;</span></span></span><span class="meta string python"><span class="string quoted double python">w<span class="punctuation definition string end python">&quot;</span></span></span></span><span class="punctuation section arguments end python">)</span></span> <span class="meta statement with python"><span class="keyword control flow with as python">as</span></span></span><span class="meta statement with python"> <span class="meta generic-name python">_out</span><span class="punctuation section block with python">:</span></span>
<span class="aws-code-block-marker"></span>        <span class="meta function-call python"><span class="meta qualified-name python"><span class="meta generic-name python">_out</span><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">write</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta function-call python"><span class="meta qualified-name python"><span class="meta generic-name python">json</span><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">dumps</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta qualified-name python"><span class="meta generic-name python">data</span></span><span class="punctuation separator arguments python">,</span> <span class="variable parameter python">sort_keys</span><span class="keyword operator assignment python">=</span><span class="constant language python">True</span><span class="punctuation separator arguments python">,</span> <span class="variable parameter python">indent</span><span class="keyword operator assignment python">=</span><span class="constant numeric integer decimal python">2</span><span class="punctuation separator arguments python">,</span> <span class="variable parameter python">default</span><span class="keyword operator assignment python">=</span><span class="meta qualified-name python"><span class="support type python">str</span></span></span><span class="punctuation section arguments end python">)</span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta statement if python"><span class="keyword control flow conditional python">if</span> <span class="meta qualified-name python"><span class="support variable magic python">__name__</span></span> <span class="keyword operator comparison python">==</span> <span class="meta string python"><span class="string quoted double python"><span class="punctuation definition string begin python">&quot;</span></span></span><span class="meta string python"><span class="string quoted double python">__main__<span class="punctuation definition string end python">&quot;</span></span></span><span class="punctuation section block conditional python">:</span></span>
<span class="aws-code-block-marker"></span>    <span class="meta function-call python"><span class="meta qualified-name python"><span class="variable function python">get_json</span></span><span class="punctuation section arguments begin python">(</span><span class="punctuation section arguments end python">)</span></span></span></code></pre></section>


<section class="p-section default-flow">


<p>The code's a little brittle in terms of doing a split to pull out the data instead of more advanced parsing with something like Beautiful Soup<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-bs-text"
    id="footnote-bs-link"
    >bs</a></sup>. That's not a big deal. If they change the page and things break I'll just update the script.</p>


<p>-a</p></section>


</div>
  <div class="end-block">
          <section class="endnotes-section default-flow xxlarge-bottom-margin">
            <h3 class="back-matter">Endnotes</h3>
            <div class="xxlarge-flow">
          
        


<section class="endnote-section default-flow">
  


<p>The EDHREC data uses Scryfall IDs. Combining data sets is no fuss, no muss.</p>
</section>
            </div>
          </section>
    
        <section class="footnotes-section flow">
            <h3 class="back-matter">Footnotes</h3>
        
        


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-mdb-link">
        <span id="footnote-mdb-text">mdb &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div><a href="https://www.al9000.com/magic-deck-builder/"><strong>Magic Deck Builder</strong></a></div>
    <div class="default-flow">


<p>The little tool I'm making to make Magic decks. Still very much a work in progress at press time.</p></div>
    
  </div>


</section>


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-sf-link">
        <span id="footnote-sf-text">sf &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div><a href="https://scryfall.com/"><strong>Scryfall</strong></a></div>
    <div class="default-flow">


<p><em class="emphasis-shorthand-span">The</em> place to search for Magic cards. Even better, they provide <a href="https://scryfall.com/docs/api/bulk-data" >bulk data downloads</a>.</p></div>
    
  </div>


</section>


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-edh-link">
        <span id="footnote-edh-text">edh &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div><a href="https://edhrec.com/"><strong>EDHREC</strong></a></div>
    <div class="default-flow">


<p>Fantastic fan content for all things Magic. They've got articles and stuff which I'm sure are great. I'm only there for the deck lists and rankings though.</p></div>
    
  </div>


</section>


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-bs-link">
        <span id="footnote-bs-text">bs &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div><a href="https://beautiful-soup-4.readthedocs.io/en/latest/"><strong>Beautiful Soup</strong></a></div>
    <div class="default-flow">


<p>For those times when doing simple splits doesn't get you what you need, try Beautiful Soup. It's the only way to fly with python HTML parsing.</p></div>
    
  </div>


</section>
        </section>
    </div>
]]></description> 
</item><item>
<title><![CDATA[Parse a String of Text into JSON in Python]]></title>
<link>https://www.alanwsmith.com/en/3b/e8/gm/e5/</link>
<pubDate>Sun, 29 Mar 2026 22:38:08 -0400</pubDate>
<guid>03cd724e-133c-599f-9fab-05f1a55fb6b9</guid>
<description><![CDATA[<div class="flow body-block">


<section class="title-section default-flow"></section>


<section class="code-section default-flow"><pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source python"><span class="meta statement import python"><span class="keyword control import python">import</span> <span class="meta qualified-name python"><span class="meta generic-name python">json</span></span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta qualified-name python"><span class="support function builtin python">input</span></span> <span class="keyword operator assignment python">=</span> <span class="meta string python"><span class="string quoted single python"><span class="punctuation definition string begin python">&#39;</span></span></span><span class="meta string python"><span class="string quoted single python">{ &quot;alfa&quot;: &quot;bravo&quot;, &quot;charlie&quot;: &quot;delta&quot; }<span class="punctuation definition string end python">&#39;</span></span></span>
<span class="aws-code-block-marker"></span><span class="meta qualified-name python"><span class="meta generic-name python">data</span></span> <span class="keyword operator assignment python">=</span> <span class="meta function-call python"><span class="meta qualified-name python"><span class="meta generic-name python">json</span><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">loads</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta qualified-name python"><span class="support function builtin python">input</span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span><span class="meta function-call python"><span class="meta qualified-name python"><span class="support function builtin python">print</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta qualified-name python"><span class="meta generic-name python">data</span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span><span class="meta function-call python"><span class="meta qualified-name python"><span class="support function builtin python">print</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta string python"><span class="string quoted double python"><span class="punctuation definition string begin python">&quot;</span></span></span><span class="meta string python"><span class="string quoted double python">----<span class="punctuation definition string end python">&quot;</span></span></span></span><span class="punctuation section arguments end python">)</span></span>
<span class="aws-code-block-marker"></span><span class="meta function-call python"><span class="meta qualified-name python"><span class="support function builtin python">print</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta function-call python"><span class="meta qualified-name python"><span class="meta generic-name python">json</span><span class="punctuation accessor dot python">.</span></span><span class="meta qualified-name python"><span class="variable function python">dumps</span></span><span class="punctuation section arguments begin python">(</span><span class="meta function-call arguments python"><span class="meta qualified-name python"><span class="meta generic-name python">data</span></span><span class="punctuation separator arguments python">,</span> <span class="variable parameter python">sort_keys</span><span class="keyword operator assignment python">=</span><span class="constant language python">True</span><span class="punctuation separator arguments python">,</span> <span class="variable parameter python">indent</span><span class="keyword operator assignment python">=</span><span class="constant numeric integer decimal python">2</span><span class="punctuation separator arguments python">,</span> <span class="variable parameter python">default</span><span class="keyword operator assignment python">=</span><span class="meta qualified-name python"><span class="support type python">str</span></span></span><span class="punctuation section arguments end python">)</span></span></span><span class="punctuation section arguments end python">)</span></span></span></code></pre></section>


<section class="results-section">
<div class="results-header">Output:</div>
<div class="results-body">
<pre><code>{&#x27;alfa&#x27;: &#x27;bravo&#x27;, &#x27;charlie&#x27;: &#x27;delta&#x27;}
----
{
  &quot;alfa&quot;: &quot;bravo&quot;,
  &quot;charlie&quot;: &quot;delta&quot;
}</code></pre>
</div></section>





</div>
  <div class="end-block"></div>
]]></description> 
</item><item>
<title><![CDATA[Using IndexedDB to Store Key Value Pairs with Vanilla JavaScript]]></title>
<link>https://www.alanwsmith.com/en/3b/yu/de/lh/</link>
<pubDate>Sat, 28 Mar 2026 02:10:06 -0400</pubDate>
<guid>c92d7b3c-b9a2-5675-aa1a-a4fdf53cf91a</guid>
<description><![CDATA[<hr />
  <div>
    <strong>Dear RSS Reader:<br />The original version of this page includes
    JavaScript. It probably won't run in here. So, any
    functionality it might have had probably won't work.
    <a href="https://www.alanwsmith.com/en/3b/yu/de/lh/">Check out the 
    original page</a> to see it in action.
    </strong>
  </div><hr /><div class="flow body-block">


<section class="title-section default-flow"></section>


<section class="forward-section default-flow">


<p>I'm working on a Magic Deck Builder<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-magic-text"
    id="footnote-magic-link"
    >magic</a></sup>. There's about 30,000 cards to choose from. Keeping track of them is beyond the capabilities of localStorage<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-ls-text"
    id="footnote-ls-link"
    >ls</a></sup>. IndexedDB<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-idb-text"
    id="footnote-idb-link"
    >idb</a></sup>, on the other hand, has no problem hanging on to that much stuff.</p>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>An Actual Solution</h2>


<p>Most documentation and tutorials on IndexedDB are disapointing. They show how to store values just fine. They fail to demonstrate how to pull data out in a useful way. The only thing they give you is how to print to <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="meta function-call method js"><span class="support type object console js">console</span><span class="punctuation accessor js">.</span><span class="support function console js">log</span><span class="meta group js"><span class="punctuation section group js">(</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span></code>. Nothing about how to, you know, actually use the data outside the functions that query it<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-results-text"
    id="footnote-results-link"
    >results</a></sup>.</p>


<p>The examples also lock in on storing full objects. That's great and all, but I want to use IndexedDB as a simple key/value store<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-kv-text"
    id="footnote-kv-link"
    >kv</a></sup>.</p>


<p>This is how I'm doing that:</p></section></section>






<section class="javascript-section default-flow"><div class="flow show-javascript">

    <h4 class="show-javascript-heading">JavaScript</h4><div class="javascript-body">
      <pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="storage type js">const</span> <span class="variable other constant js">DB_NAME</span> <span class="keyword operator assignment js">=</span> <span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>example_db<span class="punctuation definition string end js">&quot;</span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other constant js">STORE_NAME</span> <span class="keyword operator assignment js">=</span> <span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>storage<span class="punctuation definition string end js">&quot;</span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other constant js">DB_VERSION</span> <span class="keyword operator assignment js">=</span> <span class="constant numeric js">1</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta function declaration js"><span class="storage type js">async</span> <span class="storage type function js">function</span> <span class="entity name function js">initDB</span><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="keyword control flow js">return</span> <span class="meta instance constructor js"><span class="keyword operator word new js">new</span><span class="meta function-call constructor js"> <span class="support class builtin js">Promise</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="variable parameter function js">resolve</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">reject</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>    <span class="storage type js">const</span> <span class="variable other readwrite js">request</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">indexedDB</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="support function dom js">open</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">DB_NAME</span><span class="punctuation separator comma js">,</span> <span class="variable other constant js">DB_VERSION</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onsuccess</span></span> <span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="meta function-call js"><span class="variable function js">resolve</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onerror</span></span><span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="meta function-call js"><span class="variable function js">reject</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onupgradeneeded</span></span> <span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="variable parameter function js">event</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>      <span class="storage type js">const</span> <span class="variable other readwrite js">db</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">event</span><span class="punctuation accessor js">.</span><span class="meta property object js">target</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>      <span class="meta conditional js"><span class="keyword control conditional js">if</span> <span class="meta group js"><span class="punctuation section group js">(</span><span class="keyword operator logical js">!</span><span class="variable other object js">db</span><span class="punctuation accessor js">.</span><span class="meta property object js">objectStoreNames</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">contains</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">STORE_NAME</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation section group js">)</span></span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>        <span class="variable other object js">db</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">createObjectStore</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">STORE_NAME</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>      </span><span class="meta block js"><span class="punctuation section block js">}</span></span></span>
<span class="aws-code-block-marker"></span>    <span class="punctuation section block js">}</span></span>
<span class="aws-code-block-marker"></span>  <span class="punctuation section block js">}</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta function declaration js"><span class="storage type js">async</span> <span class="storage type function js">function</span> <span class="entity name function js">putValue</span><span class="punctuation section group begin js">(</span><span class="variable parameter function js">value</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">key</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">db</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">await</span> <span class="meta function-call js"><span class="variable function js">initDB</span><span class="meta group js"><span class="punctuation section group js">(</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="keyword control flow js">return</span> <span class="meta instance constructor js"><span class="keyword operator word new js">new</span><span class="meta function-call constructor js"> <span class="support class builtin js">Promise</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="variable parameter function js">resolve</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">reject</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>    <span class="storage type js">const</span> <span class="variable other readwrite js">store</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">db</span>
<span class="aws-code-block-marker"></span>      <span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">transaction</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">STORE_NAME</span><span class="punctuation separator comma js">,</span> <span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>readwrite<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span>
<span class="aws-code-block-marker"></span>      <span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">objectStore</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">STORE_NAME</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="storage type js">const</span> <span class="variable other readwrite js">request</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">store</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">put</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">value</span><span class="punctuation separator comma js">,</span> <span class="variable other readwrite js">key</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onsuccess</span></span> <span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="meta function-call js"><span class="variable function js">resolve</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onerror</span></span><span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="meta function-call js"><span class="variable function js">reject</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="punctuation section block js">}</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta function declaration js"><span class="storage type js">async</span> <span class="storage type function js">function</span> <span class="entity name function js">getValue</span><span class="punctuation section group begin js">(</span><span class="variable parameter function js">key</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">db</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">await</span> <span class="meta function-call js"><span class="variable function js">initDB</span><span class="meta group js"><span class="punctuation section group js">(</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="keyword control flow js">return</span> <span class="meta instance constructor js"><span class="keyword operator word new js">new</span><span class="meta function-call constructor js"> <span class="support class builtin js">Promise</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="variable parameter function js">resolve</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">reject</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>    <span class="storage type js">const</span> <span class="variable other readwrite js">store</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">db</span>
<span class="aws-code-block-marker"></span>      <span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">transaction</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">STORE_NAME</span><span class="punctuation separator comma js">,</span> <span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>readonly<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span>
<span class="aws-code-block-marker"></span>      <span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">objectStore</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">STORE_NAME</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="storage type js">const</span> <span class="variable other readwrite js">request</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">store</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">get</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">key</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onsuccess</span></span> <span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="meta function-call js"><span class="variable function js">resolve</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onerror</span></span><span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="meta function-call js"><span class="variable function js">reject</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="punctuation section block js">}</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta function declaration js"><span class="storage type js">async</span> <span class="storage type function js">function</span> <span class="entity name function js">deleteValue</span><span class="punctuation section group begin js">(</span><span class="variable parameter function js">key</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">db</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">await</span> <span class="meta function-call js"><span class="variable function js">initDB</span><span class="meta group js"><span class="punctuation section group js">(</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="keyword control flow js">return</span> <span class="meta instance constructor js"><span class="keyword operator word new js">new</span><span class="meta function-call constructor js"> <span class="support class builtin js">Promise</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="variable parameter function js">resolve</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">reject</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>    <span class="storage type js">const</span> <span class="variable other readwrite js">store</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">db</span>
<span class="aws-code-block-marker"></span>      <span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">transaction</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">STORE_NAME</span><span class="punctuation separator comma js">,</span> <span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>readwrite<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span>
<span class="aws-code-block-marker"></span>      <span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">objectStore</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other constant js">STORE_NAME</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="storage type js">const</span> <span class="variable other readwrite js">request</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">store</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">delete</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">key</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onsuccess</span></span> <span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="meta function-call js"><span class="variable function js">resolve</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>    <span class="meta function declaration js"><span class="support class js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js"><span class="entity name function js">onerror</span></span><span class="keyword operator assignment js">=</span> </span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="meta function-call js"><span class="variable function js">reject</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">request</span><span class="punctuation accessor js">.</span><span class="meta property object js">result</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="punctuation section block js">}</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="keyword control flow js">await</span> <span class="meta function-call js"><span class="variable function js">putValue</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>this is alfa<span class="punctuation definition string end js">&quot;</span></span><span class="punctuation separator comma js">,</span> <span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>alfa<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other readwrite js">afterPut</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">await</span> <span class="meta function-call js"><span class="variable function js">getValue</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>alfa<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other readwrite js">afterPutEl</span> <span class="keyword operator assignment js">=</span> <span class="support type object dom js">document</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">querySelector</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>#afterPut<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="variable other object js">afterPutEl</span><span class="punctuation accessor js">.</span><span class="meta property object js">innerHTML</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">afterPut</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="keyword control flow js">await</span> <span class="meta function-call js"><span class="variable function js">deleteValue</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>alfa<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other readwrite js">afterDelete</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">await</span> <span class="meta function-call js"><span class="variable function js">getValue</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>alfa<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other readwrite js">afterDeleteEl</span> <span class="keyword operator assignment js">=</span> <span class="support type object dom js">document</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">querySelector</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>#afterDelete<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="variable other object js">afterDeleteEl</span><span class="punctuation accessor js">.</span><span class="meta property object js">innerHTML</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">afterDelete</span><span class="punctuation terminator statement js">;</span></span></code></pre>
    </div>
  </div>
</section>


<section class="html-section default-flow show-html"><h4 class="show-html-heading">HTML</h4><pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="text html basic"><span class="meta tag block any html"><span class="punctuation definition tag begin html">&lt;</span><span class="entity name tag block any html">div</span> <span class="meta attribute-with-value id html"><span class="entity other attribute-name id html">id</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value id html"><span class="string quoted double html"><span class="punctuation definition string begin html">&quot;</span></span></span><span class="meta attribute-with-value id html"><span class="string quoted double html"><span class="meta toc-list id html">afterPut</span><span class="punctuation definition string end html">&quot;</span></span></span><span class="punctuation definition tag end html">&gt;</span></span>--<span class="meta tag block any html"><span class="punctuation definition tag begin html">&lt;/</span><span class="entity name tag block any html">div</span><span class="punctuation definition tag end html">&gt;</span></span>
<span class="aws-code-block-marker"></span><span class="meta tag block any html"><span class="punctuation definition tag begin html">&lt;</span><span class="entity name tag block any html">div</span> <span class="meta attribute-with-value id html"><span class="entity other attribute-name id html">id</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value id html"><span class="string quoted double html"><span class="punctuation definition string begin html">&quot;</span></span></span><span class="meta attribute-with-value id html"><span class="string quoted double html"><span class="meta toc-list id html">afterDelete</span><span class="punctuation definition string end html">&quot;</span></span></span><span class="punctuation definition tag end html">&gt;</span></span>--<span class="meta tag block any html"><span class="punctuation definition tag begin html">&lt;/</span><span class="entity name tag block any html">div</span><span class="punctuation definition tag end html">&gt;</span></span></span></code></pre>

<h4 class="show-html-heading">Output</h4>

<div class="faded-reverse-border default-padding default-border-radius">
  <div id="afterPut">--</div>
<div id="afterDelete">--</div>
</div>

</section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Bulk Storage</h2>


<p>That's a "non-trivial amount of code". It's also async/await based which adds to the complexity of using it. It would be nice if it was easier to work with, but the flexibility makes the complexity worth it.</p>


<p>-a</p></section>


</div>
  <div class="end-block">
          <section class="endnotes-section default-flow xxlarge-bottom-margin">
            <h3 class="back-matter">Endnotes</h3>
            <div class="xxlarge-flow">
          
        


<section class="endnote-section default-flow">
  


<p>Using localStorage to do the same thing looks like this:</p>


<section class="code-section default-flow"><pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="variable other object js">localStorage</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">setItem</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>bravo<span class="punctuation definition string end js">&quot;</span></span><span class="punctuation separator comma js">,</span> <span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>this is bravo<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other readwrite js">afterSet</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">localStorage</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">getItem</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>bravo<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other readwrite js">afterSetEl</span> <span class="keyword operator assignment js">=</span> <span class="support type object dom js">document</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">querySelector</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>#afterSet<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="variable other object js">afterSetEl</span><span class="punctuation accessor js">.</span><span class="meta property object js">innerHTML</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">afterSet</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="variable other object js">localStorage</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">removeItem</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>bravo<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other readwrite js">afterRemove</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">localStorage</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">getItem</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>bravo<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="storage type js">const</span> <span class="variable other readwrite js">afterRemoveEl</span> <span class="keyword operator assignment js">=</span> <span class="support type object dom js">document</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">querySelector</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string quoted double js"><span class="punctuation definition string begin js">&quot;</span>#afterRemove<span class="punctuation definition string end js">&quot;</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="variable other object js">afterRemoveEl</span><span class="punctuation accessor js">.</span><span class="meta property object js">innerHTML</span> <span class="keyword operator assignment js">=</span> <span class="variable other readwrite js">afterRemove</span><span class="punctuation terminator statement js">;</span></span></code></pre></section>


<section class="p-section default-flow">


<p>Less than ten lines compared to more than sixty with no async to worry about is nice. It just falls over when trying to store large amounts of data since browsers have much lower limits on localStorage vs IndexedDB.</p></section>
</section>





<section class="endnote-section default-flow">
  


<p>Normally, you'd check the return values in both the IndexedDB and localStorage approaches before trying to use them. I've skipped both here to reduce the code.</p>
</section>


<section class="endnote-section default-flow">
  


<p>I'm using <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="variable other object js">store</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">put</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">value</span><span class="punctuation separator comma js">,</span> <span class="variable other readwrite js">key</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span></code> to add the values to the database. This is an <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">upsert</span></code> style change that updates the value if it exists and adds it if it doesn't. <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="variable other object js">store</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="support function dom js">add</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">value</span><span class="punctuation separator comma js">,</span> <span class="variable other readwrite js">key</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span></code> can be used to do an add without the update functionality.</p>
</section>


<section class="endnote-section default-flow">
  


<p>The AI search results have the same problem with only showing how to log data instead of using it. When prompted for how to actually use the data they point to external libraries. <a href="https://dexie.org/" >Dexie</a>, in particular. It looks great. It does tons of stuff including auth. Overkill for what I'm doing right now so I'm avoiding the dependency. It's on the radar though.</p>
</section>
            </div>
          </section>
    
        <section class="references-section flow">
            <h3 class="back-matter large-bottom-padding">References</h3>
            <div class="default-flow">
        
        


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://www.youtube.com/watch?v=J8fr-xc3bis">IndexedDB: What Makes It Better Than LocalStorage and Cookies? - YouTube</a>
    </div>
    <div class="default-flow">
      


<p>This is the video where I got the approach. It uses React and TypeScript. My version is vanilla JS.</p>
    </div>
</section>


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">IndexedDB API - MDN</a>
    </div>
    <div class="default-flow">
      
    </div>
</section>


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Terminology">IndexedDB key characteristics and basic terminology - MDN</a>
    </div>
    <div class="default-flow">
      
    </div>
</section>


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB">Using IndexedDB - MDN</a>
    </div>
    <div class="default-flow">
      
    </div>
</section>


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/createObjectStore">IDBDatabase: createObjectStore() method - MDN</a>
    </div>
    <div class="default-flow">
      
    </div>
</section>


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise - MDN</a>
    </div>
    <div class="default-flow">
      
    </div>
</section>
      </div>
        </section>
    
        <section class="footnotes-section flow">
            <h3 class="back-matter">Footnotes</h3>
        
        


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-magic-link">
        <span id="footnote-magic-text">magic &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div><a href="https://www.al9000.com/magic-deck-builder/"><strong>My Magic Deck Builder</strong></a></div>
    <div class="default-flow">


<p>Very much a Work-In-Progress at press time. It's a lot like <a href="https://archidekt.com/" >Archidekt</a>. Just refined down only the feature I want (and a way to kick the tires for <a href="https://bittyjs.com" >bitty</a>.</p></div>
    
  </div>


</section>


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-ls-link">
        <span id="footnote-ls-text">ls &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage"><strong>localStorage</strong></a></div>
    <div class="default-flow">


<p>The traditional way to store data for a web site when you need something more than a cookie. Great for simple key/value pairs when the values are strings and you don't have too many of them. Storing objects requires jumping through <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="support class js">JSON</span><span class="punctuation accessor js">.</span><span class="meta property object js">stringify</span></span></code> and <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="support class js">JSON</span><span class="punctuation accessor js">.</span><span class="meta property object js">parse</span></span></code>. There are stricter size limits than IndexedDB as well.</p></div>
    
  </div>


</section>


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-idb-link">
        <span id="footnote-idb-text">idb &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div><a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API"><strong>The IndexedDB API</strong></a></div>
    <div class="default-flow">


<p>The new hotness in web app data storage. Just gotta jump through some more hoops.</p></div>
    
  </div>


</section>


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-results-link">
        <span id="footnote-results-text">results &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div></div>
    <div class="default-flow">


<p>Using results from IndexedDB without async/await promises moves you into the world of callbacks. I could probably remember how do do that if I tried. I'd rather not.</p></div>
    
  </div>


</section>


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-kv-link">
        <span id="footnote-kv-text">kv &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div></div>
    <div class="default-flow">


<p>The general IndexedDB tutorials show how to store objects with IDs. The requires putting the ID in the object. Great when you need it. More complicated than necessary when all you need is a key/value.</p></div>
    
  </div>


</section>
        </section>
    </div>
]]></description> 
</item><item>
<title><![CDATA[Music for Today (March 15, 2026)]]></title>
<link>https://www.alanwsmith.com/en/3b/08/4i/uv/</link>
<pubDate>Sun, 15 Mar 2026 18:40:34 -0400</pubDate>
<guid>55a67f66-dbac-5a58-a441-db0c1b6c868e</guid>
<description><![CDATA[<div class="flow body-block">


<section class="title-section default-flow">


<p>I published a big block of work last night. Stayed up super late to do it.</p>


<p>Today, I'm zoned out. In the post-deployment come down. I've mostly been poking around youtube. Lots of music in the mix.</p>


<p>A few selections from the day.</p></section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Down to the River to Pray - The Petersens</div><youtube-player 
:video="PvSMiHFAjzo"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/PvSMiHFAjzo" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Tom Waits - "Get Behind The Mule"</div><youtube-player 
:video="O_v2HChe350"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/O_v2HChe350" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Going to California - Led Zeppelin - Sierra Eagleson Cover</div><youtube-player 
:video="FEcoxUZnsMc"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/FEcoxUZnsMc" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Getting Ready to Get Down - Josh Ritter - 2017-13-05</div><youtube-player 
:video="3eyzc11gsWc"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/3eyzc11gsWc" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">San Fermin - Daedalus</div><youtube-player 
:video="MY9cuETTWC0"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/MY9cuETTWC0" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">the Mountain Goats - This Year - Jordan Lake Sessions</div><youtube-player 
:video="2Se76S0XH-I"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/2Se76S0XH-I" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Siren Song - Didn't Leave Nobody but the Baby - O Brother, Where Art Thou</div><youtube-player 
:video="jI99ScMCWMg"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/jI99ScMCWMg" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Lake Street Dive feat. Tiny Habits - "Leaving on a Jet Plane" - Live From the Road</div><youtube-player 
:video="zusFHHAhim4"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/zusFHHAhim4" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Chet Faker - Gold</div><youtube-player 
:video="hi4pzKvuEQM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/hi4pzKvuEQM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">San Fermin - Daedalus</div><youtube-player 
:video="MY9cuETTWC0"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/MY9cuETTWC0" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Sweet Child O' Mine Bluegrass Cover - Thunder and Rain</div><youtube-player 
:video="SDfBxudHWIA"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/SDfBxudHWIA" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="youtube-section default-flow"><div class="youtube-player-title">Can't Find My Way Home (Blind Faith) - Rachael Price - Live from Here with Chris Thile</div><youtube-player 
:video="1xZxxVlu7BM"></youtube-player>

<noscript>
  <iframe 
    width="560" 
    height="315" 
    src="https://www.youtube.com/embed/1xZxxVlu7BM" 
    title="YouTube video player" 
    frameborder="0" 
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
    referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</noscript>
</section>


<section class="p-section default-flow">


<p>It's gray outside. A light rain. Perfect for the chill mood.</p>


<p>-a</p></section>


</div>
  <div class="end-block"></div>
]]></description> 
</item><item>
<title><![CDATA[You can't update an input text value with keydown]]></title>
<link>https://www.alanwsmith.com/en/3a/ww/ey/gr/</link>
<pubDate>Sat, 14 Mar 2026 12:03:28 -0400</pubDate>
<guid>d12dd06a-008a-52ee-a7a8-1798ba2c9fee</guid>
<description><![CDATA[<div class="flow body-block">


<section class="title-section default-flow">


<p>It doesn't look like there's a way to update the value of an <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text html basic"><span class="meta tag inline form html"><span class="punctuation definition tag begin html">&lt;</span><span class="entity name tag inline form html">input</span><span class="punctuation definition tag end html">&gt;</span></span></span></code> field with <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">keydown</span></code> events.</p>


<p>You can, of course, just update the value directly.</p>


<p>Simulating keyboard interactions needs to be done with something like puppeteer.</p></section>


</div>
  <div class="end-block"></div>
]]></description> 
</item><item>
<title><![CDATA[Update CSS Live using contenteditable (No JavaScript Required)]]></title>
<link>https://www.alanwsmith.com/en/3a/wg/pw/xg/</link>
<pubDate>Sat, 14 Mar 2026 09:49:58 -0400</pubDate>
<guid>987005bf-1dbd-5e47-9e9d-cd8645d243af</guid>
<description><![CDATA[
  <hr />
  <div>
    <strong>Dear RSS Reader:<br />The original version of this page includes
    custom CSS to style the page. It probably won't work in here.
    <a href="https://www.alanwsmith.com/en/3a/wg/pw/xg/">Check out the 
    original page</a> to see it in action.
    </strong>
  </div><hr /><div class="flow body-block">


<section class="title-section default-flow">


<p>I was reading the <a href="https://html.spec.whatwg.org/#attr-contenteditable" > HTML Living Standard for contenteditable </a> to figure some stuff out for bitty<sup class="xsmall-font-size"><a class="footnote-shorthand-span" href="#footnote-1-text"
    id="footnote-1-link"
    >1</a></sup>. Found a fun little tidbit: You can edit CSS live on a page without JavaScript.</p>


<p>Check this out:</p></section>


<section class="html-section default-flow show-html"><h4 class="show-html-heading">HTML</h4><pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="text html basic"><span class="meta tag block any html"><span class="punctuation definition tag begin html">&lt;</span><span class="entity name tag block any html">div</span> <span class="meta attribute-with-value class html"><span class="entity other attribute-name class html">class</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value class html"><span class="string quoted double html"><span class="punctuation definition string begin html">&quot;</span></span></span><span class="meta attribute-with-value class html"><span class="string quoted double html"><span class="meta class-name html">example</span><span class="punctuation definition string end html">&quot;</span></span></span><span class="punctuation definition tag end html">&gt;</span></span>the quick brown fox<span class="meta tag block any html"><span class="punctuation definition tag begin html">&lt;/</span><span class="entity name tag block any html">div</span><span class="punctuation definition tag end html">&gt;</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta tag style begin html"><span class="punctuation definition tag begin html">&lt;</span><span class="entity name tag style html">style</span></span><span class="meta tag style begin html"> <span class="meta attribute-with-value class html"><span class="entity other attribute-name class html">class</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value class html"><span class="string quoted double html"><span class="punctuation definition string begin html">&quot;</span></span></span><span class="meta attribute-with-value class html"><span class="string quoted double html"><span class="meta class-name html">style-editor</span><span class="punctuation definition string end html">&quot;</span></span></span> <span class="meta attribute-with-value html"><span class="entity other attribute-name html">contenteditable</span><span class="punctuation separator key-value html">=</span></span><span class="meta attribute-with-value html"><span class="string quoted double html"><span class="punctuation definition string begin html">&quot;</span>plaintext-only<span class="punctuation definition string end html">&quot;</span></span></span></span><span class="meta tag style begin html"><span class="punctuation definition tag end html">&gt;</span></span><span class="source css embedded html"><span class="source css"><span class="comment block css"><span class="punctuation definition comment css">/*</span> change the color to green <span class="punctuation definition comment css">*/</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta selector css"><span class="entity other attribute-name class css"><span class="punctuation definition entity css">.</span>example</span> </span><span class="meta property-list css"><span class="punctuation section property-list css">{</span>
<span class="aws-code-block-marker"></span>  <span class="meta property-name css"><span class="support type property-name css">color</span></span><span class="punctuation separator key-value css">:</span><span class="meta property-value css"> </span><span class="meta property-value css"><span class="support constant color w3c-extended-color-keywords css">crimson</span></span><span class="punctuation terminator rule css">;</span>
<span class="aws-code-block-marker"></span></span><span class="punctuation section property-list css">}</span>
<span class="aws-code-block-marker"></span></span></span><span class="meta tag style end html"><span class="punctuation definition tag begin html">&lt;/</span><span class="entity name tag style html">style</span><span class="punctuation definition tag end html">&gt;</span></span></span></code></pre>

<h4 class="show-html-heading">Output</h4>

<div class="faded-reverse-border default-padding default-border-radius">
  <div class="example">the quick brown fox</div>

<style class="style-editor" contenteditable="plaintext-only">/* change the color to green */

.example {
  color: crimson;
}
</style>
</div>

</section>


<section class="p-section default-flow">


<p>The contenteditable attribute does most of the work. The only other thing you need is to make the contents of the style tag visible by applying a <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source css"><span class="meta selector css">display: block</span></span></code> to it with something like:</p></section>


<section class="css-section flow show-css"><h4 class="show-css-heading">CSS</h4><pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source css"><span class="meta selector css"><span class="entity other attribute-name class css"><span class="punctuation definition entity css">.</span>style-editor</span> </span><span class="meta property-list css"><span class="punctuation section property-list css">{</span> 
<span class="aws-code-block-marker"></span>  <span class="meta property-name css"><span class="support type property-name css">border</span></span><span class="punctuation separator key-value css">:</span><span class="meta property-value css"> </span><span class="meta property-value css"><span class="meta function-call css"><span class="support function var css">var</span><span class="meta group css"><span class="punctuation definition group begin css">(</span><span class="support type custom-property css"><span class="punctuation definition custom-property css">--</span><span class="support type custom-property name css">default-border</span></span></span><span class="meta group css"><span class="punctuation definition group end css">)</span></span></span></span><span class="punctuation terminator rule css">;</span>
<span class="aws-code-block-marker"></span>  <span class="meta property-name css"><span class="support type property-name css">display</span></span><span class="punctuation separator key-value css">:</span><span class="meta property-value css"> </span><span class="meta property-value css"><span class="support constant property-value css">block</span></span><span class="punctuation terminator rule css">;</span> 
<span class="aws-code-block-marker"></span>  <span class="meta property-name css"><span class="support type property-name css">margin</span>-block</span><span class="punctuation separator key-value css">:</span><span class="meta property-value css"> </span><span class="meta property-value css"><span class="constant numeric css">1<span class="keyword other unit css">rem</span></span></span><span class="punctuation terminator rule css">;</span>
<span class="aws-code-block-marker"></span>  <span class="meta property-name css"><span class="support type property-name css">padding</span></span><span class="punctuation separator key-value css">:</span><span class="meta property-value css"> </span><span class="meta property-value css"><span class="constant numeric css">0.7<span class="keyword other unit css">rem</span></span></span><span class="punctuation terminator rule css">;</span>
<span class="aws-code-block-marker"></span>  <span class="meta property-name css"><span class="support type property-name css">white-space</span></span><span class="punctuation separator key-value css">:</span><span class="meta property-value css"> </span><span class="meta property-value css"><span class="support constant property-value css">pre</span></span><span class="punctuation terminator rule css">;</span>
<span class="aws-code-block-marker"></span></span><span class="punctuation section property-list css">}</span></span></code></pre>
</section>


<section class="p-section default-flow">


<p>First thing that comes to mind to do with it is to set up a process on the backend that you can submit it to. It would update your actual stylesheet with it. Basically, live, on-page editing with immediate deployment.</p>


<p>A nice little reduction in friction.</p>


<p>-a</p></section>


</div>
  <div class="end-block">
          <section class="endnotes-section default-flow xxlarge-bottom-margin">
            <h3 class="back-matter">Endnotes</h3>
            <div class="xxlarge-flow">
          
        


<section class="endnote-section default-flow">
  


<p>Editing your global styles would be nice. Even better would be creating a supplemental stylesheet for each page. You could apply whatever tweaks you want directly on the page then just have them go live.</p>


<p>(Of course, it wouldn't have to be an external stylesheet. You could just have your CMS embed the custom styles directly on the page.)</p>
</section>


<section class="endnote-section default-flow">
  


<p>Probably less practical, but you could write a browser extension that opens any pages CSS in a little window to change things live that way too. What would be more interesting is to see if you can select/click on something and get its styles in an editable box on the page.</p>


<p>It would save you from having to open the console to kill the thing where sites disable the ability to paste a password.</p>
</section>


<section class="endnote-section default-flow">
  


<p>You might be able to add syntax highlighting too. I'm not set up to test that at the moment.</p>
</section>
            </div>
          </section>
    
        <section class="footnotes-section flow">
            <h3 class="back-matter">Footnotes</h3>
        
        


<section class="footnote-section small-font-size">
  <div><sup>
      <a href="#footnote-1-link">
        <span id="footnote-1-text">1 &#x2934;
        </span>
      </a>
      </sup></div>
  <div>
    
    <div><a href="https://bittyjs.com/"><strong>bitty - a little front-end framework for the web</strong></a></div>
    <div class="default-flow"></div>
    
  </div>


</section>
        </section>
    </div>
]]></description> 
</item><item>
<title><![CDATA[Restart fseventsd on a mac]]></title>
<link>https://www.alanwsmith.com/en/3a/ut/av/na/</link>
<pubDate>Fri, 13 Mar 2026 22:12:29 -0400</pubDate>
<guid>716a3d7e-ced9-51e9-ba40-d81b173a0f96</guid>
<description><![CDATA[<div class="flow body-block">


<section class="title-section default-flow">


<p>if fseventsd is taking 100% or more of a CPU you can restart it by quitting it in Activity Monitor (after which it restarts automatically).</p></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
Open Activity Monitor</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">fseventsd</span></code> will probably be visible if it's having an issue. You can also search for it, if it's not for some reason.</li>


<li class="default-flow">
Double click it.</li>


<li class="default-flow">
Click <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">Quit</span></code> in the pop-up window.</li></ul>
</section>


<section class="p-section default-flow">


<p>It's usually not an issue, but when my machine has been up for a couple weeks and I've been using multiple file watchers a bunch it can freak out.</p>


<p>Quitting it and letting it restart itself clears things up.</p>


<p>-a</p></section>


</div>
  <div class="end-block"></div>
]]></description> 
</item><item>
<title><![CDATA[Guidelines for Building a Static Site Generator (2026 Edition)]]></title>
<link>https://www.alanwsmith.com/en/3a/rr/9g/jz/</link>
<pubDate>Thu, 12 Mar 2026 16:49:12 -0400</pubDate>
<guid>1bde7104-4715-51c6-b776-ef9b5bfda948</guid>
<description><![CDATA[<div class="flow body-block">


<section class="title-section default-flow"></section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>The Next Generation</h2>


<p>I've built several static site generators for personal use. Early ones were to support <a href="https://neopolitan.alanwsmith.com/" >neopolitan</a>. Later ones were to make it easier to build sites in general.</p>


<p>Now, I'm looking to move my site from <a href="https://www.alanwsmith.com/" >alanwsmith.com</a> to <a href="https://al9000.com/" >al9000.com</a>. Part of the reason I want to make the move is to pull <a href="https://links.alanwsmith.com" >all my sub-domains</a> back under the main site. It'll make things a lot easier to link back and forth and to update with global templates.</p>


<p>I also want to expand the site by adding in my Rust Grimoire. I've got tons of rust notes on the site already, but the grimoire isn't included. Examples in it span multiple files that my current site generator isn't set up to accommodate.</p></section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>TODOish</h2>


<p>The new generator is just for me. No need to worry about it making sense for other folks. So, I'll mostly be building things as need arises. That said, there are some basics that I want to make sure I've thought through before kicking off. Here's the list (which I'll add to whenever I think of something).</p></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
Split out the neopolitan parser so that it's its own thing that can be included in other projects.</li>


<li class="default-flow">
Use MiniJinja as the template engine (it's Jinja, but in rust).</li>


<li class="default-flow">
Every page on the site gets loaded as a template that can be included by any other page.</li>


<li class="default-flow">
Template names are the full path to the file (as opposed to one of my current site builders where the leading <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/</span></code> isn't there in the template names)</li>


<li class="default-flow">


<p>Syntax highlighting of blocks. (Return values won't include and pre tags, just the spans to put into a pre tag).</p>


<p>Ideally this can be <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! highlight_block(&quot;html&quot;) !][! endhighlight_block !]</span></code></p>


<p>But I think i may have to be <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! filter highlight_block(&quot;html&quot;) !][! endfilter !]</span></code></p>


<p>TODO: look to see if there's a way to use the built in <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! block KEY !][! endblock !]</span></code> tokens and pass them extra options for the highlighting.</p></li>


<li class="default-flow">


<p>Syntax highlighting of spans.</p>


<p><code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! filter highlight_span(&quot;html&quot;) !][! endfilter !]</span></code></p>


<p>As well as this, maybe:</p>


<p><code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[@ hlspan(&quot;html&quot;, &quot;the string to highlight&quot;) @]</span></code></p></li>


<li class="default-flow">
I was originally thinking about adding a way to highlight a file directly (e.g. <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! highlight_file(&quot;key&quot;) !]</span></code>), but that causes issues if the files being highlighted have minijinja tokens in them (i.e. they won't be parsed and the tokens will show up instead of the output they should produce).</li>


<li class="default-flow">
Funciton to pull specific lines from a file with syntax highlighting applied (i.e. the syntax highlighting happens on the entire file and then the lines are pulled)</li>


<li class="default-flow">
Cache syntax highlighting since it can take some time.</li>


<li class="default-flow">
Use tracing library to be able to meausre performance when necessary.</li>


<li class="default-flow">
Shorthand for <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! filter some_filter !][! endfilter !]</span></code> that is <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! f some_filter !][! endf !]</span></code>.</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! md !][! endmd !]</span></code> filter for markdown.</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! neo !][! endneo !]</span></code> for neopolitan.</li>


<li class="default-flow">
Good error messages for where things went wrong in template processing or neopolitan parsing.</li>


<li class="default-flow">
Update the most recently changed file first and send refresh to browser when its updated. (this will get tricky if the file being updated is an include. so this will only happen later if the base performance isn't good enough)</li>


<li class="default-flow">
Auto populate `/last-update/index.html` with whatever the most recent .html file to have changed is.</li>


<li class="default-flow">
Any valid JSON files is available from a <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[@ j @]</span></code> variable (e.g. <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/some/data.json</span></code> is available at <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[@ j.some.data.KEYS @]</span></code></li>


<li class="default-flow">
The top level <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/config.json</span></code> file is available at <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[@ c.KEYS @]</span></code>.</li>


<li class="default-flow">
Was originally thinking about having hooks that can run scripts before and after processing. But, the first approach will be to either run stuff manually or build the feature into the engine itself (e.g. A feature that grabs JSONs from external URls and drops then in place prior to running the build. That should cover most of what's necessary.)</li>


<li class="default-flow">
Provide JS minifier</li>


<li class="default-flow">
Provide CSS minifier</li>


<li class="default-flow">
Auto genreate RSS feeds. One for all posts. One each for different tags.</li>


<li class="default-flow">
Auto generate pages for each tag (with pagination)</li>


<li class="default-flow">
Auto generate index link pages for posts (with pagination)</li>


<li class="default-flow">
Provide details on the time it takes to render each page.</li>


<li class="default-flow">
files and directories that have `.inc` in their names are avaialbe as includes but don't get output to the site themselves (e.g. the <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">wrappers.inc</span></code> directory will hold all the wrapper templates that everything uses but doesn't go out to the site).</li>


<li class="default-flow">
If you put a JSON file next to a file with the same filename stem it becomes avialble via a `data` variable in during processing.</li>


<li class="default-flow">
Arbitrary blocks of code should be able to be added to the head of the document from inside a content page. (This can be done with basic <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">block</span></code> tags in minijinja)</li>


<li class="default-flow">
Put in template hooks with defaults to override parts of the main template.</li>


<li class="default-flow">
Create a block for including bitty templates so they can be added to the end of the page or included via another file (This is really just an implementation detail for the wrapper templates).</li></ul>
</section>





<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Neopolitan</h2></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
Need to do more thinking about how to integration Neopllitan and MiniJinja.</li>


<li class="default-flow">
I think the biggest thing will be setting up the <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">-- template</span></code> in page metadata to define the minijinja template to include from.</li>


<li class="default-flow">
There will have to be some things that build out a little differently. I think it's basically going to require a preprocessor that turns neopolitan files into base level HTML files that are ready to be processed by minijinja.</li>


<li class="default-flow">
More thinking (and, more importantly, prototyping) to figure that out.</li></ul>
</section>





<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Images</h2></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
A single image folder that can have any folder/file structure inside it.</li>


<li class="default-flow">
Image calls in content are done with just the image file name without the extension. The engine finds the right file and links it up based on the name.</li>


<li class="default-flow">
Auto generate responsive image sites.</li>


<li class="default-flow">
Auto generate responsive image tags with the available sizes.</li>


<li class="default-flow">
Output files are generated in the same places as their inputs. That is, <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/path/filename.html</span></code> does not become <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/path/filename/index.html</span></code>.</li>


<li class="default-flow">
File extension can change (e.g. "file-name.neo" becomes "file-name.html").</li></ul>
</section>





<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>File Metadata</h2>


<p>During processing every file has access to a <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">metadata</span></code> variable that holds metadata including:</p></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
File name with extension.</li>


<li class="default-flow">
File name without extension.</li>


<li class="default-flow">
The source file extension.</li>


<li class="default-flow">
The destination file extension.</li>


<li class="default-flow">
The full string path to the source file.</li>


<li class="default-flow">
The string path to the parent folder.</li>


<li class="default-flow">
An array containing strings for the path to the parent folder split on each directory level.</li>


<li class="default-flow">
A variable that points to the files directory for calling JSON in it. (e.g. <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/path/to/file.html</span></code> and <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/path/to/data.json</span></code> would have a variable called <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[@ local @]</span></code> that is an alias for `[@ json.path.to @]<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">so you can do </span></code>[@ local.data.KEY @] to get whatever is in the data.json file.</li>


<li class="default-flow">
TBD on how this works with includes. I think all paths are relative to the top level output page and not parsed at the include file level (e.g. if <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/page/index.html</span></code> includes <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/extra.inc/details.html</span></code> the file path value from a <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">metadata</span></code> call in <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/extra.inc/details.html</span></code> would show the path to <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">/page/index.html</span></code>.</li></ul>
</section>





<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Folder Metadata</h2></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
Similar to file metadata</li>


<li class="default-flow">
details tbd</li></ul>
</section>





<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Site Metadata and Functions</h2></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
A <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">folders()</span></code> function that returns an array of all the folders on the site where each entry is itself an array of the folder path split by directories.</li>


<li class="default-flow">
An <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">path_exists(PATH)</span></code> that returns true if a given path exists.</li></ul>
</section>





<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Two Pass Processing Probably Not Needed</h2>


<p>These are my original notes on setting up two pass processing. I had to do that in my existing static site builder in order for code highlighting to work when the code being highlighted pulled in other content via includes. I was using functions for that setup. I think I can wrap stuff in a different way and not have to deal with that.</p></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
Make a two pass system so that each page can be rendered and then the rendered version be included in the next pass.</li>


<li class="default-flow">


<p>Standard tokes that are processed on the first pass are:</p>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[! !]</span></code> functions</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[@ @]</span></code> output</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[# #]</span></code> comments</li></ul>
</section>


</li>


<li class="default-flow">


<p>Tokens for the second pass are:</p>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[2! !2]</span></code> functions</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[2@ @2]</span></code> output</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[2# #2]</span></code> comments</li></ul>
</section>





<p>During the first pass those tokens get changed to their standard counterparts so they get used normally in the second pass.</p>


<p>NOTE: it may more more sense to do <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[1@ @1]</span></code> etc to assist with caching. The idea being that you can watch files for changes and only update the ones with <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[1@ @1]</span></code> on the first run through and everything else could be cached and ready. (Not sure if that makes sense or not. Something to look into)</p></li>


<li class="default-flow">


<p>Escaping tokens is done with:</p>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[/! !/]</span></code> functions</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[/@ @/]</span></code> output</li>


<li class="default-flow">
<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">[/# #/]</span></code> comments</li></ul>
</section>





<p>After the second pass those tokens are converted to strings of their non-escaped versions via find/replace.</p></li></ul>
</section>





<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Miscellaneous</h2></section>


<section class="list-section default-flow"><ul class="default-flow">


<li class="default-flow">
Build in preview server with hot realoading on file changes (with appropriate throttle/debounce).</li>


<li class="default-flow">
files_in_folder(FOLDER_PATH) function that gets the file list prior to processing (i.e. it would see include files that won't otherwise be sent out to the site)</li>


<li class="default-flow">
files_in_folder_ext(FOLDER_PATH, EXTENSION) function (i.e. <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">files_in_folder_ext(&quot;/some/folder&quot;, &quot;jpg&quot;)</span></code> finds all the JPG files. EXTENSION can also be an array to find files with any number of extensions.</li>


<li class="default-flow">
folders_in_folder(FOLDER_PATH) function</li>


<li class="default-flow">
path(STRING, STRING...) function that assembles strings into safe paths.</li></ul>
</section>





<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Version 9000</h2>


<p>That's everything I can think of at the moment. That thinking included taking a look at my current generators and <a href="/en/2a/pl/ck/zd/" >this prior post</a> with earlier ideas. Some of that holds up. A lot I'm thinking about differently these days.</p>


<p>I've got <a href="https://bittyjs.com/" >bitty</a> in pretty good shape. Moving into this njavascript.on.jsew generator isn't too far away.</p>


<p>Pretty excited about the update, tbh,</p>


<p>-a</p></section>


</div>
  <div class="end-block"></div>
]]></description> 
</item><item>
<title><![CDATA[Get a Random Number with crypto.getRandomValues() in JavaScript]]></title>
<link>https://www.alanwsmith.com/en/3a/lf/yo/8a/</link>
<pubDate>Thu, 12 Mar 2026 12:14:24 -0400</pubDate>
<guid>65c0d391-d150-5af2-b5e3-cc10a9569274</guid>
<description><![CDATA[<hr />
  <div>
    <strong>Dear RSS Reader:<br />The original version of this page includes
    JavaScript. It probably won't run in here. So, any
    functionality it might have had probably won't work.
    <a href="https://www.alanwsmith.com/en/3a/lf/yo/8a/">Check out the 
    original page</a> to see it in action.
    </strong>
  </div><hr /><div class="flow body-block">


<section class="title-section default-flow"></section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>The Road to Random</h2>


<p>I'm adding some randomizing functions to <a href="https://bittyjs.com/" >bitty</a>. I wanted to use `crypto.getRandomValues()` instead of `Math.random()`. While it's unlikely to matter, I figure using the better tool makes sense.</p>


<p>Here's the core functions:</p></section>



<section class="javascript-section default-flow"><div class="flow show-javascript">

    <h4 class="show-javascript-heading">JavaScript</h4><div class="javascript-body">
      <pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="meta function declaration js"><span class="storage type function js">function</span> <span class="entity name function js">randomInt</span><span class="punctuation section group begin js">(</span><span class="variable parameter function js">min</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">max</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">seeker</span> <span class="keyword operator assignment js">=</span> <span class="meta instance constructor js"><span class="keyword operator word new js">new</span><span class="meta function-call constructor js"> <span class="variable type js">Uint32Array</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="constant numeric js">1</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="variable other object js">crypto</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">getRandomValues</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">seeker</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">base</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">seeker</span><span class="meta brackets js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">modder</span> <span class="keyword operator assignment js">=</span> <span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">abs</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">max</span> <span class="keyword operator arithmetic js">-</span> <span class="variable other readwrite js">min</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span> <span class="keyword operator arithmetic js">+</span> <span class="constant numeric js">1</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">let</span> <span class="variable other readwrite js">result</span> <span class="keyword operator assignment js">=</span> <span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">base</span> <span class="keyword operator arithmetic js">%</span> <span class="variable other readwrite js">modder</span><span class="punctuation section group js">)</span></span> <span class="keyword operator arithmetic js">+</span> <span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">min</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">min</span><span class="punctuation separator comma js">,</span> <span class="variable other readwrite js">max</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="keyword control flow js">return</span> <span class="variable other readwrite js">result</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span></span></code></pre>
    </div>
  </div>
</section>



<section class="javascript-section default-flow"><div class="flow show-javascript">

    <h4 class="show-javascript-heading">JavaScript</h4><div class="javascript-body">
      <pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="meta function declaration js"><span class="storage type function js">function</span> <span class="entity name function js">randomFloat</span><span class="punctuation section group begin js">(</span><span class="variable parameter function js">min</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">max</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">seeker</span> <span class="keyword operator assignment js">=</span> <span class="meta instance constructor js"><span class="keyword operator word new js">new</span><span class="meta function-call constructor js"> <span class="variable type js">Uint32Array</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="constant numeric js">1</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="variable other object js">crypto</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">getRandomValues</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">seeker</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">base</span> <span class="keyword operator assignment js">=</span> <span class="variable other object js">seeker</span><span class="meta brackets js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span> <span class="keyword operator arithmetic js">/</span> <span class="meta group js"><span class="punctuation section group js">(</span><span class="constant numeric js">0xFFFFFFFF</span> <span class="keyword operator arithmetic js">+</span> <span class="constant numeric js">1</span><span class="punctuation section group js">)</span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">distance</span> <span class="keyword operator assignment js">=</span> <span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">abs</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">max</span> <span class="keyword operator arithmetic js">-</span> <span class="variable other readwrite js">min</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">let</span> <span class="variable other readwrite js">result</span> <span class="keyword operator assignment js">=</span> <span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">base</span> <span class="keyword operator arithmetic js">*</span> <span class="variable other readwrite js">distance</span><span class="punctuation section group js">)</span></span> <span class="keyword operator arithmetic js">+</span> <span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">min</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">min</span><span class="punctuation separator comma js">,</span> <span class="variable other readwrite js">max</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="keyword control flow js">return</span> <span class="variable other readwrite js">result</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span></span></code></pre>
    </div>
  </div>
</section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Snake Eyes</h2>


<p>You pass the functions your minimum and maximum values. They spit out a random value. The numbers are inclusive. To simulate rolling a six sided die, you'd do this:</p></section>


<section class="code-section no-numbers no-buttons default-flow"><pre class="code-block no-numbers no-buttons"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="storage type js">const</span> <span class="variable other readwrite js">roll</span> <span class="keyword operator assignment js">=</span> <span class="meta function-call js"><span class="variable function js">randomInt</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">6</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span></span></code></pre></section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Negative Space</h2>


<p>I don't generally need random negative numbers. That's no reason to avoid them. The functions handles them just fine:</p></section>


<section class="code-section no-numbers no-buttons default-flow"><pre class="code-block no-numbers no-buttons"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="meta function-call js"><span class="variable function js">randomInt</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span></span></code></pre></section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>Min/Max</h2>


<p>The <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">min</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">min</span><span class="punctuation separator comma js">,</span> <span class="variable other readwrite js">max</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span></code> part of the `result` lines is a nice-to-have. It allows you to flip the inputs without breaking the function. I find that useful for negative numbers. Both of these operate on within the same range:</p></section>


<section class="code-section no-numbers no-buttons default-flow"><pre class="code-block no-numbers no-buttons"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="meta function-call js"><span class="variable function js">randomInt</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">6</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="meta function-call js"><span class="variable function js">randomInt</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">6</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">1</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span></span></code></pre></section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>How's That Now?</h2>


<p>The <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="variable other object js">crypto</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">getRandomValues</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">seeker</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span></code> function requires a different approach than <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">random</span><span class="meta group js"><span class="punctuation section group js">(</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span></code>. It works by filling an array with random numbers instead of providing a single random output like the <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">Math</span></code> function.</p>


<p>The approach here makes an array with only one item and populates it with the random number. Then, it uses the remainder operator (<code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">%</span></code>) to get a value in the min/max distance. Finally, the min value is added back in to shift it into the right place.</p>


<p>The float version works by using bytes. It divides the incoming number by <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">0xFFFFFFFF + 1</span></code>. That places the result between 0 and 1. We multiply that by the distance between the min and max numbers using the same approach generally used with <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">Math.random()</span></code>.</p></section>


<section 
   class="h2-section default-flow xxlarge-top-margin"
>

  <h2>More Code is Better (in this case)</h2>


<p>The <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">crypto</span></code> functions are notably longer than their <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="source js"><span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">random</span><span class="meta group js"><span class="punctuation section group js">(</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span></span></code> counterparts. Take this standard integer approach, for example:</p></section>


<section class="code-section no-buttons no-numbers default-flow"><pre class="code-block no-buttons no-numbers"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="meta function declaration js"><span class="storage type function js">function</span> <span class="entity name function js">randomIntViaMathRandom</span><span class="punctuation section group begin js">(</span><span class="variable parameter function js">min</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">max</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="keyword control flow js">return</span> <span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">floor</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">random</span><span class="meta group js"><span class="punctuation section group js">(</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span> <span class="keyword operator arithmetic js">*</span> <span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">max</span> <span class="keyword operator arithmetic js">-</span> <span class="variable other readwrite js">min</span> <span class="keyword operator arithmetic js">+</span> <span class="constant numeric js">1</span><span class="punctuation section group js">)</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span> <span class="keyword operator arithmetic js">+</span> <span class="variable other readwrite js">min</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span></span></code></pre></section>


<section class="p-section default-flow">


<p>That doesn't matter. The entire point of baking things into functions is to encapsulate the complexity.</p>


<p>-a</p></section>


</div>
  <div class="end-block">
          <section class="endnotes-section default-flow xxlarge-bottom-margin">
            <h3 class="back-matter">Endnotes</h3>
            <div class="xxlarge-flow">
          
        


<section class="endnote-section default-flow">
  


<p>Here's the code I used to make sure swaping the min and max worked properly:</p>


<section class="details-section default-flow">
  <details class="default-flow"><summary>test code</summary>



<section class="javascript-section default-flow"><div class="flow show-javascript">

    <h4 class="show-javascript-heading">JavaScript</h4><div class="javascript-body">
      <pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="meta function declaration js"><span class="storage type function js">function</span> <span class="entity name function js">randomIntMathCheck</span><span class="punctuation section group begin js">(</span><span class="variable parameter function js">min</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">max</span><span class="punctuation separator parameter function js">,</span> <span class="variable parameter function js">base</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">modder</span> <span class="keyword operator assignment js">=</span> <span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">abs</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">max</span> <span class="keyword operator arithmetic js">-</span> <span class="variable other readwrite js">min</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span> <span class="keyword operator arithmetic js">+</span> <span class="constant numeric js">1</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">let</span> <span class="variable other readwrite js">result</span> <span class="keyword operator assignment js">=</span> <span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">base</span> <span class="keyword operator arithmetic js">%</span> <span class="variable other readwrite js">modder</span><span class="punctuation section group js">)</span></span> <span class="keyword operator arithmetic js">+</span> <span class="support class builtin js">Math</span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">min</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">min</span><span class="punctuation separator comma js">,</span> <span class="variable other readwrite js">max</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="keyword control flow js">return</span> <span class="variable other readwrite js">result</span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta function declaration js"><span class="storage type function js">function</span> <span class="entity name function js">runTest</span><span class="punctuation section group begin js">(</span><span class="variable parameter function js">values</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="storage type js">const</span> <span class="variable other readwrite js">result</span> <span class="keyword operator assignment js">=</span> <span class="meta function-call js"><span class="variable function js">randomIntMathCheck</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other object js">values</span><span class="meta brackets js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span> <span class="variable other object js">values</span><span class="meta brackets js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span> <span class="variable other object js">values</span><span class="meta brackets js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="meta conditional js"><span class="keyword control conditional js">if</span> <span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">result</span> <span class="keyword operator comparison js">===</span> <span class="variable other object js">values</span><span class="meta brackets js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">3</span><span class="punctuation section brackets js">]</span></span><span class="punctuation section group js">)</span></span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>    <span class="meta function-call method js"><span class="support type object console js">console</span><span class="punctuation accessor js">.</span><span class="support function console js">log</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string template js"><span class="punctuation definition string template begin js">`</span>PASS: </span><span class="meta template expression js"><span class="punctuation definition template-expression begin js">${</span></span><span class="meta template expression js"><span class="source js embedded expression"><span class="variable other readwrite js">values</span></span><span class="punctuation definition template-expression end js">}</span></span><span class="string template js"><span class="punctuation definition string template end js">`</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  </span><span class="meta block js"><span class="punctuation section block js">}</span></span></span> <span class="meta conditional js"><span class="keyword control conditional js">else</span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>    <span class="meta function-call method js"><span class="support type object console js">console</span><span class="punctuation accessor js">.</span><span class="support function console js">error</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="string template js"><span class="punctuation definition string template begin js">`</span>FAIL: Got </span><span class="meta template expression js"><span class="punctuation definition template-expression begin js">${</span></span><span class="meta template expression js"><span class="source js embedded expression"><span class="variable other readwrite js">result</span></span><span class="punctuation definition template-expression end js">}</span></span><span class="string template js"> instead of </span><span class="meta template expression js"><span class="punctuation definition template-expression begin js">${</span></span><span class="meta template expression js"><span class="source js embedded expression"><span class="variable other object js">values</span><span class="meta brackets js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">3</span><span class="punctuation section brackets js">]</span></span></span><span class="punctuation definition template-expression end js">}</span></span><span class="string template js"> for </span><span class="meta template expression js"><span class="punctuation definition template-expression begin js">${</span></span><span class="meta template expression js"><span class="source js embedded expression"><span class="variable other readwrite js">values</span></span><span class="punctuation definition template-expression end js">}</span></span><span class="string template js"><span class="punctuation definition string template end js">`</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  </span><span class="meta block js"><span class="punctuation section block js">}</span></span></span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span></span></code></pre>
    </div>
  </div>
</section>



<section class="javascript-section default-flow"><div class="flow show-javascript">

    <h4 class="show-javascript-heading">JavaScript</h4><div class="javascript-body">
      <pre class="code-block"><code><span class="aws-code-block-marker"></span><span class="source js"><span class="meta function declaration js"><span class="storage type function js">function</span> <span class="entity name function js">runTests</span><span class="punctuation section group begin js">(</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span></span><span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>  <span class="meta sequence js"><span class="punctuation section brackets js">[</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">5</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">6</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">7</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">8</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">9</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">10</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">5</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">6</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">7</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">8</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">5</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">6</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">7</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">8</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">5</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">6</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">7</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">8</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">9</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">10</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">3</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">4</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">5</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">6</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">7</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">0</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">8</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">1</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">9</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>    <span class="meta sequence js"><span class="punctuation section brackets js">[</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation separator comma js">,</span> <span class="constant numeric js">10</span><span class="punctuation separator comma js">,</span> <span class="keyword operator arithmetic js">-</span><span class="constant numeric js">2</span><span class="punctuation section brackets js">]</span></span><span class="punctuation separator comma js">,</span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span>  <span class="punctuation section brackets js">]</span></span><span class="punctuation accessor js">.</span><span class="meta function-call method js"><span class="variable function js">forEach</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="meta function declaration js"><span class="punctuation section group begin js">(</span><span class="variable parameter function js">test</span><span class="punctuation section group end js">)</span><span class="meta function declaration js"> </span><span class="storage type function arrow js">=&gt;</span></span> <span class="meta block js"><span class="punctuation section block js">{</span>
<span class="aws-code-block-marker"></span>    <span class="meta function-call js"><span class="variable function js">runTest</span><span class="meta group js"><span class="punctuation section group js">(</span><span class="variable other readwrite js">test</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span>  <span class="punctuation section block js">}</span></span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span>
<span class="aws-code-block-marker"></span><span class="punctuation section block js">}</span></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span>
<span class="aws-code-block-marker"></span><span class="meta function-call js"><span class="variable function js">runTests</span><span class="meta group js"><span class="punctuation section group js">(</span></span><span class="meta group js"><span class="punctuation section group js">)</span></span></span><span class="punctuation terminator statement js">;</span></span></code></pre>
    </div>
  </div>
</section></details>
</section>



</section>



            </div>
          </section>
    
        <section class="references-section flow">
            <h3 class="back-matter large-bottom-padding">References</h3>
            <div class="default-flow">
        
        


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues">JavaScript Crypto: getRandomValues()</a>
    </div>
    <div class="default-flow">
      
    </div>
</section>


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">JavaScript Math.random()</a>
    </div>
    <div class="default-flow">
      
    </div>
</section>


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array">JavaScript Unit32Array</a>
    </div>
    <div class="default-flow">
      
    </div>
</section>


<section class="ref-section faded-reverse-left-border default-left-padding">
    <div>
      <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder">JavaScript Remainder (%)</a>
    </div>
    <div class="default-flow">
      


<p>Some languages use <code class="code-span color-alt-1-80" class="code-shorthand-span"><span class="text plain">%</span></code> as a modulo operator. It's similar, but not quite the same as the remainder. Check the link for details.</p>
    </div>
</section>
      </div>
        </section>
    </div>
]]></description> 
</item></channel>
</rss>