<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>toxdes.com - Blog</title>
    <link>https://next.toxdes.com/blog</link>
    <description>Personal blog of Vaibhav (toxdes.com)</description>
    <image>
      <url>https://next.toxdes.com/favicon.ico</url>
      <title>toxdes.com - Blog</title>
      <link>https://next.toxdes.com/blog</link>
    </image>
    <language>en</language>
    <lastBuildDate>Sat, 23 May 2026 06:48:49 GMT</lastBuildDate>
    <atom:link href="https://next.toxdes.com/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>Devlog 0x001</title>
      <link>https://next.toxdes.com/blog/devlog-0x001.html</link>
      <guid isPermaLink="true">https://next.toxdes.com/blog/devlog-0x001.html</guid>
      <pubDate>Fri, 15 May 2026 10:30:00 GMT</pubDate>
      <author>hi@toxdes.com (Vaibhav Mali)</author>
      <description>This is a new &quot;series&quot; I&apos;m starting. I haven&apos;t decided the frequency yet, but probably like weekly or biweekly or just whenever. Let&apos;s see how it goes. The goal of this series is to share what I&apos;ve...</description>
      <category>wafflings</category>
      <category>devlog</category>
      <content:encoded><![CDATA[<p>This is a new &quot;series&quot; I&#39;m starting. I haven&#39;t decided the frequency yet, but probably like weekly or biweekly or just whenever. Let&#39;s see how it goes. The goal of this series is to share what I&#39;ve been spending my time on, some thoughts and some cool or interesting things I&#39;ve learned or come across since the last Devlog.</p>
<h2 id="dev"><a href="#dev" class="heading-anchor">Dev</a></h2><p>For the past few weeks, I&#39;ve spent time building <a href="https://github.com/toxdes/chronobsky" target="_blank" rel="noopener noreferrer">chronobsky</a> and adding support for LG&#39;s WebOS to <a href="https://github.com/toxdes/jiotv_go" target="_blank" rel="noopener noreferrer">my own fork</a> of <code>jiotv_go</code>. Finally, my legacy frontend engineering skills are coming in handy. Kinda sad to see that after almost 3 years of offering free premium TV channels, Jio is now introducing subscriptions, but it was fun while it lasted.</p>
<p>Having worked extensively with React from the pre-LLM era, I automatically used to underestimate how performant the browser&#39;s HTML rendering is by default for static content, and used to add things like pagination and virtualization. With LLMs, dynamically stitching HTML components at build time has become really easy.</p>
<p>One thing I&#39;ve realized is that with AI, it&#39;s very addictive to introduce slop in your projects. For example, adding a TUI dashboard in <a href="https://github.com/toxdes/glesha" target="_blank" rel="noopener noreferrer">glesha</a> turned out to be pretty much a useless feature, but at the time of introducing it, I just couldn&#39;t resist &quot;vibe-coding&quot; one specific independent-ish module in the project, and I&#39;ve spent the past week <em>de-sloppifying</em> the codebase. Nowadays, I kinda sit on any idea that comes to my mind a little bit longer to see if I really want it in.</p>
<h2 id="tailscale"><a href="#tailscale" class="heading-anchor">Tailscale</a></h2><p>If you use more than one device and need to <code>ssh</code> to and from each other quite frequently and haven&#39;t heard of <a href="https://tailscale.com" target="_blank" rel="noopener noreferrer">Tailscale</a> yet, you should drop everything you&#39;re doing and take 5 minutes to set all devices up, and it&#39;s definitely worth it. I have been hearing about Tailscale every now and then for the past few years, but never bothered to actually check it out because I didn&#39;t even know what it does. I wish I had looked into it way earlier.</p>
<p>I have two laptops and a Raspberry Pi (Zero 2W), and I also have two different ISPs for my internet, one is stable but slow, another is unstable (frequent disconnects) but fast. <code>pi</code> is always connected to the stable but slow network, but this is not the case for my laptops. I also have a tiny VPS for tinkering, and I <code>ssh</code> into these devices very frequently.</p>
<p>Before this, I used to switch networks just to be able to connect to my Pi. I had also looked into both routers&#39; settings if I could connect them so that I could access devices connected to two different routers, but there was no <em>easy</em> way to do this so I just didn&#39;t bother. I knew one way to do this by editing <code>/etc/hosts</code> and similar files on each device and using static local IPs for each device, and maybe setting up port-forwarding to access over the internet, but it just felt like too much work, and then there&#39;s the obvious exposure-to-internet aspect. As a last resort, I googled &quot;how people usually do this&quot; and found out that Tailscale does exactly this, automatically, and only devices in the tailnet can communicate with each other, and external actors cannot because Tailscale <a href="https://tailscale.com/docs/reference/reserved-ip-addresses" target="_blank" rel="noopener noreferrer">uses a reserved IP range</a> that isn&#39;t publicly routable.</p>
<h2 id="moving-back-to-alacritty"><a href="#moving-back-to-alacritty" class="heading-anchor">Moving back to Alacritty</a></h2><p>I was using <code>alacritty</code> terminal for the longest time, and I&#39;ve been trying out alternatives like <code>st</code> and <code>foot</code>. Mainly because each window of <code>alacritty</code> terminal took <code>~200MB</code> (wasn&#39;t aware of <code>create-window</code> yet), which seemed very unfair, and also I never really noticed why GPU-acceleration was needed to just render text on screen.</p>
<p>I tried <code>st</code> at first. It felt way too barebones but on the bright side, it also took very minimal <code>~10MB</code> memory for each instance. For <code>st</code>, the font-rendering somehow felt worse for me. Also to configure <code>st</code>, it required patching source code and recompiling. As a result, I decided to move on to the next candidate, the builtin default of <code>sway</code>, the <code>foot</code> terminal. It took <code>~24MB</code> for each instance, had saner configuration support. I had been using <code>foot</code> ever since, until last week when the <code>opencode</code> CLI just kept crashing <code>foot</code>. I never thought a CLI program would be capable of crashing a terminal. After spending around 5 to 6 months with <code>foot</code> and reconsidering other options yet again, this time the candidates were <code>ghostty</code> and <code>alacritty</code>, and <code>ghostty</code> just felt too early-stage for me. </p>
<p>By the way, after using a terminal that uses CPU rendering for a while, the difference of GPU accelerated rendering is very noticeable to me, and <code>~200MB</code> feels worth it. One good thing I didn&#39;t know earlier is the use of <code>alacritty msg create-window</code> which is a life-saver and makes all the difference to me. Now it&#39;s just a single <code>~200MB</code>, with <code>~8MB</code> of <code>/bin/bash</code> for each newly spawned terminal window. So, for the foreseeable future, I think I&#39;ll stick with <code>alacritty</code> until something better comes along.</p>
<h2 id="dsa"><a href="#dsa" class="heading-anchor">DSA</a></h2><ol>
<li><p>One micro-optimization in Java is <code>computeIfAbsent</code>. Not only is it shorter to type, it also avoids creating throwaway <code>ArrayList&lt;&gt;()</code> instances.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-comment)">// bad</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">List</span><span style="color:var(--code-tk-punctuation)">&#x3C;</span><span style="color:var(--code-tk-keyword)">Integer</span><span style="color:var(--code-tk-punctuation)">></span><span style="color:var(--code-tk-variable)"> existing</span><span style="color:var(--code-tk-operator)"> =</span><span style="color:var(--code-tk-variable)"> map</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">getOrDefault</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-meta)">x</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-keyword)"> new</span><span style="color:var(--code-tk-keyword)"> ArrayList</span><span style="color:var(--code-tk-punctuation)">&#x3C;>());</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">existing</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">add</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-meta)">y</span><span style="color:var(--code-tk-punctuation)">);</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">map</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">put</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-meta)">x</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-meta)"> existing</span><span style="color:var(--code-tk-punctuation)">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-comment)">// good</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">map</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">computeIfAbsent</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-meta)">x</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-meta)"> k </span><span style="color:var(--code-tk-keyword)">-></span><span style="color:var(--code-tk-keyword)"> new</span><span style="color:var(--code-tk-keyword)"> ArrayList</span><span style="color:var(--code-tk-punctuation)">&#x3C;>()).</span><span style="color:var(--code-tk-function)">add</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-meta)">y</span><span style="color:var(--code-tk-punctuation)">);</span></span></code></pre></li>
<li><p>BFS can be done without explicitly creating the entire graph upfront, especially when finding neighbors of a vertex isn&#39;t expensive.</p>
</li>
<li><p>Sometimes, you can introduce auxiliary/dummy vertices in a graph problem; this can simplify the problem by representing repeated transitions as one step, and you can avoid doing extra repetitive work.</p>
</li>
<li><p>When creating a prime sieve, it&#39;s more efficient to start marking composite numbers from <code>i*i</code> instead of <code>2*i</code> if <code>i</code> is prime, because all composite numbers from <code>i...i*i</code> already have a prime factor that&#39;s less than <code>i</code> so they would have already been marked composite by a smaller prime number.</p>
</li>
</ol>
<h2 id="interesting-links"><a href="#interesting-links" class="heading-anchor">Interesting Links</a></h2><p>Some of the things I&#39;ve read or been reading over the past few weeks -</p>
<ul>
<li>Open social - <a href="https://overreacted.io/open-social" target="_blank" rel="noopener noreferrer">https://overreacted.io/open-social</a></li>
<li>How OpenAI delivers low-latency voice AI at scale - <a href="https://openai.com/index/delivering-low-latency-voice-ai-at-scale" target="_blank" rel="noopener noreferrer">https://openai.com/index/delivering-low-latency-voice-ai-at-scale</a></li>
</ul>
<p>By the way, if you&#39;re interested, you can check out <a href="/blog/tag/devlog">all devlogs here</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Ropes Data Structure: From the Original Paper to Implementation</title>
      <link>https://next.toxdes.com/blog/ropes-data-structure-from-the-original-paper-to-implementation.html</link>
      <guid isPermaLink="true">https://next.toxdes.com/blog/ropes-data-structure-from-the-original-paper-to-implementation.html</guid>
      <pubDate>Wed, 22 Apr 2026 10:30:00 GMT</pubDate>
      <author>hi@toxdes.com (Vaibhav Mali)</author>
      <description>One day, I was looking for asymptotic complexity of ECMAScript String&apos;s += or concat() operation out of curiosity, and wondered why JS doesn&apos;t have a traditional StringBuilder since the strings are...</description>
      <category>learnings</category>
      <category>algo</category>
      <content:encoded><![CDATA[<p>One day, I was looking for asymptotic complexity of ECMAScript String&#39;s <code>+=</code> or <code>concat()</code> operation out of curiosity, and wondered why JS doesn&#39;t have a traditional <code>StringBuilder</code> since the strings are immutable. Turns out, the JS spec doesn&#39;t specify any Big-O complexity guarantees and they are left to the implementers, but still I couldn&#39;t wrap my head around how <code>concat()</code> operations could happen in near-constant time. Coincidentally, almost all popular browser-based JS engines - <a href="https://github.com/v8/v8/blob/main/src/objects/string.h#L1032" target="_blank" rel="noopener noreferrer">V8</a>, <a href="https://searchfox.org/firefox-main/source/js/src/builtin/String.cpp#2938" target="_blank" rel="noopener noreferrer">SpiderMonkey</a>, <a href="https://github.com/WebKit/WebKit/blob/main/Source/JavaScriptCore/runtime/JSString.h#L451" target="_blank" rel="noopener noreferrer">JavaScriptCore</a> and <a href="https://github.com/LadybirdBrowser/ladybird/blob/master/Libraries/LibJS/Runtime/PrimitiveString.h#L101" target="_blank" rel="noopener noreferrer">LibJS</a> - implement this data structure internally and I still don&#39;t see people talk about it more often: <strong>Ropes.</strong></p>
<h2 id="tradeoffs"><a href="#tradeoffs" class="heading-anchor">Tradeoffs</a></h2><p>Of course, there are tradeoffs. Otherwise ropes would have been the de facto standard for implementing strings in any programming language. The reason they&#39;re not quite as popular is because they solve a very niche problem involving large immutable strings, frequent concatenation, substring sharing, or editor-like updates. As a result, almost all of the popular engines use different underlying representations for strings, based on the length. One possible use case that I can think of is React&#39;s <code>renderToString()</code>.</p>
<p>Ropes actually perform worse for short strings because of the pointer overhead and cache locality, and in a typical workload, most strings are usually small. As a result, engines use plain one-byte (ASCII) or two-byte (UTF-16) strings, until the length of the string exceeds a threshold, at which point a <em>rope-like</em> (extending the idea of ropes from the original paper) structure is used which uses flatten-on-demand. It means <code>concat()</code>s are <code>O(1)</code> since it modifies ~2 nodes, and when the tree is rebalanced (rope is flattened) is engine-specific. Mostly it&#39;s flattened when there&#39;s a request for linear char buffer, indexing, native interop, or certain substring paths. It gives the best of both worlds, <code>concat()</code>s are faster, and we don&#39;t have to spend time rebalancing until we actually need it. The amount of ad-hoc optimizations these engines do is fascinating.</p>
<h2 id="implementation"><a href="#implementation" class="heading-anchor">Implementation</a></h2><p>Alright, let&#39;s go through <a href="https://www.cs.tufts.edu/comp/150FP/archive/hans-boehm/ropes.pdf" target="_blank" rel="noopener noreferrer">the original paper</a>. The idea of storing data in the leaf nodes and information about the data in internal nodes of the tree isn&#39;t new, <a href="https://en.wikipedia.org/wiki/B%2B_tree" target="_blank" rel="noopener noreferrer">B+ trees</a> existed since early 1970s. However, B trees self-balance on insertion, with at most <code>O(log n)</code> node updates, but in case of ropes, rebalancing could cost <code>O(rope_len)</code> in the worst-case, which means worst-case adversarial input can be generated that triggers rebalancing after every <code>concat()</code>.</p>
<p>The paper mentions length of rope should be at least <code>F(n+2)</code> for a depth of <code>n</code>. But how do fibonacci numbers come in the picture while describing the definition of a balanced binary tree? The usual definition of a balanced binary tree is <code>abs(h(left)-h(right)) &lt;=1</code> (i.e. heights of left and right subtrees of every node in the tree differ by at most 1), which means for a tree to be balanced -</p>
<ol>
<li>For <code>depth=0</code>, <code>min_leaves_required=1</code></li>
<li>For <code>depth=1</code>, <code>min_leaves_required=2</code></li>
<li>For <code>depth=2</code>, <code>min_leaves_required=3</code></li>
<li>For <code>depth=3</code>, <code>min_leaves_required=5</code></li>
<li>For <code>depth=4</code>, <code>min_leaves_required=8</code> <em>... and so on</em></li>
</ol>
<p>which forms a sequence <code>1,2,3,5,8...</code> which is a standard fibonacci sequence shifted by 2, hence the bound of<code>F(n+2)</code>. You can verify these values by drawing a balanced binary tree on paper. So, given a rope&#39;s total length and current tree depth, we can efficiently get a rough estimate of whether the tree needs rebalancing after a <code>concat()</code> operation.</p>
<p>I also like how the paper just assumes you have a garbage collector at your disposal, and even hints at using reference counting if you&#39;re implementing in a language like C. Let&#39;s not implement a GC here, maybe some other day, in another post. Let&#39;s use Go and for simplicity we will only consider ASCII strings for now. We&#39;ll see how things might change for UTF-16 later.</p>
<p>The API contract looks something like this -</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-keyword)">type</span><span style="color:var(--code-tk-class)"> Rope</span><span style="color:var(--code-tk-keyword)"> interface</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-function)">  Len</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-keyword)"> int</span></span>
<span class="line"><span style="color:var(--code-tk-function)">  String</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-keyword)"> string</span></span>
<span class="line"><span style="color:var(--code-tk-function)">  Concat</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">other</span><span style="color:var(--code-tk-class)"> Rope</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-class)"> Rope</span></span>
<span class="line"><span style="color:var(--code-tk-function)">  At</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">index</span><span style="color:var(--code-tk-keyword)"> int</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-keyword)"> byte</span></span>
<span class="line"><span style="color:var(--code-tk-function)">  root</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">type</span><span style="color:var(--code-tk-class)"> rope</span><span style="color:var(--code-tk-keyword)"> struct</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-property)">  root</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-comment)">// expose root via root()</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">r </span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-function)"> root</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> r</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">root</span><span style="color:var(--code-tk-punctuation)">;</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span></code></pre><p>The paper specifies, we require some notion of &quot;sequence of characters&quot; for leaf nodes. Let&#39;s use <code>string</code>s for that. It also mentions tree indexed by position, it means we need to store some information about the length of string represented by a node. Let&#39;s use <code>totalLen</code> for that. The <code>node</code> will look something like this -</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-keyword)">type</span><span style="color:var(--code-tk-class)"> node</span><span style="color:var(--code-tk-keyword)"> struct</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-property)">  left</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span></span>
<span class="line"><span style="color:var(--code-tk-property)">  right</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span></span>
<span class="line"><span style="color:var(--code-tk-property)">  leaf</span><span style="color:var(--code-tk-keyword)"> string</span></span>
<span class="line"><span style="color:var(--code-tk-property)">  totalLen</span><span style="color:var(--code-tk-keyword)"> int</span><span style="color:var(--code-tk-comment)"> // length of substring represented by this subtree</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span></code></pre><p>Let&#39;s start with implementing easier and straight-forward <code>Len()</code> and <code>Concat()</code> first. Since we&#39;re maintaining <code>totalLen</code> for each node, <code>Len()</code> is trivial. For <code>Concat()</code>, we just create a new parent root node, and attach roots of the two ropes as left and right children of this newly created node. Note that since we&#39;re not doing any rebalancing, this operation is <code>O(1)</code>.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-comment)">// length</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">r </span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-function)"> Len</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-keyword)"> int</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-operator)"> ||</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">root</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-number)"> 0</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">root</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">totalLen</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-comment)">// concat</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">r </span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-function)"> Concat</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">other</span><span style="color:var(--code-tk-class)"> Rope</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-class)"> Rope</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-operator)"> &#x26;</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)">{</span><span style="color:var(--code-tk-property)">root</span><span style="color:var(--code-tk-punctuation)">:</span><span style="color:var(--code-tk-function)">concat</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">r</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">root</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> other</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">root</span><span style="color:var(--code-tk-punctuation)">())}</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-comment)">// helper</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-function)"> concat</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">a</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> b</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> a</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> b</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> b</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> a</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-operator)"> &#x26;</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">{</span></span>
<span class="line"><span style="color:var(--code-tk-property)">    left</span><span style="color:var(--code-tk-punctuation)">:</span><span style="color:var(--code-tk-variable)">a</span><span style="color:var(--code-tk-punctuation)">,</span></span>
<span class="line"><span style="color:var(--code-tk-property)">    right</span><span style="color:var(--code-tk-punctuation)">:</span><span style="color:var(--code-tk-variable)">b</span><span style="color:var(--code-tk-punctuation)">,</span></span>
<span class="line"><span style="color:var(--code-tk-property)">    totalLen</span><span style="color:var(--code-tk-punctuation)">:</span><span style="color:var(--code-tk-variable)"> a</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">totalLen</span><span style="color:var(--code-tk-operator)"> +</span><span style="color:var(--code-tk-variable)"> b</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">totalLen</span><span style="color:var(--code-tk-punctuation)">,</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span></code></pre><p>Let&#39;s implement <code>String()</code> now, which is a standard in-order tree traversal.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">r </span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-function)"> String</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-keyword)"> string</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-punctuation)"> ""</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">root</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">String</span><span style="color:var(--code-tk-punctuation)">()</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">n </span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-function)"> String</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-keyword)"> string</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-punctuation)"> ""</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-operator)"> &#x26;&#x26;</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">right</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">leaf</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">String</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-operator)"> +</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">right</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">String</span><span style="color:var(--code-tk-punctuation)">()</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span></code></pre><p>The idea for implementing <code>At(x)</code> is to do a DFS from root node, since we store total length represented by subtree under the node, it tells us if we need to explore left or right subtree. Once we are at the leaf node, we just return the character in the <code>leaf</code> string chunk.
For simplicity, let&#39;s ignore out-of-bounds errors.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">r </span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-function)"> At</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">index</span><span style="color:var(--code-tk-keyword)"> int</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-keyword)"> byte</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">root</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">at</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">index</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">n </span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-function)"> at</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">index</span><span style="color:var(--code-tk-keyword)"> int</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-keyword)"> byte</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-operator)"> &#x26;&#x26;</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">right</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">leaf</span><span style="color:var(--code-tk-punctuation)">[</span><span style="color:var(--code-tk-variable)">index</span><span style="color:var(--code-tk-punctuation)">]</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">  leftLen</span><span style="color:var(--code-tk-operator)"> :=</span><span style="color:var(--code-tk-number)"> 0</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-operator)"> !=</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">    leftLen</span><span style="color:var(--code-tk-operator)"> =</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">totalLen</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> index</span><span style="color:var(--code-tk-operator)"> &#x3C;</span><span style="color:var(--code-tk-variable)"> leftLen</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">at</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">index</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">right</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">at</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">index</span><span style="color:var(--code-tk-operator)">-</span><span style="color:var(--code-tk-variable)">leftLen</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span></code></pre><p>Now the only challenging part remaining is rebalancing the tree. The idea is to rebuild a balanced tree. Since the left-to-right order of leaves gives the canonical representation of the text we are storing, we first collect leaves by traversing similar to how we did it in <code>String()</code> implementation. After collecting the leaves, we build the new tree by recursively splitting the collected leaves in half and combine the two halves with <code>concat()</code>.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span>            root                            root</span></span>
<span class="line"><span>           /    \                          /    \</span></span>
<span class="line"><span>        node     "gh"       ---->       node     node</span></span>
<span class="line"><span>       /   \                           /   \    /   \</span></span>
<span class="line"><span>    node    "ef"                    "ab"  "cd" "ef" "gh"</span></span>
<span class="line"><span>   /   \</span></span>
<span class="line"><span>"ab"  "cd"</span></span>
<span class="line"><span></span></span>
<span class="line"><span>collected:["ab","cd", "ef", "gh"]</span></span></code></pre><p>Let&#39;s implement <code>rebalance()</code> now. We can call this <code>rebalance()</code> whenever it&#39;s optimal to do so.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">r </span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-function)"> rebalance</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-operator)"> ||</span><span style="color:var(--code-tk-variable)"> r</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">root</span><span style="color:var(--code-tk-punctuation)">()</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> r</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-operator)"> &#x26;</span><span style="color:var(--code-tk-class)">rope</span><span style="color:var(--code-tk-punctuation)">{</span><span style="color:var(--code-tk-property)">root</span><span style="color:var(--code-tk-punctuation)">:</span><span style="color:var(--code-tk-function)">rebalance</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">r</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-function)">root</span><span style="color:var(--code-tk-punctuation)">())}</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-comment)">// helper</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-function)"> rebalance</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">n</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> n</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-operator)"> &#x26;&#x26;</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">right</span><span style="color:var(--code-tk-operator)">  ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> n</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">  leaves</span><span style="color:var(--code-tk-operator)"> :=</span><span style="color:var(--code-tk-function)"> make</span><span style="color:var(--code-tk-punctuation)">([]</span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 0</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-function)">  collectLeaves</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">n</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-operator)"> &#x26;</span><span style="color:var(--code-tk-variable)">leaves</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-function)"> buildBalanced</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">leaves</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 0</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-function)"> len</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">leaves</span><span style="color:var(--code-tk-punctuation)">))</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-comment)">// collect leaves in order</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-function)"> collectLeaves</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">n</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> leaves</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-punctuation)">[]</span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">){</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-operator)"> &#x26;&#x26;</span><span style="color:var(--code-tk-variable)"> n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">right</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> nil</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">    *</span><span style="color:var(--code-tk-variable)">leaves</span><span style="color:var(--code-tk-operator)"> =</span><span style="color:var(--code-tk-function)"> append</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-variable)">leaves</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-operator)"> &#x26;</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">{</span><span style="color:var(--code-tk-property)">leaf</span><span style="color:var(--code-tk-punctuation)">:</span><span style="color:var(--code-tk-variable)">n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">leaf</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-property)"> totalLen</span><span style="color:var(--code-tk-punctuation)">:</span><span style="color:var(--code-tk-variable)">n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">totalLen</span><span style="color:var(--code-tk-punctuation)">})</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-function)">  collectLeaves</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> leaves</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-function)">  collectLeaves</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">n</span><span style="color:var(--code-tk-punctuation)">.</span><span style="color:var(--code-tk-variable)">right</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> leaves</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-punctuation)"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color:var(--code-tk-comment)">// build a new balanced tree</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">func</span><span style="color:var(--code-tk-function)"> buildBalanced</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">leaves</span><span style="color:var(--code-tk-punctuation)"> []</span><span style="color:var(--code-tk-operator)">*</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> L</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> R</span><span style="color:var(--code-tk-keyword)"> int</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-operator)"> *</span><span style="color:var(--code-tk-class)">node</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> L</span><span style="color:var(--code-tk-operator)"> >=</span><span style="color:var(--code-tk-variable)"> R</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-number)"> nil</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  if</span><span style="color:var(--code-tk-variable)"> R</span><span style="color:var(--code-tk-operator)">-</span><span style="color:var(--code-tk-variable)">L</span><span style="color:var(--code-tk-operator)"> ==</span><span style="color:var(--code-tk-number)"> 1</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">    return</span><span style="color:var(--code-tk-variable)"> leaves</span><span style="color:var(--code-tk-punctuation)">[</span><span style="color:var(--code-tk-variable)">L</span><span style="color:var(--code-tk-punctuation)">]</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">  }</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">  M</span><span style="color:var(--code-tk-operator)"> :=</span><span style="color:var(--code-tk-variable)"> L</span><span style="color:var(--code-tk-operator)"> +</span><span style="color:var(--code-tk-punctuation)"> (</span><span style="color:var(--code-tk-variable)">R</span><span style="color:var(--code-tk-operator)">-</span><span style="color:var(--code-tk-variable)">L</span><span style="color:var(--code-tk-punctuation)">)</span><span style="color:var(--code-tk-operator)">/</span><span style="color:var(--code-tk-number)">2</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">  left</span><span style="color:var(--code-tk-operator)"> :=</span><span style="color:var(--code-tk-function)"> buildBalanced</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">leaves</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> L</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> M</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-variable)">  right</span><span style="color:var(--code-tk-operator)"> :=</span><span style="color:var(--code-tk-function)"> buildBalanced</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">leaves</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> M</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> R</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-keyword)">  return</span><span style="color:var(--code-tk-function)"> concat</span><span style="color:var(--code-tk-punctuation)">(</span><span style="color:var(--code-tk-variable)">left</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-variable)"> right</span><span style="color:var(--code-tk-punctuation)">)</span></span>
<span class="line"><span style="color:var(--code-tk-punctuation)">}</span></span></code></pre><p>This wraps-up our basic implementation of ropes. Of course we could re-use leaf nodes and do a ton of other optimizations, but hopefully the basic idea is clear now.</p>
<h2 id="references"><a href="#references" class="heading-anchor">References</a></h2><p>For further reading:</p>
<ol>
<li><a href="https://www.cs.tufts.edu/comp/150FP/archive/hans-boehm/ropes.pdf" target="_blank" rel="noopener noreferrer">Ropes: an Alternative to Strings</a></li>
<li><a href="https://docs.google.com/document/d/1o-MJPAddpfBfDZCkIHNKbMiM86iDFld7idGbNQLuKIQ/preview" target="_blank" rel="noopener noreferrer">Fast string concatenation in JavaScript</a></li>
<li><a href="https://en.wikipedia.org/wiki/Rope_(data_structure)" target="_blank" rel="noopener noreferrer">Rope (Data Struture) - Wikipedia</a></li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>Amazon SDE-II Interview Experience</title>
      <link>https://next.toxdes.com/blog/my-amazon-sde2-interview-experience.html</link>
      <guid isPermaLink="true">https://next.toxdes.com/blog/my-amazon-sde2-interview-experience.html</guid>
      <pubDate>Sun, 12 Apr 2026 10:30:00 GMT</pubDate>
      <author>hi@toxdes.com (Vaibhav Mali)</author>
      <description>I have recently fumbled my interview rounds for the SDE-II role at Amazon big time. I think it&apos;s worth sharing. Since all of my professional work experience so far has been for early stage startups...</description>
      <category>learnings</category>
      <category>algo</category>
      <content:encoded><![CDATA[<p>I have recently fumbled my interview rounds for the SDE-II role at Amazon big time. I think it&#39;s worth sharing. Since all of my professional work experience so far has been for early stage startups, I didn&#39;t get a chance to work on stuff where horizontally scaling the servers was necessary. So, my long-term goal is to work at a place that has a product with a lot of users. Amazon is one of them, despite how bad rep they get for their work culture. </p>
<p>I applied to a few positions on Amazon&#39;s career portal a few months back because even though Amazon looked very busy breaking their own records in laying off employees, their careers page also had a few recent openings. Anyway, after 3-ish days, I received an OA, which had 2 problems to be solved in 90 minutes, a &quot;work-style simulation&quot; based on their &quot;leadership&quot; principles and a somewhat basic system design quiz.</p>
<h2 id="online-assessment"><a href="#online-assessment" class="heading-anchor">Online Assessment</a></h2><p>It had two problems, surprisingly both problems were based on bitwise operations. First problem was of medium difficulty, I cannot share the exact problem, but it was based on range <code>XOR</code> sum queries (via prefix <code>XOR</code>s), and was trivial if you knew the ball knowledge:  </p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-function)">XOR_SUM</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-variable)">a</span><span style="color:var(--code-tk-meta)">[</span><span style="color:var(--code-tk-variable)">i</span><span style="color:var(--code-tk-meta)">]</span><span style="color:var(--code-tk-punctuation)">..</span><span style="color:var(--code-tk-property)">a</span><span style="color:var(--code-tk-meta)">[</span><span style="color:var(--code-tk-variable)">j</span><span style="color:var(--code-tk-meta)">])</span><span style="color:var(--code-tk-operator)"> =</span><span style="color:var(--code-tk-variable)"> pref</span><span style="color:var(--code-tk-meta)">[</span><span style="color:var(--code-tk-variable)">j</span><span style="color:var(--code-tk-meta)">]</span><span style="color:var(--code-tk-operator)">^</span><span style="color:var(--code-tk-variable)">pref</span><span style="color:var(--code-tk-meta)">[</span><span style="color:var(--code-tk-variable)">i</span><span style="color:var(--code-tk-operator)">-</span><span style="color:var(--code-tk-number)">1</span><span style="color:var(--code-tk-meta)">]</span><span style="color:var(--code-tk-punctuation)">;</span></span></code></pre><p>Second problem was <a href="https://leetcode.com/problems/maximum-bitwise-and-after-increment-operations/description/" target="_blank" rel="noopener noreferrer">this one</a>, it was hard but I was able to come up with a greedy approach where we start with <code>0</code> as our candidate answer for final <code>AND</code>, and try to get <code>1</code> at each position of our candidate answer starting from MSB to LSB, where we check the feasibility of including <code>m</code> least expensive elements using at most <code>k</code> total increments.</p>
<p>I was able to solve first problem within ~15 minutes, and spent the rest of the time on the second problem.</p>
<p>I also skimmed through the <a href="https://www.aboutamazon.in/about-us/leadership-principles" target="_blank" rel="noopener noreferrer">Amazon LPs</a> before the OA, so I don&#39;t mess up the workstyle assessment questions.</p>
<h2 id="round---1"><a href="#round---1" class="heading-anchor">Round - 1</a></h2><p>Interviewer was SDE-2, he was younger than me, he joined 5 minutes late, I was already nervous pro max and panicking because this was my first time interviewing for FAANG, he joined and said don&#39;t worry we&#39;ll extend by 5 minutes. We introduced ourselves, and he jumped to problem solving right away. </p>
<p>First problem was <a href="https://leetcode.com/problems/generate-parentheses/" target="_blank" rel="noopener noreferrer">this one</a>, which I knew how to do, so I told the optimal solution, stated complexity, asked if I should start writing code, coded it up, we were past 20 minutes by now. </p>
<p>Then he asked the second problem <a href="https://leetcode.com/problems/word-ladder/description/" target="_blank" rel="noopener noreferrer">this one</a>, for which I was able to come up with a brute force BFS solution, but I ran out of time. I regret picking <code>java</code> as my language of choice for the interview. Also, my solution wasn&#39;t really optimal, the interviewer tried to give me hints, but I crumbled under pressure of time running out since he had mentioned in the beginning he is expecting optimal solutions to BOTH problems. As soon as the interview was over, the hint he gave clicked, but it was already too late. I was not able to complete the <code>bfs(...)</code> function because it&#39;s standard and I have run out of time. He said now he has to ask me some questions based on LPs, which he asked and I answered. </p>
<h2 id="round---2"><a href="#round---2" class="heading-anchor">Round - 2</a></h2><p>Two weeks went by, and my second round was scheduled, this guy looked really tensed for some reason. After introduction, he asked me to write API for music library app, expectation was to tell class design for entities and only requirement was that he wanted low latency for <code>getTopKPlayedSongs(k)</code> and <code>getTopKPlayedSongs(artistId, k)</code>, <code>addSong(artist, song)</code>. I started with listing out entities like <code>Player</code>, <code>Artist</code>, <code>User</code>, <code>Song</code>, <code>Library</code> etc, and then I went blank, I knew how to do <code>getTopKSongs(k)</code> in <code>O(log n)</code> with a <code>HashMap&lt;Count, Set&lt;SongId&gt;&gt;</code> and a <code>TreeSet&lt;SongId,Count&gt;</code> combo, which I told when I ran out of time, but again, the expectation was to get a &quot;production-level&quot; code in 30 minutes. </p>
<p>It requires at least one <code>soft yes</code> to get to round 3 and round 4, and knew immediately after second interview was over that I didn&#39;t get it. </p>
<p>Key takeaway is, time is way more limited in these interviews, you get ~20 minutes to explain <em>and</em> code the <em>optimal</em> solution. Good thing is, I was able to solve every problem so far, so we&#39;re past &quot;wtf do i even do here man&quot; stage, so that&#39;s some progress, but need to work on time and not panicking.</p>
<p>We&#39;re just not there yet gang, the grind must go on, maybe in next 6 months :)</p>
]]></content:encoded>
    </item>
    <item>
      <title>Big update - Current state of things</title>
      <link>https://next.toxdes.com/blog/big-update.html</link>
      <guid isPermaLink="true">https://next.toxdes.com/blog/big-update.html</guid>
      <pubDate>Thu, 09 Apr 2026 10:30:00 GMT</pubDate>
      <author>hi@toxdes.com (Vaibhav Mali)</author>
      <description>Finally, after spending a lot of time updating this website, and even more time bikeshedding about colors and spacing, it&apos;s finally ready. I have also decided to write more, I&apos;ll explain why in a b...</description>
      <category>wafflings</category>
      <content:encoded><![CDATA[<p>Finally, after spending a lot of time updating this website, and even more time <a href="https://www.urbandictionary.com/define.php?term=bikeshedding" target="_blank" rel="noopener noreferrer">bikeshedding</a> about colors and spacing, it&#39;s finally ready. I have also decided to write more, I&#39;ll explain why in a bit.</p>
<h2 id="migrating-to-a-new-domain"><a href="#migrating-to-a-new-domain" class="heading-anchor">Migrating to a new domain</a></h2><p>So, on one fine day, I was chitchatting with gemini about why my old domain <a href="https://txds.me" target="_blank" rel="noopener noreferrer">txds.me</a> was not ranking properly in the Google&#39;s search results, even after I specifically told claude to <em>&quot;make sure my site is SEO optimized&quot;</em>. It kind of did the job since I currently rank 5th if I search for <code>txds</code> on Google and that&#39;s nice for me being a nobody, and to be fair, <code>txds</code> isn&#39;t even really related to me in any way. It was just <code>toxdes</code> without vowels to get a shorter domain for my personal space on the internet. </p>
<p>Now why <code>toxdes</code>? well, I started using internet really late, so all the cool usernames that made sense were already taken everywhere, so I had to work with whatever was available at the time, and I have stuck with it ever since. Gemini also convinced me to use <code>toxdes.com</code> because nothing significant exists for this word. I also tried my <code>firstname+lastname</code> combo, but turns out my name is way too unfairly common than it should be, so here we are. </p>
<p>By the way, I also checked <a href="https://whoisfreaks.com/tools/whois/history/lookup" target="_blank" rel="noopener noreferrer">historical `whois` data</a>, and found out that <code>txds.me</code> was registered at least 8 times in the past, and <code>toxdes.com</code> wasn&#39;t registered even once. It&#39;s a really nice tool.</p>
<p>The migration is pretty much complete, and moving forward I&#39;ll be exclusively using <code>toxdes.com</code>. I currently use Cloudflare to manage DNS records, and this website is also statically hosted on Cloudflare pages. I also host some of my historic <a href="https://toxdes.com/projects" target="_blank" rel="noopener noreferrer">personal projects</a> on github pages and vercel under subdomains. Vercel&#39;s dashboard has a functionality to add <code>*.toxdes.com</code> domain, and setup redirects for<code>*.txds.me</code> to redirect to the newly added domain, so those were easy. I migrated from netlify to vercel for one old project, it was just easier to manage that way. And for the github pages site and the main <code>txds.me</code> domain, I am using Cloudflare&#39;s <a href="https://developers.Cloudflare.com/rules/url-forwarding/" target="_blank" rel="noopener noreferrer">redirect rules</a>.</p>
<h2 id="adding-likes-to-blog-posts"><a href="#adding-likes-to-blog-posts" class="heading-anchor">Adding likes to blog posts</a></h2><p>I&#39;ve been learning about system design since forever, and I thought this might be a good idea to burn some tokens add a little bit of &quot;server-side&quot; state to this website. </p>
<p>We live in exciting times nowadays where realizing an idea is just few prompts away, I quickly ended up vibe-coding <a href="https://github.com/toxdes/counter-api" target="_blank" rel="noopener noreferrer">`counter as a service`</a>.  The goal was simple, adding &quot;likes&quot; to my posts. Within 2-4 prompts, I was able to get a multi-tenant counter backend server as a single binary which exposed some HTTP endpoints and synced state to the <code>postgres</code> database. </p>
<p>I also added a small in-memory LRU cache to do async updates to the postgres database, mainly because redis felt like an overkill. Perfect little solution for a perfectly little problem. I know it can be abused easily, and cannot really scale well, I&#39;ll hopefully improve it and make it a little bit more reliable as the time goes by, but for what it&#39;s worth, it&#39;s good enough for now.</p>
<h2 id="why-write-more"><a href="#why-write-more" class="heading-anchor">Why write more</a></h2><p>I always felt like I had nothing to share, and I&#39;m not a good enough engineer to share non-trivial computer science things and with the  recent advancements of LLMs, writing blogs felt actually pointless.</p>
<p>Recently, I also had a good chat with someone who <em>smuggles</em> decent engineers to startups and he told me &quot;you&#39;re mid bruh&quot;. I mean it&#39;s true, to some extent, but man did it feel brutal. Anyway, I was weirded out when he asked why do you have only 2 blogs in three years, and I was like what&#39;s the point in writing trivial stuff. Anyway, the good takeaway from the chat was <em><u>writing a tech blog was never about storming the frontier of advancement in computer science research</u></em>, which feels strange now as I type it out, but it was <em>exactly</em> what I used to think - everything I ever knew about programming and computers always felt like explaining how to do add two numbers <code>6+7</code>.</p>
<p>After the chat, and some pondering, I have had a change of heart, and I have decided to write more. I think I&#39;ll start writing whatever trivial things I know, or will learn next. </p>
<p>I think I&#39;ll start by writing about <a href="/blog/l-my-amazon-sde2-interview-experience.html">failing my Amazon's SDE-2 interviews</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Introduction to View Transitions</title>
      <link>https://next.toxdes.com/blog/adding-view-transitions.html</link>
      <guid isPermaLink="true">https://next.toxdes.com/blog/adding-view-transitions.html</guid>
      <pubDate>Tue, 13 Jan 2026 10:30:00 GMT</pubDate>
      <author>hi@toxdes.com (Vaibhav Mali)</author>
      <description>I&apos;ve been on a bit of a minimalism kick lately. I&apos;ve stopped reaching for React for every project, realizing that for a blog like this, raw HTML and CSS is usually enough. In fact, this entire webs...</description>
      <category>learnings</category>
      <category>web</category>
      <category>css</category>
      <content:encoded><![CDATA[<p>I&#39;ve been on a bit of a minimalism kick lately. I&#39;ve stopped reaching for React for every project, realizing that for a blog like this, raw HTML and CSS is usually enough. In fact, this entire website - content, styles, scripts included - is lighter than the gzipped <code>react-dom</code> package alone.</p>
<p>But there was one thing I missed from the React world: <strong>motion</strong>.</p>
<p>Static sites often feel &quot;dead.&quot; You click a link, the screen goes blank, and the new content appears. I wanted it to feel alive, preserving context as the user navigates, but without bringing megabytes of javascript to hydrate a virtual DOM just to animate a <code>div</code>.</p>
<p>Enter the <a href="https://developer.chrome.com/docs/web-platform/view-transitions" target="_blank" rel="noopener noreferrer">View Transitions API</a></p>
<p>Specifically, <strong>Cross-Document View Transitions</strong>. This API allows the browser to snapshot the old state and the new state, then morph between them. It’s native, hardware-accelerated, and requires zero client-side routing, truly magical.</p>
<div class="alert alert-note"><strong class="alert-legend"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="28" height="28" fill="currentColor" class="alert-icon"><path d="M15.807.531c-.174-.177-.41-.289-.64-.363a3.8 3.8 0 0 0-.833-.15c-.62-.049-1.394 0-2.252.175C10.365.545 8.264 1.415 6.315 3.1S3.147 6.824 2.557 8.523c-.294.847-.44 1.634-.429 2.268.005.316.05.62.154.88q.025.061.056.122A68 68 0 0 0 .08 15.198a.53.53 0 0 0 .157.72.504.504 0 0 0 .705-.16 68 68 0 0 1 2.158-3.26c.285.141.616.195.958.182.513-.02 1.098-.188 1.723-.49 1.25-.605 2.744-1.787 4.303-3.642l1.518-1.55a.53.53 0 0 0 0-.739l-.729-.744 1.311.209a.5.5 0 0 0 .443-.15l.663-.684c.663-.68 1.292-1.325 1.763-1.892.314-.378.585-.752.754-1.107.163-.345.278-.773.112-1.188a.5.5 0 0 0-.112-.172M3.733 11.62C5.385 9.374 7.24 7.215 9.309 5.394l1.21 1.234-1.171 1.196-.027.03c-1.5 1.789-2.891 2.867-3.977 3.393-.544.263-.99.378-1.324.39a1.3 1.3 0 0 1-.287-.018Zm6.769-7.22c1.31-1.028 2.7-1.914 4.172-2.6a7 7 0 0 1-.4.523c-.442.533-1.028 1.134-1.681 1.804l-.51.524zm3.346-3.357C9.594 3.147 6.045 6.8 3.149 10.678c.007-.464.121-1.086.37-1.806.533-1.535 1.65-3.415 3.455-4.976 1.807-1.561 3.746-2.36 5.31-2.68a8 8 0 0 1 1.564-.173"/></svg> NOTE</strong><div class="alert-content">

<p>Unfortunately, <a href="https://caniuse.com/view-transitions" target="_blank" rel="noopener noreferrer">browser support</a> is not-so-good yet for cross-document view transitions, so if you are reading this in firefox, I&#39;m sorry.</p>


</div></div><p>The <a href="https://developer.chrome.com/docs/web-platform/view-transitions/cross-document" target="_blank" rel="noopener noreferrer">Chrome team's intro</a> covers the mechanics well, but here is how I&#39;m using it to make this static site feel a little bit alive.</p>
<p>The setup is deceptively simple. You just tell the browser to look out for navigations by adding the css:</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-punctuation)">@</span><span style="color:var(--code-tk-keyword)">view-transition</span><span style="color:var(--code-tk-punctuation)"> {</span></span>
<span class="line"><span style="color:var(--code-tk-meta)">  navigation: auto;</span></span>
<span class="line"><span style="color:var(--code-tk-meta)">}</span></span></code></pre><p>When user navigates from the &quot;Home&quot; page to the &quot;All Posts&quot; page, I didn&#39;t want a hard cut. I wanted the recent posts to physically travel to their new positions in the full list.</p>
<p>This is made possible with <strong>Shared Element Transitions</strong>. The concept is simple: if you give two elements on different pages the same <code>view-transition-name</code>, the browser matches them up and handles the geometry.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-comment)">&#x3C;!-- On both the Home page and the Blog List page --></span><span style="color:var(--code-fg)"> </span></span>
<span class="line"><span style="color:var(--code-tk-tag)">&#x3C;li</span><span style="color:var(--code-tk-attr)"> style</span><span style="color:var(--code-tk-punctuation)">=</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-string)">view-transition-name: post-item-${slug}</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-tag)">></span></span>
<span class="line"><span style="color:var(--code-tk-comment)">  &#x3C;!-- The entire item morphs --></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">&#x3C;/li></span></span></code></pre><p>Things are a bit more interesting when you click into a specific article. I wanted the title and date to translate from the item and settle into the header of the post.</p>
<p>To make this work, we need to be more granular. Instead of transitioning the whole item, let&#39;s assign specific names to the text nodes <em>inside</em> the card.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-comment)">&#x3C;!-- In the List Item --></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">&#x3C;li></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">  &#x3C;span</span><span style="color:var(--code-tk-attr)"> style</span><span style="color:var(--code-tk-punctuation)">=</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-string)">view-transition-name: post-date-${slug}</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-tag)">></span><span style="color:var(--code-fg)">2026-01</span><span style="color:var(--code-tk-tag)">&#x3C;/span></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">  &#x3C;span</span><span style="color:var(--code-tk-attr)"> style</span><span style="color:var(--code-tk-punctuation)">=</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-string)">view-transition-name: post-title-${slug}</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-tag)">></span><span style="color:var(--code-fg)">Introduction to View Transitions</span><span style="color:var(--code-tk-tag)">&#x3C;/span></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">&#x3C;/li></span></span></code></pre><pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-comment)">&#x3C;!-- In the Blog Post Header --></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">&#x3C;article></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">  &#x3C;h1</span><span style="color:var(--code-tk-attr)"> style</span><span style="color:var(--code-tk-punctuation)">=</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-string)">view-transition-name: post-title-${slug}</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-tag)">></span><span style="color:var(--code-fg)">Introduction to View Transitions</span><span style="color:var(--code-tk-tag)">&#x3C;/h1></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">  &#x3C;div</span><span style="color:var(--code-tk-attr)"> class</span><span style="color:var(--code-tk-punctuation)">=</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-string)">post-meta</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-tag)">></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">    &#x3C;i</span><span style="color:var(--code-tk-attr)"> style</span><span style="color:var(--code-tk-punctuation)">=</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-string)">view-transition-name: post-date-${slug}</span><span style="color:var(--code-tk-punctuation)">"</span><span style="color:var(--code-tk-tag)">></span><span style="color:var(--code-fg)">Published Jan. 2026</span><span style="color:var(--code-tk-tag)">&#x3C;/i></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">  &#x3C;/div></span></span>
<span class="line"><span style="color:var(--code-tk-comment)">  &#x3C;!-- rest of the content --></span></span>
<span class="line"><span style="color:var(--code-tk-tag)">&#x3C;/article></span></span></code></pre><p>Because the names match, the browser performs a smooth &quot;morph&quot; transition, scaling the font size and translating the position automatically. BROWSER DOES ALLAT FOR YOU, isn&#39;t that cool?</p>
]]></content:encoded>
    </item>
    <item>
      <title>Hitchhikers guide to using &apos;Date&apos; in JS</title>
      <link>https://next.toxdes.com/blog/hitchhikers-guide-to-js-date.html</link>
      <guid isPermaLink="true">https://next.toxdes.com/blog/hitchhikers-guide-to-js-date.html</guid>
      <pubDate>Fri, 24 Nov 2023 10:30:00 GMT</pubDate>
      <author>hi@toxdes.com (Vaibhav Mali)</author>
      <description>The JavaScript Date API is a nice example of how taxing &quot;We don&apos;t deprecate, ever&quot; can get. The Date constructor has six completely different behaviors depending on what you pass it. Not variants. ...</description>
      <category>learnings</category>
      <category>web</category>
      <category>js</category>
      <content:encoded><![CDATA[<p>The JavaScript <code>Date</code> API is a nice example of how taxing <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features" target="_blank" rel="noopener noreferrer">"We don't deprecate, ever"</a> can get. The Date constructor has six completely different behaviors depending on what you pass it. Not variants. Different behaviors.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-comment)">// Current time</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">()</span></span>
<span class="line"><span style="color:var(--code-tk-comment)">// Milliseconds since epoch</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">1736533800000</span><span style="color:var(--code-tk-meta)">)</span></span>
<span class="line"><span style="color:var(--code-tk-comment)">// String parsing</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-string)">2023-11-24</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-meta)">)</span></span>
<span class="line"><span style="color:var(--code-tk-comment)">// Year, month, day</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">2023</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 10</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 24</span><span style="color:var(--code-tk-meta)">)</span></span>
<span class="line"><span style="color:var(--code-tk-comment)">// Year, month, day, hour, minute</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">2023</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 10</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 24</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 21</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 30</span><span style="color:var(--code-tk-meta)">)</span></span>
<span class="line"><span style="color:var(--code-tk-comment)">// Year, month, day, hour, minute, second, ms</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">2023</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 10</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 24</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 21</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 30</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 45</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 500</span><span style="color:var(--code-tk-meta)">)</span></span></code></pre><p>If you give it an ISO date without a time (just <code>YYYY-MM-DD</code>), it assumes UTC midnight. But if you add a time without the <code>Z</code>, some browsers treat it as <code>local</code>, others as <code>UTC</code>. This isn&#39;t theoretical. Chrome and Firefox have behaved differently on this exact case.</p>
<p>The Z matters. Always add it if you want UTC. </p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-comment)">// parsing date string</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-string)">2023-11-24</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)"> // ISO date (no time)</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-string)">2023-11-24T21:30</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)"> // ISO date with time (no timezone)</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-string)">2023-11-24T21:30Z</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)"> // ISO date with time (UTC)</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-string)">2023-11-24T21:30+05:30</span><span style="color:var(--code-tk-punctuation)">'</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)"> // ISO date with timezone offset</span></span></code></pre><div class="alert alert-tldr"><strong class="alert-legend"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="28" height="28" fill="currentColor" class="alert-icon"><path d="M15.807.531c-.174-.177-.41-.289-.64-.363a3.8 3.8 0 0 0-.833-.15c-.62-.049-1.394 0-2.252.175C10.365.545 8.264 1.415 6.315 3.1S3.147 6.824 2.557 8.523c-.294.847-.44 1.634-.429 2.268.005.316.05.62.154.88q.025.061.056.122A68 68 0 0 0 .08 15.198a.53.53 0 0 0 .157.72.504.504 0 0 0 .705-.16 68 68 0 0 1 2.158-3.26c.285.141.616.195.958.182.513-.02 1.098-.188 1.723-.49 1.25-.605 2.744-1.787 4.303-3.642l1.518-1.55a.53.53 0 0 0 0-.739l-.729-.744 1.311.209a.5.5 0 0 0 .443-.15l.663-.684c.663-.68 1.292-1.325 1.763-1.892.314-.378.585-.752.754-1.107.163-.345.278-.773.112-1.188a.5.5 0 0 0-.112-.172M3.733 11.62C5.385 9.374 7.24 7.215 9.309 5.394l1.21 1.234-1.171 1.196-.027.03c-1.5 1.789-2.891 2.867-3.977 3.393-.544.263-.99.378-1.324.39a1.3 1.3 0 0 1-.287-.018Zm6.769-7.22c1.31-1.028 2.7-1.914 4.172-2.6a7 7 0 0 1-.4.523c-.442.533-1.028 1.134-1.681 1.804l-.51.524zm3.346-3.357C9.594 3.147 6.045 6.8 3.149 10.678c.007-.464.121-1.086.37-1.806.533-1.535 1.65-3.415 3.455-4.976 1.807-1.561 3.746-2.36 5.31-2.68a8 8 0 0 1 1.564-.173"/></svg> TL;DR</strong><div class="alert-content">

<p>Remember, when using <code>Date</code> constructor with strings, only <code>ISO 8601</code> format is reliable.</p>


</div></div><p>When you pass numbers to the constructor, things get strange fast.</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">2023</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 10</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 24</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)">  // November 24, 2023</span></span></code></pre><p>Wait. November? We passed 10. Why November?</p>
<p>Because months are zero-indexed. January is 0, December is 11. This comes from C&#39;s tm struct from 1972. Java copied it. JavaScript copied Java. Now we&#39;re stuck with it. Does that mean 24 is also actually 25? Well...no, days are numbered from 1 to 31.</p>
<p>One more thing: </p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">2023</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)">      // Not year 2023!</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">2023</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 0</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)">   // This is year 2023</span></span></code></pre><p>A single number isn&#39;t a year. It&#39;s milliseconds since January 1, 1970. So <code>new Date(2023)</code> is <code>2.023</code> seconds after the epoch, which is <code>January 1, 1970, 00:00:02.023</code>. So, If you want year 2023, you need at least two arguments: year and month.</p>
<p>But wait, there&#39;s more:</p>
<pre style="background-color:var(--code-bg);color:var(--code-fg)"><code><span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">99</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 0</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 1</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)">   // January 1, 1999</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">100</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 0</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 1</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)">  // January 1, 100 AD</span></span>
<span class="line"><span style="color:var(--code-tk-operator)">new</span><span style="color:var(--code-tk-function)"> Date</span><span style="color:var(--code-tk-meta)">(</span><span style="color:var(--code-tk-number)">2023</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 0</span><span style="color:var(--code-tk-punctuation)">,</span><span style="color:var(--code-tk-number)"> 1</span><span style="color:var(--code-tk-meta)">)</span><span style="color:var(--code-tk-comment)"> // January 1, 2023</span></span></code></pre><p>Years 0-99 get treated as 1900+n. This is Y2K panic code. Someone was worried about legacy code passing two-digit years, so they added this special case. Year 99 becomes 1999. Year 100 is literal.</p>
<div class="alert alert-tldr"><strong class="alert-legend"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="28" height="28" fill="currentColor" class="alert-icon"><path d="M15.807.531c-.174-.177-.41-.289-.64-.363a3.8 3.8 0 0 0-.833-.15c-.62-.049-1.394 0-2.252.175C10.365.545 8.264 1.415 6.315 3.1S3.147 6.824 2.557 8.523c-.294.847-.44 1.634-.429 2.268.005.316.05.62.154.88q.025.061.056.122A68 68 0 0 0 .08 15.198a.53.53 0 0 0 .157.72.504.504 0 0 0 .705-.16 68 68 0 0 1 2.158-3.26c.285.141.616.195.958.182.513-.02 1.098-.188 1.723-.49 1.25-.605 2.744-1.787 4.303-3.642l1.518-1.55a.53.53 0 0 0 0-.739l-.729-.744 1.311.209a.5.5 0 0 0 .443-.15l.663-.684c.663-.68 1.292-1.325 1.763-1.892.314-.378.585-.752.754-1.107.163-.345.278-.773.112-1.188a.5.5 0 0 0-.112-.172M3.733 11.62C5.385 9.374 7.24 7.215 9.309 5.394l1.21 1.234-1.171 1.196-.027.03c-1.5 1.789-2.891 2.867-3.977 3.393-.544.263-.99.378-1.324.39a1.3 1.3 0 0 1-.287-.018Zm6.769-7.22c1.31-1.028 2.7-1.914 4.172-2.6a7 7 0 0 1-.4.523c-.442.533-1.028 1.134-1.681 1.804l-.51.524zm3.346-3.357C9.594 3.147 6.045 6.8 3.149 10.678c.007-.464.121-1.086.37-1.806.533-1.535 1.65-3.415 3.455-4.976 1.807-1.561 3.746-2.36 5.31-2.68a8 8 0 0 1 1.564-.173"/></svg> TL;DR</strong><div class="alert-content">

<p>Remember when using <code>Date</code> constructor with <strong>numbers</strong>, <code>0-99</code> for years means <code>1900-1999</code>; months are <strong>zero indexed</strong> from <code>0-11</code>; days start from <code>1-31</code>, will wrap to next month if they overflow; only passing single number argument isn&#39;t the year, it&#39;s <strong>epoch</strong>. </p>


</div></div><h2 id="guess-the-output-a-simple-algorithm"><a href="#guess-the-output-a-simple-algorithm" class="heading-anchor">Guess the Output: A Simple Algorithm</a></h2><p>Here&#39;s how you would do to predict what the <code>Date</code> constructor will do:</p>
<p><strong>Step 1: Count the arguments</strong></p>
<ol>
<li><p>0 arguments? Current time.</p>
</li>
<li><p>1 argument and it&#39;s a <code>number</code>? Milliseconds since epoch. Not a year.</p>
</li>
<li><p>1 argument and it&#39;s a <code>string</code>? Parse as date string. <code>ISO 8601</code> is safe. Anything else is a gamble.</p>
</li>
<li><p>2+ arguments? <code>year, month (0-indexed), day, hour, minute, second, millisecond</code> in that order. Everything is in local time.</p>
</li>
</ol>
<p><strong>Step 2: For 2+ args, Check for two-digit years</strong></p>
<ol>
<li><p>If first argument is between 0-99, add 1900. Year 25 becomes 1925.</p>
</li>
<li><p>If first argument is 100+, it&#39;s the literal year.</p>
</li>
</ol>
<p><strong>Step 3: Month wrapping</strong></p>
<ol>
<li><p>Month argument is 0-indexed. 0 = January, 11 = December.</p>
</li>
<li><p>Month 12? Wraps to January of next year, same with larger values. So, <code>new Date(2023, 20)</code> is <code>01 Sep 2026</code>.</p>
</li>
<li><p>Similarly, Month -1? Wraps to December of previous year.</p>
</li>
</ol>
<p><strong>Step 4: Day wrapping</strong></p>
<ol>
<li><p>Days range from 1 to <code>&lt;max_for_the_month&gt;</code>. </p>
</li>
<li><p>Any numbers outside of the range, are wrapped to next/previous month. So, <code>new Date(2023, 2, 32)</code> (allegedly 32nd march) becomes <code>01 April 2023</code>. Same with negative numbers.</p>
</li>
</ol>
<p><strong>Step 5: Timezone</strong></p>
<ol>
<li><p>String with Z? UTC.</p>
</li>
<li><p>String with timezone offset like +05:30? Parses offset but doesn&#39;t store it.</p>
</li>
<li><p>String without timezone? Pray.</p>
</li>
<li><p>Number constructor (2+ args)? Always local time.</p>
</li>
</ol>
<p><strong>Step 6: Invalid input</strong></p>
<ol>
<li><p>String that doesn&#39;t parse? <code>Invalid Date</code> object. No error thrown.</p>
</li>
<li><p><code>NaN</code> in any argument? <code>Invalid Date</code>.</p>
</li>
<li><p><code>undefined</code> in any argument? Treated as <code>NaN</code>, so <code>Invalid Date</code>.</p>
</li>
</ol>
]]></content:encoded>
    </item>
  </channel>
</rss>