<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss"
        xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
        xmlns:media="http://search.yahoo.com/mrss/"><channel>
<title>Mavnn's blog</title>
<atom:link href="https://blog.mavnn.eu/rss.xml" rel="self" type="application/rss+xml" />
<link>https://blog.mavnn.eu/</link>
<description><![CDATA[]]></description>
<language>en</language>
<pubDate>Fri, 13 Mar 2026 14:18:58 +0100</pubDate>
<lastBuildDate>Fri, 13 Mar 2026 14:18:58 +0100</lastBuildDate>
<generator>Emacs 30.1 Org-mode 9.8-pre</generator>
<webMaster>michael@mavnn.eu (Michael Newton)</webMaster>
<image>
<url>http://blog.mavnn.eu/images/swirl.svg</url>
<title>Mavnn's blog</title>
<link>https://blog.mavnn.eu/</link>
</image>

<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#ID-B56E2E4A-F2C9-4A7E-8D1B-EBB49E5E8C1F">1. VisualInk Tutorial Videos</a></li>
<li><a href="#ID-515B83EB-713E-4435-8537-705A730C3D15">2. Stacks in Ink: Deep dive edition</a>
<ul>
<li><a href="#ID-EAFF133A-3744-49AD-9AD0-F17D1FD14B54">2.1. The basics</a></li>
</ul>
</li>
<li><a href="#ID-F481A812-BAD8-47C3-A0E7-262E298ED5B5">3. Stacks in Ink</a></li>
<li><a href="#ID-7E453C3D-2A65-424C-8959-758D1DCB3ACC">4. Publishing with VisualInk</a></li>
<li><a href="#ID-26BB433F-E0DF-4CF5-88D4-1D8C3A6C0046">5. Coding games with a story</a></li>
<li><a href="#ID-61DE1B32-DB3F-4701-BE71-63A56E727026">6. Stun lock procrastination</a></li>
<li><a href="#ID-0C23E268-F37F-4C6C-8E38-F04C03486EED">7. Conflict free syncthing notes</a></li>
<li><a href="#ID-897A1F78-39B6-4704-AF2F-2A774F9B1F72">8. A gentle introduction to Effect TS</a></li>
<li><a href="#ID-16B63501-8C0C-4F3A-82FA-5EE453BBBBC7">9. Types et al as accessibility tools for the ADHD brain</a></li>
<li><a href="#ID-C5304514-2083-4AC1-8D8E-8C3C9847EACC">10. With style: Dev Journal 6</a></li>
<li><a href="#ID-B941379A-C4F4-4F4A-A91A-E36FEC62483B">11. Internal quality review: Dev Journal 5</a></li>
<li><a href="#ID-9446CB6A-562A-4AE4-B1B2-BE4FCC6864C5">12. Log in, log out: Dev Journal 4 (part 2)</a></li>
<li><a href="#ID-1565AEF9-2C11-4E6F-823D-A0AC6F5C264B">13. Log in, log out: Dev Journal 4 (part 1)</a></li>
<li><a href="#ID-1AE3A2A8-3195-475C-A52B-4D3112AB0395">14. ADHD and TDD</a></li>
<li><a href="#ID-117F4C69-5241-45C3-A2B0-24D22F5F47F7">15. Does it run? Dev Journal 3</a></li>
<li><a href="#ID-CDFD82E0-56A0-4033-AFBE-0929A09F9BA7">16. Do notation for TypeScript</a></li>
<li><a href="#ID-F998AFD4-A5F4-4A54-A0DD-F24DC7B56D66">17. Scaffolding: Dev Journal 2</a></li>
<li><a href="#ID-BEC296E9-14FB-4C4B-9F41-B15462323B56">18. Foundations: Dev Journal 1</a></li>
<li><a href="#ID-13C93632-F856-4CE5-A937-12C264E40684">19. Short term help</a>
<ul>
<li><a href="#ID-A8AA8023-D6F9-4E11-B81C-9B3C71480A34">19.1. Consulting</a></li>
<li><a href="#ID-B1F03D3A-062B-42FF-BD83-B781F5A890E0">19.2. Workshops and training</a></li>
<li><a href="#ID-3BD12BF2-88E3-423A-AFC7-A2F5F0C48ADA">19.3. Bespoke software creation</a></li>
<li><a href="#ID-1AC24D36-F2CC-4484-B158-758BFABCCFAB">19.4. Logistics</a></li>
</ul>
</li>
<li><a href="#ID-F7FC3366-60BA-4C64-8676-1322BA969965">20. Writing CVs for more senior roles</a></li>
<li><a href="#ID-9A5F6DB1-046A-499E-BBDE-F08E79E7DB67">21. TypeScript Enums and Serialization</a></li>
<li><a href="#ID-60B5CF3B-7B1A-4A2C-BC1E-2447BB198097">22. ADHD and me</a></li>
<li><a href="#ID-6B05BC22-A1B3-41EA-9BCA-8F5009AC8841">23. Teaching (coding) wisdom</a></li>
<li><a href="#ID-8D0788A6-4741-42C5-B4CE-0DEA3690E294">24. Why your Typescript compiles when you thought you were safe</a></li>
<li><a href="#ID-E3FA71EE-1158-410F-B346-DE14DD04D019">25. Literate CSS</a></li>
<li><a href="#ID-6D9C4068-3A6D-4671-93C6-5C276925DC95">26. New Beginnings</a></li>
</ul>
</div>
</nav>
<item>
<title>VisualInk Tutorial Videos</title>
<link>https://blog.mavnn.eu/2026/03/13/visual_ink_tutorial_videos.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2026/03/13/visual_ink_tutorial_videos.html</guid>
<pubDate>Fri, 13 Mar 2026 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
This post is a mostly here to serve as an announcement that I've started making short tutorial videos for Ink (and VisualInk). <a href="https://visualink.mavnn.eu/">VisualInk</a> is a platform for building first time visual novels that focusses heavily on the narrative at the expense of deep interface customization, designed for younger writers and fast prototypes (or younger writers creating fast prototypes...). <a href="https://www.inklestudios.com/ink/">Ink</a> is a narrative scripting language that can be used in multiple game engines, including in VisualInk.
</p>

<p>
At the moment the videos are on YouTube; they are individually short and try to stay extremely focussed on just one thing. I'm hoping to add more fairly rapidly, and would love to here feedback on the existing videos or hear ideas for future vidoes. Follow the <a href="https://bonfire.mavnn.eu/@VisualInk">VisualInk fediverse</a> account for more news or comment on the announcement of this blog post at <a href="https://bonfire.mavnn.eu/post/01KKKMNVBNR04K1SCH0J6WNP9Q#">this link</a>.
</p>

<p>
The <a href="https://www.youtube.com/playlist?list=PLEHPQ4mwkWb7CYRkySfzQyTNC4yUMEajy">VisualInk tutorial playlist</a> is officially open for business.
</p>
]]></description>
</item>
<item>
<title>Stacks in Ink: Deep dive edition</title>
<link>https://blog.mavnn.eu/2026/01/22/stacks_in_ink_2.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2026/01/22/stacks_in_ink_2.html</guid>
<pubDate>Thu, 22 Jan 2026 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
Warning! This entire blog post is about a <b>proposed</b> addition to the Ink language. It is not included in the current official builds of Ink. It may not ever become part of the language, or even if the idea does this specific implementation may not.
</p>

<p>
To try out the stacks presented here, you can run the examples at <a href="https://visualink.mavnn.eu/script/demo">VisualInk</a> which uses a version of Ink that includes the stack functionality.
</p>

<p>
To use the 'stack' data type in your own project right now, you would have to either build your own copy of Ink including the changes from <a href="https://github.com/inkle/ink/pull/969">the proposal pull request</a> and <a href="https://github.com/inkle/ink/pull/971">this bug fix</a> or you would need to trust me enough to download the <a href="https://code.mavnn.eu/mavnn/VisualInk/src/branch/main/external">pre-compiled versions</a> I'm using for the VisualInk server.
</p>
</blockquote>

<p>
Last <a href="#ID-F481A812-BAD8-47C3-A0E7-262E298ED5B5">time I was blogging</a>, I wrote about tracking 'ordered data' in Ink by using a compiler extension to generate Ink code. It works, but it doesn't have the most friendly interface in the world and it isn't great from an efficiency point of view either at runtime or in terms of the compiled Ink json output it produces.
</p>

<p>
So over the Christmas holidays, I thought that I'd see what a fully integrated data type could look like it if were to be added to the actual language design as opposed to layered on top.
</p>

<p>
Meet the new and improved stack.
</p>
<div id="outline-container-ID-EAFF133A-3744-49AD-9AD0-F17D1FD14B54" class="outline-3">
<h3 id="ID-EAFF133A-3744-49AD-9AD0-F17D1FD14B54"><span class="section-number-3">2.1.</span> The basics</h3>
<div class="outline-text-3" id="text-2-1">
<p>
Stack literals are declared by wrapping a comma separated list of values in square brackets (<code>[</code> / <code>]</code>).
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">my_stack</span> = ["hello", "stacks"]
</pre>
</div>

<p>
There's no particular restrictions on what a stack can hold, except when declaring a global variable for the first time when the normal restrictions on not referencing other variables apply.
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">my_stack</span> = ["hello", 22, false, <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">bananas</span>]

<span class="org-ink-shadow">==</span> <span class="org-ink-knot">bananas</span>
Hmmm. Bananas.
<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">END</span>
</pre>
</div>

<p>
Mixing types up like this in a stack is generally not recommended, but you be you if you want to deal with the headaches it would cause down the line <i>or</i> you know exactly what you're doing and why.
</p>

<p>
Like most data in Ink, stacks are "immutable". That means if you want to add or remove something from a stack, you create a new stack with items added or removed instead. That sounds complex, but this is already exactly how things like strings and numbers work in Ink.
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">my_number</span> = 5

Who is Number 1?
You are Number <span class="org-constant">{</span>my_number + 1<span class="org-constant">}</span>!

<span class="org-comment-delimiter">// </span><span class="org-comment">my_number is still 5, not 6</span>

<span class="org-keyword">VAR</span> <span class="org-variable-name">my_stack</span> = ["strawberries"]
You eat your <span class="org-constant">{</span>my_stack + "cream"<span class="org-constant">}</span>.

<span class="org-comment-delimiter">// </span><span class="org-comment">my_stack is still ["strawberries"]</span>
</pre>
</div>

<p>
We say two stacks are equal if they have the same number of items, and all of the items in the two stacks are equal to each other when compared in order.
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">stack</span>1 = ["one", "two"]
<span class="org-keyword">VAR</span> <span class="org-variable-name">stack</span>2 = ["one", "two"] <span class="org-comment-delimiter">// </span><span class="org-comment">equal to stack1</span>
<span class="org-keyword">VAR</span> <span class="org-variable-name">stack</span>3 = ["two", "one"] <span class="org-comment-delimiter">// </span><span class="org-comment">not equal to stack1</span>
<span class="org-keyword">VAR</span> <span class="org-variable-name">stack</span>4 = ["one"] <span class="org-comment-delimiter">// </span><span class="org-comment">not equal to stack1</span>
</pre>
</div>

<p>
And we can 'add' or 'substract' with stacks, although with a slightly different meaning to numerical addition and substraction. Addition concatinates the two stacks (i.e. sticks them together, in order).
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">stack</span>1 = ["one", "two"]
<span class="org-comment-delimiter">// </span><span class="org-comment">["one", "two", "three", "four"]</span>
<span class="org-constant">{</span>stack1 + ["three", "four"]<span class="org-constant">}</span>
</pre>
</div>

<p>
While subtraction looks for the first time each value in the subtrahend (the stack on the right) appears in the minuend and removes it <i>if it exists</i>. It is not an error to 'subtract' a value that isn't in the original stack, it just results in an unchanged stack.
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">stack</span>1 = ["three", "one", "one", "two"]
<span class="org-comment-delimiter">// </span><span class="org-comment">In order, we remove the first "one" (leaving the second) then the "three"</span>
<span class="org-comment-delimiter">// </span><span class="org-comment">["one", "two"]</span>
<span class="org-constant">{</span>stack1 - ["one", "three"]<span class="org-constant">}</span>
</pre>
</div>

<p>
For the other mathematicians in the audience: these operations are not inverses, and addition is not commutative. I apologize for the brain hurty.
</p>
</div>
<div id="outline-container-ID-64F2F813-D3A3-4AE5-B03C-0CD3910015DB" class="outline-4">
<h4 id="ID-64F2F813-D3A3-4AE5-B03C-0CD3910015DB"><span class="section-number-4">2.1.1.</span> Example</h4>
<div class="outline-text-4" id="text-2-1-1">
<p>
We've already got something quite nice here for situations where it is important for our story to know if things have been selected in the correct order. Let's say you want to have a runic magic system in your game similar to the one from <a href="https://crpgaddict.blogspot.com/2010/11/dungeon-master-runic-magic.html">Dungeon Master</a>. We can set up a list of valid, meaningful spells easily and add more as needed.
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">LIST</span> <span class="org-variable-name">runes</span> = fire, earth, water, air, me, target, explode, weal, woe

<span class="org-keyword">VAR</span> <span class="org-variable-name">fireball</span> = [woe, fire, target, explode]
<span class="org-keyword">VAR</span> <span class="org-variable-name">heal</span> = [weal, me, water]
<span class="org-keyword">VAR</span> <span class="org-variable-name">current_cast</span> = []

Time to cast a spell. <span class="org-ink-shadow">&lt;&gt;</span>

<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">select_rune_or_cast</span> <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">END</span>

<span class="org-ink-shadow">==</span> <span class="org-ink-knot">select_rune_or_cast</span>

Add a rune, or release the magic! <span class="org-constant">{</span>current_cast<span class="org-constant">}</span>

<span class="org-type">+ </span><span class="org-ink-bracket">[Fire]</span> <span class="org-constant">{</span>add_rune(fire)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[Earth]</span> <span class="org-constant">{</span>add_rune(earth)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[Water]</span> <span class="org-constant">{</span>add_rune(water)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[Air]</span> <span class="org-constant">{</span>add_rune(air)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[Internal]</span> <span class="org-constant">{</span>add_rune(me)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[External]</span> <span class="org-constant">{</span>add_rune(target)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[Explode]</span> <span class="org-constant">{</span>add_rune(explode)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[Weal]</span> <span class="org-constant">{</span>add_rune(weal)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[Woe]</span> <span class="org-constant">{</span>add_rune(woe)<span class="org-constant">}</span>
<span class="org-type">+ </span><span class="org-ink-bracket">[Cast the spell!]</span> <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">cast_spell</span> <span class="org-ink-arrow">-&gt;-&gt;</span>
<span class="org-type">-</span>

<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">select_rune_or_cast</span>

<span class="org-ink-shadow">===</span> <span class="org-ink-knot">cast_spell</span>
<span class="org-constant">{</span>
<span class="org-type">-</span> current_cast == fireball:
  Kaboom!
<span class="org-type">-</span> current_cast == heal:
  Oooh. Refreshing!
<span class="org-type">-</span> else:
  Fizz, buzz
<span class="org-constant">}</span>
<span class="org-type">~</span><span class="org-variable-name">current_cast</span> = []
<span class="org-ink-arrow">-&gt;-&gt;</span>

<span class="org-ink-shadow">===</span> <span class="org-keyword">function</span> <span class="org-ink-knot">add_rune</span><span class="org-variable-name">(r)</span> <span class="org-ink-shadow">===</span>
<span class="org-type">~</span><span class="org-variable-name">current_cast +</span>= r
</pre>
</div>
</div>
</div>
<div id="outline-container-ID-1FCAEED9-96D6-4A43-99D7-24DFE5FE4440" class="outline-4">
<h4 id="ID-1FCAEED9-96D6-4A43-99D7-24DFE5FE4440"><span class="section-number-4">2.1.2.</span> Stack functions</h4>
<div class="outline-text-4" id="text-2-1-2">
<p>
We also have several functions that allow use to work through the values in a stack. 
</p>

<p>
The simplest is <code>STACK_COUNT</code> which returns the current number of values in a stack. We then have three variations of the <code>STACK_POP</code> function; <code>STACK_POP_NEWEST</code>, <code>STACK_POP_OLDEST</code>, and <code>STACK_POP_RANDOM</code>. All three functions work in the same way: they take two parameters, which must be a stack and a variable. They will return the stack with the "popped" value removed, and they will assign the popped value to the variable. They will return a null value if the  stack doesn't contain anything.
</p>

<p>
Example:
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">stack</span>1 = ["oldest item", "middle item", "newest item"]
<span class="org-keyword">VAR</span> <span class="org-variable-name">popped</span> = ""

<span class="org-type">~</span><span class="org-function-name">STACK_POP_NEWEST</span>(stack1, popped)
<span class="org-constant">{</span>popped<span class="org-constant">}</span> <span class="org-comment-delimiter">// </span><span class="org-comment">"newest item"</span>

<span class="org-type">~</span>stack1 = <span class="org-function-name">STACK_POP_NEWEST</span>(stack1, popped)
<span class="org-constant">{</span>popped<span class="org-constant">}</span> <span class="org-comment-delimiter">// </span><span class="org-comment">still "newest item" - we didn't update stack1 last time</span>
<span class="org-constant">{</span>stack1<span class="org-constant">}</span> <span class="org-comment-delimiter">// </span><span class="org-comment">now "oldest item, middle item"</span>

<span class="org-type">~</span><span class="org-function-name">STACK_POP_OLDEST</span>(stack1, popped)
<span class="org-constant">{</span>popped<span class="org-constant">}</span> <span class="org-comment-delimiter">// </span><span class="org-comment">"oldest item"</span>

<span class="org-type">~</span>stack1 = <span class="org-function-name">STACK_POP_RANDOM</span>(stack1, popped)
<span class="org-constant">{</span>popped<span class="org-constant">}</span> <span class="org-comment-delimiter">// </span><span class="org-comment">might be "oldest item" or "middle item"</span>
<span class="org-constant">{</span>stack1<span class="org-constant">}</span> <span class="org-comment-delimiter">// </span><span class="org-comment">a stack with which ever item wasn't popped at random</span>
</pre>
</div>

<p>
We can combine the use of these functions to build knots that work their way through a stack in an order chosen by the player - either directly as below, or implicitly by the choices they made along the way.
</p>

<p>
Small technical note here: if you want to add (or subtract) diverts with a stack, you'll need to wrap it in square brackets to make sure it can't be confused with other operators such as the minus sign.
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">visits</span> = []

<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">pick_visits</span>

<span class="org-ink-shadow">==</span> <span class="org-ink-knot">pick_visits</span>

Which patient will you visit <span class="org-constant">{</span>first<span class="org-constant">|</span>after that<span class="org-constant">}</span>?

<span class="org-type">* </span><span class="org-ink-bracket">[Critically ill guy]</span>
<span class="org-type">  ~</span><span class="org-variable-name">visits +</span>= [<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">critical</span>]
<span class="org-type">* </span><span class="org-ink-bracket">[Grazed child]</span>
<span class="org-type">  ~</span><span class="org-variable-name">visits +</span>= [<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">grazed</span>]
<span class="org-type">* </span><span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">do_rounds</span>
<span class="org-type">-</span>

<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">pick_visits</span>

<span class="org-ink-shadow">==</span> <span class="org-ink-knot">do_rounds</span>
<span class="org-constant">{</span>
<span class="org-type">-</span> STACK_COUNT(visits):
<span class="org-type">  ~</span><span class="org-keyword">temp</span> next_visit = <span class="org-string">""</span>
<span class="org-type">  ~</span>visits = <span class="org-function-name">STACK_POP_OLDEST</span>(visits, next_visit)
  <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">next_visit</span> <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">do_rounds</span>
<span class="org-type">-</span> else:
  Well, I'm done for the day!
<span class="org-constant">}</span>

<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">END</span>

<span class="org-ink-shadow">==</span> <span class="org-ink-knot">critical</span>
Check if it is too late.
<span class="org-ink-arrow">-&gt;-&gt;</span>

<span class="org-ink-shadow">==</span> <span class="org-ink-knot">grazed</span>
Doesn't matter when you get here.
<span class="org-ink-arrow">-&gt;-&gt;</span>
</pre>
</div>

<p>
Possibly most useful of all, is the ability to present a choice for each item in a stack by combining stacks and threads. Going back to our runic magic system, we can automate the spell casting menu system by building it from stacks rather than writing it all out by hand.
</p>

<p>
This opens up new possibilities; in our next example, the player only has a limited number of owned runes and may need multiple copies of the same rune to activate a spell. This allows us to write narratives where runes are found over time, or can be stolen. It also allows us as game designers to add to the list of runes that exist without having to change any of the underlying mechanics that already exist.
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">LIST</span> <span class="org-variable-name">runes</span> = fire, earth, water, air, protect, attack

<span class="org-keyword">VAR</span> <span class="org-variable-name">ignite</span> = [fire]
<span class="org-keyword">VAR</span> <span class="org-variable-name">fireball</span> = [fire, fire, attack]
<span class="org-keyword">VAR</span> <span class="org-variable-name">heal</span> = [protect, water]
<span class="org-keyword">VAR</span> <span class="org-variable-name">current_cast</span> = []
<span class="org-keyword">VAR</span> <span class="org-variable-name">owned_runes</span> =  [fire, fire, protect, attack]
<span class="org-keyword">VAR</span> <span class="org-variable-name">available_runes</span> = []

Time to cast a spell.

<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">select_rune_or_cast</span> <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">END</span>

<span class="org-ink-shadow">==</span> <span class="org-ink-knot">select_rune_or_cast</span>

Add a rune, or release the magic!

<span class="org-type">~</span><span class="org-variable-name">available_runes</span> = owned_runes

<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">pick_available_rune</span>(available_runes) <span class="org-ink-arrow">-&gt;-&gt;</span>

<span class="org-ink-shadow">===</span> <span class="org-ink-knot">pick_available_rune</span><span class="org-variable-name">(still_available_runes)</span>
<span class="org-constant">{</span>
<span class="org-type">-</span> STACK_COUNT(still_available_runes):
<span class="org-type">  ~</span><span class="org-keyword">temp</span> next_rune = <span class="org-string">""</span>
<span class="org-type">  ~</span><span class="org-keyword">temp</span> remaining_runes = <span class="org-function-name">STACK_POP_NEWEST</span>(still_available_runes, next_rune)
  <span class="org-ink-arrow">&lt;-</span> <span class="org-ink-link">pick_available_rune</span>(remaining_runes)
<span class="org-type">  + </span>[Add <span class="org-constant">{</span>next_rune<span class="org-constant">}</span> to spell]
<span class="org-type">    ~</span><span class="org-function-name">add_rune</span>(next_rune)
    You're currently casting: <span class="org-constant">{</span>current_cast<span class="org-constant">}</span>
<span class="org-type">    ~</span><span class="org-variable-name">available_runes -</span>= next_rune
    <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">pick_available_rune</span>(available_runes)
<span class="org-type">-</span> else:
<span class="org-type">  + </span><span class="org-ink-bracket">[Cast the spell!]</span> <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">cast_spell</span> <span class="org-ink-arrow">-&gt;-&gt;</span>
<span class="org-constant">}</span>

<span class="org-ink-shadow">===</span> <span class="org-ink-knot">cast_spell</span>
<span class="org-constant">{</span>
<span class="org-type">-</span> current_cast == fireball:
  Kaboom!
<span class="org-type">-</span> current_cast == heal:
  Oooh. Refreshing!
<span class="org-type">-</span> else:
  Fizz, buzz
<span class="org-constant">}</span>
<span class="org-type">~</span><span class="org-variable-name">current_cast</span> = []
<span class="org-ink-arrow">-&gt;-&gt;</span>

<span class="org-ink-shadow">===</span> <span class="org-keyword">function</span> <span class="org-ink-knot">add_rune</span><span class="org-variable-name">(r)</span> <span class="org-ink-shadow">===</span>
<span class="org-type">~</span><span class="org-variable-name">current_cast +</span>= r
</pre>
</div>

<p>
I'm sure that there are other uses for stacks as well; these are just the use cases that pushed me to looking into implementing them as I already had them in mind. I hope this has given you all some inspiration, and we'll see whether stacks become part of Ink beyond VisualInk in the future or not.
</p>

<p>
Got any thoughts or suggestions? I suppose on this occasion the best idea is to pop into the Inkle discord and join in the #ink channel (for thoughts on usage) or #ink-engine-dev (for thoughts on the implementation). Be seeing you!
</p>
</div>
</div>
</div>
]]></description>
</item>
<item>
<title>Stacks in Ink</title>
<link>https://blog.mavnn.eu/2025/12/12/stacks_in_ink.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2025/12/12/stacks_in_ink.html</guid>
<pubDate>Fri, 12 Dec 2025 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
I'm currently running courses on building visual novels using Ink (with my <a href="https://visualink.mavnn.eu/">VisualInk</a> site providing both editing environment and 'runner'). Shameless plug: if you're looking for an unusual present for a 9-18 year old in your life, you could book them onto one of these courses for next term - <a href="https://www.thinkersmeetup.com/scholars/michael-newton">link to my page at the course provider</a>.
</p>

<p>
I chose Ink because it is brilliant at helping manage the complexity of branching narrative, but in working through the examples in the course there was one particular weakness we came upon. Because Ink is designed to be embedded in a larger game, it deliberately limits the options for state management within the Ink language - that's not the job it is there for. VisualInk, on the other hand, is built on the assumption that the Ink <i>is</i> the game, and it is just providing the sound and visuals.
</p>

<p>
Ink LISTs are very powerful for capturing flags, but they don't capture the order in which things are added to the list, and they can't contain duplicate values. Let's look at two examples that made us struggle, and then I'll move on to how I'm solving the problem.
</p>
<div id="outline-container-ID-2F7686FA-474D-43B0-801E-88E9547E914A" class="outline-4">
<h4 id="ID-2F7686FA-474D-43B0-801E-88E9547E914A"><span class="section-number-4">3.0.1.</span> What is best in life, sensei?</h4>
<div class="outline-text-4" id="text-3-0-1">
<p>
In the example visual novel Tournament you play a martial artist sent out into the world by your sensei. If you want to try it, you can play it <a href="https://visualink.mavnn.eu/published/KJtX3GyWGqeciSHmm4j33E76">here</a> (it's a couple of minutes long). The novel opens by establishing what is important to your sensei, where you flashback to your training and select what he taught you as foundational, as being important, and as final polish.
</p>

<p>
These are the qualities in question:
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">LIST</span> <span class="org-variable-name">qualities</span> =
  strength, skill, control, 
  speed, honour
</pre>
</div>

<p>
Ideally, it would be trivial to just add the qualities to a variable of some kind in order, at which point you'd immediately know which is which. Instead, we end up having to create multiple variables and keep track of which one it is we're filling.
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">VAR</span> <span class="org-variable-name">most_important</span> = honour
<span class="org-keyword">VAR</span> <span class="org-variable-name">important</span> = honour
<span class="org-keyword">VAR</span> <span class="org-variable-name">least_important</span> = honour
</pre>
</div>
</div>
</div>
<div id="outline-container-ID-9DF3051F-351E-43E1-ABC9-7A7F2960B8AB" class="outline-4">
<h4 id="ID-9DF3051F-351E-43E1-ABC9-7A7F2960B8AB"><span class="section-number-4">3.0.2.</span> Card battler</h4>
<div class="outline-text-4" id="text-3-0-2">
<p>
We discussed in one of the lessons the idea of a 'card battler' mechanic within our visual novels, and quickly realized that keeping track of a deck of cards within Ink that could have cards added to it during the story (especially duplicate cards) would be very hard if not impossible.
</p>
</div>
</div>
<div id="outline-container-ID-FA5A25C5-0171-4D2C-A0CA-9E4AD5C80178" class="outline-4">
<h4 id="ID-FA5A25C5-0171-4D2C-A0CA-9E4AD5C80178"><span class="section-number-4">3.0.3.</span> The solution</h4>
<div class="outline-text-4" id="text-3-0-3">
<p>
Fortunately, all is not lost. Ink allows compiler plugins, and VisualInk now implements one for STACKs. 
</p>

<p>
A stack definition consists of a name, a maximum size, and the "empty" value for the stack - the value you'll be given if you ask for a stack slot that isn't filled, or "pop" a value from an empty stack. It allows us to do things like this:
</p>

<div class="org-src-container">
<pre class="src src-ink"><span class="org-keyword">LIST</span> <span class="org-variable-name">qualities</span> =
  strength, skill, control, 
  speed, honour

STACK sensei_values 3 strength

<span class="org-type">~</span><span class="org-function-name">sensei_values_push</span>(strength)
<span class="org-type">~</span><span class="org-function-name">sensei_values_push</span>(skill)
<span class="org-type">~</span><span class="org-function-name">sensei_values_push</span>(honour)

<span class="org-comment-delimiter">// </span><span class="org-comment">Oops, sensei had a change of heart</span>
<span class="org-type">~</span><span class="org-function-name">sensei_values_set</span>(3, speed)

Sensei values <span class="org-constant">{</span>sensei_values_index(1)<span class="org-constant">}</span>, <span class="org-constant">{</span>sensei_values_index(2)<span class="org-constant">}</span>, <span class="org-ink-shadow">&lt;&gt;</span>
<span class="org-constant">{</span>sensei_values_index(3)<span class="org-constant">}</span>.

<span class="org-comment-delimiter">// </span><span class="org-comment">Outputs: Sensei values strength, skill, and speed.</span>
</pre>
</div>

<p>
As you can see, the stack tracks values being pushed into it, and can change and read values at specific indexes (the first value in at <code>1</code>, not <code>0</code>, for the programmers among you).
</p>

<p>
The push and pop functions also let you know if you're successfully pushing or popping if that's important. Push returns true for success, and false if the stack is full, while pop will return the "empty" value you specified if the stack has no more values.
</p>

<div class="org-src-container">
<pre class="src src-ink">STACK cards 2 false

<span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">draw_card</span>

<span class="org-ink-shadow">===</span> <span class="org-ink-knot">draw_card</span>
<span class="org-type">~</span><span class="org-keyword">temp</span> did_draw = <span class="org-function-name">cards_push</span>(RANDOM(1, 10))
<span class="org-constant">{</span> did_draw:
  You now have <span class="org-constant">{</span>cards_last<span class="org-constant">}</span> cards in your hand
  <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">draw_card</span>
<span class="org-type">-</span> else:
  Your hand is full
  <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">play_card</span>
<span class="org-constant">}</span>

<span class="org-ink-shadow">===</span> <span class="org-ink-knot">play_card</span>
<span class="org-type">~</span><span class="org-keyword">temp</span> next_card = <span class="org-function-name">cards_pop</span>()
<span class="org-constant">{</span> next_card == false:
  You're out of cards!
  <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">END</span>
<span class="org-type">-</span> else:
  You play a <span class="org-constant">{</span>next_card<span class="org-constant">}</span>.
  <span class="org-ink-arrow">-&gt;</span> <span class="org-ink-link">play_card</span>
<span class="org-constant">}</span>

<span class="org-comment-delimiter">// </span><span class="org-comment">Draws two cards and then plays two cards</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-ID-5B962180-1369-4429-B7C9-69EE9D81537F" class="outline-4">
<h4 id="ID-5B962180-1369-4429-B7C9-69EE9D81537F"><span class="section-number-4">3.0.4.</span> I'm not using VisualInk and I don't want to build my own compiler plugin</h4>
<div class="outline-text-4" id="text-3-0-4">
<p>
We have you covered! The plugin is just generating Ink code to include under the hood (see below), and you can get the same code by browsing to <a href="https://visualink.mavnn.eu/inkTools/cards/2/false">https://visualink.mavnn.eu/inkTools/cards/2/false</a> and copying and pasting the code there into a file to include in your project manually. Just change the last three parts of the address to match what you need.
</p>
</div>
</div>
<div id="outline-container-ID-8CC3EDFC-80CF-4FDA-AFF0-58C51513514D" class="outline-4">
<h4 id="ID-8CC3EDFC-80CF-4FDA-AFF0-58C51513514D"><span class="section-number-4">3.0.5.</span> The implementation</h4>
<div class="outline-text-4" id="text-3-0-5">
<p>
Things get immediately technical from here on in, so if you just want to use stacks you can feel free to leave at this point! If, on the other hand, you're interested in extending Ink in a larger coding project, here's how I did it.
</p>

<p>
The implementation of this is two fold. Firstly, we have a <code>IPlugin</code> for the Ink compiler that does a simple search and replace on the script provided. It looks for lines in the correct format, and replaces them with <code>INCLUDE</code> lines with, er, slightly odd filenames.
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">module</span> <span class="org-type">VisualInk.Server.VisualInkPlugin</span>

<span class="org-keyword">open</span> <span class="org-type">Ink</span>
<span class="org-keyword">open</span> <span class="org-type">System.Text.RegularExpressions</span>

<span class="org-keyword">let</span> <span class="org-keyword">private</span> <span class="org-variable-name">StackDefinitionRegex</span> =
  Regex(
    <span class="org-string">"^STACK\s+(?&lt;label&gt;\w+)\s+(?&lt;size&gt;\d+)\s+(?&lt;nil&gt;.*)$"</span>,
    RegexOptions.Multiline ||| RegexOptions.Compiled
  )

<span class="org-keyword">let</span> <span class="org-keyword">private</span> <span class="org-variable-name">StackIncludeRegex</span> =
  Regex(
    <span class="org-string">"^VisualInkStack (?&lt;label&gt;\w+) (?&lt;size&gt;\d+) (?&lt;nil&gt;.*)$"</span>,
    RegexOptions.Multiline ||| RegexOptions.Compiled
  )

<span class="org-keyword">type</span> <span class="org-type">PluginInclude</span> =
    <span class="org-fsharp-ui-operator">|</span> StackInclude <span class="org-keyword">of</span> string * int * string

<span class="org-keyword">type</span> <span class="org-type">VisualInkPlugin</span>() =
  <span class="org-keyword">interface</span> IPlugin <span class="org-keyword">with</span>
    <span class="org-keyword">member</span> <span class="org-variable-name">_</span>.<span class="org-function-name">PreParse</span>(<span class="org-variable-name">storyContent</span>: <span class="org-type">byref</span><span class="org-fsharp-ui-generic">&lt;string&gt;</span>) : <span class="org-type">unit</span> =
      storyContent &lt;-
        StackDefinitionRegex.Replace(
          storyContent,
          <span class="org-string">"INCLUDE VisualInkStack ${label} ${size} ${nil}"</span>
        )

    <span class="org-keyword">member</span> <span class="org-variable-name">_</span>.<span class="org-function-name">PostExport</span>
      (<span class="org-variable-name">parsedStory</span>: <span class="org-type">Parsed.</span><span class="org-variable-name">Story</span>, <span class="org-variable-name">runtimeStory</span>: <span class="org-type">byref</span><span class="org-fsharp-ui-generic">&lt;Runtime.Story&gt;</span>)
      : <span class="org-type">unit</span> =
      ()

    <span class="org-keyword">member</span> <span class="org-variable-name">_</span>.<span class="org-function-name">PostParse</span>(<span class="org-variable-name">parsedStory</span>: <span class="org-type">byref</span><span class="org-fsharp-ui-generic">&lt;Parsed.Story&gt;</span>) : <span class="org-type">unit</span> = ()
</pre>
</div>

<p>
This means we replace lines on a 1-1 basis, preserving lint error locations and similar without having to do any complex mapping work.
</p>

<p>
In our implementation of <code>Ink.IFileHandler</code> (responsible for finding included Ink files for the compiler), we then add a check for filenames matching the include regular expression above. If it matches, we provide generated content instead of the content of an other actual file.
</p>

<p>
The actual Ink code driving the stack is simple, but very verbose. Here's the F# code for generating it:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-function-name">generatePluginInclude</span> (<span class="org-variable-name">StackInclude</span> (<span class="org-variable-name">label</span>, <span class="org-variable-name">size</span>, <span class="org-variable-name">nil</span>)) =
    <span class="org-keyword">let</span> <span class="org-variable-name">last</span> = $<span class="org-string">"{label}_last"</span>
    <span class="org-keyword">let</span> <span class="org-variable-name">content</span> = seq {
      <span class="org-comment-delimiter">// </span><span class="org-comment">Set up storage</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"VAR {label}_size = {size}"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"VAR {last} = 0"</span>
      <span class="org-keyword">for</span> i <span class="org-keyword">in</span> 1 .. size <span class="org-keyword">do</span>
        <span class="org-keyword">yield</span> $<span class="org-string">"VAR {label}_{i} = {nil}"</span>
      <span class="org-keyword">yield</span> <span class="org-string">""</span>

      <span class="org-comment-delimiter">// </span><span class="org-comment">Access via index</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"=== function {label}_index(index)"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"{ index:"</span>
      <span class="org-keyword">for</span> i <span class="org-keyword">in</span> 1 .. size <span class="org-keyword">do</span>
        <span class="org-keyword">yield</span> $<span class="org-string">"  - {i}:"</span>
        <span class="org-keyword">yield</span> $<span class="org-string">"    ~return {label}_{i}"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"}"</span>
      <span class="org-keyword">yield</span> <span class="org-string">""</span>

      <span class="org-comment-delimiter">// </span><span class="org-comment">Set via index</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"=== function {label}_set(index, value)"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"{ index:"</span>
      <span class="org-keyword">for</span> i <span class="org-keyword">in</span> 1 .. size <span class="org-keyword">do</span>
        <span class="org-keyword">yield</span> $<span class="org-string">"  - {i}:"</span>
        <span class="org-keyword">yield</span> $<span class="org-string">"    ~{label}_{i} = value"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"}"</span>
      <span class="org-keyword">yield</span> <span class="org-string">""</span>

      <span class="org-comment-delimiter">// </span><span class="org-comment">Push</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"=== function {label}_push(value)"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"{{ {last} &gt;= {size}:"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"  ~return false"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"- else:"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"  ~{last}++"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"  ~{label}_set({last}, value)"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"  ~return true"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"}"</span>

      <span class="org-comment-delimiter">// </span><span class="org-comment">Pop</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"=== function {label}_pop()"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"{{ {last} &lt;= 0:"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"  ~return {nil}"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"- else:"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"  ~temp result = {label}_index({last})"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"  ~{label}_set({last}, {nil})"</span>
      <span class="org-keyword">yield</span> $<span class="org-string">"  ~{last}--"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"  ~return result"</span>
      <span class="org-keyword">yield</span> <span class="org-string">"}"</span>
    }
    content <span class="org-fsharp-ui-operator">|&gt;</span> String.concat <span class="org-string">"\n"</span>
</pre>
</div>

<p>
I think that's about it for now; at the moment I'm only really expecting this to be a VisualInk specific plugin, so it isn't independently available. If you're an Ink user and you think you'd find it hopeful, I can always package up a sharable version of it. Let me know!
</p>

<p>
Comments or thoughts? The <a href="https://bonfire.mavnn.eu/post/01KC9ABBQS9A09RQTX11XT438X#">blog announcement</a> post is a good place to leave them!
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>Publishing with VisualInk</title>
<link>https://blog.mavnn.eu/2025/11/14/visualink_milestone.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2025/11/14/visualink_milestone.html</guid>
<pubDate>Fri, 14 Nov 2025 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
VisualInk is my current project to work with novice coders (children, but also potentially adults as well) who are interested in story telling. It hit a big milestone today as I added the ability to publish visual novels on the platform - which is slightly more challenging than you'd think as that means threading through the ability to see assets that belong to a known user without accidentally opening up the user's underlying script files or letting people edit their content.
</p>

<p>
As a side effect, I was also able to add a feature I've been wanting from the beginning: <a href="https://visualink.mavnn.eu/examples/AloneInTheDark">an example mini-visual novel</a> that you can play through without having to sign up or create an account. For bonus points, you can <a href="https://visualink.mavnn.eu/script/demo">view the script of the example</a> in a fully functional editor to get a handle of how Ink works (although you can't save or run your changes unless you set up an account).
</p>

<p>
Anyway; I'm pretty chuffed about all of this. If you're interested in spreading the joy of writing interactive fiction, I'd love some more example stories to show case, and if you're interested in how my F# code for the server is evolving I'm always up for pull requests and happy to answer questions. In either case, the place to suggest things is at the <a href="https://code.mavnn.eu/mavnn/VisualInk">project repository</a>.
</p>

<p>
If you'd just like to comment on this milestone, then <a href="https://mastodon.sdf.org/@mavnn/115548826768453925">this mastodon post</a> is the place to be.
</p>
]]></description>
</item>
<item>
<title>Coding games with a story</title>
<link>https://blog.mavnn.eu/2025/10/29/coding_games_with_a_story.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2025/10/29/coding_games_with_a_story.html</guid>
<pubDate>Wed, 29 Oct 2025 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
A short post this time, but one that will probably lead to more content here.
</p>

<p>
I'm teaming up with the long established and trusted <a href="https://www.thinkersmeetup.com/">Thinkers Meetup</a> to offer a course for 9-13 year old thinkers to write visual novels called <a href="https://www.thinkersmeetup.com/service-page/coding-games-with-a-story-ages-9-13">Coding Games with a Story</a>. I'm hoping this will be the first of many!
</p>

<p>
If you know people in that age range who would in interested, or you're wondering what on earth I'm talking about, this video might help!
</p>

<div style="text-align: center;">
<iframe width="560" height="315" src="https://www.youtube.com/embed/bF32DSFe0Hw?si=4bZwyRu6a3bMNhVY" 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>
</div>

<p>
For those of you who have been following along for a while, you might be more interested to hear that the course is being powered by an open source website written in F#, including some code that might look very familiar from my previous "dev journals" a year or two back. If you're interested in having a look at what a full (if not huge) F# project looks like, with realistically unpolished code, the repository is at <a href="https://code.mavnn.eu/mavnn/VisualInk/">https://code.mavnn.eu/mavnn/VisualInk/</a>.
</p>

<p>
Got comments? This <a href="https://mastodon.sdf.org/@mavnn/115458607249000834">Mastodon post</a> is a great place to leave them.
</p>
]]></description>
</item>
<item>
<title>Stun lock procrastination</title>
<link>https://blog.mavnn.eu/2025/09/16/stun_lock_procrastination.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2025/09/16/stun_lock_procrastination.html</guid>
<pubDate>Tue, 16 Sep 2025 00:00:00 +0200</pubDate>

<description><![CDATA[<p>
One of the primary markers of ADHD is <i>not starting</i>. There are many other aspects, for sure, but often what looks like "hyperactivity" is actually just the noise getting in the way of what we <i>want</i> to be doing but that we haven't started yet.
</p>

<p>
So when I first came across the idea of procrastination as a tool via <a href="https://www.structuredprocrastination.com/">structured procrastination</a> years before my ADHD diagnosis it somewhat resonated... but not completely. The essay is well written, funny, and makes some good points but something felt fundamentally "off" about it when I tried to see if I could use the techniques. John Perry describes his trick as filling the top of the to do list with a certain type of task:
</p>

<blockquote>
<p>
The ideal sorts of things have two characteristics, First, they seem to have clear deadlines (but really don't). Second, they seem awfully important (but really aren't).
</p>
</blockquote>

<p>
He rightly points out that interacting with pretty much any organisation of any size will be stuffed full of such tasks.
</p>

<p>
This then allows him to procrastinate on the things at the top of the list by doing things that are actually more important but "less urgent". Turns out: my brain does not work like that. A sentence that I live by a little more often than is strictly comfortable.
</p>

<p>
My default state of procrastination is not the same as John Perry's; he describes a state in which he chooses to do something else, where he decides to do something different. Mine tends to fall into one of two categories:
</p>

<ul class="org-ul">
<li>I do something for hours, and when I'm next interrupted I wonder "why was I even doing that?"</li>
<li>I realise that I need to do something and I cannot make myself do it so I do <i>nothing</i></li>
</ul>

<p>
And on that latter point, I really do mean <i>nothing</i>. If I know that I need to do the washing up, but I can't face it, I will "stun lock" sitting on a chair for anything from minutes to multiple hours because washing up is what I <i>need to do</i> and the washing up is what I <i>cannot do</i>. I have lost entire days to not being able to face trivial ten minute tasks because they were the crucial thing that needed to get done, and I could not face starting them.
</p>

<p>
On the "why was I even" form of procrastination, I have to admit that the only thing I've really found helpful is good medication and trying to build at least some structure into the day - although without either the medication or outside help the structure doesn't tend to be that reliable.
</p>

<p>
But for the second kind I've slowly begun to realise that it is an experience that I can learn to recognise. It is the historical experience of beating myself up for being too lazy to do the thing that needed doing. Never mind that I wasn't actually doing what I wanted to do instead; if you blink long enough to look objectively, it would be a strange definition of laziness that included "not doing the things I want to do for hours at a time while feeling miserable." In fact, that sounds rather more like hard work to me.
</p>

<p>
By combining learning to recognise the experience with the processing I needed to do after my diagnosis, it became possible to accept it as something which is going to happen to me not because I'm intolerably lazy, but because sometimes my brain is going to find task initiation objectively difficult. The final piece of the puzzle was spotting in the research that it is very unpredictable <i>what</i> tasks will be difficult to initiate.
</p>

<p>
Slowly, a light appeared in the depressive haze of not getting stuff done: what if, instead of trying to force myself to do <i>this</i> thing, or trying to trick myself into doing it by "doing something fun" first, I just asked the question: "what can I do right now?" Trying to consult a to do list or be certain I'm doing something important is often a task I <i>can't</i> do right now, so I look for tasks that are short, productive, and feel achievable without trying to check too hard if they are the <i>most</i> important, or the <i>most</i> urgent, of the tasks I might theoretically be able to do right now.
</p>

<p>
Turns out, it actually works pretty well. Especially because <i>starting</i> really is the hardest bit. For example, I've written this blog post now that I've been meaning to write for weeks having promised someone I'd explain a throw away comment in a bit more detail. And once it's posted, I'm pretty sure that I've built up enough momentum that I'll be able to fill in the form that I was "supposed" to be filling in this morning as the most urgent task on the list.
</p>

<p>
And if I haven't, there's still the washing up.
</p>

<p>
Thoughts? Comments? Here's a <a href="https://mastodon.sdf.org/@mavnn/115213753851467347">Mastodon post</a> to leave them on.
</p>
]]></description>
</item>
<item>
<title>Conflict free syncthing notes</title>
<link>https://blog.mavnn.eu/2025/08/15/conflict_free_syncthing_notes.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2025/08/15/conflict_free_syncthing_notes.html</guid>
<pubDate>Fri, 15 Aug 2025 00:00:00 +0200</pubDate>

<description><![CDATA[<p>
Just a short trick this time, mostly for my own records. As a family we've started moving to Syncthing for syncing files across devices, and "open" note taking formats like ".org" and ".md" for long term note taking. I've been using org-mode for a while personally, and now the rest of the family have been burned enough by the alternatives over the years that they're coming to similar conclusions even if not all of them want to use Emacs!
</p>

<p>
Syncthing has a sensible general purpose policy with conflicts of creating a copy of a file where a conflict exists by adding a <code>.sync-conflict-&lt;date&gt;-&lt;time&gt;-&lt;device-id&gt;.</code> pseudo-extension before the file's true extension (or to the end of the filename if it didn't have one).
</p>

<p>
In general, this is great as it means that a) all in sync devices have a shared understanding of the "winning" version of the file, and b) you can manually do any comparisons you need to and by saving a new version of the "original" file name and deleting the conflicting copies you resolve the conflict for everybody.
</p>

<p>
But with plain text note files, we can actually do a bit better than that. Because these files are always text, we can use a standard merge algorithm on them. And because the places where conflicts happen most are (almost by definition) things like todo lists and similar, we can even go a step further and specify that even if there is a line/word level conflict that the algorithm can't resolve, we can allow the resolution to be "just in line the changes from both sides."
</p>

<p>
So there's now a cron job running on the Raspberry Pi that acts as our "introducer" node in our Syncthing mesh, which looks like this:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span class="org-tree-sitter-hl-faceXcomment">#!/usr/bin/</span><span class="org-keyword">env</span><span class="org-tree-sitter-hl-faceXcomment"> bash</span>
<span class="org-tree-sitter-hl-faceXcomment"># Find all files that are syncthing conflict markers, and have</span>
<span class="org-tree-sitter-hl-faceXcomment"># a "note" extension (md or txt or org)</span>
<span class="org-tree-sitter-hl-faceXfunctionXcall">readarray</span> <span class="org-tree-sitter-hl-faceXconstant">-t</span> CONFLICTS <span class="org-tree-sitter-hl-faceXoperator">&lt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXspecial">&lt;(</span> <span class="org-sh-escaped-newline">\</span>
  <span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXfunctionXcall">find</span></span><span class="org-tree-sitter-hl-faceXembedded"> /syncthing/share/parent/directory </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXconstant">-type</span></span><span class="org-tree-sitter-hl-faceXembedded"> f \</span>
<span class="org-tree-sitter-hl-faceXembedded">       </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXconstant">-name</span></span><span class="org-tree-sitter-hl-faceXembedded"> </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring">"*.sync-conflict*"</span></span><span class="org-tree-sitter-hl-faceXembedded"> \</span>
<span class="org-tree-sitter-hl-faceXembedded">       \( </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXconstant">-name</span></span><span class="org-tree-sitter-hl-faceXembedded"> </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring">"*.md"</span></span><span class="org-tree-sitter-hl-faceXembedded"> </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXconstant">-o</span></span><span class="org-tree-sitter-hl-faceXembedded"> </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXconstant">-name</span></span><span class="org-tree-sitter-hl-faceXembedded"> </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring">"*.org"</span></span><span class="org-tree-sitter-hl-faceXembedded"> </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXconstant">-o</span></span><span class="org-tree-sitter-hl-faceXembedded"> </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXconstant">-name</span></span><span class="org-tree-sitter-hl-faceXembedded"> </span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring">"*.txt"</span></span><span class="org-tree-sitter-hl-faceXembedded"> \)</span> <span class="org-sh-escaped-newline">\</span>
<span class="org-tree-sitter-hl-faceXpunctuationXspecial">)</span>
<span class="org-tree-sitter-hl-faceXcomment"># For each file:</span>
<span class="org-tree-sitter-hl-faceXkeyword">for</span> <span class="org-tree-sitter-hl-faceXproperty">CONFLICT</span> <span class="org-tree-sitter-hl-faceXkeyword">in</span> <span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">${</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXproperty">CONFLICTS</span></span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded">[@]</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">}</span></span><span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXoperator">;</span>
<span class="org-tree-sitter-hl-faceXkeyword">do</span>
   <span class="org-tree-sitter-hl-faceXcomment"># Build the regex for matching conflict files and extracting</span>
   <span class="org-tree-sitter-hl-faceXcomment"># the original file name.</span>
   <span class="org-tree-sitter-hl-faceXcomment"># 1. The marker, capturing the file name in a group.</span>
   <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">REG</span></span>=<span class="org-tree-sitter-hl-faceXstring">"\(.*\)sync-conflict-"</span>
   <span class="org-tree-sitter-hl-faceXcomment"># 2. The date</span>
   <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">REG</span></span>+=<span class="org-tree-sitter-hl-faceXstring">"[[:digit:]]\{8\}-"</span>
   <span class="org-tree-sitter-hl-faceXcomment"># 3. The time</span>
   <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">REG</span></span>+=<span class="org-tree-sitter-hl-faceXstring">"[[:digit:]]\{6\}-"</span>
   <span class="org-tree-sitter-hl-faceXcomment"># 4. The originating device ID</span>
   <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">REG</span></span>+=<span class="org-tree-sitter-hl-faceXstring">"[A-Z0-9]\{7\}"</span>
   <span class="org-tree-sitter-hl-faceXcomment"># 5. The original file extension</span>
   <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">REG</span></span>+=<span class="org-tree-sitter-hl-faceXstring">".\(.*\)"</span>
   <span class="org-tree-sitter-hl-faceXcomment"># Find the "winning" version with the original file name</span>
   <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">CHOSEN</span></span>=<span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXpunctuationXspecial"><span class="org-tree-sitter-hl-faceXstring">$(</span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXfunctionXcall"><span class="org-tree-sitter-hl-faceXfunctionXbuiltin">echo</span></span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"> "</span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">$</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty">CONFLICT</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring">" </span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXoperator">|</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"> </span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXfunctionXcall">sed</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"> </span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXconstant">-n</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"> "s/</span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">${</span></span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXproperty">REG</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">}</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring">/\1\2/p"</span></span><span class="org-tree-sitter-hl-faceXstring"> </span><span class="org-tree-sitter-hl-faceXpunctuationXspecial"><span class="org-tree-sitter-hl-faceXstring">)</span></span><span class="org-tree-sitter-hl-faceXstring">"</span>
   <span class="org-tree-sitter-hl-faceXfunctionXcall"><span class="org-tree-sitter-hl-faceXfunctionXbuiltin">echo</span></span> Merging <span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">$</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty">CHOSEN</span></span><span class="org-tree-sitter-hl-faceXstring">"</span> <span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">$</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty">CONFLICT</span></span><span class="org-tree-sitter-hl-faceXstring">"</span>
   <span class="org-tree-sitter-hl-faceXcomment"># If the original file actually exists (nothing stops a user from deleting it)</span>
   <span class="org-tree-sitter-hl-faceXkeyword">if</span> [ -f <span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">$</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty">CHOSEN</span></span><span class="org-tree-sitter-hl-faceXstring">"</span> ]<span class="org-tree-sitter-hl-faceXoperator">;</span> <span class="org-tree-sitter-hl-faceXkeyword">then</span>
     <span class="org-tree-sitter-hl-faceXcomment"># Merge the two versions of the file, taking from both in case of conflict;</span>
     <span class="org-tree-sitter-hl-faceXcomment"># this may cause repetition but won't lose data. Delete the conflict file</span>
     <span class="org-tree-sitter-hl-faceXcomment"># but only if the merge reported no errors.</span>
     <span class="org-tree-sitter-hl-faceXfunctionXcall">git</span> merge-file <span class="org-tree-sitter-hl-faceXconstant">--union</span> <span class="org-sh-escaped-newline">\</span>
         <span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">$</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty">CHOSEN</span></span><span class="org-tree-sitter-hl-faceXstring">"</span> <span class="org-tree-sitter-hl-faceXstring">"/syncthing/share/parent/directory/empty_file"</span> <span class="org-sh-escaped-newline">\</span>
         <span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">$</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty">CONFLICT</span></span><span class="org-tree-sitter-hl-faceXstring">"</span> <span class="org-tree-sitter-hl-faceXoperator">&amp;&amp;</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">rm</span> <span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">$</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty">CONFLICT</span></span><span class="org-tree-sitter-hl-faceXstring">"</span>
   <span class="org-tree-sitter-hl-faceXkeyword">else</span>
     <span class="org-tree-sitter-hl-faceXfunctionXcall"><span class="org-tree-sitter-hl-faceXfunctionXbuiltin">echo</span></span> <span class="org-tree-sitter-hl-faceXstring">"No current file found"</span>
   <span class="org-tree-sitter-hl-faceXkeyword">fi</span>
<span class="org-tree-sitter-hl-faceXkeyword">done</span>
</pre>
</div>

<p>
The only slight gotcha is you'll need to run <code>touch /syncthing/share/parent/directory/empty_file</code> to create an empty file to be used as the "parent" of the two conflicting versions. Extra internet points available to anyone who instead works out how to use a historical version from syncthing's archive functionality, but for me on this occasion that wasn't really needed.
</p>

<p>
Got comments or ideas? The Mastodon post for this blog can be found here: <a href="https://mastodon.sdf.org/@mavnn/115038110993820603">https://mastodon.sdf.org/@mavnn/115038110993820603</a>
</p>
]]></description>
</item>
<item>
<title>A gentle introduction to Effect TS</title>
<link>https://blog.mavnn.eu/2024/09/16/intro_to_effect_ts.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/09/16/intro_to_effect_ts.html</guid>
<pubDate>Mon, 16 Sep 2024 00:00:00 +0200</pubDate>

<description><![CDATA[<p>
I've recently been writing TypeScript again in a green field project, and we made the decision to
use the <a href="https://effect.website/">Effect</a> library. It's not a small decision to make: although you can use bits of Effect in
an existing code base, its real benefit is when it is used as (to quote the website) "the missing
standard library for TypeScript".
</p>

<p>
Overall, we're happy with the choice but the learning curve has a few sharp edges and while the
<a href="https://effect.website/docs/introduction">docs</a> aren't bad it does feel like they could do a better job of introducing the most used features
in a way that feels familiar to TypeScript developers so they can at least <b>read existing</b> Effect
code before starting to introduce the many, many, powerful features that come with the library.
</p>

<p>
This post is an attempt to do exactly that.
</p>
<div id="outline-container-ID-40BE2936-AEE9-43BF-BF10-DA2EA5131BDE" class="outline-4">
<h4 id="ID-40BE2936-AEE9-43BF-BF10-DA2EA5131BDE"><span class="section-number-4">8.0.1.</span> The Effect type</h4>
<div class="outline-text-4" id="text-8-0-1">
<p>
The very first thing you need to understand about Effect is that it is built around a specific type.
Appropriately enough, the <code>Effect</code> type. This type functions as a replacement for <code>Promise</code>, allowing
for asynchronous code, but also covers a few other needs.
</p>

<p>
Let's get started, in the traditional way:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">import</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">from</span> <span class="org-tree-sitter-hl-faceXstring">"effect"</span>

<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">hello</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">name</span><span class="org-tree-sitter-hl-faceXpunctuationXspecial">?</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXstring">`Hello, </span><span class="org-keyword">${</span><span class="org-default">name || "world"</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring">!`</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
This code is spiritually the same as writing:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">helloAsync</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">name?</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXstring">`Hello, </span><span class="org-keyword">${</span><span class="org-default">name || "world"</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring">!`</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
You can think of the <code>Effect.gen(function* () { ... })</code> as a slightly more verbose version of the <code>async</code> prefix to a function.
</p>

<p>
What about calling the function? Again, we have a similar concept but different syntax to <code>async/await</code>.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXcomment">// Effect version</span>
<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">sayHello</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">greeting</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXfunctionXcall">hello</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"world"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXfunctionXcall">sendGreetings</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>greeting<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>

<span class="org-tree-sitter-hl-faceXcomment">// Async/await version</span>
<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-variable-name">sayHelloAsync</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-keyword">const</span> <span class="org-variable-name">greeting</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">helloAsync</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"world"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">sendGreetingsAsync</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>greeting<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Given that we're using a cooperative scheduling system for asynchronous code, you can think of <code>yield*</code> as
saying "hey runtime - I'm yielding the thread now, start me back up when the effect on the right has finished."
</p>

<p>
There is, however one big difference between these two which will catch you out if you don't know about it.
</p>
</div>
</div>
<div id="outline-container-ID-CDB9688C-2D7D-485B-8D78-834F92A8C01F" class="outline-4">
<h4 id="ID-CDB9688C-2D7D-485B-8D78-834F92A8C01F"><span class="section-number-4">8.0.2.</span> Hot and cold promises</h4>
<div class="outline-text-4" id="text-8-0-2">
<p>
<code>Promise</code> is what is sometimes referred to as a "hot" or "immediate" asynchronous construct. What does that mean?
</p>

<p>
Well, in the example above <code>sayHelloAsync</code> is a constant value. As soon as the value is created, the logic within
the promise will be scheduled for execution and we will start the process of asynchronously running the <code>helloAsync</code>
function. If we await the result of <code>sayHelloAsync</code> somewhere else, we will block until the function has finished.
</p>

<p>
This also means that if we <code>await</code> <code>sayHelloAsync</code> in two different places, we will only send greetings <b>once</b>. After
all, the <code>Promise</code> type that we are handing around represents the running execution of an asynchronous process; it has
already started, and awaiting it multiple times won't start it again.
</p>

<p>
<code>Effect</code>, by contrast, is a "cold" or "thunked" asynchronous construct. It represents a series of steps that <i>will be</i>
executed <i>if</i> the result is requested.
</p>

<p>
So if we run:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">camelot</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
We will send the greetings three times, but only when somebody requests the result of running <code>camelot</code>. Until
then, nothing will happen at all.
</p>

<p>
<b>If you remember nothing else from this post</b>, remember that an <code>Effect</code> that nobody executes never runs. This <i>will</i> catch you
out with logging.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXcomment">// logs nothing</span>
<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">camelot</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Bass voice: spam a looooooot"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>

<span class="org-tree-sitter-hl-faceXcomment">// logs the bass voice</span>
<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">camelot</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Bass voice: spam a looooooot"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
Although the ability to create Effects without executing them can be extremely useful, leaving <code>yield*</code> out of
your code when you actually need it is probably the most frustrating element of learning Effect, and the one
that the compiler is least able to warn you about.
</p>
</div>
</div>
<div id="outline-container-ID-1B0B0FD4-2B3B-47B2-BA04-3D9386CC3E74" class="outline-4">
<h4 id="ID-1B0B0FD4-2B3B-47B2-BA04-3D9386CC3E74"><span class="section-number-4">8.0.3.</span> Pipes</h4>
<div class="outline-text-4" id="text-8-0-3">
<p>
Effect makes heavy usage of a concept it calls "pipes", which is a way of passing a value through a series of functions.
</p>

<p>
The main place you'll see this is that we can wrap <code>Effect</code> values in a wide variety of ways. These are very powerful,
but quickly start suffering from the "lisp effect" of a pyramid of brackets when we start combining them.
</p>

<p>
Let's rewrite the <code>camelot</code> function above using the built in <code>Effect.repeatN</code> method:
</p>


<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">camelot</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">repeatN</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)(</span>sayHello<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
Now let's add a timeout on finishing the 3 calls to <code>sayHello</code>; greetings are time critical after all:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">camelot</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">timeout</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"10 seconds"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)(</span><span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">repeatN</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)(</span>sayHello<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
You can see this is already becoming quite hard to follow. This is where pipes come in. We
can rewrite the above to become:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">camelot</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">TimeoutException</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pipe</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">repeatN</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">timeout</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"10 seconds"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
You'll see this a lot in most code bases as the Effect library contains "pipeable" methods for everything
from error handling to naming pieces of code for telemetry.
</p>
</div>
</div>
<div id="outline-container-ID-8CE282D0-8579-4A66-8903-DBC1427CBBA0" class="outline-4">
<h4 id="ID-8CE282D0-8579-4A66-8903-DBC1427CBBA0"><span class="section-number-4">8.0.4.</span> Error handling, you say?</h4>
<div class="outline-text-4" id="text-8-0-4">
<p>
In that last example, <code>Effect</code> suddenly grew its second generic parameter. The <code>timeout</code> wrapper adds the
explicit possibility that <code>camelot</code> can fail with a <code>TimeoutException</code>.
</p>

<p>
Do not get caught out! This doesn't mean that <code>camelot</code> cannot throw other exceptions; it means that we
do not consider <code>camelot</code> timing out to be a "defect" but a known behavior which we can take action on.
</p>

<p>
This is worth spending a moment on, as it can get confusing. Effect executions can "finish early" in three
main ways:
</p>

<ul class="org-ul">
<li>An exception is thrown. This is referred to as a "defect", and the Effect interrupted is said to "die".</li>
<li>A specific, known, failure type is explicitly returned. The type will be part of the type signature of the Effect, and if this happens the Effect is said to "fail".</li>
<li>The Effect runtime can interrupt an Effect that is in flight because the result is no longer needed. These Effects are "interrupted".</li>
</ul>

<p>
For example, if the timeout is triggered in the code above the <code>camelot</code> function will "fail" with a <code>TimeoutException</code> while the call to <code>sayHello</code> which has taken too long will be "interrupted".
If, instead, <code>sayHello</code> throws an exception because the network is down then it will "die" and then in turn cause the <code>camelot</code> Effect to "die" as well.
</p>

<p>
With the addition of the "empty" case (nothing went wrong!) these four categories are used to define the <code>Cause</code> of an Effect completing execution.
</p>

<p>
Here we hit a piece of (in my opinion) terrible naming on the part of the library authors. The <code>Effect.catch</code> wrapper that as a TypeScript developer
you would expect to, you know, catch thrown exceptions only catches "failures" (i.e. the known, type safe, errors deliberately returned). This is very
useful in allowing you to apply logic in code that depends on known failure routes, but if you're actually looking for what you <i>thought</i> <code>Effect.catch</code>
did you're really looking for <code>Effect.catchAllCause</code>.
</p>
</div>
<ol class="org-ol">
<li><a id="ID-D82D8669-5069-407E-BC1C-89E0C2E24611"></a>Opinion moment<br>
<div class="outline-text-5" id="text-8-0-4-1">
<p>
This is my opinion rather than something about how Effect works, but I'd recommend in general that you handle most of the library supplied failure
types very close to where they happen. The reason is that as library failures, they are by nature very generic (<code>ElementNotFoundException</code>?) and
so if you don't handle them close to the source, you won't know <i>which</i> element of what wasn't found. Even worse, if you decide that you can't
do anything about the failure anymore because the context has been lost and you upgrade it to a "defect" using the <code>Effect.orDie</code> wrapper,
the stack trace will come from the call to <code>orDie</code> <b>not</b> from the Effect that returned the failure.
</p>
</div>
</li>
</ol>
</div>
<div id="outline-container-ID-BCA9785F-7185-461D-9656-990990CA952A" class="outline-4">
<h4 id="ID-BCA9785F-7185-461D-9656-990990CA952A"><span class="section-number-4">8.0.5.</span> Signaling errors</h4>
<div class="outline-text-4" id="text-8-0-5">
<p>
If you want to signal that a function should return early due to an error, you can either use <code>Effect.fail</code> or you can
use any error that is a subtype of <code>YieldableError</code> (part of the Effect library). This introduces the slightly weird
construct of <code>return yield*</code>, as you can see below.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">canGoWrong</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">number</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">if</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input <span class="org-tree-sitter-hl-faceXoperator">&lt;</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">fail</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Input must be positive"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">IllegalArgumentException</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Input must be not too big"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXfunctionXcall">sendGreeting</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">" Moderate Number Inputter"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXstring">"Success!"</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
Why can't you just call <code>return</code>? The answer is it messes up the types; the function above has the type:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">number</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">IllegalArgumentException</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
</pre>
</div>

<p>
But if we were to write:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">canGoWrong</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">number</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">if</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input <span class="org-tree-sitter-hl-faceXoperator">&lt;</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">fail</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Input must be positive"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">IllegalArgumentException</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Input must be not too big"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXfunctionXcall">sendGreeting</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">" Moderate Number Inputter"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
...then it would end up with the type:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">number</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">IllegalArgumentException</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span>
</pre>
</div>

<p>
What's happening is that without the <code>yield*</code> we are returning the failures as possible success values.
That probably isn't what you want!
</p>

<p>
In general, if you ever find yourself with an Effect of an Effect, you're probably missing a <code>yield*</code> somewhere.
</p>
</div>
</div>
<div id="outline-container-ID-F89CFF8D-029D-489D-BF51-A69FD227B8E6" class="outline-4">
<h4 id="ID-F89CFF8D-029D-489D-BF51-A69FD227B8E6"><span class="section-number-4">8.0.6.</span> Dependencies</h4>
<div class="outline-text-4" id="text-8-0-6">
<p>
One of the most powerful features of Effect in day to day usage is the built in, type safe, dependency management. Let's apply some <a href="https://en.wikipedia.org/wiki/Inversion_of_control">inversion of control</a>
to our <code>sendGreetings</code> service.
</p>

<p>
Effect allows us to build "services", which are classes that extend <code>Context.Tag</code> to specify what interface their implementations will provide.
</p>

<p>
For example, we can specify a service for sending greetings that looks like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">import</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXconstructor">Context</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">from</span> <span class="org-tree-sitter-hl-faceXstring">"effect"</span>

<span class="org-tree-sitter-hl-faceXkeyword">interface</span> <span class="org-tree-sitter-hl-faceXtype">ISendGreetings</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">sendGreetings</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">name</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">SendGreetings</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Context</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">Tag</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"SendGreetings"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-variable-name">SendGreetings</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ISendGreetings</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span>
</pre>
</div>

<p>
And now we can rewrite <code>camelot</code> to use the service:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">sayHello</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">SendGreetings</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">sender</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXconstructor">SendGreetings</span>
  <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">greeting</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXfunctionXcall">hello</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"world"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sender<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">sendGreetings</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>greeting<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>

<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">camelot</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">TimeoutException</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">SendGreetings</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sayHello<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pipe</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">repeatN</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">timeout</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"10 seconds"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
This is where we see Effect's third and final generic parameter, which tracks which dependencies
your code requires.
</p>

<p>
"But I thought we could only yield* Effects?": well, it turns out this isn't quite true. It turns
out that as you can make your own <code>Awaitable</code> types in TypeScript that are not <code>Promises</code>, you
can also implement alternative <code>Yieldable</code> types in Effect. And that's exactly what the pre-provided
<code>Context.Tag</code> class does as a static interface. Which means, slightly bizarrely, you can <code>yield*</code>
the name of the class and it will then run all of the dependency injection logic needed to go
and get you an actual implementation at run time.
</p>

<p>
In general, you just want to let Effect build up required dependencies itself; if we add a second service then the type
system will capture that "automatically". If possible, leave the types of
your Effect functions inferred as then it will automatically pick up changes in their dependencies. That
said, I'll carry on adding them here so you can see what's happening.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">sayHello</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Effect</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">SendGreetings</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">TranslateGreeting</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor">Effect</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">gen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-tree-sitter-hl-faceXkeyword">function</span>* <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">sender</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXconstructor">SendGreetings</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">translator</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXconstructor">TranslateGreeting</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">greeting</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* <span class="org-tree-sitter-hl-faceXfunctionXcall">hello</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"world"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">translated</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* translator<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">translate</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>greeting<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXkeyword">yield</span>* sender<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">sendGreetings</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>translated<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
</pre>
</div>

<p>
Note that the types only capture <i>direct</i> dependencies. Here, the <code>TranslateGreeting</code> service almost
certainly depends in turn on some kind of user or session service, but we don't need to worry about
that. This makes providing alternative service implementations for tests, or for running on the client
versus the server, exceedingly straight forward and safe. If you can provide exactly what your code needs
you're good, and it won't ask you for any more than that. If your Effect code is starting to build up
a huge list of dependencies, that's normally a good indicator that you want to start wrapping it in
an interface of its own - that way, the things that call your code don't inherit a huge dependency tree,
and they in turn become more maintainable.
</p>

<p>
It is the responsibility of the entry point to the runtime to make sure that all services are
provided, which is done via the <code>Layer</code> type which provides facilities to manage service implementations
with caching and life cycle management. But that, unfortunately, is definitely the subject of a complete
write up of its own.
</p>
</div>
<ol class="org-ol">
<li><a id="ID-18C3DE1B-15BA-4627-94D5-B37A7345121A"></a>Have thoughts?<br>
<div class="outline-text-5" id="text-8-0-6-1">
<p>
Leave your thoughts and comments on the <a href="https://mastodon.sdf.org/@mavnn/113147588182072037">Mastodon</a> announcement post, and I'll engage with them there.
</p>
</div>
</li>
</ol>
</div>
]]></description>
</item>
<item>
<title>Types et al as accessibility tools for the ADHD brain</title>
<link>https://blog.mavnn.eu/2024/05/17/adhd_refs.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/05/17/adhd_refs.html</guid>
<pubDate>Fri, 17 May 2024 00:00:00 +0200</pubDate>

<description><![CDATA[<p>
I ended up with a fair number of references for my talks at <a href="https://www.youtube.com/watch?v=vd1-rAIYV6I">Software You Can Love</a> and <a href="https://www.youtube.com/watch?v=DG5gLPFKcbk">LambdaDays 2024</a> on how I use various tools and techniques to compensate for my late diagnosed ADHD. The two talks are based off the same outline and slides, although the speaker having ADHD the content does vary a bit between them...
</p>

<p>
Now, the list of links!
</p>
<div id="outline-container-ID-B4A5140D-79AA-4F28-A8C6-87122DC32499" class="outline-4">
<h4 id="ID-B4A5140D-79AA-4F28-A8C6-87122DC32499"><span class="section-number-4">9.0.1.</span> About ADHD</h4>
<div class="outline-text-4" id="text-9-0-1">
<p>
"How to ADHD" has lots of material on what ADHD is, how it manifests, and what you can do about it: <a href="https://howtoadhd.com/">https://howtoadhd.com/</a>
</p>

<p>
A paper reviewing research on working memory in adults with ADHD: <a href="https://psycnet.apa.org/record/2013-16996-001">https://psycnet.apa.org/record/2013-16996-001</a>
</p>

<p>
Mads Torgersen (lead designer of C# at Microsoft) talks about his own diagnosis on the No Dogma Podcast: <a href="https://nodogmapodcast.bryanhogan.net/165-mads-torgersen-adhd/">https://nodogmapodcast.bryanhogan.net/165-mads-torgersen-adhd/</a>
</p>

<p>
(Bonus extra: that last link has <i>more</i> links to more ADHD resources)
</p>

<p>
Finally, I mentioned at one point an organization tool that happens to mesh fairly well with my own variant of ADHD called SkedPal: <a href="https://skedpal.com/">https://skedpal.com/</a>. You prioritize tasks in advance, and assign them to "time maps" (i.e. this times are work times, these times are home times). Then you hit the button and it suggests a calendar of tasks. I've found it useful because it allows things like "this task is important to me but it doesn't matter when it is done" and "this task isn't very important but if I'm going to do it, it needs happen by Friday" and it will suggest a sane next thing to do. And when you (inevitably) fail to actually follow the plan, you just hit the button again and it suggests a new plan based on the things you actually did rather than the things it thought you were going to do. Caveat: it's not free software, and it does charge a monthly fee.
</p>
</div>
</div>
<div id="outline-container-ID-78B48E08-53BB-47A7-BB39-8A0A630434B7" class="outline-4">
<h4 id="ID-78B48E08-53BB-47A7-BB39-8A0A630434B7"><span class="section-number-4">9.0.2.</span> Evidence (or not) of my favourite programming techniques being better</h4>
<div class="outline-text-4" id="text-9-0-2">
<p>
Dan Luu's tour de force review of research into whether or not strong typing leads to more reliable code: <a href="https://danluu.com/empirical-pl/">https://danluu.com/empirical-pl/</a>
</p>

<p>
Brian Marick has a well thought out post on why he's not fully convinced by property based testing: <a href="https://www.crustofcode.com/a-reluctant-rebuttal/">https://www.crustofcode.com/a-reluctant-rebuttal/</a>. Most importantly he links to a paper written in <i>1990</i> that partition testing has some issues, all of which would also apply to property based testing: <a href="https://www.site.uottawa.ca/~gvj/papers/Software%20Engineering%20IEEE%20Transactions%20on%201990%20Hamlet.pdf">https://www.site.uottawa.ca/~gvj/papers/Software%20Engineering%20IEEE%20Transactions%20on%201990%20Hamlet.pdf</a>. It is worth noting that both Marick (about PBT), and Hamlet and Taylor (about partition testing) do state that they see use cases for these testing methods, but that they do also have concerns.
</p>

<p>
The arguments I've heard against domain driven design have tended to be more anecdotal but mostly boil down to: "you're making the code harder to understand by forcing developers to understand both the code <i>and</i> the specialist terminology of the users at the same time."
</p>
</div>
</div>
<div id="outline-container-ID-2386DEA4-944F-4A18-8694-2C6205AA1B4B" class="outline-4">
<h4 id="ID-2386DEA4-944F-4A18-8694-2C6205AA1B4B"><span class="section-number-4">9.0.3.</span> Going deeper on Property Based Testing</h4>
<div class="outline-text-4" id="text-9-0-3">
<p>
I happen to be a fan of Scott Wlaschin's video and blog posts at <a href="https://fsharpforfunandprofit.com/pbt/">https://fsharpforfunandprofit.com/pbt/</a> titled "The lazy programmer's guide to writing 1000's of tests".
</p>

<p>
Otherwise, a quick google search for "John Hughes" will net you many talks from the author of the first property based testing framework.
</p>

<p>
Fuzz testing is a related topic which somewhat overlaps, but with a different focus.
</p>
</div>
</div>
<div id="outline-container-ID-EC0190DB-D50D-4F8D-8A40-FA92DDE5D7D8" class="outline-4">
<h4 id="ID-EC0190DB-D50D-4F8D-8A40-FA92DDE5D7D8"><span class="section-number-4">9.0.4.</span> Leaning into union types, and domain driven design</h4>
<div class="outline-text-4" id="text-9-0-4">
<p>
I cannot over stress how amazing a book "Domain Modeling Made Functional" is (again, by Scott Wlaschin) <a href="https://pragprog.com/titles/swdddf/domain-modeling-made-functional/">https://pragprog.com/titles/swdddf/domain-modeling-made-functional/</a>. There is also a talk covering the basics available at <a href="https://www.youtube.com/watch?v=MlPQ0FsPxPY">https://www.youtube.com/watch?v=MlPQ0FsPxPY</a>.
</p>
</div>
</div>
<div id="outline-container-ID-2E66E04E-386B-4B40-BCA8-43F86A9CF423" class="outline-4">
<h4 id="ID-2E66E04E-386B-4B40-BCA8-43F86A9CF423"><span class="section-number-4">9.0.5.</span> Pushing the boundaries on types</h4>
<div class="outline-text-4" id="text-9-0-5">
<p>
Probably the place to start is the Idris programming language <a href="https://www.idris-lang.org/">https://www.idris-lang.org/</a>
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>With style: Dev Journal 6</title>
<link>https://blog.mavnn.eu/2024/03/19/dev_journal_6.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/03/19/dev_journal_6.html</guid>
<pubDate>Tue, 19 Mar 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
This post is part 6 of the "Dev Journal" series. <a href="https://blog.mavnn.eu/../../../2024/01/31/dev-journal-1.html">Part 1</a> contains the series index, while the <a href="https://gitlab.com/mavnn/caldance/-/commits/DevJournal6?ref_type=tags">DevJournal6</a> tag for the CalDance project in GitLab holds the state of the repository as described here.
</p>
</blockquote>

<p>
In theory, our log in mechanism works. But in reality it looks like this:
</p>


<figure id="orgca32fae">
<img src="https://blog.mavnn.eu/2024/03/19/before.png" alt="before.png">

<figcaption><span class="figure-number">Figure 1: </span>Two unstyled, unlabeled text boxes next to a "Submit" button</figcaption>
</figure>

<p>
This is the post where we give it a make over, so that it starts looking more like this...
</p>


<figure id="org4327bc2">
<img src="https://blog.mavnn.eu/2024/03/19/after.png" alt="after.png">

<figcaption><span class="figure-number">Figure 2: </span>A snazzy looking login page</figcaption>
</figure>

<p>
...while also starting to build in some interactivity, usability, and feedback via HTMX.
</p>
<div id="outline-container-ID-4B05DDD9-706E-49FD-97C9-CA4EBE67F443" class="outline-4">
<h4 id="ID-4B05DDD9-706E-49FD-97C9-CA4EBE67F443"><span class="section-number-4">10.0.1.</span> The good, the bad, and the ugly</h4>
<div class="outline-text-4" id="text-10-0-1">
<p>
You may remember from <a href="https://blog.mavnn.eu/../../../2024/01/31/dev-journal-1.html">part 1</a> that HTMX and Falco's markup library are both tools I'm trying out for the first time. This means that while I'm happy with the <i>results</i> I achieved in this post, I'm not all that happy with the resulting code. Yet. There will be a refactoring follow up.
</p>

<p>
Which translates to: don't take anything as an active recommendation of how to do things, but a chance to follow along as I learn a new tool.
</p>
</div>
</div>
<div id="outline-container-ID-30590793-83EB-4FD3-AFC1-411B8280D45F" class="outline-4">
<h4 id="ID-30590793-83EB-4FD3-AFC1-411B8280D45F"><span class="section-number-4">10.0.2.</span> The logic behind our changes</h4>
<div class="outline-text-4" id="text-10-0-2">
<p>
My first attempt at nice server side UI building hinges on two key ideas. 1) each domain module should be responsible for its own UI requirements and 2) the overall UI should look coherent.
</p>

<p>
This sounds like a place for a style guide, so I created a <code>StyleGuide</code> directory and started hacking. We ended up with four files in here, each with their own little area of responsibility.
</p>
</div>
<ol class="org-ol">
<li><a id="ID-A17A6655-D65B-4D93-A18C-D80617B57947"></a>Htmx<br>
<div class="outline-text-5" id="text-10-0-2-1">
<p>
The <code>Htmx.fs</code> file (<a href="https://gitlab.com/mavnn/caldance/-/merge_requests/5/diffs#e08193e43a637c573f535f953ec65131eded9044">link to the diff</a>) is arguably not really part of the style guide, but it seemed the best place I had to put it.
</p>

<p>
It defines a series of HTMX related attributes that I can then add to elements in other places without worrying about misspelling them.
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-function-name">post</span> <span class="org-variable-name">url</span> = Attr.create <span class="org-string">"hx-post"</span> url
<span class="org-keyword">let</span> <span class="org-function-name">get</span> <span class="org-variable-name">url</span> = Attr.create <span class="org-string">"hx-get"</span> url
<span class="org-keyword">let</span> <span class="org-function-name">target</span> <span class="org-variable-name">elemId</span> = Attr.create <span class="org-string">"hx-target"</span> elemId
<span class="org-keyword">let</span> <span class="org-function-name">swap</span> <span class="org-variable-name">details</span> = Attr.create <span class="org-string">"hx-swap"</span> details
<span class="org-keyword">let</span> <span class="org-variable-name">boost</span> = Attr.createBool <span class="org-string">"hx-boost"</span>
<span class="org-keyword">let</span> <span class="org-function-name">indicator</span> <span class="org-variable-name">selector</span> = Attr.create <span class="org-string">"hx-indicator"</span> selector
</pre>
</div>

<p>
It also provides a helper for endpoints responding to requests which may or may not be coming from HTMX. Remember that HTMX works by allowing you to respond to a request with a fragment of HTML which will then get embedded into the already loaded page, rather than requiring a full page refresh. This is great, but it means that endpoints which represent a "whole page" can end up being called in one of two ways: by HTMX wanting just the body of the page to embed, and by the browser trying to just load a URL.
</p>

<p>
It felt like the logic for branching between these scenarios was going to come up enough it was worth capturing in a named function, so I did:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-function-name">htmxOrFull</span> <span class="org-variable-name">branches</span> =
  handler {
    <span class="org-keyword">let!</span> headers = Request.getHeaders <span class="org-fsharp-ui-operator">|&gt;</span> Handler.fromCtx

    <span class="org-keyword">let</span> <span class="org-variable-name">hasHxRequestHeader</span> =
      headers.Keys.Contains <span class="org-string">"HX-Request"</span>

    <span class="org-keyword">let</span> <span class="org-variable-name">isRequestingFullPage</span> =
      <span class="org-keyword">match</span>
        headers.TryGetBoolean <span class="org-string">"HX-History-Restore-Request"</span>
      <span class="org-keyword">with</span>
      <span class="org-fsharp-ui-operator">|</span> Some <span class="org-keyword">true</span> -&gt; <span class="org-keyword">true</span>
      <span class="org-fsharp-ui-operator">|</span> Some <span class="org-keyword">false</span>
      <span class="org-fsharp-ui-operator">|</span> None -&gt; <span class="org-keyword">false</span>

    <span class="org-keyword">if</span> hasHxRequestHeader &amp;&amp; (<span class="org-keyword">not</span> isRequestingFullPage) <span class="org-keyword">then</span>
      <span class="org-keyword">return!</span> branches.onHtmx
    <span class="org-keyword">else</span>
      <span class="org-keyword">return!</span> branches.onFull
  }
</pre>
</div>

<p>
We'll be seeing this again in a bit.
</p>
</div>
</li>
<li><a id="ID-77553923-976D-4723-8604-C613A736C6F5"></a>Modifier<br>
<div class="outline-text-5" id="text-10-0-2-2">
<p>
I'm planning on using Bulma as the basis for my CSS as it hits a reasonably sweet spot for me between having a good enough version of "most things" built in and not requiring me to mutate my HTML <i>too</i> much to accommodate it. So the next thing to add was constants for some of the most common modifier classes that Bulma supports.
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">module</span> <span class="org-type">Mavnn.CalDance.StyleGuide.Modifiers</span>

<span class="org-keyword">open</span> <span class="org-type">Falco.Markup</span>

<span class="org-keyword">let</span> <span class="org-variable-name">isPrimary</span> = Attr.class' <span class="org-string">"is-primary"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">isLink</span> = Attr.class' <span class="org-string">"is-link"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">isInfo</span> = Attr.class' <span class="org-string">"is-info"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">isSuccess</span> = Attr.class' <span class="org-string">"is-info"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">isWarning</span> = Attr.class' <span class="org-string">"is-warning"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">isDanger</span> = Attr.class' <span class="org-string">"is-danger"</span>
</pre>
</div>

<p>
Boom. Done. Compiler as a spellcheck, tick.
</p>
</div>
</li>
<li><a id="ID-B5DF3A2F-E613-46DE-B57A-C6159504E6F2"></a>Layout<br>
<div class="outline-text-5" id="text-10-0-2-3">
<p>
As with the modifiers, I wanted to make it a little bit easier to do the "right thing" when creating a view, so I set up <code>Layout.fs</code> (<a href="https://gitlab.com/mavnn/caldance/-/merge_requests/5/diffs#fa9c7c3d5630a543415353918d553e91b7edc402">link to the diff</a>) which includes a <code>page</code> function that takes a title and a list of sections and a set of broadly applicable elements like titles and links.
</p>

<p>
At the moment the page template loads all of the libraries from shared CDNs, which is something we'll want to change before going to production. We're grabbing Bulma and HTMX as you'd expect, and also the "morphing" library written by the HTMX authors which attempts to only replace elements in the DOM that have actively changed. We also add a <code>meta</code> element to tell HTMX that when it adds a class to an element to signify it is loading, it should use the <code>is-loading</code> class from Bulma rather than the <code>htmx-request</code> class it defaults to.
</p>
</div>
</li>
<li><a id="ID-DE4A5001-4689-4987-9493-BD4FC4CE1396"></a>Form<br>
<div class="outline-text-5" id="text-10-0-2-4">
<p>
The <code>Form.fs</code> module (<a href="https://gitlab.com/mavnn/caldance/-/merge_requests/5/diffs#26465d4af42079e4d5f2d9c698268260af59e9a0">link to the diff</a>) is the place where I feel I've probably over engineered things. I started putting together a set of builder helpers and types for building forms and... yeah. I don't know. I think it's probably ended up a case of trying to add the abstraction before building the second use of something, and it shows. I'm not all that happy with the code that results.
</p>

<p>
I'm not going to go into too much detail on this one, I'm just going to show it in use and remind the reader that this API may change in the future.
</p>
</div>
</li>
</ol>
</div>
<div id="outline-container-ID-CF0DF514-DB81-472E-AB40-9D910120C365" class="outline-4">
<h4 id="ID-CF0DF514-DB81-472E-AB40-9D910120C365"><span class="section-number-4">10.0.3.</span> Actually doing the thing</h4>
<div class="outline-text-4" id="text-10-0-3">
<p>
With our helpers constructed, we can start using them. Simple full page endpoints are quite simple; we just swap in the new <code>Layout</code> functions and we're good to go. For example, the view for the home page now looks like this:
</p>

<div class="org-src-container">
<pre class="src src-fsharp">Layout.page
  <span class="org-string">"Home"</span>
  [ Layout.containerSection
      [ Layout.title
          Layout.T1
          (<span class="org-keyword">match</span> user <span class="org-keyword">with</span>
            <span class="org-fsharp-ui-operator">|</span> Some u -&gt; $<span class="org-string">"Hi {u.username}!"</span>
            <span class="org-fsharp-ui-operator">|</span> None -&gt; <span class="org-string">"You should go log in!"</span>)
        Layout.paragraphX
          []
          [ Text.raw <span class="org-string">"Would you like to "</span>
            Layout.link
              (greeting.greetingLink <span class="org-string">"Bob"</span>)
              <span class="org-string">"greet Bob?"</span> ] ] ]
</pre>
</div>

<p>
As soon as we get to adding things like navigation bars to the page template they will all just appear.
</p>

<p>
The magic, again, begins in the <code>User.fs</code> module. Let's have a think about the request life cycle with HTMX.
</p>
</div>
<ol class="org-ol">
<li><a id="ID-C68CC96B-EBF2-4F88-A779-9DE44418D911"></a>Option 1: the user GETS the log in (or sign up) page<br>
<div class="outline-text-5" id="text-10-0-3-1">
<p>
In this case, we want to send a full page back to the user with an empty "user details" form; this form should not show any validation errors (don't you hate it when a form tells you empty fields aren't allowed before you've started typing?!).
</p>
</div>
</li>
<li><a id="ID-1320BF8F-00EC-48CA-AAC1-BADF1DC6880C"></a>Option 2: the user POSTS invalid user data<br>
<div class="outline-text-5" id="text-10-0-3-2">
<p>
Well, if the form fields just aren't in the POST we should return a 400: something is just broken. But if the correct fields exist and this request is flagged as being made by HTMX, what we want to do is update the form with the information about what the user needs to change. Preferably without removing all the information they've already added!
</p>
</div>
</li>
<li><a id="ID-BE5067E1-0D41-48F6-BB94-34D78C045137"></a>Option 3: the user POSTS valid user data<br>
<div class="outline-text-5" id="text-10-0-3-3">
<p>
In this case we want to log the user in and navigate them somewhere else in the website. We don't just want to return the form, we want to return the special <code>HX-Location</code> header which tells HTMX "load the body of that location and substitute it in to avoid a full page reload".
</p>

<p>
In the case where we return an updated form, it is critical that as closely as possible it has exactly the same HTML structure as before to allow the merge logic to do its thing, so to allow that I built a "user data form" builder function that does all the things we need it to.
</p>

<p>
It's a bit of a monster, but let's have a look:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-keyword">private</span> <span class="org-variable-name">userForm</span>
  <span class="org-variable-name">csrfToken</span>
  <span class="org-variable-name">location</span>
  <span class="org-variable-name">usernameValue</span>
  <span class="org-variable-name">usernameProb</span>
  <span class="org-variable-name">passwordValue</span>
  <span class="org-variable-name">passwordProb</span>
  =
  <span class="org-keyword">let</span> <span class="org-variable-name">userInput</span> =
    Form.InputConfig.make <span class="org-string">"text"</span> <span class="org-string">"username"</span> <span class="org-string">"Your username"</span>
    <span class="org-fsharp-ui-operator">|&gt;</span> Form.InputConfig.addLabel <span class="org-string">"Username"</span>
    <span class="org-fsharp-ui-operator">|&gt;</span> Form.InputConfig.addIcons (Form.Left <span class="org-string">"mdi-account"</span>)
    <span class="org-fsharp-ui-operator">|&gt;</span> Form.InputConfig.setValue usernameValue
    <span class="org-fsharp-ui-operator">|&gt;</span> <span class="org-keyword">fun</span> <span class="org-variable-name">ic</span> -&gt;
        <span class="org-keyword">match</span> usernameProb <span class="org-keyword">with</span>
        <span class="org-fsharp-ui-operator">|</span> Some prob -&gt; Form.InputConfig.addError prob ic
        <span class="org-fsharp-ui-operator">|</span> None -&gt; ic
    <span class="org-fsharp-ui-operator">|&gt;</span> Form.input

  <span class="org-keyword">let</span> <span class="org-variable-name">passwordInput</span> =
    Form.InputConfig.make
      <span class="org-string">"password"</span>
      <span class="org-string">"password"</span>
      <span class="org-string">"Your password"</span>
    <span class="org-fsharp-ui-operator">|&gt;</span> Form.InputConfig.addLabel <span class="org-string">"Password"</span>
    <span class="org-fsharp-ui-operator">|&gt;</span> Form.InputConfig.addIcons (Form.Left <span class="org-string">"mdi-lock"</span>)
    <span class="org-fsharp-ui-operator">|&gt;</span> Form.InputConfig.setValue passwordValue
    <span class="org-fsharp-ui-operator">|&gt;</span> <span class="org-keyword">fun</span> <span class="org-variable-name">ic</span> -&gt;
        <span class="org-keyword">match</span> passwordProb <span class="org-keyword">with</span>
        <span class="org-fsharp-ui-operator">|</span> Some prob -&gt; Form.InputConfig.addError prob ic
        <span class="org-fsharp-ui-operator">|</span> None -&gt; ic
    <span class="org-fsharp-ui-operator">|&gt;</span> Form.input

  Form.form
    { csrfToken = csrfToken
      id = <span class="org-string">"userform"</span>
      modifiers =
        [ Htmx.post location
          Htmx.target <span class="org-string">"closest form"</span>
          Htmx.indicator <span class="org-string">"#userFormSubmit button"</span>
          Htmx.swap <span class="org-string">"morph:{ignoreActiveValue:true}"</span> ]
      controls =
        [ userInput
          passwordInput
          Form.button
            <span class="org-string">"userFormSubmit"</span>
            <span class="org-string">"submit"</span>
            <span class="org-string">"Submit"</span>
            [ Modifiers.isPrimary ]
            <span class="org-string">"Submit"</span> ] }
</pre>
</div>

<p>
The start of the function builds are two input fields, and then the interactive logic is all contained within the 4 HTMX attributes towards the end. These tell HTMX that it should post the form values to the location specified, place a loading indicator on the button within the element with ID <code>userFormSubmit</code>, and then should try and morph the HTML it gets back into the closest form element.
</p>

<p>
Now are post methods can return one of two different responses (assuming that we have form data, etc); if authentication succeeds we can send an empty 200 response with a location header and our session cookies:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-keyword">private</span> <span class="org-function-name">signIn</span> <span class="org-variable-name">authScheme</span> <span class="org-variable-name">principal</span> <span class="org-variable-name">url</span> =
  handler {
    <span class="org-keyword">do!</span>
      Handler.fromCtxTask (<span class="org-keyword">fun</span> <span class="org-variable-name">ctx</span> -&gt;
        task { <span class="org-keyword">do!</span> Auth.signIn authScheme principal ctx })

    <span class="org-keyword">return!</span>
      Handler.fromCtx (
        Response.withHeaders [ <span class="org-string">"HX-Location"</span>, url ]
        &gt;&gt; ignore
      )
  }
</pre>
</div>

<p>
If the data is invalid, we can respond with a form containing the relevant error messages, like so:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-keyword">private</span> <span class="org-function-name">authenticationFailed</span> <span class="org-variable-name">formData</span> <span class="org-variable-name">location</span> =
  <span class="org-keyword">let</span> <span class="org-variable-name">failedAuth</span> =
    <span class="org-string">"Matching username and password not found"</span>

  Response.ofHtmlCsrf (<span class="org-keyword">fun</span> <span class="org-variable-name">token</span> -&gt;
    userForm
      token
      location
      (Some formData.username)
      (Some failedAuth)
      (Some formData.password)
      (Some failedAuth))
</pre>
</div>

<p>
Notice that we're carry through the form data that was posted to us rather than clearing the form out on every submit.
</p>

<p>
This is also the module where we start making use of the HTMX branching helper we set up above, so we can add endpoints like:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-keyword">private</span> <span class="org-function-name">logoutEndpoint</span> <span class="org-variable-name">routeNamespace</span> =
  Handler.toEndpoint
    get
    (logoutRoute routeNamespace)
    (<span class="org-keyword">fun</span> () -&gt;
      Htmx.htmxOrFull
        { onHtmx =
            handler {
              <span class="org-keyword">do!</span> signOut <span class="org-string">"Cookies"</span> <span class="org-string">"/"</span>
              <span class="org-keyword">return</span> Response.ofEmpty
            }
          onFull =
            handler {
              <span class="org-keyword">return</span>
                Response.signOutAndRedirect <span class="org-string">"Cookies"</span> <span class="org-string">"/"</span>
            } })
</pre>
</div>

<p>
Browsing directly to the log out link in your browser will get you a redirect status code response, while clicking a <code>log out</code> link within the web app will take you back to the index page (logged out!) without having to do a full page refresh.
</p>
</div>
</li>
<li><a id="ID-0D737474-111B-446B-96D5-76FA95A751B2"></a>That's a wrap<br>
<div class="outline-text-5" id="text-10-0-3-4">
<p>
So, that's the main changes for this post. As normal there's the link at the top of the post to the repo as it was when the post was written. I'm not totally happy with the internal results here, but I'm happy enough that I don't want to spend time refactoring it before I've started using it on a second use case.
</p>

<p>
Speaking of which, keep an eye out for the next post where we'll actually let a user <i>do</i> something.
</p>
</div>
</li>
</ol>
</div>
]]></description>
</item>
<item>
<title>Internal quality review: Dev Journal 5</title>
<link>https://blog.mavnn.eu/2024/03/09/dev_journal_5.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/03/09/dev_journal_5.html</guid>
<pubDate>Sat, 09 Mar 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
This post is part 5 of the "Dev Journal" series. <a href="https://blog.mavnn.eu/../../../2024/01/31/dev-journal-1.html">Part 1</a> contains the series index, while the <a href="https://gitlab.com/mavnn/caldance/-/commits/DevJournal5?ref_type=tags">DevJournal5</a> tag for the CalDance project in GitLab holds the state of the repository as described here.
</p>
</blockquote>

<p>
Refactoring. One of those terms that gets thrown around a lot by developers, but rarely gets well defined.
</p>

<p>
Keeping a code base reliable, easy to maintain, and fast to deliver on is hard work, and often gets confused when we start talking about writing code that is "clean" (a word many moral implications that are not appropriate here) or "good" (what does "good" mean anyway?).
</p>

<p>
Fortunately I don't need to write much to clarify your or my thinking here, because Geepaw Hill has already done an excellent job of doing so in this <a href="https://www.geepawhill.org/2018/01/09/underplayed-the-correlation-premise-in-depth/">2018 blog post</a> where he explains the term "internal quality", which is the quality level of a code base as measured by how easy it is for <i>humans to change the code correctly</i>.
</p>

<p>
Go read the post. It's good, I'll wait. Even if (like me) you don't always practice TDD!
</p>

<p>
Once you've done that, you can come back to this post which is about our first round of "internal quality control" commits to the CalDance project now that it actually, you know, does something. <i>None</i> of these commits alter the user experience or functionality of the code in any way.
</p>
<div id="outline-container-ID-78F796F7-ABD8-40BE-A23C-BFBD676A1619" class="outline-4">
<h4 id="ID-78F796F7-ABD8-40BE-A23C-BFBD676A1619"><span class="section-number-4">11.0.1.</span> Commit 1: central package management</h4>
<div class="outline-text-4" id="text-11-0-1">
<blockquote>
<p>
<a href="https://gitlab.com/mavnn/caldance/-/commit/cdef80ad7bea6414357b99060b79d9f4b2cea9cf">Commit diff</a>
</p>
</blockquote>

<p>
The first commit eliminates a surprisingly common source of bugs in a project: mismatched dependency versions between what you test, and what you deploy.
</p>

<p>
To help combat this, in 2022 the NuGet introduced "<a href="https://devblogs.microsoft.com/nuget/introducing-central-package-management/">central package management</a>" which is a mechanism to allow each of your project files to specify <i>which</i> packages it depends on, while managing the versions of <i>all</i> packages across your whole repository in one central location.
</p>

<p>
Given that a new major version of Marten was released recently and I wanted to upgrade to use it, it seemed an ideal moment to put in a top level <code>Directory.Packages.props</code> file and remove the version numbers of dependencies from our <code>fsproj</code> files. An entire category of bugs eliminated permanently.
</p>

<p>
The only code changes in this commit are to account for changes to how custom logging is implemented in Marten 7.0.
</p>
</div>
</div>
<div id="outline-container-ID-8A612358-B65C-4F0E-B647-1EE7B1273AC3" class="outline-4">
<h4 id="ID-8A612358-B65C-4F0E-B647-1EE7B1273AC3"><span class="section-number-4">11.0.2.</span> Commit 2: logging improvements</h4>
<div class="outline-text-4" id="text-11-0-2">
<blockquote>
<p>
<a href="https://gitlab.com/mavnn/caldance/-/commit/14e38a1343566381628179e973c2b47341107a91">Commit diff</a>
</p>
</blockquote>

<p>
Talking about logging, our second commit enhances the logging we added to Marten to make sure that we carry through the <code>RequestId</code> assigned by AspNetCore to any Marten operations. We also add an environment variable switch to change over to structured JSON logging in our packaged docker container; this is considerably more verbose but means that we always know which component is logging and which request the log relates to when we start feeding the logs through to a log aggregator in production.
</p>
</div>
</div>
<div id="outline-container-ID-A8AE7ED2-F7B7-4734-8EDE-A594841AA661" class="outline-4">
<h4 id="ID-A8AE7ED2-F7B7-4734-8EDE-A594841AA661"><span class="section-number-4">11.0.3.</span> Commit 3: tests</h4>
<div class="outline-text-4" id="text-11-0-3">
<blockquote>
<p>
<a href="https://gitlab.com/mavnn/caldance/-/commit/7072d5c5d77128da5330ec03df303ccf15f484d8">Commit diff</a>
</p>
</blockquote>

<p>
I've been lax on testing so far, and the place where that bothered me most was that I wasn't completely certain that the type safe route definition library I'd built would actually construct links that would "round trip" correctly through the AspNetCore machinery.
</p>

<p>
The idea is that I can define a route definition like so:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-keyword">private</span> <span class="org-variable-name">greetingRoute</span> =
  literalSection <span class="org-string">"/greetings/"</span> ./+ stringSection <span class="org-string">"name"</span>
</pre>
</div>

<p>
And using that route definition I should be able to create links to an endpoint that receives any path parameters without them being changed.
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-comment-delimiter">// </span><span class="org-comment">Any path I create with this function...</span>
<span class="org-keyword">let</span> <span class="org-function-name">link</span> <span class="org-variable-name">yourName</span> = greetingRoute.link yourName

<span class="org-comment-delimiter">// </span><span class="org-comment">...should get handled by this endpoint, and</span>
<span class="org-comment-delimiter">// </span><span class="org-comment">~greetingHandler~ should receive ~yourName~ as an input</span>
<span class="org-keyword">let</span> <span class="org-variable-name">greetingEndpoint</span> =
  Handler.toEndpoint get greetingRoute greetingHandler
</pre>
</div>

<p>
I wasn't sure how strings requiring URL escaping would be handled, so I added unit tests that actually call the underlying AspNet libraries to make sure I wasn't going to have any unpleasant surprises.
</p>

<p>
It was a good thing I did, too, because the code did in fact do the wrong thing with strings that needed escaping. So this PR also includes the fixes.
</p>

<p>
You can see the resulting test code in the new <a href="https://gitlab.com/mavnn/caldance/-/blob/DevJournal5/Server.Test/src/RouteDef.fs">RouteDef</a> file in <code>Server.Test</code>, which also shows just how easy it is to create a set of parameterized tests in Expecto.
</p>
</div>
</div>
<div id="outline-container-ID-BD909FE7-8BD7-4160-B331-6AA082658FF4" class="outline-4">
<h4 id="ID-BD909FE7-8BD7-4160-B331-6AA082658FF4"><span class="section-number-4">11.0.4.</span> Commit 4: standardize domain module setup</h4>
<div class="outline-text-4" id="text-11-0-4">
<blockquote>
<p>
<a href="https://gitlab.com/mavnn/caldance/-/commit/f7cec1f8109d0f50ebdc0884c01b30706c137e94">Commit diff</a>
</p>
</blockquote>

<p>
In the previous post I said that I was a bit unhappy with how much of its internals the user domain module was exposing, and maybe I should give a standard way of a domain context to define itself - but it would be premature to do so with only one context.
</p>

<p>
Then I realized that in some ways I already had a couple of other contexts; the home page, which you could claim is a bit borderline to call a context, and the greetings functionality which allows you to greet somebody.
</p>

<p>
In a way this is smoke and mirrors; I'm well aware that these are not really bounded contexts within a domain in the way that we mean when talking about domain driven design. But at the same time, the point of writing this sort of "hello world" code is precisely because it starts telling you enough about the system you're building to be able to start designing based on reality rather than a set of assumptions.
</p>

<p>
Looking at the code in question, it became clear that one thing would definitely already be helpful: an interface defining what endpoints a domain context provides and what config it needed to add to Marten.
</p>

<p>
That led to the <code>DomainSetup</code> module:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">module</span> <span class="org-type">Mavnn.CalDance.DomainSetup</span>

<span class="org-keyword">open</span> <span class="org-type">Falco</span>
<span class="org-keyword">open</span> <span class="org-type">Marten</span>

<span class="org-keyword">type</span> <span class="org-type">IConstructedContext</span> =
  <span class="org-keyword">abstract</span> <span class="org-keyword">member</span> endpoints: <span class="org-type">HttpEndpoint list</span>
  <span class="org-keyword">abstract</span> <span class="org-keyword">member</span> martenConfig: <span class="org-type">StoreOptions</span> -&gt; unit
</pre>
</div>

<p>
A bit of rearranging later, and we now have three domain modules all which export a context class that both implements the interface above and is also a convenient place to expose any link builders that the module wants to expose. A lot of other code could then immediately become private to each module.
</p>
</div>
</div>
<div id="outline-container-ID-1B88A015-A23F-4131-B41D-0A4296ED7D95" class="outline-4">
<h4 id="ID-1B88A015-A23F-4131-B41D-0A4296ED7D95"><span class="section-number-4">11.0.5.</span> Wrapping up</h4>
<div class="outline-text-4" id="text-11-0-5">
<p>
If you're an F# developer (or interested in becoming one) I hope the details of the commits are helpful. But there's a bigger take away here: names don't just matter <i>in</i> our code; talking to people with terminology that is easy for them to grasp and which highlights the areas of shared importance on all sides is an enormously valuable skill. You may well struggle to explain why you want to spend time refactoring ("you want to spend time making changes to the routing module that <i>don't</i> change what the code does?"), but "we need to improve the internal quality of the routing module so that we can write new features more quickly and correctly" is probably much easier to get agreement about.
</p>

<p>
I hope you're enjoying this journey of discovery with me - as always, if you have questions or comments all of the code is in the <a href="https://gitlab.com/mavnn/caldance">CalDance</a> repository on GitLab. And if you'd like someone to help you keep the internal quality of <b>your</b> code base high then reach out about my <a href="https://blog.mavnn.eu/file://../../../2024/01/29/short_term_help.html">short term consultancy</a> services.
</p>

<p>
Next time: <a href="https://blog.mavnn.eu/../../../2024/03/19/dev_journal_6.html">starting to shape up our actual user interface</a>.
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>Log in, log out: Dev Journal 4 (part 2)</title>
<link>https://blog.mavnn.eu/2024/03/05/dev_journal_4_2.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/03/05/dev_journal_4_2.html</guid>
<pubDate>Tue, 05 Mar 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
This post is the second half of a two part update in the "Dev Journal" series. <a href="https://blog.mavnn.eu/../../../2024/03/01/dev_journal_4.html">The first half</a> talks about adding dependencies to the project on postgresql and the Marten event store library, which we'll look at using in this post. <a href="https://blog.mavnn.eu/../../../2024/01/31/dev-journal-1.html">Part 1</a> contains the series index, while the <a href="https://gitlab.com/mavnn/caldance/-/commits/DevJournal4?ref_type=tags">DevJournal4</a> tag for the CalDance project in GitLab holds the state of the repository as described here.
</p>
</blockquote>

<p>
So. We have an event store. Our website is going to have users. How do we go about user management?
</p>
<div id="outline-container-ID-5AE0DC7D-C62C-4E1C-A980-FF6F04DF428E" class="outline-4">
<h4 id="ID-5AE0DC7D-C62C-4E1C-A980-FF6F04DF428E"><span class="section-number-4">12.0.1.</span> Where's the cheese?</h4>
<div class="outline-text-4" id="text-12-0-1">
<p>
To borrow a term from domain driven design, this sounds like a "bounded context" within our system. Other parts of the code may care about certain events happening related to users (users being created, that kind of thing), but they probably shouldn't know or care about how the internals of "a user" work or what it takes to authenticate a user.
</p>

<p>
There are as many ways of organizing your code as there are grains of sand on the beach, but fundamentally all of the ones that help are about choosing where to have boundaries in your code base.
</p>

<p>
We are going to have three horizontal slices; shared library code, domain logic (our "business" code), and execution environment. Vertically we're going to slice the domain logic by bounded context - of which, admittedly, we only have one at the moment.
</p>

<p>
We end up with something like (things further down the table depend on the things above):
</p>

<!-- This HTML table template is generated by emacs 30.1 -->
<table border="1">
  <tr>
    <td colspan="2" align="left" valign="top">
      &nbsp;Http&nbsp;Handler&nbsp;abstraction,&nbsp;UI&nbsp;components&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
  </tr>
  <tr>
    <td align="left" valign="top">
      &nbsp;User&nbsp;domain&nbsp;logic&nbsp;
    </td>
    <td align="left" valign="top">
      &nbsp;Things&nbsp;users&nbsp;do&nbsp;domain&nbsp;logic&nbsp;
    </td>
  </tr>
  <tr>
    <td colspan="2" align="left" valign="top">
      &nbsp;Read&nbsp;configuration&nbsp;files,&nbsp;start&nbsp;the&nbsp;web&nbsp;server&nbsp;&nbsp;&nbsp;
    </td>
  </tr>
</table>

<p>
You'll notice that this doesn't group the code by the technical task the code is trying to achieve, a pattern you'll often find in example project templates where you'll end up with a "Controllers" directory and a "Views" directory. It's also not an organization along "clean/hexagon/ports and adapters" lines with a strict demarcation between code that speaks to the outside world achieved via interfaces and abstractions.
</p>

<p>
It's not that I feel that either of those patterns has no merit (although I feel like the main driver of the first pattern is that you can suggest it even for projects you <i>know nothing about</i> which is a useful property when writing templates and dispensing nuggets of wisdom at conferences about the <b>one true way</b> to organize code). But I do feel that for the vast majority of code bases, it is a far bigger gain to productivity to be able to co-locate code by <i>purpose</i> than by <i>type</i>.
</p>

<p>
Let's face it: while you sometimes pick up a story/card/work ticket that requires you to go and change all the controllers (normally during dependency upgrades), or replace all the database interface implementations (you're about to have a long few months), it is much more likely on a day to day basis that you're trying to add a new field to the data we store about users, and you want to update the data store, business logic, and UI of <i>users</i> to be able to do that. Taking this logic to its logical extremes leads you towards microservices - but that starts to bring in a different type of complexity of its own.
</p>

<p>
All of this to say: there's now a folder called <code>Domain</code> which holds our new, shiny, user management code in a file called: <i>drumroll, please</i> <code>User.fs</code>. Let's have a look at it in detail.
</p>
</div>
</div>
<div id="outline-container-ID-13360A34-BF57-4EE1-A6D6-18B2A2A535EA" class="outline-4">
<h4 id="ID-13360A34-BF57-4EE1-A6D6-18B2A2A535EA"><span class="section-number-4">12.0.2.</span> The cheese. We have found it.</h4>
<div class="outline-text-4" id="text-12-0-2">
<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">module</span> <span class="org-type">Mavnn.CalDance.Domain.User</span>

<span class="org-keyword">open</span> <span class="org-type">Falco</span>
<span class="org-keyword">open</span> <span class="org-type">Falco.Routing</span>
<span class="org-keyword">open</span> <span class="org-type">Falco.Markup</span>
<span class="org-keyword">open</span> <span class="org-type">Falco.Security</span>
<span class="org-keyword">open</span> <span class="org-type">Marten</span>
<span class="org-keyword">open</span> <span class="org-type">Marten.Events.Aggregation</span>
<span class="org-keyword">open</span> <span class="org-type">Marten.Events.Projections</span>
<span class="org-keyword">open</span> <span class="org-type">Mavnn.CalDance</span>
<span class="org-keyword">open</span> <span class="org-type">Mavnn.CalDance.Routing</span>
<span class="org-keyword">open</span> <span class="org-type">System.Security.Claims</span>
<span class="org-keyword">open</span> <span class="org-type">Microsoft.AspNetCore.Identity</span>
</pre>
</div>

<p>
As just mentioned, this module is going to be responsible for the whole vertical slice of the application for user management, so we start by including everything we need from the data store (<code>Marten</code>) through to the UI (<code>Falco.Markup</code>). We could have created sub modules within a Users folder if needed, but the module is only ~300 lines long so I haven't split it up (yet).
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">type</span> <span class="org-type">User</span> = { id: <span class="org-type">System.</span>Guid; username: <span class="org-type">string</span> }

<span class="org-keyword">type</span> <span class="org-type">UserState</span> =
  <span class="org-fsharp-ui-operator">|</span> Active
  <span class="org-fsharp-ui-operator">|</span> Disabled

<span class="org-preprocessor">[&lt;CLIMutable&gt;]</span>
<span class="org-keyword">type</span> <span class="org-type">UserRecord</span> =
  { Id: <span class="org-type">System.</span>Guid
    Username: <span class="org-type">string</span>
    PasswordHash: <span class="org-type">string</span>
    State: <span class="org-type">UserState</span> }

<span class="org-keyword">type</span> <span class="org-type">UserEvent</span> =
  <span class="org-fsharp-ui-operator">|</span> Created <span class="org-keyword">of</span> UserRecord
  <span class="org-fsharp-ui-operator">|</span> PasswordChanged <span class="org-keyword">of</span> passwordHash: <span class="org-type">string</span>
  <span class="org-fsharp-ui-operator">|</span> Disabled
</pre>
</div>

<p>
Next we define a few data types that represent our users, and the events that can happen to them over time. This is important because we are "event sourcing" the state of our users, meaning that the golden source of truth for what state a user is in is defined by what events have happened to them so far. The two representations of the user represent what we care about in the running system (the main <code>User</code> type) and what we need to store about them on disk (the <code>UserRecord</code> type); in general we would expect that other modules <i>might</i> make use of the <code>User</code> type but in general they should not make use of the <code>UserRecord</code> type. Its an open question in my mind whether it should actually be marked as a private type declaration, but I've erred on the side of leaving it available for now.
</p>

<p>
A minor implementation detail: to try and keep the incremental steps of the project manageable I'm using the default (de)serializers for Marten, which require the object to be deserialized from the data base has a default constructor and mutable fields, which we get from the <code>[&lt;CLIMutable&gt;]</code> attribute. We'll probably remove that going forwards by switching to a serialization strategy that works with immutable F# records.
</p>

<p>
The life cycle of our users is very simple at the moment; a <code>Created</code> event signals that a new, active, user was created. That user can change their password, or they can be marked disabled which effectively ends the lifecycle of the user. There's no way to reactivate a user now, although we could always add one later.
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">type</span> <span class="org-type">UserRecordProjection</span>() =
  <span class="org-keyword">inherit</span> <span class="org-type">SingleStreamProjection</span>&lt;UserRecord&gt;()

  <span class="org-keyword">member</span> <span class="org-variable-name">_</span>.<span class="org-function-name">Create</span>(<span class="org-variable-name">userEvent</span>, <span class="org-variable-name">metadata</span>: <span class="org-type">Events.</span><span class="org-variable-name">IEvent</span>) =
    <span class="org-keyword">match</span> userEvent <span class="org-keyword">with</span>
    <span class="org-fsharp-ui-operator">|</span> Created user -&gt; user
    <span class="org-fsharp-ui-operator">|</span> _ -&gt;
      <span class="org-comment-delimiter">// </span><span class="org-comment">We should always receive a created event</span>
      <span class="org-comment-delimiter">// </span><span class="org-comment">first so this shouldn't ever happen...</span>
      <span class="org-comment-delimiter">// </span><span class="org-comment">...but it might, and we don't want to throw</span>
      <span class="org-comment-delimiter">// </span><span class="org-comment">in projections.</span>
      { Id = metadata.Id
        Username = <span class="org-string">""</span>
        PasswordHash = <span class="org-string">""</span>
        State = UserState.Disabled }


  <span class="org-keyword">member</span> <span class="org-variable-name">_</span>.<span class="org-function-name">Apply</span>(<span class="org-variable-name">userEvent</span>, <span class="org-variable-name">userRecord</span>: <span class="org-type">UserRecord</span>) =
    task {

      <span class="org-keyword">match</span> userEvent <span class="org-keyword">with</span>
      <span class="org-fsharp-ui-operator">|</span> Created _ -&gt;
        <span class="org-comment-delimiter">// </span><span class="org-comment">Should never occur after the first event in the stream</span>
        <span class="org-comment-delimiter">// </span><span class="org-comment">so we ignore duplicates</span>
        <span class="org-keyword">return</span> userRecord
      <span class="org-fsharp-ui-operator">|</span> PasswordChanged passwordHash -&gt;
        <span class="org-keyword">match</span> userRecord <span class="org-keyword">with</span>
        <span class="org-fsharp-ui-operator">|</span> { State = UserState.Disabled } -&gt;
          <span class="org-comment-delimiter">// </span><span class="org-comment">Don't update password of disabled users</span>
          <span class="org-keyword">return</span> userRecord
        <span class="org-fsharp-ui-operator">|</span> user -&gt;
          <span class="org-keyword">return</span>
            { user <span class="org-keyword">with</span>
                PasswordHash = passwordHash }
      <span class="org-fsharp-ui-operator">|</span> Disabled -&gt;
        <span class="org-keyword">match</span> userRecord <span class="org-keyword">with</span>
        <span class="org-fsharp-ui-operator">|</span> { State = UserState.Disabled } -&gt;
          <span class="org-keyword">return</span> userRecord
        <span class="org-fsharp-ui-operator">|</span> { State = Active } -&gt;
          <span class="org-keyword">return</span>
            { userRecord <span class="org-keyword">with</span>
                State = UserState.Disabled }
    }
</pre>
</div>

<p>
<code>Marten</code> leans heavily into the code reflection capabilities of the dotnet framework, allowing us to configure our data store in terms of the in program types we want it to store. A "projection" in event sourcing is the logic which takes a list of events (our base line source of truth) and turns it into a current state, so this class defines a projection that will create and/or update <code>UserRecord</code> data in Marten's document store (we know it does this because it implements the <code>SingleStreamProjection&lt;UserRecord&gt;</code> interface). It will project <i>from</i> events of the <code>UserEvent</code> type, because that is the type of the first argument of the <code>Create</code> and <code>Apply</code> methods we have supplied.
</p>

<p>
There are a few conventions we need to follow here to allow for this minimalist a configuration. Our current state type <i>must</i> have an <code>Id</code> (or <code>id</code>) field of type string, uuid, or integer. And when an event matching the signature of our projection is pushed to a stream with an ID, the resulting update to the current status type must produce a document with the same ID as the stream ID.
</p>

<p>
We're treating our records as immutable objects (because we're planning to make them immutable going forward), so our create and apply methods return a <code>Task&lt;UserRecord&gt;</code>; if the document type was mutable we would also have the options of mutating it in place and returning void.
</p>

<p>
With that explanation out of the way, hopefully the state machine that represents our user life cycle is clear in the code above.
</p>

<p>
Now that we can store information about our users, and update them based on what is happening to them, it's time to start implementing the actual responsibilities of the module. We're keeping things minimal to get started, so we'll implement only the three things we <i>really</i> need: sign up, log in, and log out.
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">type</span> <span class="org-type">LoginFormData</span> = { username: <span class="org-type">string</span>; password: <span class="org-type">string</span> }

<span class="org-keyword">let</span> <span class="org-function-name">findUserRecord</span> (<span class="org-variable-name">username</span>: <span class="org-type">string</span>) =
  Marten.withMarten (<span class="org-keyword">fun</span> <span class="org-variable-name">marten</span> -&gt;
    marten
      .Query&lt;UserRecord&gt;()
      .SingleOrDefaultAsync(<span class="org-keyword">fun</span> <span class="org-variable-name">ur</span> -&gt;
        ur.Username = username))
  <span class="org-fsharp-ui-operator">|&gt;</span> Handler.map Marten.returnOption

<span class="org-keyword">let</span> <span class="org-variable-name">loginRoute</span> = RouteDef.literalSection <span class="org-string">"/login"</span>
<span class="org-keyword">let</span> <span class="org-variable-name">logoutRoute</span> = RouteDef.literalSection <span class="org-string">"/logout"</span>
<span class="org-keyword">let</span> <span class="org-variable-name">signupRoute</span> = RouteDef.literalSection <span class="org-string">"/signup"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">getSessionUser</span>: <span class="org-type">Handler</span><span class="org-fsharp-ui-generic">&lt;User option&gt;</span> =
  Handler.fromCtx (<span class="org-keyword">fun</span> <span class="org-variable-name">ctx</span> -&gt;
    <span class="org-keyword">match</span> ctx.User <span class="org-keyword">with</span>
    <span class="org-fsharp-ui-operator">|</span> <span class="org-keyword">null</span> -&gt; None
    <span class="org-fsharp-ui-operator">|</span> principal -&gt;
      <span class="org-keyword">match</span>
        (System.Guid.TryParse(
          principal.FindFirstValue(<span class="org-string">"userId"</span>)
         ),
         principal.FindFirstValue(<span class="org-string">"name"</span>))
      <span class="org-keyword">with</span>
      <span class="org-fsharp-ui-operator">|</span> ((<span class="org-keyword">false</span>, _), _)
      <span class="org-fsharp-ui-operator">|</span> (_, <span class="org-keyword">null</span>) -&gt; None
      <span class="org-fsharp-ui-operator">|</span> ((<span class="org-keyword">true</span>, id), username) -&gt;
        Some { id = id; username = username })
</pre>
</div>

<p>
A few definitions and helpers start us off; what data a form needs to capture for someone to sign up/log on, what urls exist and are managed by this module, and a couple of helper functions for obtaining a user record and a user session from the current HTTP context (using the <code>Handler</code> type we talked about in the last post).
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-variable-name">loginGetEndpoint</span> =
  Handler.toEndpoint get loginRoute (<span class="org-keyword">fun</span> () -&gt;
    Handler.return' (
      Response.ofHtmlCsrf (<span class="org-keyword">fun</span> <span class="org-variable-name">csrfToken</span> -&gt;
        Elem.html
          []
          [ Elem.body
              []
              [ Elem.form
                  [ Attr.<span class="org-keyword">method</span> <span class="org-string">"post"</span> ]
                  [ Elem.input [ Attr.name <span class="org-string">"username"</span> ]
                    Elem.input [ Attr.name <span class="org-string">"password"</span> ]
                    Xss.antiforgeryInput csrfToken
                    Elem.input
                      [ Attr.type' <span class="org-string">"submit"</span>
                        Attr.value <span class="org-string">"Submit"</span> ] ] ] ])
    ))
</pre>
</div>

<p>
Our first end point is straight forward. When we receive a get request to the login path, we reply with a form containing a token to prevent cross site vulnerabilities and username and password fields.
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-keyword">private</span> <span class="org-function-name">makePrincipal</span> <span class="org-variable-name">userRecord</span> =
  <span class="org-keyword">let</span> <span class="org-variable-name">claims</span> =
    [ <span class="org-keyword">new</span> Claim(<span class="org-string">"name"</span>, userRecord.Username)
      <span class="org-keyword">new</span> Claim(<span class="org-string">"userId"</span>, userRecord.Id.ToString()) ]

  <span class="org-keyword">let</span> <span class="org-variable-name">identity</span> = <span class="org-keyword">new</span> ClaimsIdentity(claims, <span class="org-string">"Cookies"</span>)

  <span class="org-keyword">new</span> ClaimsPrincipal(identity)

<span class="org-keyword">let</span> <span class="org-variable-name">passwordHasher</span> = PasswordHasher()

<span class="org-keyword">let</span> <span class="org-function-name">updateUser</span> (<span class="org-variable-name">id</span>: <span class="org-type">System.</span><span class="org-variable-name">Guid</span>, <span class="org-variable-name">events</span>: <span class="org-type">seq</span><span class="org-fsharp-ui-generic">&lt;UserEvent&gt;</span>) =
  handler {
    <span class="org-keyword">do!</span>
      Marten.withMarten (<span class="org-keyword">fun</span> <span class="org-variable-name">marten</span> -&gt;
        task {
          <span class="org-comment-delimiter">// </span><span class="org-comment">explicitly assign this as an array of objects</span>
          <span class="org-comment-delimiter">// </span><span class="org-comment">so that Marten chooses the correct method</span>
          <span class="org-comment-delimiter">// </span><span class="org-comment">overload for `Append`</span>
          <span class="org-keyword">let</span> <span class="org-variable-name">eventObjs</span>: <span class="org-type">obj[</span>] =
            Array.ofSeq events <span class="org-fsharp-ui-operator">|&gt;</span> Array.map box

          marten.Events.Append(id, eventObjs) <span class="org-fsharp-ui-operator">|&gt;</span> ignore
          <span class="org-keyword">return!</span> marten.SaveChangesAsync()
        })

    <span class="org-keyword">return!</span>
      Marten.withMarten (<span class="org-keyword">fun</span> <span class="org-variable-name">marten</span> -&gt;
        marten.LoadAsync&lt;UserRecord&gt;(id))
  }
</pre>
</div>

<p>
Our next end point is going to actually handle the form coming in, so it requires a few more helpers. The web framework we're using will handle things like sessions for us, but only if we "buy into" the .NET standard ways of representing a user, in this case using the <code>ClaimsPrincipal</code> type - so we have a helper to map from one of our user records to a claims principal. We initialize a password hasher which will salt and hash our passwords for us (don't roll your own crypto, folks, especially when your language ecosystem has a decent implementation ready for you). And finally we add an other method that works within our HTTP context expressions - <code>updateUser</code> takes the ID of a user and a list of events and returns the updated <code>UserRecord</code>.
</p>

<p>
With all of that in place, we can write the <code>loginPostEndpoint</code>.
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-variable-name">loginPostEndpoint</span> =
  Handler.toEndpoint post loginRoute (<span class="org-keyword">fun</span> () -&gt;
    handler {
      <span class="org-keyword">let!</span> loginData =
        Handler.formDataOrFail
          (Response.withStatusCode 400 &gt;&gt; Response.ofEmpty)
          (<span class="org-keyword">fun</span> <span class="org-variable-name">f</span> -&gt;
            Option.map2
              (<span class="org-keyword">fun</span> <span class="org-variable-name">username</span> <span class="org-variable-name">password</span> -&gt;
                { username = username
                  password = password })
              (f.TryGetStringNonEmpty <span class="org-string">"username"</span>)
              (f.TryGetStringNonEmpty <span class="org-string">"password"</span>))

      <span class="org-keyword">let!</span> userRecord =
        findUserRecord loginData.username
        <span class="org-fsharp-ui-operator">|&gt;</span> Handler.ofOption (
          Response.withStatusCode 403 &gt;&gt; Response.ofEmpty
        )

      <span class="org-keyword">let</span> <span class="org-variable-name">verificationResult</span> =
        passwordHasher.VerifyHashedPassword(
          userRecord,
          userRecord.PasswordHash,
          loginData.password
        )

      <span class="org-keyword">match</span> verificationResult <span class="org-keyword">with</span>
      <span class="org-fsharp-ui-operator">|</span> PasswordVerificationResult.Failed -&gt;
        <span class="org-keyword">return</span>
          (Response.withStatusCode 403 &gt;&gt; Response.ofEmpty)
      <span class="org-fsharp-ui-operator">|</span> PasswordVerificationResult.Success -&gt;
        <span class="org-keyword">return</span>
          Response.signInAndRedirect
            <span class="org-string">"Cookies"</span>
            (makePrincipal userRecord)
            <span class="org-string">"/"</span>
      <span class="org-fsharp-ui-operator">|</span> PasswordVerificationResult.SuccessRehashNeeded -&gt;
        <span class="org-keyword">let!</span> _ =
          updateUser (
            userRecord.Id,
            [ PasswordChanged(
                passwordHasher.HashPassword(
                  userRecord,
                  loginData.password
                )
              ) ]
          )

        <span class="org-keyword">return</span>
          Response.signInAndRedirect
            <span class="org-string">"Cookies"</span>
            (makePrincipal userRecord)
            <span class="org-string">"/"</span>
      <span class="org-fsharp-ui-operator">|</span> _ -&gt;
        <span class="org-keyword">return</span>
          failwithf
            <span class="org-string">"Unknown password verification result type %O"</span>
            verificationResult

    })
</pre>
</div>

<p>
Time to actually use our <code>handler</code> expression in earnest! There is some personal preference in play here, but personally I really like the clear flow of the request we can see happening in this code. We either have the form data we need, or we return a <code>400</code> error. Then we either find a user record with a matching username, or we return a <code>403</code> error (we don't want to reveal whether a username exists or not, so we return the same code as for when the password is incorrect; security +1, helpful error messages to users -1). Then we check the password, and we either return <code>403</code> (if it is wrong) or log you in if it is correct. A minor piece of extra complexity is introduced by the fact that the password hasher may signal that the password is correct but the <i>hash</i> needs updating in storage, a background operation that the user does not need to know about.
</p>

<p>
I'll leave the other end points for the reader to read at their leisure <a href="https://gitlab.com/mavnn/caldance/-/blob/e62126228d63e77834112a193fcb0396f4410bc5/Server/src/Domain/User.fs">on Gitlab</a>, as they are either trivial (<code>logoutEndpoint</code>) or very similar to the log in end points (<code>signupGetEndpoint</code> and <code>signupPostEndpoint</code>).
</p>

<p>
Finally, we get to the end of the module where we export everything that the web server setup code (the bottom layer in my newly christened "julienned domain sandwich" architecture).
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-variable-name">endpoints</span> =
  [ loginGetEndpoint
    loginPostEndpoint
    logoutEndpoint
    signupGetEndpoint
    signupPostEndpoint ]

<span class="org-keyword">let</span> <span class="org-function-name">martenConfig</span> (<span class="org-variable-name">storeOptions</span>: <span class="org-type">Marten.</span><span class="org-variable-name">StoreOptions</span>) =
  storeOptions.Projections.Add&lt;UserRecordProjection&gt;(
    ProjectionLifecycle.Inline
  )
</pre>
</div>

<p>
At the moment, with only one domain, this is just an adhoc export of the end points we're wanting to add to the webserver and the projections we want to add to <code>Marten</code>. As the project grows, we'll probably add an interface that each of our domain modules will export which will provide to allow a standardized process for consuming the needed configuration. But there's little point trying to proactively create an abstraction over a single example of a pattern.
</p>

<p>
And there you have it; event sourced (basic) user management for our web application. If you have thoughts and questions, drop them as an issue on the <a href="https://gitlab.com/mavnn/caldance/-/blob/e62126228d63e77834112a193fcb0396f4410bc5/Server/src/Domain/User.fs">CalDance repository</a>. I'd love to see example repositories having in depth discussions of when the architecture they suggest is or isn't useful, even if (especially if!) that discussion includes comments critical of the architecture demonstrated.
</p>

<p>
Next up: <a href="https://blog.mavnn.eu/../../../2024/03/09/dev_journal_5.html">a round of internal quality control</a>.
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>Log in, log out: Dev Journal 4 (part 1)</title>
<link>https://blog.mavnn.eu/2024/03/01/dev_journal_4.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/03/01/dev_journal_4.html</guid>
<pubDate>Fri, 01 Mar 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
This post is part of the "Dev Journal" series. <a href="#ID-BEC296E9-14FB-4C4B-9F41-B15462323B56">Foundations: Dev Journal 1</a> contains the series index, while the <a href="https://gitlab.com/mavnn/caldance/-/commits/DevJournal4?ref_type=tags">DevJournal4</a> tag for the CalDance project in GitLab holds the state of the repository as described here.
</p>
</blockquote>

<p>
This is the big one: we have our first piece of event sourcing, and a bunch of infrastructure to get us there. So big, in fact, that I'm going to split the post into two and publish the remainder early next week.
</p>

<p>
A lot has changed, and I'm not going to go into every single detail so if you're following along by hand I made a pull request for the changes added here so that you can <a href="https://gitlab.com/mavnn/caldance/-/merge_requests/2/diffs">see them all in one place</a>.
</p>
<div id="outline-container-ID-E33C5E61-AE0F-4B74-A29E-73E5FD67E09E" class="outline-4">
<h4 id="ID-E33C5E61-AE0F-4B74-A29E-73E5FD67E09E"><span class="section-number-4">13.0.1.</span> Nix pulling its weight</h4>
<div class="outline-text-4" id="text-13-0-1">
<p>
We're about to add a database to our project, and this is an area where Nix really shines.
</p>

<p>
Adding services with pinned versions of dependencies to are development environment is as simple as adding them to the list in <code>flake.nix</code>:
</p>

<div class="org-src-container">
<pre class="src src-nix"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">devShells</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXproperty">default</span></span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">mkShell</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">buildInputs</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">dnc</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">sdk_8_0</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">nixfmt</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">skopeo</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">overmind</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">tmux</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">postgresql</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">fantomas</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">format-all</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">format-stdin</span></span>
    <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">local_postgres</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
The only clever thing we're doing here is also adding a <code>local_postgres</code> command which runs postgres with its data directory set to be a git ignored directory in the repository. This means that a simple git clean will reset the database along with everything else.
</p>

<p>
As a courtesy to developers who may work on code that isn't CalDance, we also set a non-standard port for postgres to use in our <code>.envrc</code> file so that we don't compete with any system wide installations that may already be running.
</p>

<p>
Overmind is a process runner that runs processes as defined in a <code>Procfile</code>, so we add one to the root of the project with the following:
</p>

<div class="org-src-container">
<pre class="src src-procfile">server: dotnet watch --project Server/CalDance.Server.fsproj
postgres: local_postgres
</pre>
</div>

<p>
Now we can run <code>overmind s</code> to start both postgres and a dotnet watcher to live recompile our server code as it changes.
</p>
</div>
</div>
<div id="outline-container-ID-A5DDE40C-9644-4849-BCE1-9514ACB77EC5" class="outline-4">
<h4 id="ID-A5DDE40C-9644-4849-BCE1-9514ACB77EC5"><span class="section-number-4">13.0.2.</span> Adding some nuget dependencies</h4>
<div class="outline-text-4" id="text-13-0-2">
<p>
We're adding dependencies to our server of <a href="https://martendb.io/">Marten</a> (document/event database library that sits on top of postgres) and <a href="https://serilog.net/">Serilog</a> (a nice structured log library).
</p>

<p>
Marten depends on a postgres library with native (i.e. non-dotnet) dlls, so to allow Nix to cache and link to the correct versions of the native code we have to specify which runtimes we expect to be building our code for. For the curious minded, you don't need to do this to be able to run <code>dotnet build</code> directly because the <code>dotnet</code> cli will dynamically download and add the required native libraries - which breaks Nix's caching strategy of a reproducible output from a fixed set of input files.
</p>

<p>
This isn't a huge issue once you know you need to do it; you just add a <code>RuntimeIdentifiers</code> node to your project files under the <code>TargetFramework</code> node like so:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">PropertyGroup</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">OutputType</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span><span class="org-nxml-text">Exe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">OutputType</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">TargetFramework</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span><span class="org-nxml-text">net8.0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">TargetFramework</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">RuntimeIdentifiers</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span><span class="org-nxml-text">osx-arm64;linux-x64;linux-arm64</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">RuntimeIdentifiers</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">PropertyGroup</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
</pre>
</div>

<p>
Then we can add our nuget packages as normal and everything continues to work:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">ItemGroup</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">PackageReference</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Include</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">Falco</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Version</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">4.0.6</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">PackageReference</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Include</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">Marten</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Version</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">6.4.1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">PackageReference</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Include</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">Serilog</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Version</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">3.1.1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">PackageReference</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Include</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">Serilog.AspNetCore</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Version</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">8.0.1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">PackageReference</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Include</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">Serilog.Sinks.Console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Version</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">5.0.1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">ItemGroup</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
</pre>
</div>
</div>
</div>
<div id="outline-container-ID-D19E248C-32B0-4EA2-95A4-E76A4767DA4A" class="outline-4">
<h4 id="ID-D19E248C-32B0-4EA2-95A4-E76A4767DA4A"><span class="section-number-4">13.0.3.</span> Opinionated endpoint builders</h4>
<div class="outline-text-4" id="text-13-0-3">
<p>
In general, the code to handle an endpoint in an AspNet.Core application is a function from <code>HttpContext</code> to <code>Task</code>, where we mutate the HTTP context and then write the correct output stream.
</p>

<p>
Falco gives us an abstraction a little higher than that by giving us a set of composable functions for manipulating the HTTP context, which is already a step forward. But I was finding them harder to compose than I would like because in several cases the functions took two inputs and effectively "branched" the response that could be given - for example, do I have the form fields I expect in this POST request, or am I logged in.
</p>

<p>
I quickly realized that I'd be happier with some kind of "result" mechanism - a way to be able to declare during the specification of a handler that I wanted to short circuit from this point onwards with a failure response.
</p>

<p>
I also knew that I wanted a type safe way of writing handlers for paths with "place holder" sections.
</p>

<p>
Because of that, I added a <code>Routing</code> module in which I've defined a <code>Handler</code> type as below:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">type</span> <span class="org-type">Handler</span>&lt;'a&gt; =
  HttpContext -&gt; Task&lt;HttpContext * Result&lt;'a, HttpHandler&gt;&gt;
</pre>
</div>

<p>
For the sharp eyed among you with functional programming experience you may have spotted this is the same shape as the monad type of a stateful either monad, and indeed we also define a computational expression called <code>handler</code> that allows us to now write our handlers in a more declarative style.
</p>

<p>
The revised <code>indexEndpoint</code> in the main program file gives a good example of what it looks like:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-variable-name">indexRoute</span> = literalSection <span class="org-string">"/"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">indexEndpoint</span> =
  Handler.toEndpoint get indexRoute (<span class="org-keyword">fun</span> () -&gt;
    handler {
      <span class="org-keyword">let!</span> user = User.getSessionUser

      <span class="org-keyword">return</span>
        (Response.ofHtml (
          Elem.html
            []
            [ Elem.body
                []
                [ Elem.h1
                    []
                    [ <span class="org-keyword">match</span> user <span class="org-keyword">with</span>
                      <span class="org-fsharp-ui-operator">|</span> Some u -&gt;
                        Text.raw $<span class="org-string">"Hi {u.username}!"</span>
                      <span class="org-fsharp-ui-operator">|</span> None -&gt;
                        Text.raw <span class="org-string">"You should go log in!"</span> ]
                  Elem.p
                    []
                    [ Text.raw <span class="org-string">"Would you like to "</span>
                      Elem.a
                        [ Attr.href (
                            greetingRoute.link <span class="org-string">"Bob"</span>
                          ) ]
                        [ Text.raw <span class="org-string">"greet Bob?"</span> ] ] ] ]
        ))
    })
</pre>
</div>

<p>
Note the <code>let!</code> on the first line where we pull the user session out of the HTTP context which the computational expression is "invisibly" carrying along for us.
</p>
</div>
</div>
<div id="outline-container-ID-D457E179-8B26-46AA-91B1-3505EAA6F86A" class="outline-4">
<h4 id="ID-D457E179-8B26-46AA-91B1-3505EAA6F86A"><span class="section-number-4">13.0.4.</span> Connecting up the database</h4>
<div class="outline-text-4" id="text-13-0-4">
<p>
Having defined our handler type, it makes sense to make the rest of our tooling easy to use from within the abstraction.
</p>

<p>
The new <code>Marten</code> module contains some boiler plate to configure Marten and add Serilog logging to it, but most importantly it also adds:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-function-name">withMarten</span> <span class="org-variable-name">f</span> =
  Handler.fromCtx (<span class="org-keyword">fun</span> <span class="org-variable-name">ctx</span> -&gt;
    ctx.GetService&lt;IDocumentSession&gt;())
  <span class="org-fsharp-ui-operator">|&gt;</span> Handler.bind (f &gt;&gt; Handler.returnTask)

<span class="org-comment-delimiter">// </span><span class="org-comment">Marten returns null if a record isn't found, but</span>
<span class="org-comment-delimiter">// </span><span class="org-comment">F# records declare they can't be null. This works</span>
<span class="org-comment-delimiter">// </span><span class="org-comment">around that to return an option instead</span>
<span class="org-keyword">let</span> <span class="org-function-name">returnOption</span> <span class="org-variable-name">v</span> =
  <span class="org-keyword">if</span> (v <span class="org-fsharp-ui-operator">|&gt;</span> box <span class="org-fsharp-ui-operator">|&gt;</span> isNull) <span class="org-keyword">then</span> None <span class="org-keyword">else</span> Some v
</pre>
</div>

<p>
Now from within any HTTP handler we're writing, we can write code like:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let!</span> user =
  Marten.withMarten (<span class="org-keyword">fun</span> <span class="org-variable-name">marten</span> -&gt;
    marten.LoadAsync&lt;UserRecord&gt;(id))
</pre>
</div>

<p>
...and as if by magic the request specific Marten session will be pulled out of the HTTP context of the request and we can use it to connect to our data source.
</p>
</div>
</div>
<div id="outline-container-ID-FF489FF2-97BE-43A0-B126-7FA01E630A01" class="outline-4">
<h4 id="ID-FF489FF2-97BE-43A0-B126-7FA01E630A01"><span class="section-number-4">13.0.5.</span> To be continued...</h4>
<div class="outline-text-4" id="text-13-0-5">
<p>
I think that's about enough for this blog post, because I want to leave a whole post for the real meat of this set of changes: our first domain entity, the <code>User</code>.
</p>

<p>
If you want a sneak peak, you can check out the PR and see how we can define a neat vertical slice of responsibility in our code base. The module takes the responsibility for user management all the way from the domain object, the events that can happen to it, the Marten config to make sure those are tracked, through to the paths that it has responsibility for and the UI that will be displayed when they are requested. Lots of fun stuff for us to talk about in the next exciting installment of "Dev Journal": different time, multiple channels, next week.
</p>

<p>
Next up: <a href="https://blog.mavnn.eu/../../../2024/03/05/dev_journal_4_2.html">Log in, log out (part 2)</a>
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>ADHD and TDD</title>
<link>https://blog.mavnn.eu/2024/02/21/adhd_and_tdd.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/02/21/adhd_and_tdd.html</guid>
<pubDate>Wed, 21 Feb 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
This piece of writing started as repost comment on LinkedIn responding to a question from J. B. Rainsberger about <a href="https://www.linkedin.com/posts/jbrains_tdd-adhd-adhd-activity-7165713710492176385-xK56">how people with an ADHD diagnosis experienced TDD</a>. It's a good question, but it's the kind of topic I "own" enough that I don't want to leave my thoughts on it locked away on a platform like LinkedIn, so now they're here too!
</p>
</blockquote>

<p>
This is an interesting one for me; I have both an ADHD diagnosis and I do feel that I use certain programming practices to compensate for it. Something that interests me enough that I'm talking on the subject at Lambda Days 2024, in fact.
</p>

<p>
Any practice that starts with building a feed back loop is going to be helpful from the ADHD point of view; for example, I have a strong preference for strongly typed languages because the compiler will remind me to finish bits I've forgotten about or catch the typos of concentration lapses in the wild.
</p>

<p>
That said, I'm personally not a huge fan of TDD as I've normally met it in the wild (I can see the one true Scotsman replies from here, and some of you are probably even right). And the reason for that dislike is also ADHD related but has nothing to do with the initial writing of the code - but with refactoring.
</p>

<p>
In the vast majority of cases I've seen, TDD has led to code bases with many, many, tests that are tightly coupled to the current implementation of a piece of code because what's actually happened is that each test has been written to confirm the next piece of the implementation is doing what is expected, not to test the overall inputs/outputs of the "block". Mocks that check they are called in a certain order or with certain inputs. Carefully crafted fake dependencies which return the data needed in the correct order and type to satisfy the internal of the function being tested. (Is this what TDD is meant to be? No, not at all - I'm aware)
</p>

<p>
This makes refactoring deeply painful with a pain that hits hard at the heart of ADHD - you're faced with the choice of updating all these painful, pointless, implementation internal specific mocks on the one hand or having the argument about why your refactoring PR "reduces test coverage" on the other. If you're particularly unlucky there aren't any tests covering the actual <span class="underline">behaviour</span> of the original code at all, and now you're left wondering:
</p>

<p>
"But is my refactor really a refactor at all?"
</p>

<p>
(It would be remiss of me not to note that teaching developers how to test behaviour and not implementations is actually a service I offer, partly because I don't want to live with the consequences of them not knowing! See <a href="https://blog.mavnn.eu/../../../2024/01/29/short_term_help.html">my short term consulting page</a>.)
</p>
]]></description>
</item>
<item>
<title>Does it run? Dev Journal 3</title>
<link>https://blog.mavnn.eu/2024/02/20/dev-journal-3.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/02/20/dev-journal-3.html</guid>
<pubDate>Tue, 20 Feb 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
This post is part of the "Dev Journal" series. <a href="https://blog.mavnn.eu/../../../2024/01/31/dev-journal-1.html">Part 1</a> contains the series index, while the <a href="https://gitlab.com/mavnn/caldance/-/commits/DevJournal3?ref_type=tags">DevJournal3</a> tag for the CalDance project in GitLab holds the state of the repository as described here.
</p>
</blockquote>

<p>
A short update this time. <a href="https://gitlab.com/mavnn/caldance/-/issues/3">Gregg Bremer</a> (hi Gregg!) pointed out that running <code>nix run</code> on his linux machine resulted in an error about not being able to find <code>libssl</code>.
</p>

<p>
This neatly highlights one of the weak spots of Nix; while an excellent packaging solution, it isn't perfect. Nix sandboxes your packages by altering the path environment variable, but not everything is located via that mechanism.
</p>

<p>
In this case, <code>nix run</code> ran on my machine because I happened to have the libraries in the "right place" for a self contained dotnet core executable, but Gregg did not.
</p>

<p>
Neither, it turns out, did the docker container I was building. I built and tested it initially with a dotnet console app (which did work, not needing <code>libssl</code>) and then carried on assuming that running <code>nix run</code> on my local machine would also tell me if the docker image could run correctly.
</p>

<p>
I've now fixed up the code in the previous posts (we needed to add some <code>runtimeDeps</code> to our server package, and the docker image start up command needs to create a writable <code>/tmp</code> directory for asp.net to run correctly).
</p>

<p>
Most importantly though, I've also made sure that CI will prevent this from happening again by actually checking that the docker image produced can respond to a request to the index with a 200 response code. This is done by adding "stages" to our CI build; the first does exactly what we were doing already, the second then starts the just finished docker image as a "service" and uses <code>curl</code> to check it can respond to us.
</p>

<p>
You can check out the revised <code>.gitlab-ci.yml</code> file below:
</p>

<div class="org-src-container">
<pre class="src src-yaml">stages:
  - build-container
  - end-to-end-tests

build-container:
  stage: build-container
  image:
    name: "nixos/nix:2.19.3"
  variables:
    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  before_script:
    - nix-env --install --attr nixpkgs.skopeo
  script:
    - mkdir -p "$HOME/.config/nix"
    - echo 'experimental-features = nix-command flakes' &gt; "$HOME/.config/nix/nix.conf"
    - mkdir -p "/etc/containers/"
    - echo '{"default":[{"type":"insecureAcceptAnything"}]}' &gt; /etc/containers/policy.json
    - skopeo login --username "$CI_REGISTRY_USER" --password "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
    - 'nix build .#dockerImage .#test'
    - mkdir testResults
    - 'cp result-1/* testResults'
    - ls -lh ./result
    - 'skopeo inspect docker-archive://$(readlink -f ./result)'
    - 'skopeo copy docker-archive://$(readlink -f ./result) docker://$IMAGE_TAG'
  artifacts:
    when: always
    paths:
      - 'testResults/*.xml'
    reports:
      junit: 'testResults/*.xml'

end-to-end-tests:
  stage: end-to-end-tests
  image:
    name: "nixos/nix:2.19.3"
  variables:
    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
    GIT_STRATEGY: none
  services:
    - name: $IMAGE_TAG
      alias: caldance
  script:
    - curl -f "http://caldance:5001/"
</pre>
</div>

<p>
Next up: <a href="https://blog.mavnn.eu/../../../2024/03/01/dev_journal_4.html">adding in the database</a>
</p>
]]></description>
</item>
<item>
<title>Do notation for TypeScript</title>
<link>https://blog.mavnn.eu/2024/02/19/do-notation-for-typescript.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/02/19/do-notation-for-typescript.html</guid>
<pubDate>Mon, 19 Feb 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
This post is still here as an interesting deep dive into the mechanics of using TypeScript's type system, but
if what you're really looking for is a production ready async/result/state monad for TypeScript I'd strongly
recommend the Effect TS library rather than rolling your own - now I know it exists.
</p>

<p>
I've written a brief introduction here: <a href="https://blog.mavnn.eu/../../../2024/09/16/intro_to_effect_ts.html">A gentle introduction to Effect TS</a>.
</p>
</blockquote>

<p>
This is rather an aside from recent blog posts, but something I found interesting none the less.
</p>

<p>
Fair warning to start us off: this post assumes that you are aware of and understand "do notation" (or "computational expressions" or "monad syntax") and like the idea of having it available in TypeScript.
</p>

<p>
It starts by working through a possible way of implementing a type safe representation of a sequence of monadic operations that has a much nicer user experience than nested continuation functions, and then leads into a lengthy example of both building and showing how to use a monad which I've found very useful when working in TypeScript for handling asynchronous code that needs to meaningfully respond to both successes and failures.
</p>

<p>
The idea is that we're going to go from code that looks like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">processLaxCallback</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">laxOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">commands</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">localFunctions</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallbackDependencies</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">httpRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">try</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">laxSignatureCheck</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">checkSignature</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>httpRequest<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXkeyword">if</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">isFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">signature</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>signature<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">laxContext</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">parseRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">httpRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">laxSignatureCheck</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
    <span class="org-tree-sitter-hl-faceXkeyword">if</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">isFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">laxContext</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>laxContext<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
    <span class="org-tree-sitter-hl-faceXcomment">// ...continued</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">catch</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">e</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXcomment">// ... etc</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

</pre>
</div>

<p>
...to code that looks more like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">processLaxCallback</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">laxOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">commands</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">localFunctions</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallbackDependencies</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
  <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> httpRequest<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">HttpRequest</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallBackState</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"laxSignatureCheck"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">checkSignature</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"laxContext"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">parseRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXcomment">// ...continued</span>
</pre>
</div>

<p>
If you're impatient you can jump straight to <a href="#ID-8B8152C2-E896-4933-A30E-E01276B284A8">appendix 2</a> where you will find a cut and pastable code block with everything you need to play with the code in the TypeScript editor of your choice.
</p>

<p>
For the avoidance of any doubt, all the code in this blog post is available for re-use under the MIT license as list in <a href="#ID-E8C7C73E-C564-4CDE-B2D9-328AFDF256F1">appendix 3</a>.
</p>
<div id="outline-container-ID-873C9832-7988-4EDE-86D3-F9CE34FA0D76" class="outline-4">
<h4 id="ID-873C9832-7988-4EDE-86D3-F9CE34FA0D76"><span class="section-number-4">16.0.1.</span> The idea</h4>
<div class="outline-text-4" id="text-16-0-1">
<p>
TypeScript has one form of monad notation already - the <code>await</code> keyword. Unfortunately, there isn't any way to plug into the mechanism used and define your own alternative <code>bind</code> implementation without doing something dangerously hacky. And, frankly, the last thing your TypeScript code needs is an other sharp edge to cut yourself on.
</p>

<p>
But... what does binding a value in monad notation really do? It doesn't allow you to write code you couldn't have written anyway long hand. It allows you to give the result of a calculation in your code in name in the current scope.
</p>

<p>
So: if we consider the fact that a scope is really just a mapping from names to values, and that TypeScript allows function inputs to alter the type of their output... maybe we can do something with that?
</p>
</div>
</div>
<div id="outline-container-ID-AFA78735-D337-4044-A1CA-111441F7605B" class="outline-4">
<h4 id="ID-AFA78735-D337-4044-A1CA-111441F7605B"><span class="section-number-4">16.0.2.</span> Defining a scope</h4>
<div class="outline-text-4" id="text-16-0-2">
<p>
A type that maps names to values is reasonably easy to define in TypeScript. It looks something like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Keys</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">K</span> <span class="org-tree-sitter-hl-faceXkeyword">in</span> <span class="org-tree-sitter-hl-faceXtype">Keys</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
We can say that anything we're willing to consider as a scope is a type that extends the type above: it will have some keys, which will all be strings, and they will map to some values, which will all be sub types of <code>any</code>.
</p>

<p>
Now we need a type safe way to add a value to the scope.
</p>

<p>
We start with a calculated type which works out what the result of adding a value with a name to a scope should be:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">OldScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">NewField</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">NewValue</span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXtype">OldScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span>
  ? <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">K</span> <span class="org-tree-sitter-hl-faceXkeyword">in</span> <span class="org-keyword">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OldScope</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NewField</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">K</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">NewField</span>
        ? <span class="org-tree-sitter-hl-faceXtype">NewValue</span>
        : <span class="org-tree-sitter-hl-faceXtype">K</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-keyword">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OldScope</span>
        ? <span class="org-tree-sitter-hl-faceXtype">OldScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">K</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span>
        : <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  : <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>


<p>
<details><summary>
...doesn't <code>OldScope</code> always extend <code>any</code>?
</summary><div class="outline-text-2">
</p>

<p>
Well, yes. But it turns out that wrapping the calculated type in a check (even one which is always true) forces <code>tsc</code> to calculate what the resulting type should be.
</p>

<p>
This makes no difference to what code <code>tsc</code> considers correct, but a big difference to how it shows it in an editor; instead of:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXconstructor">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-type">aDate</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">DateTime</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXstring">"aNumber"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">number</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXstring">"aString"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
</pre>
</div>

<p>
...tool tips and error messages will show:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXpropertyXdefinition">aDate</span>: <span class="org-tree-sitter-hl-faceXconstructor">DateTime</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpropertyXdefinition">aNumber</span>: <span class="org-typescript-primitive">number</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpropertyXdefinition">aString</span>: <span class="org-typescript-primitive">string</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
...which is a heck of a lot easier to work with.
</p>

<p>
</div></div></details>
</p>

<p>
This basically says we want a new type that has all the keys in the old scope <i>and</i> the new key, and the fields in the new context are the same type as the old context except the field that has the name <code>NewField</code> which will be of type <code>NewValue</code>.
</p>

<p>
Now we can write a wrapper function that actually does the work at runtime:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">extendScope</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">OldScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">NewField</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">NewValue</span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-variable-name">oldScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OldScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-variable-name">newField</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">NewField</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-variable-name">newValue</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">NewValue</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">addToScope</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>newField<span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span>: newValue<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    ...oldScope<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    ...addToScope<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OldScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NewField</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NewValue</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
You may be wondering why we bothered with the type definition above given that <code>tsc</code> will try and infer the type of a "splat" like the one we return above.
</p>

<p>
<details><summary>
The short answer is: <code>tsc</code> infers it wrong.
</summary><div class="outline-text-2">
</p>

<p>
The longer answer is: <code>tsc</code> infers it wrong when <code>NewField</code> is the same as an existing field name, but <code>NewValue</code> is different to the type of that field on <code>OldContext</code>.
</p>

<p>
<code>tsc</code> always infers the result of splatting two generic objects (<code>A</code> and <code>B</code>) as being <code>A &amp; B</code>. But if you think about an example like this one:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">AString</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> myField<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">ANumber</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> myField<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">number</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">splat</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">a</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">b</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> ...a<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> ...b <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">result</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">splat</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">AString</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ANumber</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">myField</span>: <span class="org-tree-sitter-hl-faceXstring">"hello"</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">myField</span>: <span class="org-tree-sitter-hl-faceXnumber">10</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
You can see that <code>tsc</code> inferring the type of <code>result</code> as <code>AString &amp; ANumber</code> is obviously incorrect. Interestingly, it works out correctly that it is <code>ANumber</code> if you create the <code>splat</code> function with fixed types known at compile time, but that doesn't help us much here.
</div></details>
</p>

<p>
This is all starting to look quite hopeful with us now having a representation of a scope, and a type safe way to add values to it.
</p>
</div>
</div>
<div id="outline-container-ID-2AC459AE-C95A-495C-A64A-BF60A2143E82" class="outline-4">
<h4 id="ID-2AC459AE-C95A-495C-A64A-BF60A2143E82"><span class="section-number-4">16.0.3.</span> Building an operation</h4>
<div class="outline-text-4" id="text-16-0-3">
<p>
The next question we need to answer is what is this going to be the scope <i>of</i>. Monad friendly syntax normally binds names in the scope of a function body, so let's generalize that idea slightly (and with a lot of hand waving) to the idea of the scope of an operation.
</p>

<p>
We want to be able to do two main things with this operation: we want to be able to add steps to it (using the scope accumulated so far), and we want to be able to execute it. The idea of building up an operation like this brings to mind the appropriately named "builder" pattern, where we use a class with some state to "build" up the thing we want. I'm going to call the "add step" method <code>chain</code> (because it feels a fairly intuitive name for what's happening) and the "execute" method <code>execute</code> (no reason needed). To keep the theme, we'll call the builder class a <code>SomethingChain</code> where something is a monad.
</p>

<p>
If such a builder class were to exist, it would allow us to write code like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">monadTest</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">MonadChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">name</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Monad</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">initialInput</span>: name <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"punctuation"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Monad</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"!"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"finalGreeting"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">Monad</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXstring">`Hello </span><span class="org-keyword">${</span><span class="org-default">scope.initialInput</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">${</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded">scope</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXproperty">punctuation</span></span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXbracket"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">}</span></span></span><span class="org-tree-sitter-hl-faceXstring">`</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
The type of <code>monadTest</code> above is a function that takes a string, and returns a monad value of an object with three string fields: "initialInput", "punctuation", and "finalGreeting". As you can see, each step in the chain adds to or overwrites a value in the scope while leaving the rest of the scope available for use later.
</p>

<p>
The pattern of how we implement the builder for each type of monad is going to be pretty much the same (that's the point), but we can also play some neat tricks based on the specific monad we're implementing. The magic is in the <code>chain</code> method, which wraps a perfectly normal "bind" with a call to <code>extendScope</code> from above. Let's see the pattern first in its purest possible form by creating an identity monad chain, along with some comments in the <code>chain</code> method.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXtype">T</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">namespace</span> <span class="org-tree-sitter-hl-faceXconstructor">Monad</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">bind</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">pure</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> value<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">MonadChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> <span class="org-typescript-access-modifier">readonly</span> operation<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">starter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">operation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> starter<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">chain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">MonadChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXcomment">// We need to build the operation to pass to</span>
    <span class="org-tree-sitter-hl-faceXcomment">// the constructor of the chain we're going</span>
    <span class="org-tree-sitter-hl-faceXcomment">// to return</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">chainedOperation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Monad</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
      <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
    <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXcomment">// Get the monadic value of the chain</span>
      <span class="org-tree-sitter-hl-faceXcomment">// up to this point.</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">previousResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Monad</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
        previousResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">output</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
          <span class="org-tree-sitter-hl-faceXcomment">// Use the output from the chain so far /twice/.</span>
          <span class="org-tree-sitter-hl-faceXcomment">// The first time to work out the new value that is</span>
          <span class="org-tree-sitter-hl-faceXcomment">// going to be added to the scope, and the second</span>
          <span class="org-tree-sitter-hl-faceXcomment">// time to as the starting scope passed to ~extendScope~</span>
          <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Monad</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">nextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
            <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Monad</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
              <span class="org-tree-sitter-hl-faceXfunctionXcall">extendScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> nextOutput<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
            <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXcomment">// Wrap the function back into the builder class</span>
    <span class="org-tree-sitter-hl-faceXcomment">// so we can carry on calling chain on it</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">MonadChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>chainedOperation<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-ID-BE3A6B87-2C42-498D-B592-AD9CBB820ABC" class="outline-4">
<h4 id="ID-BE3A6B87-2C42-498D-B592-AD9CBB820ABC"><span class="section-number-4">16.0.4.</span> Some working examples</h4>
<div class="outline-text-4" id="text-16-0-4">
</div>
<ol class="org-ol">
<li><a id="ID-0EAA2D22-8FA4-402D-89B3-BB27766CFB13"></a>Maybe<br>
<div class="outline-text-5" id="text-16-0-4-1">
<p>
Let's start with the classics. Tried of handling nulls and undefined manually? Redefine our bind method and we're done: apart from changing the name, nothing else changes.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXtype">T</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-constant">null</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-constant">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">namespace</span> <span class="org-tree-sitter-hl-faceXconstructor">Maybe</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">bind</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">if</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-constant">null</span> <span class="org-tree-sitter-hl-faceXoperator">||</span> prev <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-variable-name">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-constant">null</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">else</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">pure</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> value<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>


<p>
<details><summary>
The rest of the code is behind the cut to avoid us being too repetitive.
</summary><div class="outline-text-2">
</p>

<div class="org-src-container">
<pre class="src src-typescript"> <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">MaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> <span class="org-typescript-access-modifier">readonly</span> operation<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">starter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">operation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> starter<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">chain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">MaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">chainedOperation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Maybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
      <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
    <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">previousResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Maybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
        previousResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">output</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
          <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Maybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">nextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
            <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Maybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
              <span class="org-tree-sitter-hl-faceXfunctionXcall">extendScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> nextOutput<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
            <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">MaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>chainedOperation<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">maybeTest</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">MaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">name</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
  <span class="org-tree-sitter-hl-faceXconstructor">Maybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">initialInput</span>: name <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"punctuation"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Maybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"!"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"finalGreeting"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">Maybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXstring">`Hello </span><span class="org-keyword">${</span><span class="org-default">scope.initialInput</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">${</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded">scope</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXproperty">punctuation</span></span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXbracket"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">}</span></span></span><span class="org-tree-sitter-hl-faceXstring">`</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> 
</pre>
</div>
<p>
</div></details>
</p>
</div>
</li>
<li><a id="ID-F31D8690-B7F9-4A81-976B-16403C62207D"></a>AsyncMaybe<br>
<div class="outline-text-5" id="text-16-0-4-2">
<p>
Of course, TypeScript has fairly robust tools for handling null and undefined already. But they get pretty painfully verbose if you start needing to handle a lot of asynchronous calls. Chains to the rescue!
</p>

<p>
Our monad definition now looks like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">null</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">undefined</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">namespace</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">bind</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">prevAsync</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">prev</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> prevAsync
    <span class="org-tree-sitter-hl-faceXkeyword">if</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-constant">null</span> <span class="org-tree-sitter-hl-faceXoperator">||</span> prev <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-variable-name">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-constant">null</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">else</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">pure</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Promise</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">resolve</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>value<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
After a quick search and replace, we can now use our chain to start writing significantly clearer code (in my opinion, anyway!).
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXcomment">// An interface representing some external services</span>
<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">interface</span> <span class="org-tree-sitter-hl-faceXtype">MaybeData</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">getName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">null</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">getPunctuation</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXvariableXparameter">name</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">undefined</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXcomment">// Without Chain</span>
<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">before</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
  <span class="org-variable-name">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-variable-name">maybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-variable-name">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">MaybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">name</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>userId<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>name <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-variable-name">null</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-constant">null</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">punctuation</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getPunctuation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>name<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>punctuation <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-variable-name">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-constant">null</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXstring">`Hello </span><span class="org-keyword">${</span><span class="org-default">name</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">${</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded">punctuation</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXbracket"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">}</span></span></span><span class="org-tree-sitter-hl-faceXstring">`</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXcomment">// With Chain</span>
<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">after</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">pure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> userId<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">MaybeData</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"name"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">maybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"punctuation"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">maybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getPunctuation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">name</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"result"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">`</span><span class="org-keyword">${</span><span class="org-default">s.name</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring">{s.punctuation}`</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
Nicer, but still not fully nice. The constructor looks a bit weird, it's annoying that we have to call <code>AsyncMaybe.pure</code> in the last step, and we're returning our entire internal scope at the end of every operation.
</p>

<p>
We can deal with each of these fairly easily though, because one thing the builder pattern is great at is providing an API for building things.
</p>

<p>
A static method gives us a more intuitive way of starting the chain:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">OutputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXcomment">// ...snip rest of code...</span>

  <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">InputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">pure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
We can expose a map method on the chain to avoid having to manually wrap parts of the chain in <code>pure</code>:
</p>

<div class="org-src-container">
<pre class="src src-typescript"> <span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXoperator">&lt;</span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>: <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-keyword">return</span> <span class="org-typescript-this">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
And finally we can add an <code>executeTarget</code> method as an alternative to <code>execute</code> that returns only a single field from the scope.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-function-name">executeTarget</span><span class="org-tree-sitter-hl-faceXoperator">&lt;</span><span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-type">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    AsyncMaybe<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">outputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>outputScope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXbracket">])</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
This allows us to change our code to be just that bit cleaner and clearer:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXcomment">// With Chain</span>
<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">after</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXmethodXcall">start</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  userId<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">MaybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"name"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">maybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"punctuation"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">maybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getPunctuation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">name</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"result"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXstring">`</span><span class="org-keyword">${</span><span class="org-default">s.name</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring">{s.punctuation}`</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeTarget</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"result"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>


<p>
<details><summary>
The full code is here if you want to be able to see it all in context.
</summary><div class="outline-text-2">
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">null</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">undefined</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">namespace</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">bind</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">prevAsync</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">prev</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> prevAsync<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-constant">null</span> <span class="org-tree-sitter-hl-faceXoperator">||</span> prev <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-variable-name">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-constant">null</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">else</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">pure</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">Promise</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">resolve</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>value<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">OutputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> <span class="org-typescript-access-modifier">readonly</span> operation<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">starter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">operation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> starter<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">chain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">chainedOperation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
      <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
    <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">previousResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
        previousResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">output</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
          <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
            <span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
            <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">nextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
              <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
                <span class="org-tree-sitter-hl-faceXfunctionXcall">extendScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> nextOutput<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
              <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
            <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>chainedOperation<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">map</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">executeTarget</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-type">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
        <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">outputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> outputScope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">InputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">pure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>
<p>
</div></details>
</p>
</div>
</li>
</ol>
</div>
<div id="outline-container-ID-6A3FDCDB-9AC0-45EE-B664-1639CCE3D451" class="outline-4">
<h4 id="ID-6A3FDCDB-9AC0-45EE-B664-1639CCE3D451"><span class="section-number-4">16.0.5.</span> Diving deeper: handling errors with style and panache</h4>
<div class="outline-text-4" id="text-16-0-5">
<p>
For our last example we're going to both take things up a notch, and take a bit more advantage of TypeScript's type level programming.
</p>

<p>
We're going to create what I'm going to call, for brevity, the <code>Solid</code> monad. (Technically it's an asynchronous either state monad - mix and match order to taste - but that's a bit of a mouth full). This allows us to think about how to write our code in a slightly different way, separating out the logic of our "happy path" from error handling in a way that would be either very verbose or completely break type safety without some tooling like this builder.
</p>

<p>
Let's first look at the kind of use cases where this monad is useful. Imagine we've created an integration with the "Lax" messaging service, and now when a customer clicks a button in one of the messages we send out our code has to handle a call back from Lax. But we don't know anything about the incoming request initially. We don't know whether it actually comes from Lax, whether we can find the customer organization that the message was sent to, which user of Lax in that organization clicked the button, which user in our application that Lax user maps to...
</p>

<p>
This uncertainty means there's also numerous ways this process could go wrong. Maybe the message isn't actually from Lax (who cryptographically sign their callback payloads). Maybe our database is down. Or maybe Bob clicked the button 30 seconds after Fred did and you can't do that thing anymore. We also need to respond differently and to different people depending on what has failed.
</p>

<p>
To deal with this, each step in the process can either succeed or fail. What we want to do in the case of failure is often highly dependent on both what type of failure has occurred and what information we already have available. As such, it's common to see code that either returns a union type of <code>Success | SemanticallyMeaningfulErrorType(s)</code> or where each operation in turn is wrapped in <code>try ... catch</code> blocks to respond to exceptions in context.
</p>

<p>
Normally in TypeScript the resulting code will end up looking something like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">withoutChain</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
 <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">laxOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">commands</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">localFunctions</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallbackDependencies</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
 <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">httpRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">HttpRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
   <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">signatureOk</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">checkSignature</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">httpRequest</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
   <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>signatureOk<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">kind</span> <span class="org-tree-sitter-hl-faceXoperator">!==</span> <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
     <span class="org-tree-sitter-hl-faceXvariableXbuiltin">console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Error to internal logging service"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
     <span class="org-tree-sitter-hl-faceXkeyword">return</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

   <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">laxContext</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">parseRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
     <span class="org-tree-sitter-hl-faceXpropertyXdefinition">laxSignatureCheck</span>: signatureOk<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
   <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">kind</span> <span class="org-tree-sitter-hl-faceXoperator">!==</span> <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
     <span class="org-tree-sitter-hl-faceXvariableXbuiltin">console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Error to internal logging service"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
     <span class="org-tree-sitter-hl-faceXkeyword">return</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

   <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">command</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> commands<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">parseUntrustedCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
     <span class="org-tree-sitter-hl-faceXpropertyXdefinition">untrustedCommand</span>: laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">actionPayload</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
   <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>command<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">kind</span> <span class="org-tree-sitter-hl-faceXoperator">!==</span> <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
     <span class="org-tree-sitter-hl-faceXvariableXbuiltin">console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Error to internal logging service"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
     <span class="org-tree-sitter-hl-faceXcomment">// Oh! We know how to contact the user now as well!</span>
     <span class="org-tree-sitter-hl-faceXkeyword">await</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">reply</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
       <span class="org-tree-sitter-hl-faceXpropertyXdefinition">laxContext</span>: laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
       <span class="org-tree-sitter-hl-faceXpropertyXdefinition">reply</span>: <span class="org-tree-sitter-hl-faceXstring">"A suitable error message"</span> <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
     <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
     <span class="org-tree-sitter-hl-faceXkeyword">return</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

   <span class="org-tree-sitter-hl-faceXcomment">// ... more code here ...</span>
 <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
This code isn't ideal. Admittedly, it has one big advantage: anyone who has written any TypeScript can immediately see how it works. But it also has a number of flaws. The most important one is that it is so verbose, and in such a repetitive way, that it is actually hard to follow the flow of what the code "wants" to do - the sequence of operations that will be carried out if everything works as expected. Trying to work out how a particular type of error will be handled, or even which types of errors might occur, is even harder.
</p>

<p>
What if we could separate out the straight forward intent of our code on the one hand, but also ensure we handle all of the possible failure states? What if we could compose together multiple operations which each, individually, know how they might fail and end up with a larger operation that <i>still</i> knows all the ways it can fail.
</p>

<p>
Business logic that looks like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">processLaxCallback</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">laxOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">commands</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">localFunctions</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallbackDependencies</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
  <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">HttpRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallBackState</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"laxSignatureCheck"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">checkSignature</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"laxContext"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">parseRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">tap</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">laxContext</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">set</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"laxContext"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxContext<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"command"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">laxContext</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      commands<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">parseUntrustedCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">untrustedCommand</span>: laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">actionPayload</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"userInfo"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">findUserAndOrganization</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">tap</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">set</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"user"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">user</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">tap</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">set</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"organization"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">organization</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"eventsCaused"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> commands<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">executeCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"reply"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> localFunctions<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">createSuccessResponse</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">tap</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">reply</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeTarget</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"eventsCaused"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
Once we've called our code, we can then exhaustively handle any errors it may have produced, safe in the knowledge that if any of the operations we're depending on add a new failure mode the compiler will force us to deal with them appropriately. This consolidates all of our error handling into an other clear and easy to read piece of code, generally looking something like the following:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">switch</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>processResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-variable-name">type</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"NotPermitted"</span>:
    <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"You can't do that"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"ValidationFailed"</span>:
    <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"You sent the wrong information"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"UnrecognizedCommand"</span>:
    <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXstring">"Something is wrong with the message we sent you, sorry!"</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"OrganizationNotFound"</span>:
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"UserNotFound"</span>:
    <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"You don't seem to be fully set up on Lax yet"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"UnableToParseLaxContext"</span>:
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"InvalidLaxSignature"</span>:
    <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Invalid callback"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"CouldNotContactLax"</span>:
    <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXstring">"We tried to send you a message, but something went wrong at Lax's end."</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"LaxRefusedReply"</span>:
    <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXstring">"We tried to send you a message but something went wrong on our end."</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"UnhandledException"</span>:
    <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXstring">"Something went wrong, our support staff will look into it"</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-default">default</span>:
    <span class="org-tree-sitter-hl-faceXcomment">// this is just a function that takes and returns "never"</span>
    <span class="org-tree-sitter-hl-faceXcomment">// to enforce completeness</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">exhausted</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>processResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">failure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>


<p>
Let's do it! We need to both build out our monad, and then also think about how to write the code that uses it.
</p>
</div>
<ol class="org-ol">
<li><a id="ID-48D8B1F7-9E58-411E-A9AE-E2ACE42D28B0"></a>The monad itself<br>
<div class="outline-text-5" id="text-16-0-5-1">
<p>
First let's build the monad we're going to need. To write the code we want to, we know that we need a few properties. Our operations will frequently be asynchronous, so we need to deal with that. They need to be able to declare how they can fail, so we need them to return a success or failure result type. And they need to be able to capture information during the operation <i>even if the operation then fails</i> so that we can make that information available during error handling.
</p>

<p>
Standing on the shoulders of giants, this sounds very much like we're talking about a state monad stacked on top of an either (sometimes called result) monad. The type of a state monad is a function that takes the state so far, and returns the state and a result. The either monad says that the result in question can be either a success or a failure.
</p>

<p>
We're going to place one more restriction on the "state" type, because in our case it will nearly always be true and it simplifies some of the types: all of the fields on the state object being passed through the operations are optional.
</p>

<p>
Let's try and model that as a type in TypeScript.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">SolidSuccess</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  kind<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  value<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">SolidFailure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  kind<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"failure"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  failure<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  state<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  result<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidSuccess</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">SolidFailure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
Now we need a bind and a pure method.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXconstructor">Solid</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">pure</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">state</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-variable-name">result</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">kind</span>: <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">value</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">bind</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">awaitedPrevious</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>state<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">prevResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> awaitedPrevious<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prevResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">kind</span> <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">next</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prevResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">value</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)(</span>prevResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> next<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">else</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">state</span>: prevResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">result</span>: prevResult <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
This, as normal, is where the magic really happens. <code>pure</code> is fairly straight forward; we can lift any concrete value into our monad type by creating a function that takes the current state and returns the same state unchanged along with the concrete value as a "success" result.
</p>

<p>
<code>bind</code>, on the other hand, might have a type signature that is different from what you would expect. It does not limit the failure type of the continuation function to match the existing monad, but instead declares that the new resulting monad has a failure type of <code>Failure | NextFailure</code>. This means that if we, say, start with a monad that has a failure type of <code>NetworkFailure</code> and we bind a follow up operation with a failure type of <code>FileSystemFailure</code> we get a resulting monad that says it could fail with either a network <i>or</i> a file system failure.
</p>

<p>
Pretty snazzy, and one of the areas where TypeScript genuinely shines.
</p>

<p>
Life is much nicer if we also add some helper methods; a short hand for returning a failure, methods to get, set, and update the state being passed through, and finally a helper that captures thrown exceptions and turns them into a typed <code>UnhandledException</code> failure type while also capturing the stack trace.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">UnhandledExceptionFailure</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-default">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"UnhandledException"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  thrown<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXconstructor">Solid</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXcomment">// pure and bind from above go here</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">failure</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">state</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-variable-name">result</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">kind</span>: <span class="org-tree-sitter-hl-faceXstring">"failure"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-default">get</span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
      <span class="org-tree-sitter-hl-faceXpropertyXdefinition">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpropertyXdefinition">result</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">kind</span>: <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">value</span>: state <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">modify</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">newState</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>state<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">state</span>: newState<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">result</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">kind</span>: <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">value</span>: newState <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-default">set</span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Key</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-keyword">keyof</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">key</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Key</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">Key</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">modify</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> ...prev<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>key<span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span>: value <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-constant">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">noThrow</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">UnhandledExceptionFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">try</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">solid</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>state<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">catch</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">e</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">failure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
          <span class="org-default">type</span>: <span class="org-tree-sitter-hl-faceXstring">"UnhandledException"</span> <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
          <span class="org-tree-sitter-hl-faceXpropertyXdefinition">thrown</span>: e<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})(</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
We have a monad now, so our chain should look very familiar; let's put the whole thing here in full so we can admire it in all its abstract beauty. We've added a <code>tap</code> method which puts an operation in the chain that doesn't add anything to the scope, useful for things like updating the state or sending messages, and we've added a call to <code>noThrow</code> in the "execute" methods to make sure that we don't accidentally forget to capture exceptions and so break all our lovely new error handling. Apart from that, it should all look very familiar.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">OutputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> <span class="org-typescript-access-modifier">readonly</span> operation<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">starter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">operation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> starter<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">UnhandledExceptionFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">noThrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">chain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">chainedOperation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
      <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXtype">State</span>
    <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">previousResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>previousResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">output</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">nextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
          <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">extendScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> nextOutput<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>chainedOperation<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">map</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">tap</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">executeTarget</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-type">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">UnhandledExceptionFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">noThrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">outputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
          <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>outputScope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXbracket">])</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">InputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">pure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>
</div>
</li>
<li><a id="ID-8A0808E7-0C7D-4696-81A8-4B5AFB7217AF"></a>Writing the code<br>
<div class="outline-text-5" id="text-16-0-5-2">
<p>
To fully take advantage of our new shiny monad, there's a few simple rules we want to follow.
</p>

<ul class="org-ul">
<li>It should be easy to distinguish between error types; a discriminator field is great for this</li>
<li>We should aim to write our "business" functions to take a single object argument, so that a scope object can be built up that can call them</li>
<li>If at all possible, those arguments should use well known field names for well known pieces of data</li>
</ul>

<p>
This means that we'll end up with external dependencies represented as functions that look something like this (either globally, or wrapped locally for use in the chain if you're not basing your whole code architecture off this blog post: shame on you!):
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">interface</span> <span class="org-tree-sitter-hl-faceXtype">Commands</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">parseUntrustedCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    untrustedCommand<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-variable-name">Command</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-variable-name">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"UnrecognizedCommand"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-variable-name">message</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">executeCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">args</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> user<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">User</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> organization<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    command<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Command</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Events</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-default">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"NotPermitted"</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXstring">"ValidationFailed"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> message<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Following these patterns and combining them with the type safety of the chain builder is enormously powerful, especially for helping out new developers. For example, if you want to call the <code>executeCommand</code> operation you'll find that you can't put it in the chain before the operations that get the command and the user info, and you can't return a chain that doesn't explicitly flag that it may fail with the "NotPermitted" and "ValidationFailed" errors.
</p>
</div>
</li>
</ol>
</div>
<div id="outline-container-ID-AAECB8A5-2E81-49CD-8090-0AFCFC48A9A1" class="outline-4">
<h4 id="ID-AAECB8A5-2E81-49CD-8090-0AFCFC48A9A1"><span class="section-number-4">16.0.6.</span> Appendix 1: Stealing from the best</h4>
<div class="outline-text-4" id="text-16-0-6">
<p>
The advantage of using a standard abstraction like a monad is that someone has done most of the hard thinking already for you. In TypeScript we don't have a nice way of defining code that works on "anything which is a monad", but in Haskell you can - and that means that there's <a href="https://hackage.haskell.org/package/base-4.19.0.0/docs/Control-Monad.html#g:4">collections of functions</a> that you can refer to that are implemented on the basis of something being a monad. This means that if you have a working knowledge of Haskell (or Scala, or an other language where someone has done this work for you already) you can easily add features to your <code>XChain</code> class as you discover you need them.
</p>

<p>
For example, what do you do if you have an array of inputs that you want to map using a <code>Solid</code> returning function?
</p>

<p>
Well, if you check the link above you'll find the <code>mapM</code> function with the signature <code>mapM :: (Traversable t, Monad m) =&gt; (a -&gt; m b) -&gt; t a -&gt; m (t b)</code>. A <code>Traversable</code> is roughly an iterable in TypeScript speak, so we can check how <code>mapM</code> is implemented on a type that would be useful in TypeScript. It turns out it is an alias for the <code>traverse</code> function of whichever <code>t</code> is traversable, so we pick the list implementation as probably being close to what we'd want <a href="https://hackage.haskell.org/package/base-4.19.0.0/docs/src/Data.Traversable.html#line-299">and it is</a>:
</p>

<div class="org-src-container">
<pre class="src src-haskell">instance Traversable [] where
  {-# INLINE traverse #-} -- so that traverse can fuse
  traverse f = List.foldr cons_f (pure [])
    where cons_f x ys = liftA2 (:) (f x) ys
</pre>
</div>

<p>
Hmm. <code>liftA2</code> is a bit weirdly named but it allows a binary operation to happen in our monadic context. We can in turn look up a default implementation of <i>that</i> in terms of what's available in a monad, and we end up with some new helper functions on monad.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXconstructor">Solid</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXcomment">// All the existing monad operations like bind etc...</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">map</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Previous</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>success<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">apply</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">funcInMonad</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>funcInMonad<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>func<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> prev<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">lift2</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">LeftFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">RightFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-variable-name">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Right</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">LeftFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">RightFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">LeftFailure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">RightFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">apply</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Left</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Right</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>left<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> right<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> left<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      right
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">traverse</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">inputs</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> inputs<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">reduce</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">acc</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">lift2</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">results</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
            results<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">push</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>next<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
            <span class="org-tree-sitter-hl-faceXkeyword">return</span> results<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
          acc<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
          <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>next<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">([])</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
Did translating that make my brain hurt a bit? Yes, but it made my brain hurt a lot less than working out that logic for myself. And now you are just a cut and paste away from being able to reuse this same code on any other monads you want to create, and in your solid chains you can right things like:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">traverseExample</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">commandOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Commands</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">untrustedInput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[])</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXmethodXcall">start</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        untrustedInput<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> user<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">User</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> organization<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span>
    <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"parsedCommands"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">untrustedInput</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">traverse</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>untrustedInput<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> commandOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">parseUntrustedCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"resultingEvents"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">parsedCommands</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">traverse</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>parsedCommands<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">command</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
          commandOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">command</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeTarget</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"resultingEvents"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
Warning: there's an argument for not adding too many of these helpers too quickly or to not make all of the intermediate abstractions publicly available. Developers new to functional programming will quickly see the point of a method like <code>traverse</code> when shown an example, but finding something like <code>lift2</code> is going to leave a lot of people scratching their heads.
</p>
</div>
</div>
<div id="outline-container-ID-8B8152C2-E896-4933-A30E-E01276B284A8" class="outline-4">
<h4 id="ID-8B8152C2-E896-4933-A30E-E01276B284A8"><span class="section-number-4">16.0.7.</span> Appendix 2: A slightly excessive example of the Solid monad in action</h4>
<div class="outline-text-4" id="text-16-0-7">
<p>
<details><summary>
You can cut and paste this big fat code block into the TS editor of your choice and have a play with the Solid monad. Go on. It's fun!
</summary><div class="outline-text-2">
</p>


<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Keys</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">K</span> <span class="org-tree-sitter-hl-faceXkeyword">in</span> <span class="org-tree-sitter-hl-faceXtype">Keys</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">OldScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">NewField</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">NewValue</span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXtype">OldScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span>
  ? <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">K</span> <span class="org-tree-sitter-hl-faceXkeyword">in</span> <span class="org-keyword">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OldScope</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NewField</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">K</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">NewField</span>
        ? <span class="org-tree-sitter-hl-faceXtype">NewValue</span>
        : <span class="org-tree-sitter-hl-faceXtype">K</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-keyword">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OldScope</span>
        ? <span class="org-tree-sitter-hl-faceXtype">OldScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">K</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span>
        : <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  : <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">extendScope</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">OldScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">NewField</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">NewValue</span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-variable-name">oldScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OldScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-variable-name">newField</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">NewField</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-variable-name">newValue</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">NewValue</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">addToScope</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>newField<span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span>: newValue<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    ...oldScope<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    ...addToScope<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OldScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NewField</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NewValue</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">null</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">undefined</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">namespace</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">bind</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">prevAsync</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">B</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">prev</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> prevAsync<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-constant">null</span> <span class="org-tree-sitter-hl-faceXoperator">||</span> prev <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-variable-name">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-constant">null</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">else</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">pure</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">A</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Promise</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">resolve</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>value<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> <span class="org-typescript-access-modifier">readonly</span> operation<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">starter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">operation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> starter<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">chain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">chainedOperation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">previousResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>previousResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">output</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">nextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
          <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">extendScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> nextOutput<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>chainedOperation<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">map</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">executeTarget</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-type">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">outputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>outputScope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXbracket">])</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">InputScope</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">pure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">maybeTest</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> initialInput<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"punctuation"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"!"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"finalGreeting"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">`Hello </span><span class="org-keyword">${</span><span class="org-default">scope.initialInput</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">${</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded">scope</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXproperty">punctuation</span></span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXbracket"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">}</span></span></span><span class="org-tree-sitter-hl-faceXstring">`</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">interface</span> <span class="org-tree-sitter-hl-faceXtype">MaybeData</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">getName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">null</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">getPunctuation</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">name</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-type">undefined</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXcomment">// Without Chain</span>
<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">before</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
  <span class="org-variable-name">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-variable-name">maybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-variable-name">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">MaybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">name</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>userId<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>name <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-variable-name">null</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-constant">null</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">punctuation</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getPunctuation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>name<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>punctuation <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-variable-name">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-constant">null</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXstring">`Hello </span><span class="org-keyword">${</span><span class="org-default">name</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">${</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXembedded">punctuation</span></span><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXbracket"><span class="org-tree-sitter-hl-faceXpunctuationXspecial">}</span></span></span><span class="org-tree-sitter-hl-faceXstring">`</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXcomment">// With Chain</span>
<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">after</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor">AsyncMaybeChain</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXmethodXcall">start</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  userId<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  maybeData<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">MaybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"name"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">maybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">userId</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"punctuation"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">maybeData</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">getPunctuation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>s<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">name</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"result"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">s</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXstring">`</span><span class="org-keyword">${</span><span class="org-default">s.name</span><span class="org-keyword">}</span><span class="org-tree-sitter-hl-faceXstring">{s.punctuation}`</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeTarget</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"result"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">exhausted</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">narrowedType</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> narrowedType<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">SolidSuccess</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  kind<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  value<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">SolidFailure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  kind<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"failure"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  failure<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Promise</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  state<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  result<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidSuccess</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">SolidFailure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXconstructor">Solid</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">pure</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">state</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-variable-name">result</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">kind</span>: <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">value</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">failure</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">state</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-variable-name">result</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">kind</span>: <span class="org-tree-sitter-hl-faceXstring">"failure"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">bind</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">awaitedPrevious</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>state<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">prevResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> awaitedPrevious<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prevResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">kind</span> <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">next</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prevResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">value</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)(</span>prevResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> next<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">else</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">state</span>: prevResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">result</span>: prevResult <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-default">get</span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
      <span class="org-tree-sitter-hl-faceXpropertyXdefinition">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpropertyXdefinition">result</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">kind</span>: <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">value</span>: state <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">modify</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">newState</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>state<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">state</span>: newState<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">result</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">kind</span>: <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">value</span>: newState <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-default">set</span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Key</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-keyword">keyof</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">key</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Key</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">value</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">Key</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">modify</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> ...prev<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>key<span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span>: value <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-constant">undefined</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">noThrow</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">UnhandledExceptionFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">try</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">solid</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>state<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">catch</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">e</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">failure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
          <span class="org-default">type</span>: <span class="org-tree-sitter-hl-faceXstring">"UnhandledException"</span> <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
          <span class="org-tree-sitter-hl-faceXpropertyXdefinition">thrown</span>: e<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})(</span><span class="org-variable-name">state</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">map</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Previous</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>prev<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>success<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">apply</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">funcInMonad</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">prev</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextSuccess</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>funcInMonad<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>func<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> prev<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">lift2</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">LeftFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">RightFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-variable-name">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Right</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">LeftFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">RightFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">LeftFailure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">RightFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">apply</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Left</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Right</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>left<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> right<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> left<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      right
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXpropertyXdefinition"><span class="org-tree-sitter-hl-faceXmethod">traverse</span></span>: <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">inputs</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> inputs<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">reduce</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">acc</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">lift2</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">results</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Success</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
            results<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">push</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>next<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
            <span class="org-tree-sitter-hl-faceXkeyword">return</span> results<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
          acc<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
          <span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>next<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">([])</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">UnhandledExceptionFailure</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-default">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"UnhandledException"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  thrown<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
  <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">OutputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> <span class="org-typescript-access-modifier">readonly</span> operation<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">starter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">operation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> starter<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">UnhandledExceptionFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">noThrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">chain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">chainedOperation</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      <span class="org-variable-name">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
      <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXtype">State</span>
    <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">previousResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>previousResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">output</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">nextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
          <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">extendScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>output<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> nextOutput<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>chainedOperation<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">map</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-variable-name">next</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">ExtendedScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextOutput</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">next</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">tap</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">func</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">previous</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">NextFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">operation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXfunctionXcall">func</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>scope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXmethod">executeTarget</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">ResultName</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-type">keyof</span> <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-variable-name">resultName</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">ResultName</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
    <span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">OutputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXtype">ResultName</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">Failure</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXtype">UnhandledExceptionFailure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">noThrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">execute</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>input<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">outputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
          <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">pure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>outputScope<span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>resultName<span class="org-tree-sitter-hl-faceXpunctuationXbracket">])</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">InputScope</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Partial</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">SolidChain</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">never</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">pure</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">InputScope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">HttpRequest</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">User</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Command</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">Events</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">LaxMessage</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">LaxContext</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  laxUserId<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  laxOrganizationId<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  laxResponseUrl<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">URL</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  actionPayload<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">interface</span> <span class="org-tree-sitter-hl-faceXtype">LaxOperations</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">checkSignature</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    httpRequest<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">HttpRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXstring">"laxSignatureOk"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-default">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"InvalidLaxSignature"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> message<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">parseRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxContext</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    laxSignatureCheck<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"laxSignatureOk"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">LaxContext</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-default">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"UnableToParseLaxContext"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> message<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">reply</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxContext</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxContext</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    reply<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxMessage</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXkeyword"><span class="org-tree-sitter-hl-faceXtypeXbuiltin">void</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-default">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"CouldNotContactLax"</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXstring">"LaxRefusedReply"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> message<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">findUserAndOrganization</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxContext</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> user<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">User</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> organization<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-default">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"OrganizationNotFound"</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXstring">"UserNotFound"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> message<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">interface</span> <span class="org-tree-sitter-hl-faceXtype">Commands</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">parseUntrustedCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    untrustedCommand<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-variable-name">Command</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-variable-name">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"UnrecognizedCommand"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-variable-name">message</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">State</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">executeCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">State</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">Scope</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">args</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> user<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">User</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> organization<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    command<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Command</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">Solid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
    <span class="org-tree-sitter-hl-faceXtype">Events</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-default">type</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">"NotPermitted"</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXstring">"ValidationFailed"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> message<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXtype">State</span>
  <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">interface</span> <span class="org-tree-sitter-hl-faceXtype">TheseWouldBeLocalFunctions</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXmethod">createSuccessResponse</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">scope</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    command<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Command</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> user<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">User</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> organization<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    eventsCaused<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Events</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXtype">LaxMessage</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallBackState</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxContext</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  user<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">User</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  organization<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallbackDependencies</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  commands<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Commands</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  localFunctions<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">TheseWouldBeLocalFunctions</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">processLaxCallback</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">laxOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">commands</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">localFunctions</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallbackDependencies</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
  <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">start</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> httpRequest<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">HttpRequest</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallBackState</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"laxSignatureCheck"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">checkSignature</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"laxContext"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">parseRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">tap</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">laxContext</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">set</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"laxContext"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxContext<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"command"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">laxContext</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
      commands<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">parseUntrustedCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">untrustedCommand</span>: laxContext<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">actionPayload</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"userInfo"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">findUserAndOrganization</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">tap</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">set</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"user"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">user</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">tap</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">set</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"organization"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">organization</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"eventsCaused"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> commands<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">executeCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">map</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"reply"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> localFunctions<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">createSuccessResponse</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">tap</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>laxOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">reply</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeTarget</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"eventsCaused"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">laxCallbackHandler</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">deps</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">LaxCallbackDependencies</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">httpRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">HttpRequest</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">processResult</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">processLaxCallback</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>deps<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">httpRequest</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})({})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

    <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>processResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">kind</span> <span class="org-tree-sitter-hl-faceXoperator">===</span> <span class="org-tree-sitter-hl-faceXstring">"success"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXvariableXbuiltin">console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Woot! Created events: "</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> processResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">value</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">else</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXcomment">// Error handling</span>
      <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">reportError</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXkeyword">async</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">message</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXvariableXbuiltin">console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
          <span class="org-tree-sitter-hl-faceXstring">"Always report errors internally with full info including stack trace for unhandled exceptions"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
          processResult
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">if</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>processResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-variable-name">laxContext</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
          <span class="org-tree-sitter-hl-faceXcomment">// We have enough info to tell the user something went wrong.</span>
          <span class="org-tree-sitter-hl-faceXcomment">// In theory we could check if this operation failed, but</span>
          <span class="org-tree-sitter-hl-faceXcomment">// we also can't do anything about it so :shrug:</span>
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> deps<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">laxOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">reply</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
            <span class="org-tree-sitter-hl-faceXpropertyXdefinition">laxContext</span>: processResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">state</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">laxContext</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
            <span class="org-tree-sitter-hl-faceXpropertyXdefinition">reply</span>: message <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span> <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXtype">LaxMessage</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXcomment">// Let's pretend :)</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})({})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXkeyword">switch</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>processResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">failure</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-variable-name">type</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"NotPermitted"</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"You can't do that"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"ValidationFailed"</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"You sent the wrong information"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"UnrecognizedCommand"</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
            <span class="org-tree-sitter-hl-faceXstring">"Something is wrong with the message we sent you, sorry!"</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"OrganizationNotFound"</span>:
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"UserNotFound"</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"You don't seem to be fully set up on Lax yet"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"UnableToParseLaxContext"</span>:
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"InvalidLaxSignature"</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"Invalid callback"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"CouldNotContactLax"</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
            <span class="org-tree-sitter-hl-faceXstring">"We tried to send you a message, but something went wrong at Lax's end."</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"LaxRefusedReply"</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
            <span class="org-tree-sitter-hl-faceXstring">"We tried to send you a message but something went wrong on our end."</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-tree-sitter-hl-faceXkeyword">case</span> <span class="org-tree-sitter-hl-faceXstring">"UnhandledException"</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">await</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">reportError</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
            <span class="org-tree-sitter-hl-faceXstring">"Something went wrong, our support staff will look into it"</span>
          <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXkeyword">break</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        <span class="org-default">default</span>:
          <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">exhausted</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>processResult<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">result</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">failure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">traverseExample</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">commandOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Commands</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">untrustedInput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[])</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">SolidChain</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXmethodXcall">start</span></span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        untrustedInput<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
        userInfo<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> user<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">User</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> organization<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span>
    <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"parsedCommands"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">untrustedInput</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">traverse</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>untrustedInput<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> commandOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">parseUntrustedCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">chain</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"resultingEvents"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">parsedCommands</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
        <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">traverse</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>parsedCommands<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">command</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
          commandOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">command</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
        <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeTarget</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"resultingEvents"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">expandingErrors</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">commandOperations</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Commands</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">untrustedInput</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">any</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">userInfo</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> user<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">User</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> organization<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Organization</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span>
    <span class="org-tree-sitter-hl-faceXconstructor">Solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">bind</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
      commandOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">parseUntrustedCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">untrustedCommand</span>: untrustedInput<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariableXparameter">command</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> commandOperations<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">executeCommand</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">command</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">userInfo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>
<p>
</div></details>
</p>
</div>
</div>
<div id="outline-container-ID-E8C7C73E-C564-4CDE-B2D9-328AFDF256F1" class="outline-4">
<h4 id="ID-E8C7C73E-C564-4CDE-B2D9-328AFDF256F1"><span class="section-number-4">16.0.8.</span> Appendix 3: license</h4>
<div class="outline-text-4" id="text-16-0-8">
<p>
All the code (and only the code) in this blog post is licensed with the MIT license below:
</p>

<blockquote>
<p>
Copyright 2024 Michael Newton
</p>

<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
</p>

<p>
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
</p>

<p>
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</p>
</blockquote>
</div>
</div>
<div id="outline-container-ID-9CE1AF85-A083-4F29-B6AF-9AB76E92615B" class="outline-4">
<h4 id="ID-9CE1AF85-A083-4F29-B6AF-9AB76E92615B"><span class="section-number-4">16.0.9.</span> I have <i>opinions</i></h4>
<div class="outline-text-4" id="text-16-0-9">
<p>
Good stuff! You may have noticed I do as well: the "official" place to comment is on this mastodon post. <a href="https://mastodon.sdf.org/@mavnn/111957791763779112">https://mastodon.sdf.org/@mavnn/111957791763779112</a>
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>Scaffolding: Dev Journal 2</title>
<link>https://blog.mavnn.eu/2024/02/06/dev-journal-2.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/02/06/dev-journal-2.html</guid>
<pubDate>Tue, 06 Feb 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<blockquote>
<p>
This post is part of the "Dev Journal" series. <a href="https://blog.mavnn.eu/../../../2024/01/31/dev-journal-1.html">Part 1</a> contains the series index, while the <a href="https://gitlab.com/mavnn/caldance/-/commits/DevJournal2?ref_type=tags">DevJournal2</a> tag for the CalDance project in GitLab holds the state of the repository as described here.
</p>
</blockquote>

<p>
After the initial set up work that builds our project and packages it for deployment done, it looked might it could be time to write some code. Given we're planning to use htmx, we're going to be spending a lot of time constructing urls to inject into our site that need to match end points on the server so a good starting point seemed to be building a set of helpers for defining "bidirectional routing".
</p>

<p>
Adding the <code>Routing.fs</code> file to the F# project went exactly as you'd expect. We'll come back to this code when we test it properly, but to give you an idea we then updated the main server to actually start returning some HTML. The new <code>Program.fs</code> file new looks like this:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">module</span> <span class="org-type">Mavnn.CalDance.Server</span>

<span class="org-keyword">open</span> <span class="org-type">Falco.HostBuilder</span>
<span class="org-keyword">open</span> <span class="org-type">Falco.Markup</span>
<span class="org-keyword">open</span> <span class="org-type">Mavnn.CalDance.Routing</span>
<span class="org-keyword">open</span> <span class="org-type">Mavnn.CalDance.Routing.Operators</span>

<span class="org-keyword">let</span> <span class="org-variable-name">greetingRoute</span> =
  literalSection <span class="org-string">"greetings/"</span> ./+ stringSection <span class="org-string">"name"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">indexRoute</span> = literalSection <span class="org-string">"/"</span>

<span class="org-keyword">let</span> <span class="org-variable-name">indexEndpoint</span> =
  htmxGet indexRoute (<span class="org-keyword">fun</span> () <span class="org-variable-name">_</span> -&gt;
    Elem.html
      []
      [ Elem.body
          []
          [ Elem.h1 [] [ Text.raw <span class="org-string">"Hi!"</span> ]
            Elem.p
              []
              [ Text.raw <span class="org-string">"Would you like to "</span>
                htmxLink greetingRoute <span class="org-string">"Bob"</span> <span class="org-string">"greet Bob?"</span> ] ] ])

<span class="org-keyword">let</span> <span class="org-variable-name">greetingEndpoint</span> =
  htmxGet greetingRoute (<span class="org-keyword">fun</span> <span class="org-variable-name">name</span> <span class="org-variable-name">_</span> -&gt;
    Elem.html
      []
      [ Elem.body
          []
          [ Elem.h1 [] [ Text.rawf <span class="org-string">"Hi %s!"</span> name ] ] ])

webHost [||] {
  add_antiforgery
  endpoints [ indexEndpoint; greetingEndpoint ]
}
</pre>
</div>

<p>
We now have two routes, one which starts with <code>greetings/</code> and then matches any string, and one which responds at <code>/</code>. You can see in index end point we use our new <code>htmxLink</code> helper to construct a link that will be matched by the greeting end point, and in the greeting end point we supply a handler that knows it is going to receive a string.
</p>

<p>
This is all type safe, and that's lovely and all... but now we have two problems.
</p>

<p>
Let's tackle the biggest problem first!
</p>
<div id="outline-container-ID-CCC21D39-DD12-44D3-BC3F-931A5E1518CB" class="outline-4">
<h4 id="ID-CCC21D39-DD12-44D3-BC3F-931A5E1518CB"><span class="section-number-4">17.0.1.</span> Clarity and style</h4>
<div class="outline-text-4" id="text-17-0-1">
<p>
Writing lists of lists is a succinct and powerful way of representing HTML, but it is also a pain in the backside to format nicely by hand. It's also very easy to bike shed about, leading to a lot of wasted time and churn in commits.
</p>

<p>
One of the best solutions to this is to automate code formatting following a reasonable style guide. This is especially important at the beginning of a project, or (ahem) when writing code you'd like people to follow as an example as it means all of the changes made to the project are because something meaningful has actually changed and there is a consistent style to follow along with.
</p>

<p>
<a href="https://fsprojects.github.io/fantomas/docs/index.html">Fantomas</a> is the code formatter generally used by the F# community. We always want everyone to be using the same version and config, so let's build it into our <code>nix</code> configuration. The nix files we use to structure the set up of the repository are a programming language in their own right, so we can write a function to provide the correct version of Fantomas taking the version of the dotnet runtime as an input argument (we've put this in a separate file in the <code>nix</code> directory to keep things neat).
</p>

<div class="org-src-container">
<pre class="src src-nix"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariableXparameter">pkgs</span></span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariableXparameter">dnc</span></span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>:
<span class="org-tree-sitter-hl-faceXkeyword">let</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">version</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">"6.2.3"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXkeyword">in</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">stdenv</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXproperty">.</span></span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXproperty">mkDerivation</span></span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">pname</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">"fantomas"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">version</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">version</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">nativeBuildInputs</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXkeyword">with</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">unzip</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">makeWrapper</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">src</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXproperty">fetchurl</span></span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">url</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">"https://globalcdn.nuget.org/packages/fantomas.</span><span class="org-nix-antiquote">${</span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">version</span></span></span></span><span class="org-nix-antiquote">}</span><span class="org-tree-sitter-hl-faceXstring">.nupkg"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">hash</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">"sha256-Aol10o5Q7l8s6SdX0smVdi3ec2IgAx+gMksAMjXhIfU="</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">unpackPhase</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">''</span>
<span class="org-tree-sitter-hl-faceXstring">    ls -al $src</span>
<span class="org-tree-sitter-hl-faceXstring">    unzip "$src" -d $out</span>
<span class="org-tree-sitter-hl-faceXstring">  ''</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">installPhase</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">''</span>
<span class="org-tree-sitter-hl-faceXstring">    mkdir -p $out/bin</span>
<span class="org-tree-sitter-hl-faceXstring">    cp -r * $out/bin</span>
<span class="org-tree-sitter-hl-faceXstring">    echo '#! </span><span class="org-nix-antiquote">${</span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">bash</span></span></span></span><span class="org-nix-antiquote">}</span><span class="org-tree-sitter-hl-faceXstring">/bin/bash -e' &gt; $out/bin/fantomas</span>
<span class="org-tree-sitter-hl-faceXstring">    echo "FANTOMAS_PATH=$out/tools/net6.0/any/fantomas.dll" &gt;&gt; $out/bin/fantomas</span>
<span class="org-tree-sitter-hl-faceXstring">    echo '</span><span class="org-nix-antiquote">${</span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">dnc</span></span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">runtime_8_0</span></span></span></span><span class="org-nix-antiquote">}</span><span class="org-tree-sitter-hl-faceXstring">/bin/dotnet $FANTOMAS_PATH "$@"' &gt;&gt; $out/bin/fantomas</span>
<span class="org-tree-sitter-hl-faceXstring">    chmod +x $out/bin/fantomas</span>
<span class="org-tree-sitter-hl-faceXstring">  ''</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
This basically says that we want to download a particular version of Fantomas from nuget (the dotnet package library), unzip it, and then create a shell script that uses our dotnet core runtime to run it. This works because Fantomas is built using an "any CPU" build configuration, allowing us to supply the correct runtime as needed by the system we're currently using but still executing the same compiled dotnet code. For a package that included any CPU specific code the normal nix approach is to download the source and then build it ourselves.
</p>

<p>
Because we put the shell script in the <code>bin</code> directory of the output of this derivation (how nix refers to the definition of an enclosed package), this will be added to the path of any nix shell definition that depends on it. To make people's lives easier, we can also wrap it for common use cases which we do here to create the <code>format-all</code> and <code>format-stdin</code> commands.
</p>

<p>
In our top level <code>flake.nix</code> file we can now import these tools and expose them to our developers:
</p>

<div class="org-src-container">
<pre class="src src-nix"><span class="org-tree-sitter-hl-faceXkeyword">let</span>
  <span class="org-tree-sitter-hl-faceXcomment"># ... snip ...</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">fantomas</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXfunctionXbuiltin">import</span></span></span></span> <span class="org-nix-constant">./nix/fantomas.nix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXkeyword">inherit</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">pkgs</span></span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">dnc</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">format-all</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXfunctionXbuiltin">import</span></span></span></span> <span class="org-nix-constant">./nix/format-all.nix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXkeyword">inherit</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">pkgs</span></span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">fantomas</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">format-stdin</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXfunctionXbuiltin">import</span></span></span></span> <span class="org-nix-constant">./nix/format-stdin.nix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXkeyword">inherit</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">pkgs</span></span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">fantomas</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXcomment"># ... snip ...</span>
<span class="org-tree-sitter-hl-faceXkeyword">in</span> <span class="org-tree-sitter-hl-faceXkeyword">rec</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXcomment"># Tools we want available during development</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">devShells</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXproperty">.</span></span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">default</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXproperty">mkShell</span></span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">buildInputs</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>
      <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">dnc</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">sdk_8_0</span></span>
      <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">nixfmt</span></span>
      <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">skopeo</span></span>
      <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">fantomas</span></span>
      <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">format-all</span></span>
      <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">format-stdin</span></span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXcomment"># ... snip ...</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Now everybody has the same formatting tools available and an easy way to reference them. It even allows us to provide git hooks and/or attribute filters that users can choose to activate that will prevent unformatted code from being pushed or even format it as it is committed to the repository (check out the <a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes">section on smudge and clean filters here</a> if you're interested).
</p>

<p>
I'm normally quite keen on leaving the formatter settings on their default, but given the purpose of this particular repository I've also added a <code>.editorconfig</code> file to the repository to adjust the indentation to two spaces rather than the default four, and to reduce the aimed for line length to 60 characters to make it easier to read in the blog posts.
</p>
</div>
</div>
<div id="outline-container-ID-B7CB2B34-30B3-47AB-8CB7-3385E0950FAC" class="outline-4">
<h4 id="ID-B7CB2B34-30B3-47AB-8CB7-3385E0950FAC"><span class="section-number-4">17.0.2.</span> Testing (local)</h4>
<div class="outline-text-4" id="text-17-0-2">
<p>
Nearly as importantly as the code being readable is whether it actually works. <a href="https://github.com/haf/expecto">Expecto</a> is an F# unit test library that allows you to write executable test programs and defines tests as pieces of data rather than class methods with particular attributes. This can be insanely helpful in writing parameterized tests, which we'll get back to in a later post.
</p>

<p>
Right now though, we just want the tests to exist and be run in CI.
</p>

<p>
We'll start off by moving the existing server code into a directory called (<i>... let the suspense build ...</i>) <code>Server</code>. Next to it we'll create an F# console project called <code>Server.Test</code> and use <code>dotnet add package</code> to add Expecto, along with YoloDev.Expecto.TestSdk and Microsoft.NET.Test.Sdk which allow the project to <i>also</i> be run by calling <code>dotnet test</code> so everybody's editors know how to run the Expecto tests.
</p>

<p>
Finally, we add a project reference to <code>Server</code> from <code>Server.Test</code> and locally at least we're all set for running unit tests!
</p>

<p>
Let's add one to <code>Program.fs</code>:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">module</span> <span class="org-type">Mavnn.CalDance.Server.Test</span>

<span class="org-keyword">open</span> <span class="org-type">Expecto</span>

<span class="org-preprocessor">[&lt;Tests&gt;]</span>
<span class="org-keyword">let</span> <span class="org-variable-name">tests</span> =
  testList
    <span class="org-string">"My list"</span>
    [ testCase <span class="org-string">"hello"</span> (<span class="org-keyword">fun</span> () -&gt;
        Expect.equal
          <span class="org-string">"hello"</span>
          <span class="org-string">"hello"</span>
          <span class="org-string">"Is it me you're looking for?"</span>) ]

<span class="org-preprocessor">[&lt;EntryPoint&gt;]</span>
<span class="org-keyword">let</span> <span class="org-function-name">main</span> <span class="org-variable-name">args</span> =
  <span class="org-comment-delimiter">// </span><span class="org-comment">This allows running with different arguments from the command line,</span>
  <span class="org-comment-delimiter">// </span><span class="org-comment">as well as via `dotnet test`</span>
  runTestsWithCLIArgs [] args tests
</pre>
</div>

<p>
And then we can run it from the root of our project:
</p>

<div class="org-src-container">
<pre class="src src-shell"><span class="org-tree-sitter-hl-faceXfunctionXcall">CalDance</span> on &#57504; main via &#10052;&#65039;  impure (<span class="org-tree-sitter-hl-faceXfunctionXcall">nix-shell</span>)
<span class="org-tree-sitter-hl-faceXfunctionXcall">&#10095;</span> dotnet run <span class="org-tree-sitter-hl-faceXconstant">--project</span>  Server.Test
<span class="org-tree-sitter-hl-faceXcomment"># snipped warning messages about FSharp.Core versions</span>
[<span class="org-tree-sitter-hl-faceXfunctionXcall">15:59:00</span> INF] EXPECTO? Running tests... <span class="org-tree-sitter-hl-faceXoperator">&lt;</span>Expecto<span class="org-tree-sitter-hl-faceXoperator">&gt;</span>
[15:59:00 INF] <span class="org-tree-sitter-hl-faceXfunctionXcall">EXPECTO!</span> 1 tests run<span class="org-keyword"> in</span> 00:00:00.0262215 for My list.hello &#8211; 1 passed, 0 ignored, 0 failed, 0 errored. Success! <span class="org-tree-sitter-hl-faceXoperator">&lt;</span>Expecto<span class="org-tree-sitter-hl-faceXoperator">&gt;</span>

CalDance on &#57504; main via &#10052;&#65039;  impure (<span class="org-tree-sitter-hl-faceXfunctionXcall">nix-shell</span>)
<span class="org-tree-sitter-hl-faceXfunctionXcall">&#10095;</span>
</pre>
</div>

<p>
The current version of Expecto hasn't been updated to the latest FSharp.Core yet but it appears to work fine so we'll just keep an eye on that for now.
</p>
</div>
</div>
<div id="outline-container-ID-1772184B-A936-46B4-906C-E8F14D343119" class="outline-4">
<h4 id="ID-1772184B-A936-46B4-906C-E8F14D343119"><span class="section-number-4">17.0.3.</span> Testing (CI)</h4>
<div class="outline-text-4" id="text-17-0-3">
<p>
Now though, we have a problem. The promise of using Nix was that we wouldn't need to configure CI with lots of setup for things likes tests because our build environment is self contained, and that we could incrementally and deterministically build our sub-components. But now we either create a single nix derivation that has both our projects in, or we need to somehow package the tests separately. We don't want to create a joint derivation because we're compiling down our server code into a self contained enclosure including its own copy of the dotnet runtime.
</p>

<p>
But we can't reference that build output directly from our test project, because it <i>is</i> built as a self contained enclosure but in the test project we want to reference it as a library in a different executable.
</p>

<p>
This is where we play some slightly interesting tricks to get all the properties we want. Do you remember above, where we put the output of the Fantomas derivation in the <code>bin</code> directory to declare that the file in question was an executable? Turns out that we can also put a file in the <code>share</code> directory to signify that it is available to other derivations but is not directly used by any executables in this one.
</p>

<p>
It also turns out that the way the F# helpers in nix manage incremental builds is by assuming that F# nix derivations will provide a Nuget package in the <code>share</code> directory. This means that we can build the server code once as a self-contained executable and put it in the <code>bin</code> folder, but we can <i>also</i> build it again without the self-contained flag and package it into the <code>share</code> folder by adding a hook to our derivation:
</p>

<div class="org-src-container">
<pre class="src src-nix"><span class="org-tree-sitter-hl-faceXcomment"># ... snip ...</span>
<span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">postInstall</span></span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">''</span>
<span class="org-tree-sitter-hl-faceXstring">  </span><span class="org-tree-sitter-hl-faceXpunctuationXspecial"><span class="org-tree-sitter-hl-faceXstring">${</span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">dnc</span></span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">sdk_8_0</span></span></span></span><span class="org-tree-sitter-hl-faceXpunctuationXspecial"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span></span></span><span class="org-tree-sitter-hl-faceXstring">/bin/dotnet \</span>
<span class="org-tree-sitter-hl-faceXstring">      pack \</span>
<span class="org-tree-sitter-hl-faceXstring">      -p:ContinuousIntegrationBuild=true \</span>
<span class="org-tree-sitter-hl-faceXstring">      -p:Deterministic=true \</span>
<span class="org-tree-sitter-hl-faceXstring">      --output "$out/share" \</span>
<span class="org-tree-sitter-hl-faceXstring">      --configuration "Release"</span>
<span class="org-tree-sitter-hl-faceXstring">''</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXcomment"># ... snip ...</span>
</pre>
</div>

<p>
We'll move the derivation into <a href="https://gitlab.com/mavnn/caldance/-/blob/adfe02a71f7193e93fdefd7518f465e592ead6d8/nix/server.test.nix">its own file</a> while we're at it to stop the main <code>flake.nix</code> file getting too confusing and noisy, and start passing in things like the dotnet core version and project name as variables to make it easier to keeps changes between components in sync.
</p>

<p>
Aside: there is actually a helpful boolean flag that can be used to pack F# libraries but it fairly reasonably complains if you try and package a self-contained build.
</p>

<p>
This in turn allows us to define a derivation for the <a href="https://gitlab.com/mavnn/caldance/-/blob/adfe02a71f7193e93fdefd7518f465e592ead6d8/nix/server.test.nix">test project</a> which looks very similar to the server derivation, just that it takes to server derivation as an argument so that it can declare a project reference on it along with all the previous arguments.
</p>

<p>
<b>Quirk alert</b>: this works very, very, well giving us cached incremental builds but it does also require us to add a conditional <i>package</i> dependency on the server to our test project for the build to complete successfully under Nix. This means you end up with a project file that contains something like:
</p>

<div class="org-src-container">
<pre class="src src-xml"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">ItemGroup</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">ProjectReference</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Include</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">..\Server\CalDance.Server.fsproj</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">PackageReference</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Include</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">CalDance.Server</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Version</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring">*</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-nxml-attribute-local-name">Condition</span></span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span><span class="org-tree-sitter-hl-faceXstring"> '$(ContinuousIntegrationBuild)'=='true' </span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">"</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&lt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-slash">/</span></span><span class="org-tree-sitter-hl-faceXtag"><span class="org-nxml-element-local-name">ItemGroup</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-nxml-tag-delimiter">&gt;</span></span>
</pre>
</div>

<p>
To finish off our test setup, we add a new output to our flake file - a request for a JUnit formatted xml file containing our test results.
</p>

<div class="org-src-container">
<pre class="src src-nix"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">packages</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXproperty">test</span></span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">stdenv</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXproperty">.</span></span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">mkDerivation</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">name</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">"</span><span class="org-tree-sitter-hl-faceXpunctuationXspecial"><span class="org-tree-sitter-hl-faceXstring">${</span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">baseName</span></span></span></span><span class="org-tree-sitter-hl-faceXpunctuationXspecial"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span></span></span><span class="org-tree-sitter-hl-faceXstring">.TestResults"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">version</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">version</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">unpackPhase</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">"true"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">installPhase</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">''</span>
<span class="org-tree-sitter-hl-faceXstring">    </span><span class="org-tree-sitter-hl-faceXpunctuationXspecial"><span class="org-tree-sitter-hl-faceXstring">${</span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">testExecutable</span></span></span></span><span class="org-tree-sitter-hl-faceXpunctuationXspecial"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span></span></span><span class="org-tree-sitter-hl-faceXstring">/bin/CalDance.Server.Test --junit-summary $out/server.test.junit.xml</span>
<span class="org-tree-sitter-hl-faceXstring">  ''</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
Now we can run <code>nix build .#test</code> in our root directory and we will get a result directory containing the test results (which will be cached unless the code of either the server or the test project changes).
</p>

<p>
Some boiler plate additions to the GitLab CI configuration finishes things off; we tell the build to build both <code>.#dockerImage</code> <i>and</i> <code>.#test</code> (which nix will happily build run in parallel for us) and then copy the test results to a folder in the actual build directory which we tell GitLab contains junit xml results. This is needed because the <code>result-1</code> directory they are created in is a symlink to the a hash addressable store that nix uses, and it turns out GitLab's build artifact upload mechanism can't follow the symlink.
</p>

<div class="org-src-container">
<pre class="src src-yaml"># Nothing before the build command in the script has changed since the previous post
  - 'nix build .#dockerImage .#test'
  - mkdir testResults
  - 'cp result-1/* testResults'
  - ls -lh ./result
  - 'skopeo inspect docker-archive://$(readlink -f ./result)'
  - 'skopeo copy docker-archive://$(readlink -f ./result) docker://$IMAGE_TAG'
artifacts:
  when: always
  paths:
    - 'testResults/*.xml'
  reports:
    junit: 'testResults/*.xml'
</pre>
</div>
</div>
</div>
<div id="outline-container-ID-AF3E6D34-5CB7-42AF-8285-B95F9E8508D5" class="outline-4">
<h4 id="ID-AF3E6D34-5CB7-42AF-8285-B95F9E8508D5"><span class="section-number-4">17.0.4.</span> Wrapping it all up</h4>
<div class="outline-text-4" id="text-17-0-4">
<p>
That seems like a nice breaking off point for now. In this next stage we have:
</p>

<ul class="org-ul">
<li>Provided shared versions of formatting tools to help keep the code base consistent</li>
<li>Added a test project to allow us to unit test our code</li>
<li>Updated CI to run and report on those tests</li>
<li>Created a standard pattern for being able to add more F# projects to our repository which will all be built deterministically and for which the build results can be independently cached</li>
</ul>

<p>
As always, if you have questions or comments on what's happened so far then leave an issue on the <a href="https://gitlab.com/mavnn/caldance/-/issues">CalDance GitLab repository</a>. And as a thank you note for reading this far (and to see if anyone actually is!) we now have a bonus "choose your own adventure" poll.
</p>

<p>
If you'd like to see the next post focusing on testing the code we already have, hit the thumbs up on <a href="https://gitlab.com/mavnn/caldance/-/issues/1">this issue</a>.
</p>

<p>
If you'd like to see the next post starting to actually hook up a form and a data store, hit the thumbs up on <a href="https://gitlab.com/mavnn/caldance/-/issues/2">this issue instead</a>!
</p>
</div>
</div>
<div id="outline-container-ID-26C52F18-AA3B-4CBE-9AFF-636CAA3408CA" class="outline-4">
<h4 id="ID-26C52F18-AA3B-4CBE-9AFF-636CAA3408CA"><span class="section-number-4">17.0.5.</span> Next</h4>
<div class="outline-text-4" id="text-17-0-5">
<p>
<a href="https://blog.mavnn.eu/../../../2024/02/20/dev-journal-3.html">Part 3</a> continues with an end to end test of our docker container.
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>Foundations: Dev Journal 1</title>
<link>https://blog.mavnn.eu/2024/01/31/dev-journal-1.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/01/31/dev-journal-1.html</guid>
<pubDate>Wed, 31 Jan 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
This is something a little bit new. A series I'm starting that documents the building of a simple project from the ground up using a set of tools and techniques I've come to either really like, or that I'd like to try out.
</p>

<p>
On the one hand this is a personal project. On the other, I'd like to take advantage of nice things like CI/CD, testing, etc, even when I'm working on something for myself. So this is also a mini-tour of many of the things I would do setting up a new greenfield project for a team.
</p>

<p>
As the series progresses, I'll carry on adding the sections here.
</p>

<p>
<b>The series so far</b>
</p>

<ol class="org-ol">
<li><a href="https://blog.mavnn.co.uk/2024/01/31/dev-journal-1.html">Foundations</a>: Build and package</li>
<li><a href="https://blog.mavnn.eu/../../../2024/02/06/dev-journal-2.html">Scaffolding</a>: Testing and consistency</li>
<li><a href="https://blog.mavnn.eu/../../../2024/02/20/dev-journal-3.html">Does it run?</a>: Make sure the docker container is valid and stays valid</li>
<li><a href="https://blog.mavnn.eu/../../../2024/03/01/dev_journal_4.html">Log in, log out</a> (and <a href="https://blog.mavnn.eu/../../../2024/03/05/dev_journal_4_2.html">part 2</a>): Adding the database and the ability to log into our web site</li>
<li><a href="https://blog.mavnn.eu/../../../2024/03/09/dev_journal_5.html">Internal quality review</a>: making it easier to make correct changes to our code</li>
<li><a href="https://blog.mavnn.eu/../../../2024/03/19/dev_journal_6.html">With style</a>: Adding style and interactivity with server side HTML</li>
</ol>
<div id="outline-container-ID-08347765-D34A-4954-B262-25744DCABC89" class="outline-4">
<h4 id="ID-08347765-D34A-4954-B262-25744DCABC89"><span class="section-number-4">18.0.1.</span> Part 1: Foundations</h4>
<div class="outline-text-4" id="text-18-0-1">
<p>
Our application will eventually be a little web site for <code>redacted in case I change my mind</code>. I'm going to be using mix of tried and new tech (for me personally).
</p>

<p>
On the things I'd like to try front, we have:
</p>

<ul class="org-ul">
<li><a href="https://htmx.org/">htmx</a> (probably with <a href="https://bulma.io/">bulma</a> for initial styling) to provide the UI. This isn't going to be hugely interactive application, it is mostly going to collect information from forms, and display nice looking output tables so htmx's server side rendering model seems a perfect fit. I've used server side rendering in other projects and liked it, and htmx seems a low impact way to take that to the next level.</li>
<li><a href="https://www.falcoframework.com/">falco</a> for writing the backend server in F#. <a href="https://xyncro.github.io/sites-freya.io/">Freya</a>, my webserver of choice for F# back in the day, is no longer actively maintained but it looks like Falco has taken some of its nicer features and done its own thing with them.</li>
</ul>

<p>
On the technologies I've used before and found useful front, we have:
</p>

<ul class="org-ul">
<li><a href="https://nixos.org/">nix</a> to give a version controlled build/development environments and reproducible packaging.</li>
<li><a href="https://direnv.net/">direnv</a> for seamless local development environments.</li>
<li><a href="https://github.com/JasperFx/marten">marten</a> from the "Critter Stack" as an event store on top of postgresql to build our datastore.</li>
<li><a href="https://gitlab.com/">gitlab</a> for code repository, container registry and CI/CD pipeline.</li>
</ul>

<p>
I'm not sure how far I'm going to take this experiment publicly, but what I'm going to focus on first is just the basics of any online app: people being able to sign up, log in, and manage an account for a paid service. At least that far the whole project will be MIT licensed, so if you like what you see you can just pick it up and use it as a starter template for your own project.
</p>

<p>
For today, let's start with a <i>minimum deployable product</i>: a "Hello world" Falco server with CI/CD pipeline in place. We'll have a gitlab hosted project anybody with a working nix environment can pull down and:
</p>

<ul class="org-ul">
<li>run <code>nix run</code> and have a webserver running locally that will respond to get requests to <code>/</code> with "Hello world"</li>
<li>run <code>nix build .#dockerImage</code> to build a docker image with the same architecture they're using (i.e. <code>aarch64-darwin</code> if you run it on a Mac)</li>
<li>by pushing a commit to gitlab trigger a CI pipeline building said docker image for <code>x86_64-linux</code> and pushing it to a package registry ready to deploy</li>
</ul>

<p>
Enough bullet points. What did I actually do? (Sneak preview: <a href="https://gitlab.com/mavnn/caldance/-/tree/6b39d13d98199220d623870faf2b49fbda58d8a5">browse the gitlab repo at the time of the commit that this post describes</a>)
</p>
</div>
<ol class="org-ol">
<li><a id="ID-B9452CD5-89B5-4D34-9D51-04D7C5524E58"></a>Setup a nix flake to provide our environment<br>
<div class="outline-text-5" id="text-18-0-1-1">
<p>
A nix "flake" is a declarative description of a set of packages we'd like to be able to reference. You can read the <a href="https://gitlab.com/mavnn/caldance/-/blob/6b39d13d98199220d623870faf2b49fbda58d8a5/flake.nix">whole file</a> but the important part for today is that our <code>flake.nix</code> file specifies three outputs in this stanza:
</p>

<div class="org-src-container">
<pre class="src src-nix"><span class="org-tree-sitter-hl-faceXcomment"># Tools we want available during development</span>
<span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">devShells</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXproperty">default</span></span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">mkShell</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">buildInputs</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">dnc</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">sdk_8_0</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">nixfmt</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">skopeo</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXcomment"># Default result of running `nix build` with this</span>
<span class="org-tree-sitter-hl-faceXcomment"># flake; it builds the F# project `CalDance.fsproj`</span>
<span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">packages</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">default</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">buildDotnetModule</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">pname</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">name</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">version</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">"0.1"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">src</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-nix-constant">./.</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">projectFile</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXstring">"CalDance.fsproj"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">nugetDeps</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">nugets</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXcomment"># We set nix to create an output that contains</span>
  <span class="org-tree-sitter-hl-faceXcomment"># everything needed, rather than depending</span>
  <span class="org-tree-sitter-hl-faceXcomment"># on the dotnet runtime</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">selfContainedBuild</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXvariableXbuiltin">true</span></span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXcomment"># This is a webserver, and it complains if it</span>
  <span class="org-tree-sitter-hl-faceXcomment"># has no access to openssl</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">runtimeDeps</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">openssl</span></span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">cacert</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">dotnet-sdk</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">dnc</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">sdk_8_0</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">dotnet-runtime</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">dnc</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">runtime_8_0</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">executables</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span> <span class="org-tree-sitter-hl-faceXstring">"CalDance"</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXcomment"># A target that builds a fully self-contained docker</span>
<span class="org-tree-sitter-hl-faceXcomment"># file with the project above</span>
<span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">packages</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">dockerImage</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">dockerTools</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXproperty">.</span></span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">buildImage</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">name</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">name</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">config</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXcomment"># asp.net likes a writable /tmp directory</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">Cmd</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction"><span class="org-tree-sitter-hl-faceXproperty">writeShellScript</span></span></span> <span class="org-tree-sitter-hl-faceXstring">"runServer"</span> <span class="org-tree-sitter-hl-faceXstring">''</span>
<span class="org-tree-sitter-hl-faceXstring">      </span><span class="org-nix-antiquote">${</span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">coreutils</span></span></span></span><span class="org-nix-antiquote">}</span><span class="org-tree-sitter-hl-faceXstring">/bin/mkdir -p /tmp</span>
<span class="org-tree-sitter-hl-faceXstring">      </span><span class="org-nix-antiquote">${</span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">pkgs</span></span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">coreutils</span></span></span></span><span class="org-nix-antiquote">}</span><span class="org-tree-sitter-hl-faceXstring">/bin/mount -t tmpfs tmp /tmp</span>
<span class="org-tree-sitter-hl-faceXstring">      </span><span class="org-nix-antiquote">${</span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">packages</span></span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span></span></span><span class="org-tree-sitter-hl-faceXembedded"><span class="org-tree-sitter-hl-faceXstring"><span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">default</span></span></span></span><span class="org-nix-antiquote">}</span><span class="org-tree-sitter-hl-faceXstring">/bin/CalDance.Server</span>
<span class="org-tree-sitter-hl-faceXstring">    ''</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">Env</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span> <span class="org-tree-sitter-hl-faceXstring">"DOTNET_EnableDiagnostics=0"</span> <span class="org-tree-sitter-hl-faceXstring">"ASPNETCORE_URLS=http://+:5001"</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">ExposedPorts</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXstring">"5001/tcp"</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
</pre>
</div>

<p>
First we say we want a shell environment which includes the dotnet core SDK (version 8), nixfmt (for formatting nix files), and skopeo which we can use for moving docker images around.
</p>

<p>
Then we define the default output for this flake: it uses the <code>buildDotnetModule</code> to specify that in our case it should build the executable <code>CalDance</code> based on the F# project file <code>CalDance.fsproj</code>. A helper makes sure that Nix is aware of which nuget packages the project has referenced, so that they can be packaged correctly.
</p>

<p>
Finally, we define the <code>dockerImage</code> which uses the <code>dockerTools.buildImage</code> helper to say we want to be able to build a docker image that contains the executable from the default package above, everything it needs to run and <i>nothing else at all</i>. In our case, this produces a docker image weighing in at around 80MB - similar to what you'd get optimising a <a href="https://blogit.create.pt/telmorodrigues/2022/03/08/smaller-net-6-docker-images/">two step hand crafted dockerfile</a>, and significantly smaller than using the official <a href="https://hub.docker.com/_/microsoft-dotnet-aspnet/">Microsoft ASP.NET runtime image</a>.
</p>
</div>
</li>
<li><a id="ID-DDB0EDC9-0578-4428-8392-E53C5A2F12FA"></a>direnv<br>
<div class="outline-text-5" id="text-18-0-1-2">
<p>
Direnv is a tool that can add environment variables to your shell when you enter a directory. It also, conveniently, knows about Nix flakes.
</p>

<p>
We add a <code>.envrc</code> file to our project with the contents:
</p>

<div class="org-src-container">
<pre class="src src-bash"><span class="org-tree-sitter-hl-faceXcomment">#!/usr/bin/</span><span class="org-keyword">env</span><span class="org-tree-sitter-hl-faceXcomment"> bash</span>
<span class="org-tree-sitter-hl-faceXcomment"># the shebang is ignored, but nice for editors</span>
<span class="org-tree-sitter-hl-faceXfunctionXcall">use</span> flake
</pre>
</div>

<p>
Next time we move into this directory, direnv will ask us to allow this <code>.envrc</code> file. If we accept, our normal local shell will have everything specified in the <code>devShell</code> above added to its path. This means we can, for example, use the <code>dotnet</code> command and we will use the version specified in <code>flake.nix</code> even if we haven't installed a system wide version of dotnet at all.
</p>
</div>
</li>
<li><a id="ID-152728E8-41A6-4459-ACD7-83C0E59ED575"></a>The F# project<br>
<div class="outline-text-5" id="text-18-0-1-3">
<p>
There's absolutely nothing special about this at all. I just created an F# project with <code>dotnet</code> on the command line, moved <code>Program.fs</code> into a sub directory called <code>src</code> because I prefer it that way, and then added a package dependency on <code>Falco</code> using <code>dotnet add package Falco</code>.
</p>

<p>
Replace the contents of <code>Program.fs</code> with:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">module</span> <span class="org-type">Mavnn.CalDance.Server</span>

<span class="org-keyword">open</span> <span class="org-type">Falco</span>
<span class="org-keyword">open</span> <span class="org-type">Falco.Routing</span>
<span class="org-keyword">open</span> <span class="org-type">Falco.HostBuilder</span>

webHost [||] {
    endpoints [
        get <span class="org-string">"/"</span> (Response.ofPlainText <span class="org-string">"Hello World"</span>)
    ]
}
</pre>
</div>
</div>
</li>
<li><a id="ID-52BA31CC-77DB-4708-9DD6-041102A0DDA8"></a>Set up the CI pipeline<br>
<div class="outline-text-5" id="text-18-0-1-4">
<p>
Having used Nix for our development environment, our CI pipeline becomes exceedingly straight forward. All we need is a build container with Nix available and we have all the other information we need for the build already. Nix themselves provide a <code>nixos/nix</code> image (Nix is the package manager, NixOS is the linux distribution that uses Nix as its package manager) so we'll just use that.
</p>

<p>
There's a little bit of boilerplate to tell nix that we want to allow flakes and to allow connection to the gitlab package registry. Once that is done, we log into the registry for this project using the CI provided environment variables, run <code>nix build .#dockerImage</code> and then push the results up to the registry.
</p>

<div class="org-src-container">
<pre class="src src-yaml">build-container:
  image:
    name: "nixos/nix:2.19.3"
  variables:
    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  before_script:
    - nix-env --install --attr nixpkgs.skopeo
  script:
    - mkdir -p "$HOME/.config/nix"
    - echo 'experimental-features = nix-command flakes' &gt; "$HOME/.config/nix/nix.conf"
    - mkdir -p "/etc/containers/"
    - echo '{"default":[{"type":"insecureAcceptAnything"}]}' &gt; /etc/containers/policy.json
    - skopeo login --username "$CI_REGISTRY_USER" --password "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
    - 'nix build .#dockerImage'
    - ls -lh ./result
    - 'skopeo inspect docker-archive://$(readlink -f ./result)'
    - 'skopeo copy docker-archive://$(readlink -f ./result) docker://$IMAGE_TAG'
</pre>
</div>

<p>
It's worth noting here that Nix is a deterministic build system (for example, stripping dates from compiled metadata so building the same source code on a different day doesn't product a different binary). In a "real life" context I would be caching the results of the nix build steps to a service like <a href="https://www.cachix.org/">Cachix</a> so that they could be reused between builds, which becomes increasingly useful as the project grows and starts to be comprised of multiple build steps (Nix will be able to cache each "step" individually, even if you only ask for the final outcome of the process).
</p>
</div>
</li>
<li><a id="ID-74B8C73E-8EEA-41B0-BE1C-B29C423D7BCE"></a>Wrapping it all up<br>
<div class="outline-text-5" id="text-18-0-1-5">
<p>
Not a bad first days work, I'd say. Our project is already at a stage that we can work on it with standard .NET tooling (for instance, adding a new nuget package with <code>dotnet package add ...</code> will automatically flow through to that package being added to the docker image) and CI will produce on push a lean deployable artifact. Versions of <i>everything</i> we are using from the .NET SDK to the nuget package we're depending on are fixed across all environments, and we have a nice place to add more developer tooling as we move forwards - for example standardizing the version of postgresql that will be used during development and in CI.
</p>

<p>
As a bonus extra, anybody with nix installed can build and run the project without having to know .NET or have any .NET tooling installed; a very nice feature when you have others depending on your work who might want to run your code locally, but may not have chosen the same tech stack.
</p>
</div>
</li>
<li><a id="ID-264CC257-5599-4D04-AED1-3D35B3B14D3A"></a>Feedback? Comments?<br>
<div class="outline-text-5" id="text-18-0-1-6">
<p>
Have questions? Comments? Hate something, love something, know a better way of doing something? Drop an issue on the repository at <a href="https://gitlab.com/mavnn/caldance">https://gitlab.com/mavnn/caldance</a> and let me know. I'll be pointing a tag at the commit referenced by each blog post, so I can always branch off and include your ideas in a future revision!
</p>
</div>
</li>
<li><a id="ID-83C2E589-8D1D-42AF-822D-6280BE45CCBD"></a>Next<br>
<div class="outline-text-5" id="text-18-0-1-7">
<p>
<a href="https://blog.mavnn.eu/../../../2024/02/06/dev-journal-2.html">Part 2</a> adds unit tests and consistent formatting to the project.
</p>
</div>
</li>
</ol>
</div>
]]></description>
</item>
<item>
<title>Short term help</title>
<link>https://blog.mavnn.eu/2024/01/29/short_term_help.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/01/29/short_term_help.html</guid>
<pubDate>Mon, 29 Jan 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
These days I generally work longer term contracts, which means I'm not often available for the more immediate "pay money for a solved problem" services I could offer while I was consulting. Right now though, I'm between long term contracts.
</p>

<p>
"But Michael," I hear you say, "what problems can I give you money to solve so that I can avoid distracting my own amazing team from actually <b>building the product</b>?"
</p>

<p>
I'm so glad you asked. Or, you know, you can just skip straight to the <a href="#ID-1AC24D36-F2CC-4484-B158-758BFABCCFAB">logistics</a> section if you already know what you want.
</p>
<div id="outline-container-ID-A8AA8023-D6F9-4E11-B81C-9B3C71480A34" class="outline-3">
<h3 id="ID-A8AA8023-D6F9-4E11-B81C-9B3C71480A34"><span class="section-number-3">19.1.</span> Consulting</h3>
<div class="outline-text-3" id="text-19-1">
</div>
<div id="outline-container-ID-8FD25D59-031C-438A-8623-FB1F7DFF0E82" class="outline-4">
<h4 id="ID-8FD25D59-031C-438A-8623-FB1F7DFF0E82"><span class="section-number-4">19.1.1.</span> Build, packaging, and continuous integration</h4>
<div class="outline-text-4" id="text-19-1-1">
<p>
I have spent a <i>lot</i> of time getting build, test, and deployment pipelines up and running. Most of the advice out there assumes that you are using one technology and you can just use "the build tool" for that stack. Reality tends to be more complicated than that, with many projects involving multiple languages, code generation, and extensive test set up.
</p>

<p>
What kind of things could your CI/CD process do for you? It depends on <i>your</i> needs, but things that have really helped in other places include:
</p>

<ul class="org-ul">
<li>Making sure that CI/CD is managed <b>in the code repository</b> so that running the build locally and on the build server does the same thing in the same way, and the build can evolve in a safe, version controlled way just like the rest of your code</li>
<li>Helping trace and encode the <i>real</i> dependencies in your code base to unlock incremental, cachable build steps and reduce overall build times with concurrency</li>
<li>Split your test suite so tests can be run in parallel (yes, even integration tests) and then aggregate the results</li>
<li>Use tools like Nix or multi-step docker/podman builds to create minimal containers that only contain what they really need
<ul class="org-ul">
<li>bonus extra: doing this with Nix also gives you development environments as code and reproducible deployment artifacts - same code in, same container out</li>
</ul></li>
</ul>

<p>
If this is a new product/project and you just want someone to make all these considerations go away I can also build you <a href="#ID-3AC61BA9-2E22-4737-9FCE-ADA321234F5E">a project skeleton</a> with everything set up and ready to go for your preferred CI provider and deployment environment.
</p>
</div>
</div>
<div id="outline-container-ID-66D42273-20E9-4571-9E3E-2437E9173D2B" class="outline-4">
<h4 id="ID-66D42273-20E9-4571-9E3E-2437E9173D2B"><span class="section-number-4">19.1.2.</span> Architecture review</h4>
<div class="outline-text-4" id="text-19-1-2">
<p>
Putting together a new project, or have a code base that's moving from "minimum viable" to "oh - I've got customers"? I can review your plans, or, given your constraints and objectives I can put together a suggested system architecture for you.
</p>

<p>
It's worth noting that I don't have a personal axe to grind here. I won't tell you to use a "clean" architecture because that's my thing, or to use microservices because they are fashionable. Different architectural styles exist for a reason, and each has its own trade offs in terms of constraints you choose to accept in order to gain certain benefits.
</p>

<p>
I have the advantage of having helped architect and design solutions in a variety of styles in production environments.
</p>

<p>
This is a bit of a hybrid service that includes aspects of <a href="#ID-E0CFE33C-7348-4459-A534-800B83DDE672">technology evaluation</a> and <a href="#ID-B7BDA429-6D17-46FD-B712-86B750E1C3A9">code audit</a> with a splash of <a href="#ID-DB44E6D2-DCF4-4997-B326-5B4E4D0B89C4">domain driven design by example</a> (so that I understand what you're building) - but zoomed out to look at "how do I put all this together."
</p>
</div>
</div>
<div id="outline-container-ID-B7BDA429-6D17-46FD-B712-86B750E1C3A9" class="outline-4">
<h4 id="ID-B7BDA429-6D17-46FD-B712-86B750E1C3A9"><span class="section-number-4">19.1.3.</span> Code audit</h4>
<div class="outline-text-4" id="text-19-1-3">
<p>
For ecosystems I've built decent sized projects in (.NET, TypeScript) I can spend some time reviewing your code and pointing out things you may want to improve.
</p>

<p>
This isn't the kind of code review you'd do on an individual PR: this is the kind of code review where I can (as an outsider) come in with fresh eyes and point out broader patterns in your code base that may be problematic. I can also help you take your conventions and "traditions" and turn them into a coding style guide with (in many cases) automated tooling to help the team put it into practice.
</p>
</div>
</div>
<div id="outline-container-ID-E0CFE33C-7348-4459-A534-800B83DDE672" class="outline-4">
<h4 id="ID-E0CFE33C-7348-4459-A534-800B83DDE672"><span class="section-number-4">19.1.4.</span> Technology evaluation</h4>
<div class="outline-text-4" id="text-19-1-4">
<p>
Considering buying a new service, picking up a new programming language, or changing to a new database library? I can do the research and evaluation you need based on your requirements. I've been helping drive technology choices in organizations for well over a decade now, and I can help you spot the good, the bad, and the ugly of the options you're considering. I may even be aware of options you haven't considered.
</p>
</div>
</div>
</div>
<div id="outline-container-ID-B1F03D3A-062B-42FF-BD83-B781F5A890E0" class="outline-3">
<h3 id="ID-B1F03D3A-062B-42FF-BD83-B781F5A890E0"><span class="section-number-3">19.2.</span> Workshops and training</h3>
<div class="outline-text-3" id="text-19-2">
<p>
Unlike more general consultancy, workshops on topics I know well such as the ones below are a fairly fixed commitment. If you're considering using your training budget, you can assume around 2500 euros/day for up to 6 people online. In person will increase the cost but allows for groups of up to 10 people.
</p>

<p>
I have also offered bespoke training courses in the past (examples: giving a team of Ruby developers a 5 day crash course in everything they needed to know to take over maintenance of a .NET code base, tailored to the project in question) but that requires significant preparation and a quote.
</p>
</div>
<div id="outline-container-ID-DB44E6D2-DCF4-4997-B326-5B4E4D0B89C4" class="outline-4">
<h4 id="ID-DB44E6D2-DCF4-4997-B326-5B4E4D0B89C4"><span class="section-number-4">19.2.1.</span> Domain driven design coaching</h4>
<div class="outline-text-4" id="text-19-2-1">
<p>
At its heart, the promise of domain driven design is simple: a code base that uses the same language as the people using it do, so that developers and domain experts can accurately share understanding of what the code <i>should</i> do and why.
</p>

<p>
Actually <i>doing</i> domain driven design is not simple at all, because it is a process to help you model reality and it turns out <a href="http://johnsalvatier.org/blog/2017/reality-has-a-surprising-amount-of-detail">reality has a surprising amount of detail</a>.
</p>

<p>
I can help with the process of getting started with DDD, help lead the early exploratory meetings between developers and domain experts, and give advice on how to capture what you discover in code while keeping everything maintainable.
</p>
</div>
</div>
<div id="outline-container-ID-F06E5183-9787-4C2F-8473-7013F31998F2" class="outline-4">
<h4 id="ID-F06E5183-9787-4C2F-8473-7013F31998F2"><span class="section-number-4">19.2.2.</span> Event sourcing</h4>
<div class="outline-text-4" id="text-19-2-2">
<p>
Event sourcing is a technique for capturing all the events that "have happened" and using those to calculate the current state of your system.
</p>

<p>
For example, if a customer of yours moves you may publish a <code>CustomerHasMoved</code> event when they tell you, and a <code>CustomerAddressHasChanged</code> event when you have finished the business process that manages customers moving.
</p>

<p>
This has enormous benefits for auditing, for being able to look at how the system has changed over time, and for being able to fix bugs "retroactively" as you don't only have the current state of the system but also all of the steps that got you here.
</p>

<p>
It <i>also</i> requires a slightly different way of thinking about your code base and some specific tooling to avoid a system that slows down over time. And it affects how you think about business constraints like data retention and <a href="https://www.dataprotection.ie/en/individuals/know-your-rights/right-erasure-articles-17-19-gdpr">the right to erasure</a>.
</p>

<p>
As the saying goes: been there, done that. I can help you do it too.
</p>
</div>
</div>
<div id="outline-container-ID-C4BBFDE6-9DAC-472E-9B19-7A48317298E8" class="outline-4">
<h4 id="ID-C4BBFDE6-9DAC-472E-9B19-7A48317298E8"><span class="section-number-4">19.2.3.</span> Teach property based testing</h4>
<div class="outline-text-4" id="text-19-2-3">
<p>
I'm a huge fan of property based testing, and I'm more than happy to give interactive workshops on getting started with it in .NET, TypeScript, and probably other languages if you ask nicely. Why pay for this when you could download a conference talk about it for free (including ones I've given myself)? Because I'll use a piece of <i>your</i> code to get started with you will walk away with an up and running example in your code base. This will keep us focused on the reality of doing property based testing in practice rather than seeing the nice, easy, examples you tend to be shown in a 45 minute talk.
</p>
</div>
</div>
</div>
<div id="outline-container-ID-3BD12BF2-88E3-423A-AFC7-A2F5F0C48ADA" class="outline-3">
<h3 id="ID-3BD12BF2-88E3-423A-AFC7-A2F5F0C48ADA"><span class="section-number-3">19.3.</span> Bespoke software creation</h3>
<div class="outline-text-3" id="text-19-3">
</div>
<div id="outline-container-ID-E7E0899B-3812-47AF-8F1B-DE29456F500E" class="outline-4">
<h4 id="ID-E7E0899B-3812-47AF-8F1B-DE29456F500E"><span class="section-number-4">19.3.1.</span> Build a tool/library</h4>
<div class="outline-text-4" id="text-19-3-1">
<p>
I do just write good code as well. If you need a self contained library or a small solution built, I can do that for you. Whether it is parsing an obscure data format, efficient immutable directed graph data structures, or just a nice F# wrapper around a dotnet library, I will make sure it fits the style you're asking for and is well tested. Significant discounts apply if the results are going to be released under an open source licence.
</p>
</div>
</div>
<div id="outline-container-ID-3AC61BA9-2E22-4737-9FCE-ADA321234F5E" class="outline-4">
<h4 id="ID-3AC61BA9-2E22-4737-9FCE-ADA321234F5E"><span class="section-number-4">19.3.2.</span> Build a project skeleton</h4>
<div class="outline-text-4" id="text-19-3-2">
<p>
If you're starting a green field project, I can create a "skeleton" repository with a managed developer environment, CI/CD and testing story set up and ready to use. You and your team get to start with actually writing your product.
</p>
</div>
</div>
</div>
<div id="outline-container-ID-1AC24D36-F2CC-4484-B158-758BFABCCFAB" class="outline-3">
<h3 id="ID-1AC24D36-F2CC-4484-B158-758BFABCCFAB"><span class="section-number-3">19.4.</span> Logistics</h3>
<div class="outline-text-3" id="text-19-4">
<p>
Let's cover the basics. I don't want us to waste time, so I'm going to try and keep this as straight forward as possible:
</p>

<ul class="org-ul">
<li>I will <i>always</i> want to have an extensive conversation(s) and will normally want to provide a quote before starting a short term piece of work. Book a slot to talk on <a href="https://calendly.com/mavnn/1-hour-slot">Calendly</a> or just send me an email (michael at mavnn.eu)</li>
<li>I currently live in Italy, about an hour away from Rome. I can offer all of the services above remotely. Asking me to attend in person will add travel costs and at least 2 billable days of my time.</li>
<li>You can hire me by the day, but in general for short term work I quote and then charge you for the work delivered rather than bill by unit time. I will consider discounts for non-profits, student organizations, etc. It it's easier for you, I can give a quote that includes all expenses rather than reclaiming them separately. (Hint: if you're in a large organization and this is the first time you're arranging to get a consultant in - <i>this will be easier for you</i>)
<ul class="org-ul">
<li>I am VAT registered in the EU</li>
</ul></li>
<li>In the rare occasion where it turns out that I cannot deliver what I promised (I'm just one human - things like illness can happen) I will let you know promptly, and before the work is due to be delivered, so we can renegotiate where to go from the reality of the situation.</li>
</ul>

<p>
That's about everything, I think.
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>Writing CVs for more senior roles</title>
<link>https://blog.mavnn.eu/2024/01/26/writing_a_cv.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2024/01/26/writing_a_cv.html</guid>
<pubDate>Fri, 26 Jan 2024 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
A while back (<i>checks notes, gulps</i>) I wrote a fairly successful <a href="https://blog.mavnn.co.uk/good-developer-cvs/">blog post on the types of CVs</a> I liked receiving as one of the people screening technical applications, and some of the mistakes I was seeing applicants making.
</p>

<p>
What I didn't speak about at all was the "structure" of the CV; how to arrange it, and what sections to include/not include.
</p>

<p>
Today somebody asked me for an actual CV for the first time in... quite a while actually. The last couple of jobs both had their own interview process that didn't include one, so that means it's been at least 5 years.
</p>

<p>
Turns out that having been on the other side of the table a few more times now, and hiring for more senior candidates, my CV creation style has changed radically. The result is four broad categories of ways I've been effective in previous jobs, with a brief description of when I became senior enough to start doing that. So rather than having a big timeline of work history and education, I end up with things like:
</p>

<blockquote>
<p>
<b>Training and mentoring</b>
</p>

<p>
For over a decade I have provided mentoring and training both to team members and as a service offered. This has ranged from people learning to code for the first time (CodeInstitute), to week long courses teaching professional developers new programming languages or architectural styles (@mavnn ltd), to giving talks at conferences on topics from the obscure to the philosophical (SDDConf, NDC, F# Exchange, Lambda Days, etc).
</p>

<p>
Apart from formal training I have mentored teams several times during the introduction of new programming languages, libraries, and techniques (15below, NoRedInk, Blissfully/Vendr).
</p>
</blockquote>

<p>
Again - your mileage may vary; it's not like I've had any feed back on the application yet, or even that a single response tells you much about how the CV be received in general. But I can tell you that from the other side of the table that I'm much more interested in what <b>you</b> think are the areas you've made a difference, or that you're proud of, than I am in the job descriptions of your last 5 posts and where you went to secondary school.
</p>

<p>
One slight caveat: I did include my LinkedIn profile, which has all the gritty dates and things. It just wasn't what I chose to highlight in the part of the process that I can control. Your CV is your chance to control the narrative - take it.
</p>
]]></description>
</item>
<item>
<title>TypeScript Enums and Serialization</title>
<link>https://blog.mavnn.eu/2022/11/24/typescript_enums_and_serialization.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2022/11/24/typescript_enums_and_serialization.html</guid>
<pubDate>Thu, 24 Nov 2022 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
In general, TypeScript is <a href="https://blog.mavnn.eu/../../../2022/01/07/types-in-typescript.html">not its own language</a> - it's a set of annotations that
can be added to JavaScript to help check the "correctness" of you program. The
authors have been very reluctant to add features to TypeScript that don't exist
in JavaScript, and so normally you can turn your TypeScript into JavaScript purely
by <i>deleting</i> the type annotations that you've added.
</p>

<p>
Enums, though, are a bit different. They actually generate JavaScript code based on
the TypeScript you write. Today, we're going to look at a piece of code that allows
you to deserialize enums with string values in a type safe manner. And we're going
to take advantage of the fact that enums (according to the TypeScript compiler) are
both a type, and a value with a different type - at the same time.
</p>

<p>
For context, we're going to be using <a href="https://www.npmjs.com/package/schemawax">SchemaWax</a> to create our decoder, so we can
build it into a larger contextual decoder as needed.
</p>

<p>
First: the code! If you already know SchemaWax, you don't care about types, and
you're here because it was a hit for "deserialize any enum" on Google this is
the bit to cut and paste.
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">import</span> * <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span> <span class="org-tree-sitter-hl-faceXkeyword">from</span> <span class="org-tree-sitter-hl-faceXstring">"schemawax"</span>

<span class="org-tree-sitter-hl-faceXcomment">// This is only type safe if passed a Enum with string values.</span>
<span class="org-tree-sitter-hl-faceXcomment">// I don't think there's anyway to stop someone passing { "boo": "broken" }</span>
<span class="org-tree-sitter-hl-faceXcomment">// in TypeScripts type system :(</span>
<span class="org-tree-sitter-hl-faceXcomment">// At least this stops us from rewriting the same unsafe code every time though.</span>
<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXfunction">stringEnumDecoder</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Enum</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>name<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>
  <span class="org-tree-sitter-hl-faceXvariableXparameter">targetEnum</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Enum</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Decoder</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Enum</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-type">keyof</span> <span class="org-tree-sitter-hl-faceXtype">Enum</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">literalUnion</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>...<span class="org-tree-sitter-hl-faceXconstructor">Object</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">values</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-type">targetEnum</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span> <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Decoder</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Enum</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-type">keyof</span> <span class="org-tree-sitter-hl-faceXtype">Enum</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span>
</pre>
</div>

<p>
That's it. The whole thing. How do you use it?
</p>

<p>
Like this:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">import</span> * <span class="org-tree-sitter-hl-faceXkeyword">as</span> <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span> <span class="org-tree-sitter-hl-faceXkeyword">from</span> <span class="org-tree-sitter-hl-faceXstring">"schemawax"</span>
<span class="org-tree-sitter-hl-faceXkeyword">import</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> stringEnumDecoder <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXkeyword">from</span> <span class="org-tree-sitter-hl-faceXstring">"./enum"</span>

<span class="org-tree-sitter-hl-faceXkeyword">enum</span> <span class="org-tree-sitter-hl-faceXconstructor">TestEnum1</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXstring">"why"</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXstring">"would"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXstring">"anyone"</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXstring">"do"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  <span class="org-tree-sitter-hl-faceXstring">"this"</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXstring">"!"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">ObjectWithEnumField</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  testEnum<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">TestEnum1</span>
  name<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span>
  age<span class="org-tree-sitter-hl-faceXpunctuationXspecial">?</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">number</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXfunctionXcall">describe</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"stringEnumDecoder"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXfunctionXcall">it</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"decodes string enums"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">result</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">stringEnumDecoder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">TestEnum1</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">forceDecode</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"!"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXfunctionXcall">expect</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>result<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">toEqual</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">TestEnum1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">this</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
  <span class="org-tree-sitter-hl-faceXfunctionXcall">it</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"rejects invalid enum values"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">result</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXfunctionXcall">stringEnumDecoder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">TestEnum1</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">decode</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"this"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
    <span class="org-tree-sitter-hl-faceXfunctionXcall">expect</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>result<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">toBeNull</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>

  <span class="org-tree-sitter-hl-faceXfunctionXcall">it</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"can be used in larger decoders"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">objectDecoder</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtype">Decoder</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">ObjectWithEnumField</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">object</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span>
      <span class="org-tree-sitter-hl-faceXpropertyXdefinition">required</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">testEnum</span>: <span class="org-tree-sitter-hl-faceXfunctionXcall">stringEnumDecoder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor">TestEnum1</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">name</span>: <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpropertyXdefinition">optional</span>: <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
        <span class="org-tree-sitter-hl-faceXpropertyXdefinition">dateOfBirth</span>: <span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">D</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">string</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">andThen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">((</span><span class="org-tree-sitter-hl-faceXvariableXparameter">str</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXoperator">=&gt;</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">Date</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>str<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
      <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>

    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">inputFromApi</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXstring">`{ "testEnum": "!", "name": "bob", "dateOfBirth": "2022-11-24"}`</span>
    <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-tree-sitter-hl-faceXvariable">result1</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> objectDecoder<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">decode</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXconstructor"><span class="org-tree-sitter-hl-faceXconstant">JSON</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">parse</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>inputFromApi<span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span>
    <span class="org-tree-sitter-hl-faceXfunctionXcall">expect</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>result1<span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">toEqual</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">({</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">testEnum</span>: <span class="org-tree-sitter-hl-faceXconstructor">TestEnum1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">name</span>: <span class="org-tree-sitter-hl-faceXstring">"bob"</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXpropertyXdefinition">dateOfBirth</span>: <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">Date</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"2022-11-24"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">})</span>
</pre>
</div>

<p>
How does this work? How can we write a function that can take an enum type as an
argument, and then generate a decoder? (Feel free to drop out if you were just
here to solve your immediate problem!)
</p>

<p>
If you type an enum into the online TypeScript playground (<a href="https://www.typescriptlang.org/play?#code/KYOwrgtgBAYg9nKBvAUFKB5EwoF4oBEc2BANGlACoDui+BALrWSgL4pA">here's one I prepared
earlier</a>), you'll see that the enum (with string values) is, in fact, compiled
into a variable that ends up with a simple record with string keys and values
attached to it.
</p>

<p>
Going back to the implementation, you'll see that's exactly the constraint on
the argument we pass into <code>stringEnumDecoder</code>.
</p>

<div class="org-src-container">
<pre class="src src-typescript">...
<span class="org-tree-sitter-hl-faceXkeyword">export</span> <span class="org-tree-sitter-hl-faceXkeyword">const</span> <span class="org-variable-name">stringEnumDecoder</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">Enum</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>name<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>... rest <span class="org-tree-sitter-hl-faceXkeyword">of</span> <span class="org-tree-sitter-hl-faceXvariableXparameter">implementation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
</pre>
</div>

<p>
Then some slightly weird magic happens: when you pass an enum into the function,
the TypeScript compiler infers that the type of the argument is the <code>typeof</code> the
enum you passed in. Whatever is happening internally here, it keeps track of the
fact that the keys of this type are the types of the valid enum cases, so it
turns <code>Enum[keyof Enum]</code> into the union type of each of the possible enum value
types which is, if you squint hard enough, actually the enum itself. We then
return a decoder that accepts a string, checks that said string is actually one
of the <i>values</i> stored in the enum object, and then tells the compiler that this
decoder will only ever return valid enum values. Unfortunately with a cast - but
the full context we need to check this cast is valid is contained within this
one line of code.
</p>

<p>
So there you have it: a safe way to deserialize strings into enums, and it even
composes nicely into more complex decoders.
</p>

<p>
Until next time!
</p>

<p>
Want to comment on something you've read here? <a href="https://mastodon.sdf.org/@mavnn/109400451463740531">This mastodon post</a> is the
official commenting point!
</p>
]]></description>
</item>
<item>
<title>ADHD and me</title>
<link>https://blog.mavnn.eu/2022/10/14/adhd_and_me.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2022/10/14/adhd_and_me.html</guid>
<pubDate>Fri, 14 Oct 2022 00:00:00 +0200</pubDate>

<description><![CDATA[<p>
This morning, I did the washing up.
</p>

<p>
Now: your first response might be "Michael: why do I care? Do I look like a
washing up blog reader?"
</p>

<p>
But that would miss the point. This morning I did the washing up, and only the
washing up. I didn't procrastinate with some Twitter or YouTube videos first. I
didn't need to listen to a podcast at the same time to avoid getting lost
staring off into space thinking about something completely different.
</p>

<p>
Most importantly: no crushing feeling of overwhelm about needing to do this task
that both feels insurmountable but is obviously (objectively) trivial. It's
embarrassing to admit that I've been repeatedly reduced to tears by the need to
do the washing up.
</p>

<p>
This change, it appears, is the impact of methylphenidate (Ritalin®) on my
brain. I was recently diagnosed with ADHD, and yesterday I undertook a series of
"challenge tests" to see if I am one of the <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2732009/">75% of adult's with ADHD whose
symptoms are helped by the drug</a>.
</p>

<p>
I did the same series of tests twice: once in the morning, before taking
methylphenidate; the other in the afternoon an hour after taking the first trial
intake under observation (methylphenidate is a controlled substance here in
Italy).
</p>

<p>
It was a strange, and almost disturbing, experience to feel my brain acting
differently. Recall was smoother. Free association on a topic easier because my
brain stayed on <i>that</i> topic, without veering away onto side lines that I needed
to filter out from what I was saying. My thoughts were still my own, but
with... less in the way.
</p>

<p>
You see: trying to do stuff (and by stuff I mean pretty much <i>anything</i> that you
need to choose to do, rather than that you happen to start because it distracted
you...) with ADHD is hard. I didn't realize how hard until some of that effort
was lifted.
</p>

<p>
The closest I've come to being able to describe it is that having ADHD is like
your brain wearing an ancient near eastern tunic to work a farm.
</p>

<p>
Ever hear the phrase "gird your loins"? It's the <a href="https://www.artofmanliness.com/skills/manly-know-how/how-to-gird-up-your-loins-an-illustrated-guide/">process of tying up your tunic</a>
(designed primarily to keep you cool) so that you can run, or fight, or carry
out hard physical labour at ground level without the 'skirt' of the tunic
getting in the way and tripping you up.
</p>

<p>
My brain wears a tunic: I need to put effort into preparing to do things before
I can even start doing them. So it takes energy and effort just to <i>get ready to
start</i>. And if you make a mistake in the girding, or the knot slips? Well, now
you're half way through your task with a bunch of cloth swishing around your
legs and getting in the way.
</p>

<p>
Methylphenidate is the equivalent of putting on jeans. You can be casual still,
but you can also just... do stuff? Finish your morning coffee, look across the
kitchen, and go: "I need to do the washing up."
</p>

<p>
This morning, I did the washing up.
</p>
]]></description>
</item>
<item>
<title>Teaching (coding) wisdom</title>
<link>https://blog.mavnn.eu/2022/06/20/teaching-coding-wisdom.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2022/06/20/teaching-coding-wisdom.html</guid>
<pubDate>Mon, 20 Jun 2022 00:00:00 +0200</pubDate>

<description><![CDATA[<blockquote>
<p>
[talking about the teaching of wisdom]
</p>

<p>
There are these distillations that we get throughout the story, like in the ten commandments or in the Sermon on the Mount. At points, it’s very clear: “Don’t murder.” “Honor your ma and pa.” “Do to others what you want them to do to you.” But if you really think about it, you don’t want a list. You might want a list for a certain season that will train your moral compass. Then, when you confront really complex situations, like Joshua or Moses, and it’s not clear, and there’s no list, you’ve been shaped to be the kind of person who knows how to figure out the right way forward. Lists will not help you do that. Wisdom will help you do that.
</p>

<p>
--- <a href="https://bibleproject.com/podcast/wisdom-lifes-complexity/">https://bibleproject.com/podcast/wisdom-lifes-complexity/</a>
</p>
</blockquote>

<p>
Listening to the podcast above earlier and thinking that it feels very similar to how to teach good coding practices. We use the short hand of rules, and lists of recommendations… sometimes. But that doesn’t teach you how to deal with the complex situations, the edge cases, the actual real problems that need solving.
</p>

<p>
The flip side being that as soon as you’re guided by wisdom, by the stories of what works, the shaping of thinking, you start getting into interpretation and ambiguity because you’re actually needing to think about the decisions you’re making. It can become hard to explain why you’re doing things, and different experiences will have coloured the “wisdom” that you’ve formed over the years. Which is why it becomes so important to have a variety of backgrounds and a willingness to communicate in a technical team that’s actually going to get things done. Why the lists and rules (microservices rule the world! TDD is the one true way! pure code is the only real code!) only get you so far, and should be starting points - not ending points.
</p>

<p>
If you'd like to comment on this post, or suggest a correction, you can <a href="https://github.com/mavnn/blog/blob/master/2022/06/20/teaching-coding-wisdom.org">submit suggestions for changes</a> (GitHub account required). Just hit the "edit this file button" and go from there - or log an issue on the repository.
</p>
]]></description>
</item>
<item>
<title>Why your Typescript compiles when you thought you were safe</title>
<link>https://blog.mavnn.eu/2022/01/07/types-in-typescript.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2022/01/07/types-in-typescript.html</guid>
<pubDate>Fri, 07 Jan 2022 00:00:00 +0100</pubDate>

<description><![CDATA[<div id="outline-container-ID-A6417EF5-B15C-40B0-A0A8-37728F0B79F9" class="outline-4">
<h4 id="ID-A6417EF5-B15C-40B0-A0A8-37728F0B79F9"><span class="section-number-4">24.0.1.</span> These are not the types you are looking for</h4>
<div class="outline-text-4" id="text-24-0-1">
<p>
TypeScript's compiler will let you write code that looks illegal - but compiles just fine.
</p>

<p>
This is the story of one such piece of code, and the epiphany it led me to: TypeScript doesn't use your type definitions to decide if a type is compatible, it uses the JavaScript that could represent that type.
</p>

<p>
Let's walk through what that means.
</p>
</div>
</div>
<div id="outline-container-ID-4425BDBE-158E-4F46-B92D-B0C3BDC2DF85" class="outline-4">
<h4 id="ID-4425BDBE-158E-4F46-B92D-B0C3BDC2DF85"><span class="section-number-4">24.0.2.</span> The code</h4>
<div class="outline-text-4" id="text-24-0-2">
<p>
I'm writing code to make defining GraphQL resolvers a type safe experience (earlier developer feedback for the win). You don't need to know the details of GQL to follow this example though; all you need to know is that I have a type for defining the configuration of a resolver, and once certain information is supplied, I know the config is valid.
</p>

<p>
Let's have a look at some code:
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">ConfigValid</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXstring">"valid"</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXstring">"invalid"</span>

<span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">ConfigValid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> myConfig<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-constant">null</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-constant">null</span>

  <span class="org-typescript-access-modifier">private</span> <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span>

  <span class="org-typescript-access-modifier">public</span> <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">make</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"invalid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"invalid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXcomment">// I want this function to only accept valid configurations, and I want to</span>
  <span class="org-tree-sitter-hl-faceXcomment">// check if they are valid *at compile time*</span>
  <span class="org-typescript-access-modifier">public</span> <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">build</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">config</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"valid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXcomment">// do stuff!</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>config<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">myConfig</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Pop quiz: <code>Config.make</code> always returns a <code>Config&lt;"invalid"&gt;</code>, and <code>Config.build</code> only takes a <code>Config&lt;"valid"&gt;</code>. Will the code <code>Config.build(Config.make())</code> compile or not?
</p>

<p>
Given I'm asking, you've probably guessed that it <b>does</b> compile, breaking both my intuition... and my code.
</p>

<p>
Why?
</p>
</div>
</div>
<div id="outline-container-ID-46FCA670-3370-4304-AA6C-7315B08E42AA" class="outline-4">
<h4 id="ID-46FCA670-3370-4304-AA6C-7315B08E42AA"><span class="section-number-4">24.0.3.</span> What actually <i>is</i> TypeScript anyway?</h4>
<div class="outline-text-4" id="text-24-0-3">
<p>
Don't get whiplash, I'm going somewhere with this.
</p>

<p>
What is TypeScript?
</p>

<p>
Let's hit the <a href="https://www.typescriptlang.org/">TypeScript website</a>. It starts with "TypeScript is JavaScript with syntax for types", and then continues with "TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale". 
</p>

<p>
To my way of thinking, that first quote looks accurate. The second is a lie.
</p>

<p>
Okay, okay: "strongly typed" has <a href="https://en.wikipedia.org/wiki/Strong_and_weak_typing">"no precise technical definition"</a> so you can argue that it's half true; I wouldn't agree, given the code above, but you can argue it. But what I'm really calling a lie is the statement that TypeScript is a programming language.
</p>

<p>
I would instead argue that TypeScript is an inline theorem prover for JavaScript. Because anything that <b>does</b> something in your code is really JavaScript - after all, TypeScript compiles to JavaScript, and all your lovely types are erased. While all of the <i>TypeScript</i> in your code (anything that isn't valid JavaScript) is just there trying to prove that your code is correct. 
</p>

<p>
TypeScript has been designed to make demonstrating correctness as easy as possible when dealing with existing (untyped) JavaScript. (Hint: as easy as possible doesn't mean easy...)
</p>
</div>
</div>
<div id="outline-container-ID-C46E6C04-543D-40A4-9BD3-7C822B3A3496" class="outline-4">
<h4 id="ID-C46E6C04-543D-40A4-9BD3-7C822B3A3496"><span class="section-number-4">24.0.4.</span> Erm... what's this got to do with the code above?</h4>
<div class="outline-text-4" id="text-24-0-4">
<p>
We're not there yet. Stage 2 in our journey is structural typing.
</p>

<p>
Most strongly typed programming languages use "nominal" typing. Roughly, it's the "name" of the type that matters and if you give two types two different names (not aliases, actual different names), the compiler will keep track of which one you use where and treat them as different things - <i>even if they hold exactly the same data</i>.
</p>

<p>
So in, for example, F#, the following two types are not the same, and a function that accepts one will not accept the other:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">type</span> <span class="org-type">FirstRecord</span> = {
    name: <span class="org-type">string</span>
}

<span class="org-keyword">type</span> <span class="org-type">SecondRecord</span> = {
    name: <span class="org-type">string</span>
}

<span class="org-keyword">let</span> <span class="org-function-name">withFirstRecord</span> (<span class="org-variable-name">record</span>: <span class="org-type">FirstRecord</span>) =
  record.name
</pre>
</div>

<p>
Trying to send a record of <code>SecondRecord</code> to <code>withFirstRecord</code> would be a compile time error. Now, in F# there's an alternative; the function below will accept any type with a member called <code>name</code>:
</p>

<div class="org-src-container">
<pre class="src src-fsharp"><span class="org-keyword">let</span> <span class="org-keyword">inline</span> <span class="org-function-name">withName</span> <span class="org-variable-name">arg</span> =
  (^a : (<span class="org-keyword">member</span> <span class="org-function-name">name</span> : <span class="org-type">string</span>) arg)
</pre>
</div>

<p>
Notice a few things here:
</p>

<ul class="org-ul">
<li>That syntax is horrific; turns out this is a deliberate choice to discourage overuse (see the rest of the bullets for why)</li>
<li>I had to add the <code>inline</code> keyword to get it to compile. This literally means that in each place this method is used, the compiler will inline a version that uses the type inferred in that location in the code base. This can be good or bad.</li>
<li>You can probably imagine that the error messages from this type of code become explosively unreadable if you nest several layers of functions using this technique, and the constraints start to grow. F# can no longer tell you "you need to give my a <code>FirstRecord</code>"; instead it has to resort to "here's a list of constraints, find me something that meets them all."</li>
</ul>

<p>
This is structural typing, checking types based on the type of data that they hold. And here we wrap back around to TypeScript, which always uses structural typing. 
</p>

<p>
The question is: <i>what</i> are we comparing to see if things are structurally compatible? And this is where my intuition was broken.
</p>

<p>
In F#, we're comparing the <b>type definition</b> to the constraints. But in TypeScript, we're comparing the <b>JavaScript representation of the type</b> to the constraints <i>because TypeScript exists to make JavaScript safer</i>, not to be a programming language in its own right.
</p>
</div>
</div>
<div id="outline-container-ID-DA810DBC-D22B-4948-A1DE-C43DA94F2DC4" class="outline-4">
<h4 id="ID-DA810DBC-D22B-4948-A1DE-C43DA94F2DC4"><span class="section-number-4">24.0.5.</span> The mystery resolved</h4>
<div class="outline-text-4" id="text-24-0-5">
<p>
Back to our code:   
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">ConfigValid</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXstring">"valid"</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXstring">"invalid"</span>

<span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">ConfigValid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> myConfig<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-constant">null</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-constant">null</span>

  <span class="org-typescript-access-modifier">private</span> <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{}</span>

  <span class="org-typescript-access-modifier">public</span> <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">make</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"invalid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"invalid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXcomment">// I want this function to only accept valid configurations, and I want to</span>
  <span class="org-tree-sitter-hl-faceXcomment">// check if they are valid *at compile time*</span>
  <span class="org-typescript-access-modifier">public</span> <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">build</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">config</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"valid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXcomment">// do stuff!</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>config<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">myConfig</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
What is the difference between the JavaScript representations of <code>Config&lt;"invalid"&gt;</code> and <code>Config&lt;"valid"&gt;</code>?
</p>

<p>
Answer: nothing.
</p>

<p>
The generic parameter on the type is not used or stored at runtime (i.e. in JavaScript) on <code>Config</code>, and therefore it gets completely erased when we compile to JavaScript. Suddenly, it becomes no surprise that the compiler is perfectly happy to allow the use of <code>Config&lt;"invalid"&gt;</code> anywhere we specify <code>Config&lt;"valid"&gt;</code> - by TypeScript's standards they are structurally equivalent.
</p>
</div>
</div>
<div id="outline-container-ID-746DEAE1-71A8-4FA7-89DE-726921BBA596" class="outline-4">
<h4 id="ID-746DEAE1-71A8-4FA7-89DE-726921BBA596"><span class="section-number-4">24.0.6.</span> But: the safety?!</h4>
<div class="outline-text-4" id="text-24-0-6">
<p>
Okay, so the code above doesn't work. But now we know what the problem actually is, so... let's fix it!
</p>

<div class="org-src-container">
<pre class="src src-typescript"><span class="org-tree-sitter-hl-faceXkeyword">type</span> <span class="org-tree-sitter-hl-faceXtype">ConfigValid</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-tree-sitter-hl-faceXstring">"valid"</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-tree-sitter-hl-faceXstring">"invalid"</span>

<span class="org-tree-sitter-hl-faceXkeyword">class</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXtype">T</span> <span class="org-tree-sitter-hl-faceXkeyword">extends</span> <span class="org-tree-sitter-hl-faceXtype">ConfigValid</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-typescript-access-modifier">private</span> myConfig<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtypeXbuiltin">string</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">|</span> <span class="org-constant">null</span> <span class="org-tree-sitter-hl-faceXoperator">=</span> <span class="org-constant">null</span>
  <span class="org-typescript-access-modifier">private</span> _isValid<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">T</span>

  <span class="org-typescript-access-modifier">private</span> <span class="org-tree-sitter-hl-faceXmethod">constructor</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">isValid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">T</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">this</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty"><span class="org-tree-sitter-hl-faceXvariable">_isValid</span></span> <span class="org-tree-sitter-hl-faceXoperator">=</span> isValid
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-typescript-access-modifier">public</span> <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">make</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">()</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"invalid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXkeyword">return</span> <span class="org-tree-sitter-hl-faceXkeyword">new</span> <span class="org-tree-sitter-hl-faceXconstructor">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"invalid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"invalid"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXcomment">// I want this function to only accept valid configurations, and I want to</span>
  <span class="org-tree-sitter-hl-faceXcomment">// check if they are valid *at compile time*</span>
  <span class="org-typescript-access-modifier">public</span> <span class="org-tree-sitter-hl-faceXkeyword">static</span> <span class="org-tree-sitter-hl-faceXmethod">build</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-variable-name">config</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXtype">Config</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&lt;</span></span><span class="org-tree-sitter-hl-faceXstring">"valid"</span><span class="org-tree-sitter-hl-faceXoperator"><span class="org-tree-sitter-hl-faceXpunctuationXbracket">&gt;</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXcomment">// do stuff!</span>
    <span class="org-tree-sitter-hl-faceXvariableXbuiltin">console</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-function-name">log</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span>config<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXproperty">myConfig</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
You see that <code>_isValid</code> field? Now we're storing a value in that field, and that value will exist at runtime in the compiled JavaScript. Now TypeScript cares about it, and now we can call <code>Config.build</code> safe in the knowledge it will only take a valid configuration instance.
</p>
</div>
</div>
<div id="outline-container-ID-8F6268A6-27BB-4CD3-8055-997853DD331F" class="outline-4">
<h4 id="ID-8F6268A6-27BB-4CD3-8055-997853DD331F"><span class="section-number-4">24.0.7.</span> That's a wrap</h4>
<div class="outline-text-4" id="text-24-0-7">
<p>
I hope you've enjoyed this little journey into making <a href="https://blog.janestreet.com/effective-ml-revisited/">making illegal states unrepresentable</a>, and if you think you could enjoy this kind of thing (or even using the results to just build stuff!) I'm currently working with Blissfully and we're <a href="https://www.blissfully.com/careers/">currently hiring</a> (it says backend developers, but we're also hiring for our Elm frontend where making illegal states unrepresentable is even easier...).
</p>

<p>
If you feel a burning need to comment on this post, or suggest a correction, you can <a href="https://github.com/mavnn/blog/blob/master/org/2022/01/07/types-in-typescript.org">submit suggestions for changes</a>(GitHub account required). Just hit the "edit this file button" and go from there.
</p>

<p>
With special thanks to <a href="https://twitter.com/mech_elephant">Matthew Griffith</a> and <a href="https://twitter.com/aaronwhite">Aaron White</a> for reading, pushing for and suggesting a stronger title and introductory paragraph.
</p>
</div>
</div>
]]></description>
</item>
<item>
<title>Literate CSS</title>
<link>https://blog.mavnn.eu/2021/10/04/LiterateCSS.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2021/10/04/LiterateCSS.html</guid>
<pubDate>Mon, 04 Oct 2021 00:00:00 +0200</pubDate>

<description><![CDATA[<p>
One of the benefits of writing my blog in Org-Mode in Emacs, is that my blog posts are a functional literate programming environment. Which is pretty handy for keeping track of things like "how does my CSS work", for example.
</p>

<p>
Well, in general Org-Mode injects a basic set of CSS into web pages as it exports them, but I'm planning to amend that slightly as I go forward. Meaning this blog post will be a bit of a living document, evolving over time. Hi, future me! Hope you like it.
</p>

<p>
We're going to cheat a bit and use a "classless CSS framework" (<a href="https://github.com/kognise/water.css">water.css</a> is going to be my first attempt). This means we can remove a lot of default styling, and focus only on the more specific classes org adds. The entire unminified water.css file is included at the end of this file so that it gets bundled together with my custom css. I may build a workflow to minimize the results in the future, but honestly it seems a false optimization right now.
</p>

<p>
Load fonts early to avoid glitches and spacing issues:
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-builtin">@font-face</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">charter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-stretch</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">src</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'/fonts/charter_regular.woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">format</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@font-face</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">charter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">italic</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-stretch</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">src</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'/fonts/charter_italic.woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">format</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@font-face</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">charter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">bold</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-stretch</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">src</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'/fonts/charter_bold.woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">format</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@font-face</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">charter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">italic</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">bold</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-stretch</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">src</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'/fonts/charter_bold_italic.woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">format</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@font-face</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">source_code_pro</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">regular</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">src</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'/fonts/SourceCodePro-Regular.otf.woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">format</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">'woff2'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Colour variables, so we don't need to keep on repeating them and we have some consistency.
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-tree-sitter-hl-faceXcomment">/**</span>
<span class="org-tree-sitter-hl-faceXcomment"> * These colors are taken from `water.css`, rearranged to</span>
<span class="org-tree-sitter-hl-faceXcomment"> * my liking and expanded a bit for code highlighting.</span>
<span class="org-tree-sitter-hl-faceXcomment"> *</span>
<span class="org-tree-sitter-hl-faceXcomment"> * Automatic version:</span>
<span class="org-tree-sitter-hl-faceXcomment"> * Uses light theme by default but switches to dark theme</span>
<span class="org-tree-sitter-hl-faceXcomment"> * if a system-wide theme preference is set on the user's device.</span>
<span class="org-tree-sitter-hl-faceXcomment"> */</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">root</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXcomment">/* re-usable names for quickly experimenting */</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--dominant-base</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">EC0000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--complement-base</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">00BD00</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--secondary-base</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">EC6B00</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--secondary-complement-base</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">008E8E</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--dominant</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--dominant-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--complement</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--complement-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">25</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--secondary</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">25</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--secondary-complement</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary-complement-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--mixin-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">black</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--mixin-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">white</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--nearly-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">98</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--mostly-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">95</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--half-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--slightly-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">25</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--nearly-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">99</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--mostly-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">94</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--half-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--slightly-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">25</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--text-main</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--dominant</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--nearly-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--text-bright</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--dominant</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mostly-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--text-muted</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--dominant</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--slightly-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--background-body</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--complement-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--nearly-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--complement-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mostly-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--background-alt</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--complement-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--half-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--code-keyword</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--dominant</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--code-value</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--complement</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--code-type</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--code-comment</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary-complement</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--code-punctuation</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--code-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--code</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--selection</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--complement</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--links</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--focus</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary-complement</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--animation-duration</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--button-base</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--button-hover</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span><span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--slightly-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--form-placeholder</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-muted</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--form-text</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--variable</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--highlight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--complement</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--select-arrow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23161f27'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">root</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--mixin-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">white</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--mixin-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">121212</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--dominant</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--dominant-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--complement</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--complement-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--secondary</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--secondary-complement</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">color-mix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">in</span> <span class="org-tree-sitter-hl-faceXvariable">oklab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary-complement-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--mixin-foreground</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">))</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--nearly-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">98</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--mostly-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">95</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--half-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--slightly-foreground</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">25</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--nearly-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">90</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--mostly-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">75</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--half-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">--slightly-background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>

<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Responsive text and content sizes from the absolutely amazing <a href="https://practicaltypography.com/">Practical Typography</a> from Matthew Butterick.
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-tree-sitter-hl-faceXtag">html</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 2.4<span class="org-tree-sitter-hl-faceXstring">vw</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/** Make sure that while font size scales smoothly, it never gets</span>
<span class="org-tree-sitter-hl-faceXcomment"> * too big or small.</span>
<span class="org-tree-sitter-hl-faceXcomment"> */</span>
<span class="org-builtin">@media</span> all and <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">min-width</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXnumber">1000</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXtag">html</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">24</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-builtin">@media</span> all and <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">max-width</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXnumber">670</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXtag">html</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">18</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">body</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> 0.5<span class="org-tree-sitter-hl-faceXstring">rem</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">max-width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1000</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">min-height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">position</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">relative</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">z-index</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">-10000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">-webkit-font-smoothing</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">subpixel-antialiased</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXcomment">/* corrects safari rendering */</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">charter</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariable">serif</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">line-height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 1.4<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">word-wrap</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">break-word</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-body</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-rendering</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">optimizeLegibility</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
My nice little "go home" header needs some CSS to get it looking as cute as I'd want it.
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-tree-sitter-hl-faceXtag">img</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">home-logo</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">3</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">white</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">#</span><span class="org-tree-sitter-hl-faceXtag">org-div-home-and-up</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">70</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">flex</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">flex-direction</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">row</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">align-items</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">justify-content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">flex-end</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">gap</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Adding some horizontal rules helps keep sections separate.
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-tree-sitter-hl-faceXtag">header</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">after</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">""</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">block</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXcomment">/* The class given to divs containing a top level org heading */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">outline-2</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Keeping the minimalist footer neat:
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-tree-sitter-hl-faceXcomment">/* positioning only, the rest of the header styling is defined in the default water css below */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">#</span><span class="org-tree-sitter-hl-faceXtag">my-contacts</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">flex</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">flex-flow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">row</span> <span class="org-tree-sitter-hl-faceXvariable">wrap</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">align-items</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">gap</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Code colouring. There's a slightly interesting quirk here as each language can define its own custom token types as well as the more general shared set. We get around that by using fairly permissive <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors">attribute selectors</a> to categorise classes within source blocks (for example, colouring all spans with a class including the string keyword or primitive the same way rather than rather a separate rule for <code>.org-typescript-primitive</code>).
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-tree-sitter-hl-faceXcomment">/* This class is applied to a wrapper div around code blocks */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">word-wrap</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/** Combines with the language specific rules below to add a "tab"</span>
<span class="org-tree-sitter-hl-faceXcomment"> * showing the language contained in the code block</span>
<span class="org-tree-sitter-hl-faceXcomment"> */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">block</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">italic</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.8<span class="org-tree-sitter-hl-faceXstring">em</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">fit-content</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">5</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code-value</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-muted</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">8</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">8</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">source_code_pro</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXvariable">monospace</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.8<span class="org-tree-sitter-hl-faceXstring">rem</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">position</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">relative</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">white-space</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXcomment">/* Code can be long; especially on mobile, it might need to scroll */</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">overflow-x</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code-background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">5</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">8</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">8</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">code</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">80</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXcomment">/* Rule for keywords etc */</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"keyword"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"access-modifier"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code-keyword</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXcomment">/* Rule for as many literal values as I can think of */</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"string"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"constant"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"number"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code-value</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXcomment">/* Rule for punctuation */</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"punctuation"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"rainbow"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"bracket"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code-punctuation</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXcomment">/* Rule for comments */</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"comment"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code-comment</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXcomment">/* Rule for types etc */</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"type"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"attribute"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"tag"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"primitive"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"property"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
  &amp; <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXtag">span</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>class<span class="org-tree-sitter-hl-faceXoperator">*=</span><span class="org-tree-sitter-hl-faceXstring">"builtin"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
      <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code-type</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
Everything below this point is modified from the default org style sheet, that normally gets embedded into every page. I'm going to separate it out here so that I can start hacking on it, and then set the export not to inject it every time.
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">todo</span>   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">monospace</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">red</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">done</span>   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">monospace</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">green</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">priority</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">monospace</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">orange</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">tag</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">span</span>   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--secondary</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.2<span class="org-tree-sitter-hl-faceXstring">rem</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.1<span class="org-tree-sitter-hl-faceXstring">rem</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">75</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">timestamp</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">bebebe</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">timestamp-kwd</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">5f9ea0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-right</span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-left</span>   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-center</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">#</span><span class="org-tree-sitter-hl-faceXtag">postamble</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">p</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">#</span><span class="org-tree-sitter-hl-faceXtag">preamble</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">p</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">90</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> .2<span class="org-tree-sitter-hl-faceXstring">em</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">min-height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXtag">p</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">verse</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">3</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/* Languages per Org manual */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-asymptote</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Asymptote'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-awk</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Awk'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-C</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'C'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/* pre.src-C++ doesn't work in CSS */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-clojure</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Clojure'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-css</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'CSS'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-D</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'D'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ditaa</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'ditaa'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-dot</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Graphviz'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Emacs Calc'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-emacs-lisp</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Emacs Lisp'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-fortran</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Fortran'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-gnuplot</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'gnuplot'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-haskell</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Haskell'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-hledger</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'hledger'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-java</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Java'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-js</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Javascript'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-latex</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'LaTeX'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ledger</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Ledger'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-lisp</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Lisp'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-lilypond</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Lilypond'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-lua</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Lua'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-matlab</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'MATLAB'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-mscgen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Mscgen'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ocaml</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Objective Caml'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-octave</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Octave'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-org</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Org mode'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-oz</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'OZ'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-plantuml</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Plantuml'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-processing</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Processing.js'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-python</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Python'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-R</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'R'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ruby</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Ruby'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-sass</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Sass'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Scheme'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-screen</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Gnu Screen'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-sed</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Sed'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-sh</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'shell'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-sql</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'SQL'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-sqlite</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'SQLite'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/* additional languages in org.el's org-babel-load-languages alist */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-forth</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Forth'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-io</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'IO'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-J</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'J'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-makefile</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Makefile'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-maxima</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Maxima'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-perl</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Perl'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-picolisp</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Pico Lisp'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-scala</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Scala'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-shell</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Shell Script'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ebnf2ps</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'ebfn2ps'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/* additional language identifiers per "defun org-babel-execute"</span>
<span class="org-tree-sitter-hl-faceXcomment">     in ob-*.el */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-cpp</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'C++'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-abc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'ABC'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-coq</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Coq'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-groovy</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Groovy'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/* additional language identifiers from org-babel-shell-names in</span>
<span class="org-tree-sitter-hl-faceXcomment">   ob-shell.el: ob-shell is the only babel language using a lambda to put</span>
<span class="org-tree-sitter-hl-faceXcomment">   the execution function name together. */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-bash</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'bash'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-csh</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'csh'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ash</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'ash'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-dash</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'dash'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ksh</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'ksh'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-mksh</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'mksh'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-posh</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'posh'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/* Additional Emacs modes also supported by the LaTeX listings package */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ada</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Ada'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-asm</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Assembler'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-caml</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Caml'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-delphi</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Delphi'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-html</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'HTML'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-idl</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'IDL'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-mercury</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Mercury'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-metapost</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'MetaPost'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-modula-2</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Modula-2'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-pascal</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Pascal'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ps</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'PostScript'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-prolog</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Prolog'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-simula</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Simula'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-tcl</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'tcl'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-tex</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'TeX'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-plain-tex</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Plain TeX'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-verilog</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Verilog'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-vhdl</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'VHDL'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-xml</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'XML'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-nxml</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'XML'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXcomment">/* add a generic configuration mode; LaTeX export needs an additional</span>
<span class="org-tree-sitter-hl-faceXcomment">   (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-conf</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'Configuration File'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXcomment">/* added manually after generation */</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-typescript</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'TypeScript'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-fsharp</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'F#'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-nix</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'nix'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-procfile</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'procfile'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-yaml</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'yaml'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-src-container</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">has</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">src-ink</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'ink'</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">caption</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">t-above</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">caption-side</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">top</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXtag">caption</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">t-bottom</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">caption-side</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">bottom</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXtag">th</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-right</span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXtag">th</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-left</span>   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXtag">th</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-center</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXtag">td</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-right</span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXtag">td</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-left</span>   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>   <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXtag">td</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-center</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">footpara</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inline</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">footdef</span>  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">figure</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">figure</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">p</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">equation-container</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">table</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">equation</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">vertical-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">middle</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">equation-label</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">table-cell</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">right</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">vertical-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">middle</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">inlinetask</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXvariable">gray</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">ffffcc</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">linenr</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">smaller</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">code-highlighted</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">ffff00</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-info-js_info-navigation</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">#</span><span class="org-tree-sitter-hl-faceXtag">org-info-js_console-label</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">bold</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">white-space</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">nowrap</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-info-js_search-highlight</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">ffff00</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">bold</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">.</span><span class="org-tree-sitter-hl-faceXtag">org-svg</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span> <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">90</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
This is the contents of the MIT licensed `water.css` file that we're choosing to use, and which aren't already included above!
</p>

<div class="org-src-container">
<pre class="src src-css"><span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> 0.1<span class="org-tree-sitter-hl-faceXstring">s</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>
    <span class="org-tree-sitter-hl-faceXvariable">background-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">border-color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">color</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">box-shadow</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">linear</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
    <span class="org-tree-sitter-hl-faceXvariable">transform</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--animation-duration</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">ease</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h1</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 2.2<span class="org-tree-sitter-hl-faceXstring">em</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h2</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h3</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h4</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h5</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h6</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">24</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h1</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">h1</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h2</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">h2</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h3</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">h3</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h4</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">h4</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h5</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">h5</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h6</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">h6</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">strong</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">strong</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">h1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h2</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h3</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h4</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h5</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">h6</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">b</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">strong</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">th</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">600</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">q</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">q</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">after</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">blockquote</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 1.5<span class="org-tree-sitter-hl-faceXstring">em</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.5<span class="org-tree-sitter-hl-faceXstring">em</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">blockquote</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">q</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 1.5<span class="org-tree-sitter-hl-faceXstring">em</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.5<span class="org-tree-sitter-hl-faceXstring">em</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">italic</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">q</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">blockquote</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">footer</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">blockquote</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">cite</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">address</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">a</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>href<span class="org-tree-sitter-hl-faceXoperator">^=</span><span class="org-tree-sitter-hl-faceXstring">'mailto\:'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'&#128231; '</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">a</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>href<span class="org-tree-sitter-hl-faceXoperator">^=</span><span class="org-tree-sitter-hl-faceXstring">'tel\:'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'&#128222; '</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">a</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>href<span class="org-tree-sitter-hl-faceXoperator">^=</span><span class="org-tree-sitter-hl-faceXstring">'sms\:'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">before</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">content</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXstring">'&#128172; '</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">mark</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">ff0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--highlight</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">mark</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efdb43</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--highlight</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">a</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">code</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">a</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">strong</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">select</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'submit'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'reset'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'button'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'checkbox'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'radio'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">cursor</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">pointer</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">block</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'checkbox'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'radio'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">initial</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1d1d1d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-text</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">outline</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-text</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1d1d1d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-text</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">outline</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-text</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1d1d1d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-text</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">outline</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-text</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1d1d1d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-text</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inherit</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">outline</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-text</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">d0cfcf</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0c151c</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'submit'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">d0cfcf</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'submit'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0c151c</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'reset'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">d0cfcf</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'reset'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0c151c</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'button'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">d0cfcf</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-left</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'button'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0c151c</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-base</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">9b9b9b</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">040a0f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'submit'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">9b9b9b</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'submit'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">040a0f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'reset'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">9b9b9b</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'reset'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">040a0f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'button'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">9b9b9b</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'button'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">040a0f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--button-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'color'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">min-height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">rem</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">8</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">cursor</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">pointer</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'checkbox'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'radio'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'radio'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">vertical-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">top</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">label</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">vertical-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">middle</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">inline-block</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">input</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXfunction">not</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">([</span><span class="org-tree-sitter-hl-faceXvariable">type='checkbox'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">])</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXfunction">not</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">([</span><span class="org-tree-sitter-hl-faceXvariable">type='radio'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">])</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXvariable">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-tree-sitter-hl-faceXvariable">type='range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXvariable">select</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXvariable">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXvariable">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable">-webkit-appearance:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">block</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-sizing</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">border-box</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">resize</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">vertical</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">textarea</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">not</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">([</span><span class="org-css-selector">cols</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">])</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">textarea</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">not</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">([</span><span class="org-css-selector">rows</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">])</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">min-height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">40</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">140</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23161f27'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--select-arrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">35</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--select-arrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--select-arrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--select-arrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">select</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span> <span class="org-tree-sitter-hl-faceXfunction">url</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXstring">"data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--select-arrow</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXfunction">calc</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">-</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span> <span class="org-tree-sitter-hl-faceXoperator">/</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">no-repeat</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">select</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-expand</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">select</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">multiple</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-right</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-image</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">overflow-y</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">select</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">select</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">textarea</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">textarea</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'checkbox'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>active<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'radio'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>active<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'submit'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>active<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'reset'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>active<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'button'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span>active<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">active</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">active</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transform</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">translateY</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">disabled</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">select</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">disabled</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">disabled</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">textarea</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">disabled</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">cursor</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">not-allowed</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">opacity</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.5<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-placeholder</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">949494</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-placeholder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-input-placeholder</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">949494</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-placeholder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-input-placeholder</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">949494</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-placeholder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">placeholder</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">949494</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-placeholder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-placeholder</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">a9a9a9</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-placeholder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-input-placeholder</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">a9a9a9</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-placeholder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-input-placeholder</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">a9a9a9</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-placeholder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">placeholder</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">a9a9a9</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--form-placeholder</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">fieldset</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span> <span class="org-tree-sitter-hl-faceXvariable">solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">12</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">fieldset</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0096bfab</span> <span class="org-tree-sitter-hl-faceXvariable">solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--focus</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXvariable">solid</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">legend</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.9<span class="org-tree-sitter-hl-faceXstring">em</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-weight</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">600</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">type</span><span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">transparent</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">outline</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-slider-runnable-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 9.5<span class="org-tree-sitter-hl-faceXstring">px</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">-webkit-transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.2<span class="org-tree-sitter-hl-faceXstring">s</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.2<span class="org-tree-sitter-hl-faceXstring">s</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">3</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-slider-runnable-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-slider-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0d0d0d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">-webkit-appearance</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">-7</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-slider-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-slider-runnable-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-slider-runnable-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-range-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 9.5<span class="org-tree-sitter-hl-faceXstring">px</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">-moz-transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.2<span class="org-tree-sitter-hl-faceXstring">s</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">transition</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.2<span class="org-tree-sitter-hl-faceXstring">s</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">3</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-range-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-range-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0d0d0d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-range-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 9.5<span class="org-tree-sitter-hl-faceXstring">px</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">transparent</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">transparent</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">16</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">transparent</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-fill-lower</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.2<span class="org-tree-sitter-hl-faceXstring">px</span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">010101</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">3</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0d0d0d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-fill-lower</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-fill-upper</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 0.2<span class="org-tree-sitter-hl-faceXstring">px</span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">010101</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">3</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0d0d0d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-fill-upper</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">box-shadow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0d0d0d</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">20</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">50</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-fill-lower</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-fill-lower</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-fill-upper</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span>type<span class="org-tree-sitter-hl-faceXoperator">=</span><span class="org-tree-sitter-hl-faceXstring">'range'</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-ms-fill-upper</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">a</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-decoration</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0076d1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--links</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">a</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">41adff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--links</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">a</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-decoration</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">underline</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">code</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 2.5<span class="org-tree-sitter-hl-faceXstring">px</span> <span class="org-tree-sitter-hl-faceXnumber">5</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">code</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">ffbe85</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">code</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">samp</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 2.5<span class="org-tree-sitter-hl-faceXstring">px</span> <span class="org-tree-sitter-hl-faceXnumber">5</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">samp</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">ffbe85</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">samp</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">time</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> 2.5<span class="org-tree-sitter-hl-faceXstring">px</span> <span class="org-tree-sitter-hl-faceXnumber">5</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-size</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">time</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">ffbe85</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--code</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">time</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">code</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">block</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">overflow-x</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">var</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">39a33c</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--variable</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-style</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">normal</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">font-family</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">monospace</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">var</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">d941e2</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--variable</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">kbd</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">363636</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">2</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">kbd</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">kbd</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">kbd</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">img</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">video</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">max-width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">auto</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">hr</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">hr</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">table</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-collapse</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">collapse</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">100</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">%</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">table-layout</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">fixed</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">table</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">caption</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">td</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">th</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">left</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">vertical-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">top</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">word-wrap</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">break-word</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">thead</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">thead</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">tfoot</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">tfoot</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">tbody</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">tr</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">nth-child</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">even</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">tbody</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">tr</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">nth-child</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">even</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">tbody</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">tr</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">nth-child</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">even</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">f7f7f7</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">tbody</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">tr</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">nth-child</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">even</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">button</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1a242f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">tbody</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">tr</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">nth-child</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">even</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-body</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">tbody</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">tr</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">nth-child</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">even</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">202b38</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-body</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">height</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">width</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar-track</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">rgb</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">170</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">170</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">170</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--scrollbar-thumb</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">040a0f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--scrollbar-thumb</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar-thumb</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">040a0f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--scrollbar-thumb</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar-thumb</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">9b9b9b</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--scrollbar-thumb-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar-thumb</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">rgb</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--scrollbar-thumb-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-scrollbar-thumb</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">rgb</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--scrollbar-thumb-hover</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-selection</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">9e9e9e</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--selection</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">selection</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">9e9e9e</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--selection</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-selection</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">selection</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-bright</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-moz-selection</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1c76c5</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--selection</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">selection</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1c76c5</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--selection</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">details</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">flex</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">flex-direction</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">column</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">align-items</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">flex-start</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">f7f7f7</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">em</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">overflow</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">hidden</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">details</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1a242f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">details</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">open</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">details</span> <span class="org-tree-sitter-hl-faceXoperator">&gt;</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">last-child</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">details</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">[</span><span class="org-css-selector">open</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">]</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">summary</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-bottom</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">summary</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">display</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">list-item</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">-10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">-10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">cursor</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">pointer</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">outline</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">summary</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">hover</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">focus</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-decoration</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">underline</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">details</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">not</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-details-marker</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">363636</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-details-marker</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">dialog</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">f7f7f7</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">363636</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">none</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">dialog</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">dialog</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-main</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">dialog</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">1a242f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background-alt</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">dialog</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">header</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">first-child</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">efefef</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-radius</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">6</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">0</span> <span class="org-tree-sitter-hl-faceXnumber">0</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">-10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">-30</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-align</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">center</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">dialog</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">header</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">first-child</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">161f27</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--background</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">dialog</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-backdrop</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0000009c</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">-webkit-backdrop-filter</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">blur</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">backdrop-filter</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">blur</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">dialog</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">backdrop</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">0000009c</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">-webkit-backdrop-filter</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">blur</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
          <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">backdrop-filter</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">blur</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXnumber">4</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">footer</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">dbdbdb</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">padding-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">10</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">70777f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-muted</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">footer</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">a9b1ba</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--text-muted</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXproperty">prefers-color-scheme</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">dark</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>

  <span class="org-tree-sitter-hl-faceXtag">footer</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">526980</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXfunction">var</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXvariable">--border</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-tree-sitter-hl-faceXtag">body</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXoperator">&gt;</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">footer</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">margin-top</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">40</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

<span class="org-builtin">@media</span> print <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
  <span class="org-tree-sitter-hl-faceXtag">body</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">code</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">details</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">fff</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">textarea</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">border</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXnumber">1</span><span class="org-tree-sitter-hl-faceXnumber"><span class="org-tree-sitter-hl-faceXstring">px</span></span> <span class="org-tree-sitter-hl-faceXvariable">solid</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXtag">body</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">h1</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">h2</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">h3</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">h4</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">h5</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">h6</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">pre</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">code</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">button</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">input</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">textarea</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">footer</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">,</span>
<span class="org-css-selector">  </span><span class="org-tree-sitter-hl-faceXtag">strong</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">marker</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXtag">summary</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">::</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">-webkit-details-marker</span></span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">000</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXtag">tbody</span><span class="org-css-selector"> </span><span class="org-tree-sitter-hl-faceXtag">tr</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span><span class="org-tree-sitter-hl-faceXattribute"><span class="org-tree-sitter-hl-faceXtag">nth-child</span></span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">(</span><span class="org-tree-sitter-hl-faceXtag">even</span><span class="org-tree-sitter-hl-faceXpunctuationXbracket">)</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">background-color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">f2f2f2</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>

  <span class="org-tree-sitter-hl-faceXtag">a</span> <span class="org-tree-sitter-hl-faceXpunctuationXbracket">{</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">color</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXpunctuationXdelimiter"><span class="org-tree-sitter-hl-faceXstring">#</span></span><span class="org-tree-sitter-hl-faceXstring">00f</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
    <span class="org-tree-sitter-hl-faceXvariable"><span class="org-tree-sitter-hl-faceXproperty">text-decoration</span></span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">:</span> <span class="org-tree-sitter-hl-faceXvariable">underline</span><span class="org-tree-sitter-hl-faceXpunctuationXdelimiter">;</span>
  <span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
<span class="org-tree-sitter-hl-faceXpunctuationXbracket">}</span>
</pre>
</div>

<p>
And I think that's all we need for now.
</p>
]]></description>
</item>
<item>
<title>New Beginnings</title>
<link>https://blog.mavnn.eu/2021/09/22/NewBeginnings.html</link>
<author>michael@mavnn.eu (Michael Newton)</author>
<guid isPermaLink="false">https://blog.mavnn.eu/2021/09/22/NewBeginnings.html</guid>
<pubDate>Wed, 22 Sep 2021 00:00:00 +0200</pubDate>

<description><![CDATA[<p>
This is just a short test; I'm beginning to publish my blog via Emacs Org mode rather than Jekyll because... well, because I don't enjoy updating Ruby, and blogging is something that I (partially) do for my own relaxation and enjoyment.
</p>

<p>
So... welcome to the new blog. To those few of you subscribed to my blog as a feed, apologies for the largely content free post.
</p>

<p>
If this works I'll be updating as I go along with actual posts, as well as the obligatory posts on how the blog works and why I've set it up as I'm planning to.
</p>

<p>
Remind me why every developer feels the need to do that, again?
</p>

<p>
If you feel a burning need to comment on this post, or suggest a correction, you can <a href="https://github.com/mavnn/blog/blob/master/2021/09/22/NewBeginnings.org">submit suggestions for changes</a> (GitHub account required). Just hit the "edit this file button" and go from there.
</p>
]]></description>
</item>
</channel>
</rss>
