<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet href="/index.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Dan Snow</title>
        <description>The blog, photos, and book reviews of Dan Snow</description>
        <link>https://sno.ws/</link>
        <language>en-US</language><atom:link href="https://sno.ws/index.xml" rel="self" type="application/rss+xml" /><lastBuildDate>Sun, 25 Jan 2026 00:00:00 +0000</lastBuildDate><item>
                <title>OpenTimes: Free travel times between U.S. Census geographies</title>
                <description>&lt;p&gt;Today I&amp;rsquo;m launching &lt;a href=&#34;https://opentimes.org&#34;&gt;OpenTimes&lt;/a&gt;, a free database of
pre-computed, point-to-point travel times between major U.S. Census geographies.
In addition to letting you &lt;a href=&#34;https://opentimes.org&#34;&gt;visualize travel isochrones&lt;/a&gt;,
OpenTimes also lets you download massive amounts of travel time data for free
and with no limits. Visit the dedicated &lt;a href=&#34;https://opentimes.org/about&#34;&gt;about page&lt;/a&gt;
to learn more about the project.&lt;/p&gt;
&lt;p&gt;The primary goal here is to enable research and fill a gap I noticed in the
open-source spatial ecosystem. Researchers (social scientists, economists) use
large travel time matrices to quantify things like access to healthcare, but
they often end up paying Google or Esri for the necessary data. By pre-calculating
times between commonly-used research geographies (i.e. Census) and then making
those times easily accessible via SQL, I hope to make large-scale accessibility
research cheaper and simpler.&lt;/p&gt;
&lt;p&gt;OpenTimes covers all 50 states (and D.C.), 3 travel modes (driving, biking, and
walking), and 6 Census geographies. Here&amp;rsquo;s what the actual data looks like
as a table:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;origin_id&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;destination_id&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;duration_sec&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;060750328021&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;060750328021&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;060750328021&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;060750328023&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;284.1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;060750328021&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;060750328022&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;322.5&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;060750328021&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;060750326023&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;479.7&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&amp;hellip;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;&amp;hellip;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&amp;hellip;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;And here&amp;rsquo;s that same data on the homepage map:&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2025-03-16-opentimes.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2025-03-16-opentimes.png&#34; alt=&#39;Isochrone map of travel times&#39; width=&#39;1800&#39;
        height=&#39;1300&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;p&gt;OpenTimes also has some interesting technical stuff going on, most of which
I haven&amp;rsquo;t seen replicated elsewhere:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The entire OpenTimes backend is just static Parquet files on
&lt;a href=&#34;https://www.cloudflare.com/developer-platform/products/r2/&#34;&gt;Cloudflare&amp;rsquo;s R2&lt;/a&gt;.
There&amp;rsquo;s no RDBMS or running service, just files and a CDN. The whole thing
costs about $10/month to host and costs nothing to serve. In my opinion,
this is a &lt;em&gt;great&lt;/em&gt; way to serve infrequently updated, large public datasets
at low cost (as long as you partition the files correctly).&lt;/li&gt;
&lt;li&gt;All travel times were calculated by pre-building the inputs (OSM, OSRM networks)
and then distributing the compute over
&lt;a href=&#34;https://github.com/dfsnow/opentimes/actions/workflows/calculate-times.yaml&#34;&gt;hundreds of GitHub Actions jobs&lt;/a&gt;.
This worked shockingly well for this specific workload (and was also completely free).&lt;/li&gt;
&lt;li&gt;The query layer uses a single DuckDB database file with &lt;em&gt;views&lt;/em&gt; that point
to static Parquet files via HTTP. This lets you query a table with hundreds of
billions of records after downloading just the ~5MB pointer file.&lt;/li&gt;
&lt;li&gt;The map frontend uses a Javascript Parquet library called
&lt;a href=&#34;https://github.com/hyparam/hyparquet&#34;&gt;hyparquet&lt;/a&gt; to query the same static
Parquet files as DuckDB. Once the Parquet files are cached the map is
actually super responsive.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I built most of OpenTimes during a 6-week stint at the
&lt;a href=&#34;https://www.recurse.com/scout/click?t=e5f3c6558aa58965ec2efe48b1b486af&#34;&gt;Recurse Center&lt;/a&gt;,
where it was my main project. Many thanks to the wonderful folks there!&lt;/p&gt;
</description>
                <link>https://sno.ws/opentimes/</link>
                <category domain="recommended">true</category>
                <pubDate>Mon, 17 Mar 2025 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/opentimes/</guid>
            </item><item>
                <title>Grafana creates strange DNS traffic for releases &gt;= 10.2.3</title>
                <description>&lt;p&gt;&lt;em&gt;Edit: This is &lt;strong&gt;resolved&lt;/strong&gt; and nothing malicious is happening.
See &lt;a href=&#34;https://github.com/grafana/grafana/issues/88951#issuecomment-2172781991&#34;&gt;here&lt;/a&gt;
for the GitHub issue update. The issue here appears to be the result of Safari
pre-fetching DNS for Grafana&amp;rsquo;s forums, which are linked on the Grafana
landing page and do use advertising scripts.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&#34;https://adguard.com/en/adguard-home/overview.html&#34;&gt;AdGuard Home&lt;/a&gt;
for DNS-based ad-blocking and recently noticed some suspicious looking
traffic getting consistently blocked in my DNS query logs. Lots of outbound
queries to fishy Russian and Greek ad servers (see the
&lt;a href=&#34;#queried-domains&#34;&gt;full list&lt;/a&gt; below):&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2024-06-16-adguard.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2024-06-16-adguard.png&#34; alt=&#39;DNS requests in AdGuard Home&#39; width=&#39;1590&#39;
        height=&#39;756&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;p&gt;After some investigating, I found that these requests were generated by
&lt;a href=&#34;https://grafana.com&#34;&gt;Grafana&lt;/a&gt;, which is visualization software I use to
monitor server health. Specifically, the requests are generated &lt;em&gt;only&lt;/em&gt;
by desktop Safari clients that load any local Grafana page from Docker image
&lt;code&gt;10.2.3&lt;/code&gt; or above (including &lt;code&gt;latest&lt;/code&gt; at the time of this posting). Some
details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The requests are triggered by a refresh (clicking in the UI does not trigger them).&lt;/li&gt;
&lt;li&gt;All Safari extensions are disabled.&lt;/li&gt;
&lt;li&gt;Safari version 17.4.1, macOS version 14.4.1.&lt;/li&gt;
&lt;li&gt;Safari iOS clients do not produce the requests.&lt;/li&gt;
&lt;li&gt;Chromium and Firefox do not produce the requests.&lt;/li&gt;
&lt;li&gt;Grafana has no plugins installed.&lt;/li&gt;
&lt;li&gt;Provisioning from YAML on a fresh image does not solve the issue.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tcpdump&lt;/code&gt; confirms these are client-side DNS requests coming from my MacBook.&lt;/li&gt;
&lt;li&gt;Docker images 10.2.2 and below do not produce the unusual requests, they
&lt;em&gt;only&lt;/em&gt; perform DNS queries for grafana.com.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I confirmed these results using an entirely separate MacBook client, and
they&amp;rsquo;ve also been confirmed independently &lt;a href=&#34;https://old.reddit.com/r/homelab/comments/1dfdln5/grafana_creates_strange_dns_traffic_for_releases/l8t95vd/&#34;&gt;on reddit&lt;/a&gt;.
I reached out to the Grafana security team on April 3rd and again on April 8th,
but received no response. I also created a &lt;a href=&#34;https://github.com/grafana/grafana/issues/88951&#34;&gt;GitHub issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not qualified to speculate about the implications here, security or
otherwise, but I do hope someone looks into this more. Even if the behavior
isn&amp;rsquo;t malicious, it&amp;rsquo;s still incredibly strange. Crossing my fingers
that this is a misconfiguration and not something worse, like a
supply chain attack or the start of ads in Grafana.&lt;/p&gt;
&lt;p&gt;🤞&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#queried-domains&#34;&gt;&lt;h2 id=&#34;queried-domains&#34;&gt;Queried domains&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to queried-domains section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;This is the full list of domains queried when refreshing a page. The list seems
to be static as it hasn&amp;rsquo;t changed between &lt;code&gt;10.2.3&lt;/code&gt; and &lt;code&gt;latest&lt;/code&gt;, as far as I
can tell.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ad.letmeads.com&lt;/li&gt;
&lt;li&gt;ad.planbplus.co.kr&lt;/li&gt;
&lt;li&gt;ad2.trafficgate.net&lt;/li&gt;
&lt;li&gt;adserv.ontek.com.tr&lt;/li&gt;
&lt;li&gt;adserver.html.it&lt;/li&gt;
&lt;li&gt;adv.imadrep.co.kr&lt;/li&gt;
&lt;li&gt;advmanager.techfun.pl&lt;/li&gt;
&lt;li&gt;affiliazioniads.snai.it&lt;/li&gt;
&lt;li&gt;afftrk.altex.ro&lt;/li&gt;
&lt;li&gt;app.readpeak.com&lt;/li&gt;
&lt;li&gt;axiabanners.exodus.gr&lt;/li&gt;
&lt;li&gt;bd742.com&lt;/li&gt;
&lt;li&gt;blackfridaysales.ro&lt;/li&gt;
&lt;li&gt;click.hotlog.ru&lt;/li&gt;
&lt;li&gt;event.2performant.com&lt;/li&gt;
&lt;li&gt;febrare.ru&lt;/li&gt;
&lt;li&gt;g1.v.fwmrm.net&lt;/li&gt;
&lt;li&gt;hitcounter.ru&lt;/li&gt;
&lt;li&gt;interactive.forthnet.gr&lt;/li&gt;
&lt;li&gt;izlenzi.com&lt;/li&gt;
&lt;li&gt;l.profitshare.ro&lt;/li&gt;
&lt;li&gt;pay4results24.eu&lt;/li&gt;
&lt;li&gt;promo.vador.com&lt;/li&gt;
&lt;li&gt;telegram.me&lt;/li&gt;
&lt;li&gt;top.mail.ru&lt;/li&gt;
&lt;li&gt;utimg.ru&lt;/li&gt;
&lt;li&gt;www.installads.net&lt;/li&gt;
&lt;li&gt;www.salidzini.lv&lt;/li&gt;
&lt;li&gt;www.stumbleupon.com&lt;/li&gt;
&lt;li&gt;www.trizer.pl&lt;/li&gt;
&lt;li&gt;xltube.nl&lt;/li&gt;
&lt;/ul&gt;
</description>
                <link>https://sno.ws/grafana-dns/</link>
                <category domain="recommended">false</category>
                <pubDate>Sun, 16 Jun 2024 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/grafana-dns/</guid>
            </item><item>
                <title>Exporting Jellyfin playback stats to Prometheus</title>
                <description>&lt;style media=&#34;screen&#34;&gt;
  :root { --add-media-width: 80px }
  .content &gt; .video-holder {
    margin: 2rem auto;
  }
&lt;/style&gt;
&lt;h4&gt;
&lt;a href=&#34;https://gist.github.com/dfsnow/aad4ec99afb413968c49efb03bdb1ab9&#34;&gt;GitHub gist for source code&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;Edit: It turns out there&amp;rsquo;s a much simpler way to do this. See the &lt;a href=&#34;#update-2024-02-23&#34;&gt;update&lt;/a&gt; below.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I run a small &lt;a href=&#34;https://github.com/jellyfin/jellyfin&#34;&gt;Jellyfin&lt;/a&gt; server at home to watch movies and other media I&amp;rsquo;ve collected over the years. Recently, in order to debug some playback/networking issues, I wanted a way to answer the following questions via &lt;a href=&#34;https://prometheus.io&#34;&gt;Prometheus&lt;/a&gt; and &lt;a href=&#34;https://grafana.com&#34;&gt;Grafana&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What media is Jellyfin currently playing?&lt;/li&gt;
&lt;li&gt;Who is playing that media?&lt;/li&gt;
&lt;li&gt;How much bandwidth is the playback using?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Basically, I wanted to make this graph in Grafana:&lt;/p&gt;


&lt;div class=&#34;video-holder&#34;&gt;
    &lt;video autoplay loop muted playsinline&gt;
        &lt;source src=&#39;https://content.sno.ws/videos/2023-11-24-jellyfin-grafana.mp4&#39; type=&#34;video/mp4&#34;&gt;
        &lt;source src=&#39;https://content.sno.ws/videos/2023-11-24-jellyfin-grafana.webm&#39; type=&#34;video/webm&#34;&gt;
        Your browser does not support the video tag.
    &lt;/video&gt;
&lt;/div&gt;

&lt;p&gt;This turned out to be way harder than I thought, but I eventually got it working using the Jellyfin REST API and Prometheus JSON exporter. This post walks through what I did.&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#the-jellyfin-rest-api&#34;&gt;&lt;h2 id=&#34;the-jellyfin-rest-api&#34;&gt;The Jellyfin REST API&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to the-jellyfin-rest-api section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;Jellyfin has a &lt;a href=&#34;https://jellyfin.org/docs/general/networking/monitoring/&#34;&gt;built-in Prometheus endpoint&lt;/a&gt; at &lt;code&gt;$BASE_URL/metrics&lt;/code&gt;, but it&amp;rsquo;s extremely bare-bones and didn&amp;rsquo;t return the playback stats I wanted. There are also full-featured statistics applications like &lt;a href=&#34;https://github.com/CyferShepard/Jellystat&#34;&gt;Jellystat&lt;/a&gt;, but they seemed like overkill for my needs.&lt;/p&gt;
&lt;p&gt;Eventually, I stumbled across the &lt;a href=&#34;https://api.jellyfin.org&#34;&gt;Jellyfin REST API&lt;/a&gt;. It&amp;rsquo;s an extensive API that lets you basically do whatever you want in Jellyfin. However, it&amp;rsquo;s very poorly documented and I couldn&amp;rsquo;t find many examples of actually using it to do stuff.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://jmshrv.com/posts/jellyfin-api/&#34;&gt;This blog post&lt;/a&gt; by James Harvey (creator of Finamp) turned out to be a lifesaver. It walks through the authorization setup and gives an overview of some of the API endpoints. I also found &lt;a href=&#34;https://gist.github.com/nielsvanvelzen/ea047d9028f676185832e51ffaf12a6f&#34;&gt;this Gist&lt;/a&gt; that walks through the various Jellyfin API authorization methods. I used these resources to construct a simple curl request:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TOKEN&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;example-token-here
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://jellyfin.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -X &lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$BASE_URL&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/Sessions&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Authorization: MediaBrowser Token=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TOKEN&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.[]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;TOKEN&lt;/code&gt; value here is a Jellyfin API key from &lt;strong&gt;Admin Dashboard&lt;/strong&gt; &amp;gt; &lt;strong&gt;Advanced&lt;/strong&gt; &amp;gt; &lt;strong&gt;API Keys&lt;/strong&gt;.
The request outputs a JSON object with some playback stats, capabilities, last seen times, etc. Here&amp;rsquo;s the result nicely parsed with &lt;code&gt;jq&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;PlayState&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;AdditionalUsers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;Capabilities&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;RemoteEndPoint&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1.1.1.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;Id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;UserId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;UserName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Dan&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;Client&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Jellyfin Roku&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;LastActivityDate&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2023-10-29T01:26:17.2969131Z&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;LastPlaybackCheckIn&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;0001-01-01T00:00:00.0000000Z&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;DeviceName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;50 TCL Roku TV&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is useful stuff, but not exactly the nicely summarized playback information I was hoping for. It&amp;rsquo;s &lt;em&gt;possible&lt;/em&gt; to use the REST API to gather all the relevant stats, but it takes multiple API calls to different endpoints. There turned out to be an easier way.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#fetching-aggregate-stats&#34;&gt;&lt;h2 id=&#34;fetching-aggregate-stats&#34;&gt;Fetching aggregate stats&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to fetching-aggregate-stats section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;The &lt;a href=&#34;https://github.com/jellyfin/jellyfin-plugin-playbackreporting&#34;&gt;Jellyfin Playback Reporting Plugin (PRP)&lt;/a&gt; aggregates and exposes playback stats via a dashboard on the Jellyfin admin panel. These stats are stored in a SQLite database in the Jellyfin data directory. Querying this database lets you get basically any playback stats you want. All I had to do is figure out a way to query the database remotely.&lt;/p&gt;
&lt;p&gt;Fortunately, installing the PRP also adds dedicated API endpoints at &lt;code&gt;/user_usage_stats/&lt;/code&gt;. The most useful/relevant of these is the POST endpoint &lt;code&gt;/user_usage_stats/submit_custom_query&lt;/code&gt;, which lets you pass any arbitrary SQL query to the underlying SQLite database.&lt;/p&gt;
&lt;p&gt;After lots of trial and error, I was able to update the curl request to hit the new endpoint:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -X &lt;span class=&#34;s2&#34;&gt;&amp;#34;POST&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$BASE_URL&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/user_usage_stats/submit_custom_query&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;accept: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Authorization: MediaBrowser Token=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TOKEN&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;CustomQueryString&amp;#34;: &amp;#34;SELECT * FROM PlaybackActivity LIMIT 2&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;ReplaceUserId&amp;#34;: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;  }&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;# The extra jq stuff here is just to parse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;# the output into something more readable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.results | map ({ &amp;#34;date&amp;#34;:.[0],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;user&amp;#34;:.[1],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;item_id&amp;#34;:.[2],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;type&amp;#34;:.[3],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;item_name&amp;#34;:.[4],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;method&amp;#34;:.[5],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;client&amp;#34;:.[6],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;device&amp;#34;:.[7],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;duration&amp;#34;:.[8]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;  })&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here&amp;rsquo;s what the parsed output looked like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;DateCreated&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2023-10-29 20:08:19.1115194&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;UserName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Dan&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ItemId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ItemType&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Movie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ItemName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;She&amp;#39;s the Man&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;PlaybackMethod&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Transcode (v:direct a:aac)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ClientName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Jellyfin Mobile (iOS)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;DeviceName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;iPhone&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;PlayDuration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1088&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;DateCreated&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2023-10-30 22:26:29.7812735&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;UserName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Dan&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ItemId&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ItemType&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Movie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ItemName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;My Neighbor Totoro&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;PlaybackMethod&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Transcode (v:direct a:aac)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ClientName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Jellyfin Mobile (iOS)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;DeviceName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;iPhone&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;PlayDuration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;33&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that the test query above just returned a couple arbitrary rows from the &lt;code&gt;PlaybackActivity&lt;/code&gt; table. I needed a more complicated SQLite query to fetch &amp;ldquo;live&amp;rdquo; stats. I came up with the query below, which only returns rows for things that are currently playing and also includes a timestamp for use in Prometheus.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- Return the timestamp of the record/stream to
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- replace the default Prometheus timestamp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unixepoch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DATETIME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DateCreated&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;+&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayDuration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34; seconds&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;Timestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UserId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ItemType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ItemName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlaybackMethod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClientName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DeviceName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayDuration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TRUE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsActive&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlaybackActivity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- Only return &amp;#34;active&amp;#34; streams, i.e. ones playing
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- in the last 60 seconds
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DATETIME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DateCreated&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;+&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PlayDuration&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34; seconds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DATETIME&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;now&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;localtime&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-60 seconds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hitting the &lt;code&gt;/user_usage_stats/submit_custom_query&lt;/code&gt; endpoint with this query effectively returns all currently playing Jellyfin media, which is exactly what I needed. The final piece of the puzzle was figuring out how to export the results to Prometheus.&lt;/p&gt;
&lt;p class=&#34;notice&#34;&gt;
If your Grafana instance is on the same machine as Jellyfin, it might be easier to skip Prometheus entirely. Simply use the &lt;a href=&#34;https://grafana.com/grafana/plugins/frser-sqlite-datasource/&#34;&gt;Grafana SQLite plugin&lt;/a&gt; to add the Playback Reporting Plugin database file as a Grafana datasource directly.
&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#prometheus-json-exporter&#34;&gt;&lt;h2 id=&#34;prometheus-json-exporter&#34;&gt;Prometheus JSON exporter&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to prometheus-json-exporter section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;This part of the project was actually the easiest. I used the community &lt;a href=&#34;https://github.com/prometheus-community/json_exporter&#34;&gt;json_exporter&lt;/a&gt; to load JSON output from the custom query into Prometheus. I basically just translated the curl request above into a Prometheus &lt;a href=&#34;https://prometheus.io/docs/guides/multi-target-exporter/#configuring-modules&#34;&gt;module&lt;/a&gt;. There are lots of ways to do this, but here&amp;rsquo;s one possible example. Note the comments, they&amp;rsquo;re important:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;modules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;jellyfin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The Token value here needs to be the API key from the&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# curl request. I hard-coded the value but I&amp;#39;m sure there&amp;#39;s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# a better way&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;Authorization&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;MediaBrowser Token=ADD_TOKEN_HERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;Content-Type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;application/json&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;application/json&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# This is the query from above, but condensed to a single line&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# NOTE: The string escaping/lack of newlines is&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# required for the exporter to work&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;CustomQueryString&amp;#34;: &amp;#34;SELECT unixepoch(DATETIME(DateCreated, \&amp;#34;+\&amp;#34; || PlayDuration || \&amp;#34; seconds\&amp;#34;)) AS Timestamp, UserId, ItemType, ItemName, PlaybackMethod, ClientName, DeviceName, PlayDuration, TRUE AS IsActive FROM PlaybackActivity WHERE DATETIME(DateCreated, \&amp;#34;+\&amp;#34; || PlayDuration || \&amp;#34; seconds\&amp;#34;) &amp;gt;= DATETIME(\&amp;#34;now\&amp;#34;, \&amp;#34;localtime\&amp;#34;, \&amp;#34;-60 seconds\&amp;#34;)&amp;#34;, &amp;#34;ReplaceUserId&amp;#34;: true}&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jellyfin&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;object&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;User playback metrics from Jellyfin&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .results[*] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Optionally use the SQL-generated timestamp instead of&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# the Prometheus &amp;#34;query collected at&amp;#34; timestamp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;epochTimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [0] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The JSON parsing here is basically identical to the jq&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# call above, just using JSONPath syntax instead&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;user_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [1] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;item_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [2] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;item_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [3] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;playback_method&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [4] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;client_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [5] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;device_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [6] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;play_duration&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [7] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, I added the exporter to my Prometheus config file using the &lt;a href=&#34;https://prometheus.io/docs/guides/multi-target-exporter/&#34;&gt;multi-target exporter pattern&lt;/a&gt; with relabeling and modules:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;scrape_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/probe&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jellyfin]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The module from above&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The Jellyfin PRP custom query API endpoint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;https://jellyfin.example.com/user_usage_stats/submit_custom_query&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;relabel_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;__address__]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;__param_target&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;__param_target]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;instance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;__address__&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;replacement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HOSTNAME:9115&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The exporter&amp;#39;s hostname:port&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And that&amp;rsquo;s it! A curl request to &lt;code&gt;http://$HOSTNAME:9115/probe&lt;/code&gt; now returns Prometheus metrics for any currently playing Jellyfin media, along with the user information and transcoding settings of the player. Note that metrics only exist if media &lt;em&gt;is currently playing&lt;/em&gt;, otherwise the return body will be blank.&lt;/p&gt;
&lt;p&gt;Translating the resulting metrics into useable Grafana graphs is a project by itself, but it is possible with the extensive use of transformations. I&amp;rsquo;ll save that topic for a future post.&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#update-2024-02-23&#34;&gt;&lt;h2 id=&#34;update-2024-02-23&#34;&gt;Update (2024-02-23)&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to update-2024-02-23 section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;After digging around in the &lt;a href=&#34;https://api.jellyfin.org&#34;&gt;API docs&lt;/a&gt; for awhile, I realized that using the Playback Reporting Plugin is totally unnecessary. The &lt;code&gt;Sessions/&lt;/code&gt; endpoint returns everything you need and works more consistently.&lt;/p&gt;
&lt;p&gt;The trick is to grab stuff from the &lt;code&gt;NowPlayingItem&lt;/code&gt; key of each session, which only exists when something is playing. Here&amp;rsquo;s the updated YAML to reflect the new target:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;modules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;jellyfin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;Authorization&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;MediaBrowser Token=ADD_TOKEN_HERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;Content-Type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;application/json&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;application/json&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# The body is no longer needed since this is now GET&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# This will return all active sessions regardless of&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# whether something is playing. You can use a combination&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# of label and value filters in Grafana to only get actively&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# playing sessions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jellyfin&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;object&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;User playback metrics from Jellyfin&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Only look at sessions with the NowPlayingItem key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ [?(@.NowPlayingItem)] }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;user_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .UserName }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Use PromQL label_join and label_replace to concatenate&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# these values into a nice item description&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;item_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .NowPlayingItem.Type }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;item_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .NowPlayingItem.Name }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;item_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .NowPlayingItem.Path }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;series_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .NowPlayingItem.SeriesName }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;episode_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;e{ .NowPlayingItem.IndexNumber }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;season_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;s{ .NowPlayingItem.ParentIndexNumber }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;client_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .Client }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;device_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .DeviceName }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Include the unique session ID in case the above&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# labels aren&amp;#39;t a unique combination&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;session_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .Id }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;is_paused&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;{ .PlayState.IsPaused }&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And the Prometheus config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;scrape_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/probe&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;jellyfin]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# Change the target to point at the sessions endpoint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;https://jellyfin.example.com/Sessions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;relabel_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;__address__]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;__param_target&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;source_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;__param_target]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;instance&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;target_label&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;__address__&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;replacement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;HOSTNAME:9115&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
                <link>https://sno.ws/jellyfin-stats/</link>
                <category domain="recommended">false</category>
                <pubDate>Sat, 25 Nov 2023 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/jellyfin-stats/</guid>
            </item><item>
                <title>Comparing 500 billion rows with data.table</title>
                <description>&lt;p&gt;Recently, I&amp;rsquo;ve been working on a project that requires the element-wise comparison of many rows. The goal is to calculate a sort of similarity score between two tables. A simplified version of the data/problem looks like this:&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;margin:-1rem;display:block;text-align:center;&#34;&gt;&lt;strong&gt;Table X&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V1&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V2&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V3&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V4&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V5&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;9&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;4&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;5&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;9&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;span style=&#34;margin-bottom:-1rem;display:block;text-align:center;&#34;&gt;&lt;strong&gt;Table Y&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V1&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V2&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V3&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V4&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V5&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;9&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;9&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;9&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;7&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;9&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;8&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Each row of Table X is compared to each row of Table Y and the elements are replaced with a boolean. This happens element-wise, so &lt;code&gt;X1, V1&lt;/code&gt; is compared to &lt;code&gt;Y1, V1&lt;/code&gt;, &lt;code&gt;X1, V2&lt;/code&gt; is compared to &lt;code&gt;Y1, V2&lt;/code&gt;, etc. The comparison of row X1 to all rows in Table Y looks like this:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID_X&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID_Y&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V1&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V2&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V3&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V4&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V5&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;TRUE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;TRUE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;TRUE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;FALSE&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Each row of this boolean table is multiplied by a vector of pre-determined weights (the same length as the number of columns) and then summed to determine the final similarity between row X1 and the rows of Table Y. If the weights are &lt;code&gt;5, 4, 3, 2, 1&lt;/code&gt;, then the resulting table becomes:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID_X&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID_Y&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V1&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V2&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V3&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V4&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;V5&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;5&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;4&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;5&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Summed by row, the total similarity score between row X1 and all of Table Y is:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID_X&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID_Y&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;score&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;9&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;5&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;And for all rows of Table X and all rows of Table Y:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID_X&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;ID_Y&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;score&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;9&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;5&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y1&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;8&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;7&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;X2&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;Y3&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;5&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Great, seems simple enough, right? We can loop through the rows of Table X and sum the resulting rows for each comparison to Table Y. What&amp;rsquo;s the problem?&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#problem&#34;&gt;&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to problem section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;The real table X and Y are &lt;em&gt;big&lt;/em&gt;, and the product of their comparison is absolute &lt;em&gt;huge&lt;/em&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Table X is 1.1M rows by 1,500 columns.&lt;/li&gt;
&lt;li&gt;Table Y is 450K rows by 1,500 columns.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Comparing just one row of Table X to Table Y requires 450K comparisons, and each comparison is between a 1,500 element vector. Comparing all of Table X to Table Y requires &lt;code&gt;1.1M * 450K&lt;/code&gt; comparisons and thus results in around 500 billion similarity scores.&lt;/p&gt;
&lt;p&gt;At that scale, many of the obvious solutions to this problem just sort of&amp;hellip; break. They quickly run out of memory or have runtimes measured in weeks. In order to make this data useful, we must find a solution that not only &lt;em&gt;runs&lt;/em&gt; but that also runs &lt;em&gt;extremely fast&lt;/em&gt;.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#caveats&#34;&gt;&lt;h3 id=&#34;caveats&#34;&gt;Caveats&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to caveats section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;To make the problem slightly more tractable for this post, we will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Only use R, though there are probably much faster solutions in compiled languages.&lt;/li&gt;
&lt;li&gt;Generate much smaller test data than the real data so we can benchmark solutions without waiting for days. Here&amp;rsquo;s the data generation in R:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;library&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data.table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;library&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;microbenchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;n_col&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;n_rows_x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;n_rows_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;10000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;runif&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Table X becomes 100 x 500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;x_df&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;data.table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;ID&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;paste0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;X&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;seq_len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n_rows_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;sample.int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n_col&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n_rows_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;TRUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ncol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n_rows_x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Table Y becomes 10000 x 500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;y_df&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;data.table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;ID&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;paste0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Y&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;seq_len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n_rows_y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;sample.int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n_col&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n_rows_y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;TRUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ncol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;n_rows_y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#solutions&#34;&gt;&lt;h2 id=&#34;solutions&#34;&gt;Solutions&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to solutions section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;The goal is to perform a weighted comparison of each row of Table X to each row of Table Y, and to do so &lt;em&gt;quickly&lt;/em&gt; and with the maximum possible memory efficiency. Here are some of the solutions I tried as well as the one I eventually landed on.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#for-loop&#34;&gt;&lt;h3 id=&#34;for-loop&#34;&gt;For loop&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to for-loop section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;The first thing I (or more accurately, my intern) tried was a simple for loop. This is very memory-efficient since it&amp;rsquo;s basically just looping through columns of existing data and sticking the results into a pre-allocated output matrix. However, it takes around 8 seconds to finish on the test data, meaning it would likely take &lt;em&gt;weeks&lt;/em&gt; to finish on the real data. No good.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;calc_sim_for&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;score&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ncol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;seq_len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;col&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;colnames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;matches&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y[[col]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x[row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;][[col]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;score[row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;score[row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights[i]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;matches&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;score&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;microbenchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;for&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;millisecond&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-output&#34; data-lang=&#34;output&#34;&gt;Unit: milliseconds
  expr  min   lq mean median   uq  max neval
   for 7478 7493 7553   7515 7612 7664     5
&lt;/code&gt;&lt;/pre&gt;&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#apply-and-matrix-ops&#34;&gt;&lt;h3 id=&#34;apply-and-matrix-ops&#34;&gt;Apply and matrix ops&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to apply-and-matrix-ops section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;Next, I tried using &lt;code&gt;apply()&lt;/code&gt; to compare each table column-wise and then using matrix multiplication for the weights. This turned out to be even slower than the for loop.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;calc_sim_apply&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;score&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ncol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;t_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;as.matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;m_x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;as.matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;seq_len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;match_matrix&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;apply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t_y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MARGIN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;==&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;m_x[row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;score[row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%*%&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;as.matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;match_matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;score&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;microbenchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;apply&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_apply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;millisecond&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-output&#34; data-lang=&#34;output&#34;&gt;Unit: milliseconds
  expr   min    lq  mean median    uq   max neval
 apply 16197 16213 16407  16422 16543 16659     5
&lt;/code&gt;&lt;/pre&gt;&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#vector-recycling&#34;&gt;&lt;h3 id=&#34;vector-recycling&#34;&gt;Vector recycling&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to vector-recycling section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;Next, I tried to take advantage of R&amp;rsquo;s fast matrix operations by comparing each row of Table X to a transposed version of Table Y. This works because vector-to-matrix comparisons are column-wise, and the single row of X (converted to a vector) is recycled automatically. This is much faster than &lt;code&gt;apply()&lt;/code&gt; or the for loop, but still isn&amp;rsquo;t nearly fast enough.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;calc_sim_mat&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;score&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ncol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;t_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;seq_len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;vec_x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;as.numeric&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x[row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;score[row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;unname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;colSums&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vec_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;score&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;microbenchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;mat&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_mat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;millisecond&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-output&#34; data-lang=&#34;output&#34;&gt;Unit: milliseconds
  expr  min   lq mean median   uq  max neval
   mat 2118 2131 2142   2133 2153 2176     5
&lt;/code&gt;&lt;/pre&gt;&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#pure-datatable&#34;&gt;&lt;h3 id=&#34;pure-datatable&#34;&gt;Pure data.table&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to pure-datatable section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;I &lt;em&gt;really&lt;/em&gt; like R&amp;rsquo;s &lt;code&gt;data.table&lt;/code&gt; package. These days I find myself reaching for it whenever speed and memory efficiency are a concern. However, I wasn&amp;rsquo;t sure it was suitable for this problem. After messing around with &lt;code&gt;lapply()&lt;/code&gt; and some other options, I found an approach that is incredibly simple &lt;em&gt;and&lt;/em&gt; fast. Here&amp;rsquo;s how it works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pivot the input matrices from wide to long using &lt;code&gt;data.table::melt()&lt;/code&gt;. The original Table X becomes the table shown below.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;data.table&lt;/code&gt;&amp;rsquo;s keys to index the resulting long tables.&lt;/li&gt;
&lt;li&gt;Join the long Table X and long Table Y on &lt;code&gt;V&lt;/code&gt; and &lt;code&gt;IDX&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Replace the value of &lt;code&gt;V&lt;/code&gt; with the corresponding weight, then sum for each group of X and Y IDs.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-output&#34; data-lang=&#34;output&#34;&gt;    ID  V IDX
 1: X1 V1   9
 2: X2 V1   9
 3: X1 V2   3
 4: X2 V2   1
 5: X1 V3   2
 6: X2 V3   2
 7: X1 V4   4
 8: X2 V4   1
 9: X1 V5   5
10: X2 V5   1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This approach gains most of its speed by taking advantage of &lt;code&gt;data.table&lt;/code&gt;&amp;rsquo;s indexed joins and aggregations. But just how fast is it?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;calc_sim_dt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;x_nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;y_nrow&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;nrow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;id_col_i&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;paste0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;i.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nf&#34;&gt;names&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;colnames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;# Pivot X and Y from wide to long, add keys to the results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;x_m&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data.table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;melt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;id.vars&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;variable.name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;V&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;value.name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;IDX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;data.table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;setkeyv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cols&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;V&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;IDX&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;physical&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;TRUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;y_m&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data.table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;melt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;id.vars&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;variable.name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;V&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;value.name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;IDX&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;data.table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;setkeyv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y_m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cols&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;V&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;IDX&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;physical&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;TRUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;# Join on the pivoted columns, then aggregate to get scores&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;out&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_m[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;x_m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;on&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;.(V&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;IDX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;nomatch&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;allow.cartesian&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;TRUE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;][&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;V&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;IDX&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;.(weights[V]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;][&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;.(score&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;keyby&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id_col_i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;# Clean up the results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;data.table&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;setnames&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;old&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id_col_i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;paste0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;_X&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;paste0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id_col&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;_Y&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Use all threads for data.table&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;setDTthreads&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Comparing all solutions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;microbenchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;for&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;apply&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_apply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;mat&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_mat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;dt&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_df&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_df&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;ID&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;millisecond&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-output&#34; data-lang=&#34;output&#34;&gt;Unit: milliseconds
  expr   min    lq  mean median    uq   max neval
   for  7547  7651  7802   7856  7887  8067     5
 apply 17223 20289 20026  20447 20697 21476     5
   mat  2169  2204  2214   2214  2217  2266     5
    dt   141   144   168    150   201   206     5
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Oh. It&amp;rsquo;s a full order of magnitude faster than everything else. Looks like &lt;code&gt;data.table&lt;/code&gt; is our winning solution!&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#conclusion&#34;&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to conclusion section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;So, that&amp;rsquo;s the test data, but what about the original problem with 500 billion rows? Can the &lt;code&gt;data.table&lt;/code&gt; solution actually finish running it?&lt;/p&gt;
&lt;p&gt;Yes it can! Though with some caveats:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;data.table&lt;/code&gt; has a limit of &lt;code&gt;2 ^ 31&lt;/code&gt; rows resulting from a join. To stay below that limit, the input Table X needs to be processed in chunks, which slows things down a bit.&lt;/li&gt;
&lt;li&gt;Saving &lt;em&gt;every&lt;/em&gt; score between rows isn&amp;rsquo;t actually necessary. What we&amp;rsquo;re really after is the top N most similar rows of Table Y given a row in X. This significantly shrinks the required memory and ultimately the size of the output.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wrote some additional code to handle these caveats and ran it on the full data. Given 1.1M rows in X and 450K rows in Y, each with 1,500 columns, the code took &lt;code&gt;31H 27M 18S&lt;/code&gt; to run on a beefy server (128G RAM, 16 cores of a Xeon Silver 4208 using &lt;code&gt;data.table&lt;/code&gt;&amp;rsquo;s built-in parallelism). Still slow, but totally manageable given the nature of the task.&lt;/p&gt;
&lt;p&gt;That said, I&amp;rsquo;m sure this could be done faster using a lower-level language. I did some quick experiments using Rcpp, but I don&amp;rsquo;t think I&amp;rsquo;m skilled enough to beat the times I got with &lt;code&gt;data.table&lt;/code&gt;. If anyone does manage to find a faster solution, feel free to email me; I&amp;rsquo;ll gladly buy you a beer.&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#update-2023-06-21&#34;&gt;&lt;h2 id=&#34;update-2023-06-21&#34;&gt;Update (2023-06-21)&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to update-2023-06-21 section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;I owe someone a beer. &lt;a href=&#34;https://nicktallant.com&#34;&gt;My friend&lt;/a&gt; pointed out that a simple nested for loop in Python using &lt;code&gt;numpy&lt;/code&gt; is nearly as fast as the &lt;code&gt;data.table&lt;/code&gt; solution.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;
Click to view setup code
&lt;/summary&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;library&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reticulate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;as.matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;as.matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y_df[&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numpy&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Import objects from R to numpy using reticulate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;w&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;weights&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Define janky microbenchmark analogue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;benchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;exp_j&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;timings&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;perf_counter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;perf_counter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;timings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;round&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Unit: milliseconds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;expr&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exp_j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34; min  lq mean median  uq max neval&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exp_j&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;quantile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.25&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;median&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;quantile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.75&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;int16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;times&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rjust&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/details&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_py&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zeros&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;idx_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x_row&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;idx_y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_row&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idx_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;idx_y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_row&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;benchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;calc_sim_py&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;py&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-output&#34; data-lang=&#34;output&#34;&gt;Unit: milliseconds
  expr min  lq mean median  uq max neval
    py 299 301  302    302 302 305     5
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that compiling the same loop with &lt;a href=&#34;https://numba.pydata.org&#34;&gt;&lt;code&gt;numba&lt;/code&gt;&lt;/a&gt;&amp;rsquo;s &lt;code&gt;@njit&lt;/code&gt; decorator reduces the time even further, down to around a half the time of &lt;code&gt;data.table&lt;/code&gt;. Pretty wild!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numba&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;njit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prange&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@njit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_py_njit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zeros&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dtype&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x_idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x_row&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_row&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;enumerate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y_idx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_row&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;benchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;calc_sim_py_njit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;py_njit&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-output&#34; data-lang=&#34;output&#34;&gt;Unit: milliseconds
    expr min  lq mean median  uq max neval
 py_njit  80  80   87     80  80 114     5
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#update-2023-06-23&#34;&gt;&lt;h2 id=&#34;update-2023-06-23&#34;&gt;Update (2023-06-23)&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to update-2023-06-23 section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;I owe two beers. My coworker has further sped up the &lt;code&gt;numpy&lt;/code&gt; loops using &lt;code&gt;numba&lt;/code&gt;&amp;rsquo;s built-in parallelization. So now we&amp;rsquo;ve dropped three orders of magnitude from the original R for loop. Can we go even faster?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;numba&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;njit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prange&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@njit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parallel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fastmath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calc_sim_py_par&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zeros&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dtype&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x_i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prange&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y_i&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y_i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x_i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y_i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;benchmark&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;calc_sim_py_par&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;py_par&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;times&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-output&#34; data-lang=&#34;output&#34;&gt;Unit: milliseconds
    expr min  lq mean median  uq max neval
  py_par   6   7    8      7   8  43    50
&lt;/code&gt;&lt;/pre&gt;</description>
                <link>https://sno.ws/big-data-table/</link>
                <category domain="recommended">false</category>
                <pubDate>Sat, 17 Jun 2023 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/big-data-table/</guid>
            </item><item>
                <title>Pivoting 100GB text files from long to wide</title>
                <description>&lt;p&gt;Recently, I&amp;rsquo;ve been working on a project involving travel time matrices. These matrices are the output of specialized &lt;a href=&#34;https://github.com/conveyal/r5&#34;&gt;routing software&lt;/a&gt; and are used in social science research, urban planning, and policy analysis. They look like this:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;origin&lt;/th&gt;
          &lt;th&gt;destination&lt;/th&gt;
          &lt;th&gt;minutes&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;B&lt;/td&gt;
          &lt;td&gt;9&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;C&lt;/td&gt;
          &lt;td&gt;15&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;B&lt;/td&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;10&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;B&lt;/td&gt;
          &lt;td&gt;B&lt;/td&gt;
          &lt;td&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;B&lt;/td&gt;
          &lt;td&gt;C&lt;/td&gt;
          &lt;td&gt;21&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;C&lt;/td&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;13&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;C&lt;/td&gt;
          &lt;td&gt;C&lt;/td&gt;
          &lt;td&gt;0&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Where &lt;strong&gt;origin&lt;/strong&gt; and &lt;strong&gt;destination&lt;/strong&gt; are the identifiers of geographic points (usually Census geography centroids) and &lt;strong&gt;minutes&lt;/strong&gt; is the travel time between the points.&lt;/p&gt;
&lt;p&gt;This is the &amp;ldquo;long&amp;rdquo; travel time matrix format. It&amp;rsquo;s the typical output of routing software, but instead of 6 rows, each matrix has millions or even billions of rows. The software outputs each matrix as a plain CSV file, which is then compressed to a more manageable size.&lt;/p&gt;
&lt;p&gt;The long matrix format is simple and easy to work with, but has some major drawbacks. Mainly, it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Repeats identifiers (A is repeated 3 times in the matrix above), which costs space.&lt;/li&gt;
&lt;li&gt;Makes lookups difficult, since finding a specific origin-destination pair requires either scanning the entire file or using an index (which costs more space).&lt;/li&gt;
&lt;li&gt;Doesn&amp;rsquo;t include pairs missing from the Cartesian product of origins and destinations. Such missing pairs are often useful for debugging routing issues.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can fix all these issues by converting our long format to &amp;ldquo;wide&amp;rdquo; format, with origins as rows and destinations as columns. The wide version of the matrix above looks like this:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;origin&lt;/th&gt;
          &lt;th&gt;A&lt;/th&gt;
          &lt;th&gt;B&lt;/th&gt;
          &lt;th&gt;C&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;0&lt;/td&gt;
          &lt;td&gt;9&lt;/td&gt;
          &lt;td&gt;15&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;B&lt;/td&gt;
          &lt;td&gt;10&lt;/td&gt;
          &lt;td&gt;0&lt;/td&gt;
          &lt;td&gt;21&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;C&lt;/td&gt;
          &lt;td&gt;13&lt;/td&gt;
          &lt;td&gt;-&lt;/td&gt;
          &lt;td&gt;0&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This format saves space, compresses better, and shows missing origin-destination pairs. It can also be converted into a modern columnar storage format like Parquet for easy column lookups, built-in compression, and handy metadata.&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#problem&#34;&gt;&lt;h2 id=&#34;problem&#34;&gt;Problem&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to problem section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;Pivoting these matrices is &lt;em&gt;hard&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In most cases, data can be easily pivoted from long to wide using functions from &lt;a href=&#34;https://github.com/Rdatatable/data.table&#34;&gt;popular data manipulation libraries&lt;/a&gt;. However, such libraries typically work with data in-memory, and travel time matrices can be over 100GB uncompressed, making them impossible to fit in-memory on most machines.&lt;/p&gt;
&lt;p&gt;As such, we need to find a method to pivot the travel time data &lt;em&gt;without storing it in-memory&lt;/em&gt;. Our method should also:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Handle missing pairs i.e. each origin doesn&amp;rsquo;t go to all destinations.&lt;/li&gt;
&lt;li&gt;Handle origin and destination lists of any size. Some matrices have 100K+ destinations for each origin.&lt;/li&gt;
&lt;li&gt;Read from a compressed file, do its work, then write to a compressed file. This is critical, as it prevents mangling disks by writing hundreds of gigabytes of uncompressed text data for each matrix.&lt;/li&gt;
&lt;li&gt;Be extremely fast, since each matrix is huge and my project involves a &lt;em&gt;lot&lt;/em&gt; of matrices.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Fortunately, we have some conditions and additional information that make this task easier. Each matrix:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Is numerically ordered by origin, then destination (as seen in the example long table).&lt;/li&gt;
&lt;li&gt;Includes a separate file containing the unique set of destinations.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I couldn&amp;rsquo;t find any off-the-shelf or obvious solutions to this problem. I imagine it&amp;rsquo;s too niche to warrant much attention. We&amp;rsquo;ll have to roll our own.&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#solutions&#34;&gt;&lt;h2 id=&#34;solutions&#34;&gt;Solutions&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to solutions section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;Given our requirements, the simplest (IMO) solution is text stream processing using bash pipes. This approach saves almost no data in-memory, is fast (enough), and uses pre-existing CLI tools to handle compression. All we need to do is write code to perform the long-to-wide pivot on the text stream.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#awk&#34;&gt;&lt;h3 id=&#34;awk&#34;&gt;Awk&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to awk section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;&lt;code&gt;awk&lt;/code&gt; is first tool I reach for when doing any sort of text stream processing. It&amp;rsquo;s stupidly powerful, if a bit esoteric and finicky.&lt;/p&gt;
&lt;p&gt;Here we can use it to iterate through rows and match each value&amp;rsquo;s position to an array of possible destinations (columns). This approach stores only the destinations and a temporary array of values in-memory.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-awk&#34; data-lang=&#34;awk&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Create an array of columns (destinations) from a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# separate input file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;BEGIN&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;FS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;OFS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;,&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;getline&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;line&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dests&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;contents&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;contents&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;numCols&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cols&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Create the CSV header by printing each destination&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;FNR&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;%s&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;numCols&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;dest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;cols&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;%s%s&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;OFS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;dest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;next&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Loop through rows, appending each value to an array&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# based on its corresponding destination. Once the&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# origin changes, print the array, then start a new row&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# in the output stream&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;FNR&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;prt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;END&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;prt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;prt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;destination&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;%s&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;numCols&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;destination&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;cols&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;destination&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;printf&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;%s%d&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;OFS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;print&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;delete&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;values&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The script (saved as &lt;code&gt;pivot.awk&lt;/code&gt;) is called using the following bash command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Read the file and add progress bar with pv, then decompress&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# the input stream (bz2), pivot with awk, and recompress with zstd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# The list of unique destinations is passed to awk as a variable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pv in.csv.bz2 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pbzip2 -dc &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; awk -v &lt;span class=&#34;nv&#34;&gt;dests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;lt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;cat dests.csv &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; paste -s -d, -&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; -f pivot.awk &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; zstd &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;gt; out.csv.zst
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This approach works, but is extremely slow for large matrices (see &lt;a href=&#34;#results&#34;&gt;results&lt;/a&gt;). Let&amp;rsquo;s find something better.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#rust-approach-a-naive&#34;&gt;&lt;h3 id=&#34;rust-approach-a-naive&#34;&gt;Rust approach A (naive)&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to rust-approach-a-naive section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;Given the need for performance, a lower-level language is the obvious next step. Let&amp;rsquo;s try using Rust.&lt;/p&gt;
&lt;p class=&#34;notice&#34;&gt;
I don&#39;t have much experience with compiled languages (most of my work uses Python/R), but I took this as an opportunity to learn something new. I chose Rust because it has great documentation, easy-to-use tooling, and a (seemingly) large community. Also, I was intimidated by the complexity of older languages like C/C++.&lt;br&gt;&lt;br&gt;I have to say, I&#39;m incredibly impressed by Rust. I managed to get a working prototype binary in about 2 hours despite &lt;em&gt;almost no experience with compiled languages&lt;/em&gt;, mostly thanks to the excellent book, linting, and compiler hints. That said, please forgive any code smell; I&#39;m learning (in public) as I go.
&lt;/p&gt;
&lt;p&gt;My naive approach does nearly the same thing as the &lt;code&gt;awk&lt;/code&gt; script. First, it stores the destinations as keys in a dictionary (&lt;code&gt;BTreeMap&lt;/code&gt; in Rust). Then, it takes lines from stdin, populates the dictionary values, and then prints the values to stdout for each origin. The code is a bit more extensive, so I&amp;rsquo;ll link to GitHub rather than showing it here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://gist.github.com/dfsnow/112621a2d9ea6e19876017fb776cf133#file-pivot-rs&#34;&gt;GitHub gist for naive rust code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The resulting binary (named &lt;code&gt;pivot&lt;/code&gt;) is called similarly to the &lt;code&gt;awk&lt;/code&gt; script:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pv in.csv.bz2 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pbzip2 -dc &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; ./pivot dests.csv &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; zstd &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;gt; out.csv.zst
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This approach is nearly 10x faster than the &lt;code&gt;awk&lt;/code&gt; script. However, there are a couple things to improve:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloning a fresh, unpopulated dictionary (only keys, no values) for each origin seems incredibly wasteful, but I&amp;rsquo;m not sure how else to clear the dictionary values.&lt;/li&gt;
&lt;li&gt;All origins and destinations are strings. Making them unsigned integers or similar might be faster.&lt;/li&gt;
&lt;li&gt;Lots of &lt;code&gt;.to_string()&lt;/code&gt; calls which may be unnecessary.&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#rust-approach-b-improved&#34;&gt;&lt;h3 id=&#34;rust-approach-b-improved&#34;&gt;Rust approach B (improved)&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to rust-approach-b-improved section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;Given my relative lack of experience with compiled languages, I figured it might be worthwhile to seek input from various Rust-specific forums. I was a little intimidated at first, but the Rust community turned out to be unreasonably helpful.&lt;/p&gt;
&lt;p&gt;I got dozens of responses, ranging from correcting small syntax issues to literally rewriting my entire project. My favorite response (credit to theiz) had a relatively straightforward approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a vector of all destinations from the separate argument file.&lt;/li&gt;
&lt;li&gt;Allocate a vector of commas with the same length as (1).&lt;/li&gt;
&lt;li&gt;Pre-allocate a big string that can hold all the minute values for a given origin.&lt;/li&gt;
&lt;li&gt;For each line from stdin, push a value into the string from (3) when the destination matches the expected value from (1), else skip and fill with commas from (2).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://gist.github.com/dfsnow/112621a2d9ea6e19876017fb776cf133#file-pivot_fast-rs&#34;&gt;GitHub gist for improved rust code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This approach uses minimal allocations, is 8x faster than the naive approach, and is almost 60x faster than the &lt;code&gt;awk&lt;/code&gt; script. I can&amp;rsquo;t think of many ways to improve it besides multithreading or similar complexity.&lt;/p&gt;
&lt;p&gt;It does have one downside: the input file &lt;em&gt;must&lt;/em&gt; be sorted by origin and destination. If the destinations are not sorted, then the loop will break. The naive approach doesn&amp;rsquo;t have this restriction.&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#results&#34;&gt;&lt;h2 id=&#34;results&#34;&gt;Results&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to results section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;We can measure the speed of each approach using two test files. Each one is sorted (by origin, then destination) and has its unique destinations extracted to a separate file.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;File A&lt;/strong&gt; - &lt;a href=&#34;https://uchicago.box.com/shared/static/kqzt7x8wwnv2qp7fniycwi8m1yrvym93.bz2&#34;&gt;17031-output-TRACT-CAR.csv.bz2&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;13MB compressed, 108M uncompressed&lt;/li&gt;
&lt;li&gt;3.8 million rows (origin-destination pairs)&lt;/li&gt;
&lt;li&gt;1318 unique origins, 2869 unique destinations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File B&lt;/strong&gt; - &lt;a href=&#34;https://uchicago.box.com/shared/static/kmnqdyd4kl99bozykrf8ej0bm7im2mvp.bz2&#34;&gt;06037-output-BLOCK-WALK.csv.bz2&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;1.1GB compressed, 11GB uncompressed&lt;/li&gt;
&lt;li&gt;~300 million rows (origin-destination pairs)&lt;/li&gt;
&lt;li&gt;105,957 unique origins, 115,936 unique destinations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The results shown below are from a 2022 MacBook Air M2 with a 1TB SSD. Speed is measured with &lt;code&gt;pv&lt;/code&gt; and total time with &lt;code&gt;time&lt;/code&gt;. Parallel bzip2 (&lt;code&gt;pbzip2&lt;/code&gt;) is used for decompression, and Z-standard (&lt;code&gt;zstd&lt;/code&gt;) is used for recompression. You can find more long matrix files on the PySAL spatial access &lt;a href=&#34;https://pysal.org/access/resources.html&#34;&gt;resources page&lt;/a&gt;.&lt;/p&gt;
&lt;table style=&#34;width:100%;&#34;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&#34;border:0;&#34;&gt;&lt;/th&gt;
      &lt;th colspan=&#34;1&#34;&gt;File A&lt;/th&gt;
      &lt;th colspan=&#34;2&#34;&gt;File B&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;Method&lt;/th&gt;
      &lt;th&gt;Time (Real)&lt;/th&gt;
      &lt;th&gt;Time (Real)&lt;/th&gt;
      &lt;th&gt;Avg. Speed&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;awk&lt;/td&gt;
      &lt;td&gt;6.45s&lt;/td&gt;
      &lt;td&gt;3h22m8.07s&lt;/td&gt;
      &lt;td&gt;124KiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Rust A (naive)&lt;/td&gt;
      &lt;td&gt;1.86s&lt;/td&gt;
      &lt;td&gt;15m23.42s&lt;/td&gt;
      &lt;td&gt;1.11MiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Rust B (improved)&lt;/td&gt;
      &lt;td&gt;1.24s&lt;/td&gt;
      &lt;td&gt;2m22.02s&lt;/td&gt;
      &lt;td&gt;7.13MiB/s&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Baseline (no pivoting)&lt;/td&gt;
      &lt;td&gt;1.15s&lt;/td&gt;
      &lt;td&gt;0m25.51s&lt;/td&gt;
      &lt;td&gt;40.6MiB/s&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Some thoughts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;awk&lt;/code&gt; is blown out of the water by the two Rust solutions, so it&amp;rsquo;s firmly out of the running for this particular task.&lt;/li&gt;
&lt;li&gt;Rust solution A is nearly as fast as B for smaller files. Considering that it&amp;rsquo;s slightly more robust (doesn&amp;rsquo;t expect sorted destinations), I may use it for matrices smaller than 1GB.&lt;/li&gt;
&lt;li&gt;Rust solution B is the only real option for super large matrices. As far as I can tell it has &lt;code&gt;O(n)&lt;/code&gt; time complexity. I tested it on a 121GB Census block matrix and found only a slight decrease in average speed. Super impressive.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notably, the compressed wide matrix files are typically 30-50% smaller than their long equivalents, depending on sparsity.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#conclusion&#34;&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to conclusion section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;So that&amp;rsquo;s it. Our matrices are pivoted and resaved as &lt;code&gt;.zst&lt;/code&gt; files. They can be loaded into any software that accepts wide matrices or converted to Parquet/ORC (more on that later).&lt;/p&gt;
&lt;p&gt;This was a fun, challenging little project and turned into a great opportunity to learn a new language. I&amp;rsquo;m really happy I chose Rust. It&amp;rsquo;s such a delight to work in, even if I don&amp;rsquo;t yet fully grok it. Feel free to email or comment on the &lt;a href=&#34;https://gist.github.com/dfsnow/112621a2d9ea6e19876017fb776cf133&#34;&gt;gist&lt;/a&gt; if I&amp;rsquo;ve missed any obvious improvements.&lt;/p&gt;
</description>
                <link>https://sno.ws/big-pivot/</link>
                <category domain="recommended">false</category>
                <pubDate>Mon, 28 Nov 2022 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/big-pivot/</guid>
            </item><item>
                <title>Favorite digital things</title>
                <description>&lt;p&gt;This is a list of my favorite digital things, excluding media. It&amp;rsquo;s basically a &lt;a href=&#34;https://indieweb.org/blogroll&#34;&gt;blogroll&lt;/a&gt;, &lt;a href=&#34;https://uses.tech&#34;&gt;&lt;code&gt;/uses&lt;/code&gt;&lt;/a&gt; page, and bookmark dump combined into one. It&amp;rsquo;s purpose is three-fold:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make cool things discoverable for others&lt;/li&gt;
&lt;li&gt;Serve as a personal bookmark page for things I like&lt;/li&gt;
&lt;li&gt;Force me to be intentional about the things I use and read&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This list is constantly updated. When I find a cool new thing, I&amp;rsquo;ll add it. When I lose interest in something, I&amp;rsquo;ll remove it. The history of this page is tracked &lt;a href=&#34;https://github.com/dfsnow/sno.ws/commits/master/content/writing/2021-08-30-favorite-digital-things.md&#34;&gt;via git&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As usual, 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 indicates an &lt;a href=&#34;https://sno.ws/hearts-and-ratings/&#34;&gt;absolute favorite&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#blogs&#34;&gt;&lt;h2 id=&#34;blogs&#34;&gt;Blogs&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to blogs section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;These are the blogs I read regularly. They&amp;rsquo;ve influenced my thinking and helped form who I am today. If they support RSS, I subscribe to them using &lt;a href=&#34;https://freshrss.org&#34;&gt;FreshRSS&lt;/a&gt; and &lt;a href=&#34;https://netnewswire.com&#34;&gt;NetNewsWire&lt;/a&gt;.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#art&#34;&gt;&lt;h3 id=&#34;art&#34;&gt;Art&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to art section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.joelsimon.net/&#34;&gt;Joel Simon&lt;/a&gt; - Beautiful &lt;a href=&#34;https://www.joelsimon.net/corals.html&#34;&gt;generative art&lt;/a&gt; mixed with code&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://larsenhusby.com/2D&#34;&gt;Larsen Husby&lt;/a&gt; - Love me &lt;a href=&#34;https://larsenhusby.com/City-Rivers-River-Cities&#34;&gt;some maps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.mattkeeter.com/projects/&#34;&gt;Matt Keeter&lt;/a&gt; - Weird &lt;a href=&#34;https://www.mattkeeter.com/projects/futureproof/&#34;&gt;shaders&lt;/a&gt;, &lt;a href=&#34;https://www.mattkeeter.com/projects/rayray/&#34;&gt;raytracers&lt;/a&gt;, and &lt;a href=&#34;https://www.mattkeeter.com/projects/pont/&#34;&gt;games&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://paulstamatiou.com&#34;&gt;Paul Stamatiou&lt;/a&gt; - Photography + hands down the &lt;a href=&#34;https://paulstamatiou.com/photos/new-zealand/coromandel-peninsula/&#34;&gt;best travelogues&lt;/a&gt; I&amp;rsquo;ve ever seen&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#general&#34;&gt;&lt;h3 id=&#34;general&#34;&gt;General&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to general section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://ohhelloana.blog&#34;&gt;Ana Rodrigues&lt;/a&gt; - Bookmarks, bookmarks everywhere&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://eveningsends.com/&#34;&gt;Evening Sends&lt;/a&gt; - Rock climbing writing, essays, and opinions&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://francescodilorenzo.com/&#34;&gt;Francesco Di Lorenzo&lt;/a&gt; - Bite-sized posts on life and programming&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://jeremymaluf.com/&#34;&gt;Jeremy Maluf&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Lists for &lt;a href=&#34;https://jeremymaluf.com/onebag/&#34;&gt;onebag packing&lt;/a&gt; and &lt;a href=&#34;https://jeremymaluf.com/walking/&#34;&gt;other stuff&lt;/a&gt;. Inspired this post&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://writing.kemitchell.com/&#34;&gt;Kyle E. Mitchell&lt;/a&gt; - Interesting posts and takes on law ∪ technology&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.paulgraham.com/articles.html&#34;&gt;Paul Graham&lt;/a&gt; - Classic essays on &lt;a href=&#34;http://www.paulgraham.com/ds.html&#34;&gt;tech&lt;/a&gt;, &lt;a href=&#34;http://www.paulgraham.com/talk.html&#34;&gt;life&lt;/a&gt;, and &lt;a href=&#34;http://www.paulgraham.com/start.html&#34;&gt;startups&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.stevencanplan.com/&#34;&gt;Steve Vance&lt;/a&gt; - Urban planning, travelogues, and Chicago thoughts&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://shkspr.mobi/blog/&#34;&gt;Terence Eden&lt;/a&gt; - Life advice, book reviews, and technology. Running for decades&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://terrytao.wordpress.com/career-advice/&#34;&gt;Terry Tao&lt;/a&gt; - Time and career advice from the world&amp;rsquo;s best mathematician&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://macwright.com/&#34;&gt;Tom MacWright&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Spatial data, development, miscellany. Inspired this blog&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#coding-and-tech&#34;&gt;&lt;h3 id=&#34;coding-and-tech&#34;&gt;Coding and tech&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to coding-and-tech section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://btxx.org&#34;&gt;Bradley Taunt&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Small websites and minimal UX&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://cassidoo.co/&#34;&gt;Cassidy Williams&lt;/a&gt; - Huge inspiration, amazing dev/streamer. Excellent &lt;a href=&#34;https://cassidoo.co/newsletter/&#34;&gt;newsletter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://danluu.com/&#34;&gt;Dan Luu&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Classic engineering blog. Mostly on &lt;a href=&#34;https://danluu.com/input-lag/&#34;&gt;measuring&lt;/a&gt; &lt;a href=&#34;https://danluu.com/cli-complexity/&#34;&gt;interesting&lt;/a&gt; &lt;a href=&#34;https://danluu.com/android-updates/&#34;&gt;things&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mcfunley.com/&#34;&gt;Dan McKinley&lt;/a&gt; - Tech talker and creator of many &lt;a href=&#34;http://boringtechnology.club/&#34;&gt;influential&lt;/a&gt; &lt;a href=&#34;https://causalinference.club/&#34;&gt;slide&lt;/a&gt; &lt;a href=&#34;http://frequentdeploys.club/&#34;&gt;decks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://bellard.org/&#34;&gt;Fabrice Bellard&lt;/a&gt; - Open-source hero and creator of ffmpeg. Enough said&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://intuitiveexplanations.com/&#34;&gt;Intuitive Explanations&lt;/a&gt; - Wonderful math explainers for &lt;a href=&#34;https://intuitiveexplanations.com/math/calculus-intuitive-explanations&#34;&gt;calculus&lt;/a&gt; and &lt;a href=&#34;https://intuitiveexplanations.com/math/linear-algebra-summary-sheet&#34;&gt;linear algebra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.joelonsoftware.com/&#34;&gt;Joel On Software&lt;/a&gt; - Classic wide-ranging blog on software, teams, and work&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://josh.works/blog&#34;&gt;Josh Thompson&lt;/a&gt; - Everything from &lt;a href=&#34;https://josh.works/parking-in-golden&#34;&gt;urban parking&lt;/a&gt; to &lt;a href=&#34;https://josh.works/remote-job-resources&#34;&gt;finding a remote job&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://jvns.ca/&#34;&gt;Julia Evans&lt;/a&gt; - &lt;a href=&#34;https://wizardzines.com/&#34;&gt;Zines&lt;/a&gt;, &lt;a href=&#34;https://jvns.ca/blog/2016/09/19/getting-things-done/&#34;&gt;life advice&lt;/a&gt;, and &lt;a href=&#34;https://jvns.ca/blog/2016/06/30/why-do-we-use-the-linux-kernels-tcp-stack/&#34;&gt;technical posts&lt;/a&gt;. Incredible human&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://juliasilge.com/&#34;&gt;Julia Silge&lt;/a&gt; - Tidymodels champion. Neat posts on R and &lt;a href=&#34;https://juliasilge.com/blog/austin-housing/&#34;&gt;predicting home prices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://iamkate.com&#34;&gt;Kate Rose Morley&lt;/a&gt; - Simple games, data viz, and CSS tricks&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://bellmar.medium.com/&#34;&gt;Marianne Bellotti&lt;/a&gt; - Computer science ∪ government ∪ management&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://nickb.dev/archive/&#34;&gt;Nick Babcock&lt;/a&gt; - Lessons on performance + some viz stuff&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tonsky.me/&#34;&gt;Nikita Prokopov&lt;/a&gt; - Creator of &lt;a href=&#34;https://github.com/tonsky/FiraCode&#34;&gt;Fira Code&lt;/a&gt;. Posts on software &lt;a href=&#34;https://tonsky.me/blog/performance-first/&#34;&gt;performance&lt;/a&gt; and &lt;a href=&#34;https://tonsky.me/blog/good-times-weak-men/&#34;&gt;design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.pragmaticengineer.com/&#34;&gt;The Pragmatic Engineer&lt;/a&gt; - Huge collection of useful &lt;a href=&#34;https://blog.pragmaticengineer.com/advice-to-myself-when-starting-as-a-software-developer/&#34;&gt;career&lt;/a&gt; and &lt;a href=&#34;https://blog.pragmaticengineer.com/readable-code/&#34;&gt;programming advice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.sanctum.geek.nz/&#34;&gt;Tom Ryder&lt;/a&gt; - Sys admin stuff and all things Unix, shell, and terminal&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://vickiboykis.com&#34;&gt;Vicki Boykis&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Data science, ML, R stuff, books, and essays&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#spatial&#34;&gt;&lt;h3 id=&#34;spatial&#34;&gt;Spatial&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to spatial section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.katiejolly.io/blog/&#34;&gt;Katie Jolly&lt;/a&gt; - Maps and geography tips for R&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://walker-data.com/blog.html&#34;&gt;Kyle Walker&lt;/a&gt; - Creator of &lt;a href=&#34;https://github.com/walkerke/tidycensus&#34;&gt;tidycensus&lt;/a&gt;, mapper extraordinaire&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.cleverelephant.ca/&#34;&gt;Paul Ramsey&lt;/a&gt; - Weird, weedsy &lt;a href=&#34;https://blog.cleverelephant.ca/2021/05/indexes-and-queries.html&#34;&gt;posts on PostGIS performance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tjukanov.org/&#34;&gt;Topi Tjukanov&lt;/a&gt; - Utterly useless (but beautiful) &lt;a href=&#34;https://tjukanov.org/accessibility-fireworks&#34;&gt;map visualizations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#posts-and-articles&#34;&gt;&lt;h2 id=&#34;posts-and-articles&#34;&gt;Posts and articles&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to posts-and-articles section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;These posts have inspired or influenced me in some way. They&amp;rsquo;re things I reread and share with others. I tend to like concise posts (lists) or posts that graphically explain something complicated.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#chicago&#34;&gt;&lt;h3 id=&#34;chicago&#34;&gt;Chicago&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to chicago section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://chicagoflaneur.com/2020/04/24/portrait-of-chicago-uptown/&#34;&gt;Portrait of Chicago: Uptown&lt;/a&gt; - History of Uptown. A little dated, but still well-done&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://newrepublic.com/article/161808/ewing-annex-hotel-housing-crisis-chicago&#34;&gt;Scenes from Chicago&amp;rsquo;s Ewing Annex Hotel&lt;/a&gt; - Stories from one the last &lt;a href=&#34;https://en.wikipedia.org/wiki/Single_room_occupancy&#34;&gt;SROs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://uchicagossecretplaces.wordpress.com/&#34;&gt;UChicago&amp;rsquo;s Secret Places&lt;/a&gt; - Cool photos and &lt;a href=&#34;https://en.wikipedia.org/wiki/Urban_exploration&#34;&gt;urbex&lt;/a&gt; on the UChicago campus&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#life&#34;&gt;&lt;h3 id=&#34;life&#34;&gt;Life&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to life section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.lesswrong.com/posts/7hFeMWC6Y5eaSixbD/100-tips-for-a-better-life&#34;&gt;100 Tips for a Better Life&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Things I wish I&amp;rsquo;d known at 20&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://training.kalzumeus.com/newsletters/archive/do-not-end-the-week-with-nothing&#34;&gt;Don&amp;rsquo;t End the Week With Nothing&lt;/a&gt; - Make things you can show&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://govleaders.org/rickover.htm&#34;&gt;Doing a Job&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 The best thing ever written on how to work and lead&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://jacobian.org/2021/apr/7/embrace-the-grind/&#34;&gt;Embrace the Grind&lt;/a&gt; - Sometimes you just have to do the boring stuff&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jefftk.com/p/focus&#34;&gt;Focus&lt;/a&gt; - Precisely describes my situation re: maintaining and cultivating focus&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://how.complexsystems.fail/&#34;&gt;How Complex Systems Fail&lt;/a&gt; - Short, prescient read on why things break&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://donellameadows.org/archives/leverage-points-places-to-intervene-in-a-system/&#34;&gt;Leverage Points: Places to Intervene in a System&lt;/a&gt; - How to make things break&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://matt.might.net/articles/phd-school-in-pictures/&#34;&gt;The Illustrated Guide to a Ph.D.&lt;/a&gt; - Visual perspective on what a Ph.D. really means&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.nashvail.me/blog/stop-learning/&#34;&gt;Stop Learning&lt;/a&gt; - You know enough, start doing things&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://terrytao.wordpress.com/career-advice/work-hard/&#34;&gt;Work Hard&lt;/a&gt; - After a certain level, there are no shortcuts for effort&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#coding-and-tech-2&#34;&gt;&lt;h3 id=&#34;coding-and-tech-2&#34;&gt;Coding and tech&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to coding-and-tech-2 section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://bellmar.medium.com/all-the-best-engineering-advice-i-stole-from-non-technical-people-eb7f90ca2f5f&#34;&gt;All the Best Engineering Advice I Stole From Non-Technical People&lt;/a&gt; - Big wisdom&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mcfunley.com/choose-boring-technology&#34;&gt;Choose Boring Technology&lt;/a&gt; - Stop reinventing ssh and grasping for shiny things&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://old.reddit.com/r/ExperiencedDevs/comments/nmodyl/drunk_post_things_ive_learned_as_a_sr_engineer/&#34;&gt;Drunk Post: Things I&amp;rsquo;ve learned as a Sr Engineer&lt;/a&gt; - Strong opinions, mostly true&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.zainrizvi.io/blog/the-interviewing-advice-no-one-shares/&#34;&gt;FAANG Interview Advice&lt;/a&gt; - Good general interview advice, not just for FAANG&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://craigmod.com/essays/fast_software/&#34;&gt;Fast Software, the Best Software&lt;/a&gt; - Speed &amp;gt; lots of features&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://interconnected.org/home/2022/10/10/servers&#34;&gt;I Wish My Web Server Were in the Corner of My Room&lt;/a&gt; - Mix virtual and physical&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://anthonynsimon.com/blog/one-man-saas-architecture/&#34;&gt;The Infrastructure of a One-Man SaaS&lt;/a&gt; - Load balancing and AWS and K8s&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.unixwiz.net/techtips/iguide-kaminsky-dns-vuln.html&#34;&gt;Kaminsky DNS Vulnerability&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 The most engaging thing ever written on DNS&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://vickiboykis.com/2021/08/05/the-local-minima-of-suckiness/&#34;&gt;The Local Minima of Suckiness&lt;/a&gt; - How I think about teaching and learning coding&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://den.dev/blog/user-hostile-software/&#34;&gt;The Rise of User-Hostile Software&lt;/a&gt; - Software now is better for devs, worse for users&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1006023&#34;&gt;Teaching Programming&lt;/a&gt; - Extremely helpful tips for teaching a class how to code&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.thea.codes/winterblooms-tech-stack/&#34;&gt;The Tech Stack of a One-Woman Hardware Company&lt;/a&gt; - Microcontrollers and C&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://chriskiehl.com/article/thoughts-after-6-years&#34;&gt;Thoughts After 6 Years&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Short post on lessons learned. Inspired &lt;a href=&#34;https://sno.ws/local-gov/&#34;&gt;my post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://idlewords.com/talks/website_obesity.htm&#34;&gt;The Website Obesity Crisis&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Why does reddit load 15 MB on every page&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://orlp.net/blog/worlds-smallest-hash-table/&#34;&gt;The World&amp;rsquo;s Smallest Hash Table&lt;/a&gt; - Optimizing code beyond all reason&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.bti360.com/what-ive-learned-in-45-years-in-the-software-industry/&#34;&gt;What I&amp;rsquo;ve Learned in 45 Years in the Software Industry&lt;/a&gt; - People &amp;gt; technology&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#data&#34;&gt;&lt;h3 id=&#34;data&#34;&gt;Data&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to data section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://erikbern.com/2021/07/07/the-data-team-a-short-story.html&#34;&gt;Building a Data Team at a Mid-Stage Startup&lt;/a&gt; - The DS experience, a short story&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://adamdrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html&#34;&gt;CLI Tools Can Be 235x Faster Than Your Hadoop Cluster&lt;/a&gt; - &lt;code&gt;awk&lt;/code&gt; &amp;gt; &lt;code&gt;hadoop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://vickiboykis.com/2019/02/13/data-science-is-different-now/&#34;&gt;Data Science Is Different Now&lt;/a&gt; - DS has a supply bubble and schools aren&amp;rsquo;t helping&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://multithreaded.stitchfix.com/blog/2016/03/16/engineers-shouldnt-write-etl/&#34;&gt;Engineers Shouldn&amp;rsquo;t Write ETL&lt;/a&gt; - They should write tools and platforms&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ianwhitestone.work/good-ds-bad-ds/&#34;&gt;Good Data Scientist, Bad Data Scientist&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 What makes a great DS anyways?&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.getdbt.com/future-of-the-modern-data-stack/&#34;&gt;The Modern Data Stack&lt;/a&gt; - Where things are and where they&amp;rsquo;re going&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#visualization&#34;&gt;&lt;h3 id=&#34;visualization&#34;&gt;Visualization&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to visualization section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.refactoringui.com/previews/building-your-color-palette&#34;&gt;Building Your Color Palette&lt;/a&gt; - Systemic approach for picking colors for UIs&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://alpercinar.com/open-cell-id/&#34;&gt;Cell Tower Distribution&lt;/a&gt; - Beautiful post on cell tower data viz&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mzucker.github.io/2016/09/20/noteshrink.html&#34;&gt;Compressing and Enhancing Hand-Written Notes&lt;/a&gt; - Shrink those scans&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://surma.dev/things/ditherpunk/&#34;&gt;Ditherpunk&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Monochrome image dithering and how it works&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ciechanow.ski/mechanical-watch/&#34;&gt;Mechanical Watch&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 One of the most technically and visually impressive treatments of a complex topic I&amp;rsquo;ve ever seen&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#math&#34;&gt;&lt;h3 id=&#34;math&#34;&gt;Math&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to math section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.incompleteideas.net/IncIdeas/BitterLesson.html&#34;&gt;The Bitter Lesson&lt;/a&gt; - Computation power and general methods &amp;gt; complex methods&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.stat.columbia.edu/~gelman/research/unpublished/stat50.pdf&#34;&gt;The Most Important Statistical Ideas of the Past 50 Years&lt;/a&gt; - Stats summary&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://web.njit.edu/~akansu/PAPERS/The%20Unreasonable%20Effectiveness%20of%20Mathematics%20(EP%20Wigner).pdf&#34;&gt;The Unreasonable Effectiveness of Mathematics&lt;/a&gt; - Plus &lt;a href=&#34;https://ned.ipac.caltech.edu/level5/March02/Hamming/Hamming.html&#34;&gt;Hamming&amp;rsquo;s response&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#other&#34;&gt;&lt;h3 id=&#34;other&#34;&gt;Other&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to other section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.nytimes.com/2021/01/09/magazine/trump-coup.html&#34;&gt;The American Abyss&lt;/a&gt; - Long political essay on Jan. 6th and how we got there&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://psyche.co/guides/how-to-gain-more-from-reading-by-taking-it-all-in-more-slowly&#34;&gt;How to Gain More From Your Reading&lt;/a&gt; - Tips for attentive, intentional reading&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://qntm.org/mmacevedo&#34;&gt;MMAcevedo&lt;/a&gt; - Horrifying short fiction on the perils of saving a brain&amp;rsquo;s state&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.newyorker.com/magazine/2021/01/04/the-plague-year&#34;&gt;The Plague Year&lt;/a&gt; - Summary of the institutional failures that made COVID so bad&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://jvns.ca/blog/2023/06/05/some-blogging-myths/&#34;&gt;Some Blogging Myths&lt;/a&gt; - The most motivating post on blogging I&amp;rsquo;ve ever found&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jofreeman.com/joreen/tyranny.htm&#34;&gt;The Tyranny of Structurelessness&lt;/a&gt; - All groups develop informal structure&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://evaparish.com/blog/how-i-edit&#34;&gt;What I Think About When I Edit&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Sound and simple writing advice&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://eveningsends.com/climbing-shoes-tight/&#34;&gt;Your Climbing Shoes Are Too Tight&lt;/a&gt; - Treat your feet right, don&amp;rsquo;t size down&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://danluu.com/cocktail-ideas/&#34;&gt;Cocktail Party Ideas&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Basically a long-form of this &lt;a href=&#34;https://xkcd.com/1831/&#34;&gt;xkcd&lt;/a&gt;. I think about this post all the time and try to remember to stay humble about the limits of my own knowledge&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#software&#34;&gt;&lt;h2 id=&#34;software&#34;&gt;Software&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to software section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;These are the things I use every day. It&amp;rsquo;s a list whittled down over about 5 years. It&amp;rsquo;s not exhaustive, but it&amp;rsquo;s pretty close; I still use other stuff like Word and Teams.&lt;/p&gt;
&lt;p&gt;I have a strong preference for software that is fast, outwardly simple, and that does one thing extremely well.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#mobile&#34;&gt;&lt;h3 id=&#34;mobile&#34;&gt;Mobile&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to mobile section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ALL&lt;/code&gt; - &lt;a href=&#34;https://bitwarden.com/&#34;&gt;Bitwarden&lt;/a&gt; - Open-source password manager. Great CLI integration&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iOS&lt;/code&gt; - &lt;a href=&#34;https://apps.apple.com/us/app/brew-timer-coffee-recipes/id1082171596&#34;&gt;Brew Timer&lt;/a&gt; - Coffee brewing timer for V60 and Aeropress&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALL&lt;/code&gt; - &lt;a href=&#34;https://www.downdogapp.com/&#34;&gt;Down Dog&lt;/a&gt; - Procedurally-generated at-home yoga and HIIT&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AND&lt;/code&gt; - &lt;a href=&#34;https://loophabits.org&#34;&gt;Loop Habit Tracker&lt;/a&gt; - Minimal, yet feature-rich and flexible habit tracker&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALL&lt;/code&gt; - &lt;a href=&#34;https://www.mountainproject.com&#34;&gt;Mountain Project&lt;/a&gt; - Find crags and track climbs, works offline&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iOS&lt;/code&gt; - &lt;a href=&#34;https://netnewswire.com&#34;&gt;NetNewsWire&lt;/a&gt; - Tiny, simple, open-source RSS reader. Also on Mac&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AND&lt;/code&gt; - &lt;a href=&#34;https://play.google.com/store/apps/details?id=bitpit.launcher&#34;&gt;Niagara Launcher&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Minimalist, fast, well-designed launcher&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALL&lt;/code&gt; - &lt;a href=&#34;https://todoist.com/&#34;&gt;Todoist&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 To-do list I&amp;rsquo;ve used for over a decade. Simple design, great UX&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iOS&lt;/code&gt; - &lt;a href=&#34;http://www.workoutdoors.net/&#34;&gt;WorkOutDoors&lt;/a&gt; - Offline maps for Apple Watch. Great for hiking and biking&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALL&lt;/code&gt; - &lt;a href=&#34;https://www.youneedabudget.com/&#34;&gt;YNAB&lt;/a&gt; - Straightforward budgeting with bank and brokerage integration&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#desktop&#34;&gt;&lt;h3 id=&#34;desktop&#34;&gt;Desktop&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to desktop section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MAC&lt;/code&gt; - &lt;a href=&#34;https://github.com/iina/iina&#34;&gt;IINA&lt;/a&gt; - Minimal Mac-only alternative to VLC&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MAC&lt;/code&gt; - &lt;a href=&#34;https://www.obdev.at/products/littlesnitch/index.html&#34;&gt;Little Snitch&lt;/a&gt; - Decide how apps talk to the internet. Must-have for any Mac&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALL&lt;/code&gt; - &lt;a href=&#34;https://obsidian.md&#34;&gt;Obsidian&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Fast notes. Free, works everywhere, plain markdown&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MAC&lt;/code&gt; - &lt;a href=&#34;https://highlyopinionated.co/swish/&#34;&gt;Swish&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Resize and move windows with super intuitive gestures&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MAC&lt;/code&gt; - &lt;a href=&#34;https://panic.com/transmit/&#34;&gt;Transmit&lt;/a&gt; - Fast, versatile file transfer utility&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALL&lt;/code&gt; - &lt;a href=&#34;https://positron.posit.co/&#34;&gt;Positron&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 VS Code fork specifically for data science&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WIN&lt;/code&gt; - &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/install-win10&#34;&gt;Terminal + WSL 2&lt;/a&gt; - Linux virtualization on Windows that just works&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#other-2&#34;&gt;&lt;h3 id=&#34;other-2&#34;&gt;Other&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to other-2 section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://freshrss.org&#34;&gt;FreshRSS&lt;/a&gt; - Free, self-hosted RSS feed aggregator. Lightweight, fast, and simple&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jetbrains.com/lp/mono/&#34;&gt;JetBrains Mono&lt;/a&gt; - Monospaced font with ligatures. Works in nearly every editor&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://parquet.apache.org/&#34;&gt;Parquet&lt;/a&gt; - Fast, space-efficient columnar storage format&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/&#34;&gt;Postgres&lt;/a&gt; - Preferred RDBMS for any big project with structured data&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://postgis.net/&#34;&gt;PostGIS&lt;/a&gt; - Spatial data extension for Postgres&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.sqlite.org/index.html&#34;&gt;SQLite&lt;/a&gt; - The go-to DB engine for any small project that requires SQL&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.wireguard.com/&#34;&gt;WireGuard&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Miracle VPN. Crazy fast and easy-to-use&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://zfsonlinux.org/&#34;&gt;ZFS&lt;/a&gt; - Filesystem for storage pooling and management&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#cli-tools&#34;&gt;&lt;h3 id=&#34;cli-tools&#34;&gt;CLI tools&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to cli-tools section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://ffmpeg.org/&#34;&gt;ffmpeg&lt;/a&gt; - Multimedia toolkit for just about everything&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/junegunn/fzf&#34;&gt;fzf&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Blazingly fast fuzzy finding. Why &lt;code&gt;cd&lt;/code&gt; when you can &lt;code&gt;Alt-C&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/&#34;&gt;hugo&lt;/a&gt; - Simple, self-contained static site builder. Used to make this site&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/neovim/neovim&#34;&gt;neovim&lt;/a&gt; - Text editor of choice. &lt;a href=&#34;https://github.com/dfsnow/dotfiles&#34;&gt;Config&lt;/a&gt; and plugins also work with vim&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/BurntSushi/ripgrep&#34;&gt;ripgrep&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 &lt;code&gt;grep&lt;/code&gt; but better. Search every file in a directory in milliseconds&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gnu.org/software/stow/manual/stow.html&#34;&gt;stow&lt;/a&gt; - Symlink, config, and dotfiles management&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/tmux/tmux&#34;&gt;tmux&lt;/a&gt; - Terminal multiplexer + keep remote terminal sessions alive&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.astral.sh/uv/&#34;&gt;uv&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Python project management. &lt;code&gt;pip&lt;/code&gt; but 100x better/faster&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/facebook/zstd&#34;&gt;zstd&lt;/a&gt; - Compression algorithm of choice. Replaced bzip2 as a favorite&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#r-packages&#34;&gt;&lt;h3 id=&#34;r-packages&#34;&gt;R packages&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to r-packages section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Rdatatable/data.table&#34;&gt;data.table&lt;/a&gt; - 
&lt;svg aria-label=&#39;Favorite&#39; role=&#34;img&#34; viewBox=&#34;0 0 32 32&#34;
    style=&#34;fill:var(--heart-color);width:0.75em;height:0.75em;&#34;&gt;
    &lt;title&gt;Favorite&lt;/title&gt;
    &lt;path d=&#34;M4 16c-3-4-2-10 3-12 5-2 8 2 9 4 1-2 5-6 10-4 5 2 5 8 2 12-3 4-12 12-12 12 0 0-9-8-12-12z&#34; /&gt;
&lt;/svg&gt;
 Impossible data manipulation magic. Faster than everything else&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dplyr.tidyverse.org/&#34;&gt;dplyr&lt;/a&gt; - Clear, intuitive data munging that plays well with other Tidyverse libraries&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://lubridate.tidyverse.org/&#34;&gt;lubridate&lt;/a&gt; - Intuitive, consistent date-time handling. Save yourself from footguns&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ggplot2.tidyverse.org/&#34;&gt;ggplot2&lt;/a&gt; - &lt;em&gt;The&lt;/em&gt; plotting lib for R. Blows matplotlib (and many others) out of the water&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ipeaGIT/r5r&#34;&gt;r5r&lt;/a&gt; - Robust, realistic transportation routing using &lt;a href=&#34;https://github.com/conveyal/r5&#34;&gt;Conveyal&amp;rsquo;s R5 engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://rstudio.github.io/renv/&#34;&gt;renv&lt;/a&gt; - Wonderful environment/package manager for R (finally)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://r-spatial.github.io/sf/&#34;&gt;sf&lt;/a&gt; - Geospatial manipulation, maps, and geometry features&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://walker-data.com/tidycensus/&#34;&gt;tidycensus&lt;/a&gt; - Useful interface for the Census API&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/r-transit/tidytransit&#34;&gt;tidytransit&lt;/a&gt; - GTFS feed reader. Make &lt;a href=&#34;https://sno.ws/transit-maps/&#34;&gt;trains go brrr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Last updated 2026-02-01&lt;/em&gt;&lt;/p&gt;
</description>
                <link>https://sno.ws/digital-things/</link>
                <category domain="recommended">false</category>
                <pubDate>Mon, 30 Aug 2021 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/digital-things/</guid>
            </item><item>
                <title>Lessons learned in local government</title>
                <description>&lt;p&gt;I&amp;rsquo;ve been working as a data scientist in local government for around a year and a half now. Not long, but long enough to learn some things and update a few of my opinions.&lt;/p&gt;
&lt;p&gt;None of these lessons are specific to my organization or role. Friends in other agencies confirm they generalize well to most positions at the intersection of data and local government.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m sharing these lessons with two goals:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;To help myself remember them and to keep a running log of what I&amp;rsquo;ve learned.&lt;/li&gt;
&lt;li&gt;To (hopefully) help other people avoid the same painful mistakes.&lt;/li&gt;
&lt;/ol&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#things-ive-learned&#34;&gt;&lt;h2 id=&#34;things-ive-learned&#34;&gt;Things I&amp;rsquo;ve learned&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to things-ive-learned section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Local government is incredibly risk averse and therefore difficult to change.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On the elected side, there&amp;rsquo;s an information problem. Voters are more likely to notice (and thus punish) bad outcomes, while good outcomes are often overlooked by both media and voters. This reduces the incentive to change the status quo (high risk, low potential reward) and turns policy into a communications problem.&lt;/li&gt;
&lt;li&gt;On the career side, there&amp;rsquo;s an incentives problem. Most career local government employees value stability. They may not prefer the status quo, but they know that shaking things up is riskier than doing nothing. They&amp;rsquo;re also unlikely to be rewarded for status quo improvements or additional effort (due to pay schedules and a slow promotion process).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Big technology changes in local government usually happen through contracting.&lt;/strong&gt; This is because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Elected and appointed employees use contracting as a way to mitigate personal risk.&lt;/li&gt;
&lt;li&gt;Contracting helps ensure the start/survival/continuity of status-quo-changing projects.&lt;/li&gt;
&lt;li&gt;Most local governments lack the technical capacity/talent to do major tech overhauls in-house.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Small things take a &lt;em&gt;long&lt;/em&gt; time if they haven&amp;rsquo;t been done before.&lt;/strong&gt; New tasks require new processes. New processes require delegation of responsibility, updated budgets, and lots of communication. All of this is very slow. It once took me around 7 months to get a VM approved and spun up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Attention causes change.&lt;/strong&gt; Most local government bodies (besides cities and police departments) receive little to no public attention. As a result, they tend to be fairly responsive when they &lt;em&gt;do&lt;/em&gt; receive attention, positive (helping an organization improve, providing feedback) or negative (vocal criticism, the threat of media scrutiny).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The boring stuff often matters the most.&lt;/strong&gt; Most people aren&amp;rsquo;t affected by the sexy, hot-button social or cultural issues covered by national media. Conversely, local things like taxes, zoning, housing, and garbage pickup have a profound impact on people&amp;rsquo;s everyday lives.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Local government data is worse than you think.&lt;/strong&gt; The systems for storing most local government data are antiquated, messy, and often have decades worth of various kludges. Government&amp;rsquo;s main advantage when collecting data is the ability to mandate compliance by law (usually from businesses).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Job satisfaction comes from impact. Impact comes from leverage.&lt;/strong&gt; Leverage is built through rapport with others, ownership of projects/processes relevant to the organization&amp;rsquo;s mission, and trust that you can implement/get things done.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#things-ive-changed-my-mind-about&#34;&gt;&lt;h2 id=&#34;things-ive-changed-my-mind-about&#34;&gt;Things I&amp;rsquo;ve changed my mind about&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to things-ive-changed-my-mind-about section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;People skills are just as important as technical skills.&lt;/strong&gt; I wish I could go back and slap myself in the face with this knowledge. Unlike at a cool startup or some FAANG company, you &lt;em&gt;will not&lt;/em&gt; be recognized in local government for your PhD-level knowledge of the latest ML techniques.&lt;/p&gt;
&lt;p&gt;Day-to-day stuff in local government gets done through collaboration and clear communication with lots of different stakeholders. That means the understandability of your work is more important than the purity of your code. The success of a project is dependent on your leverage and how well you explain the project&amp;rsquo;s utility to people above you.&lt;/p&gt;
&lt;p&gt;If you really want to do technical work in government without dealing with people, find a manager who understands the value of your technical skills and will boost/cover/hype for you.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Legacy systems aren&amp;rsquo;t necessarily bad.&lt;/strong&gt; They can be crazy fast and also very good at the specific thing they were designed for. The issues start when new requirements pop up and you need to shoehorn some horrible new process into your 1980s mainframe.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Domain knowledge is vital, especially for data people.&lt;/strong&gt; Career employees may not be able to build a cutting-edge ML model, but they probably have more knowledge about the data and its constraints than you ever will. Go talk to them, in-person if possible. If you don&amp;rsquo;t, you might spend a year thinking that &lt;code&gt;APTS = 5&lt;/code&gt; means five apartments, rather than six apartments (5 is the categorical encoding for the numeric value 6).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Management skills are incredibly valuable.&lt;/strong&gt; I entered government thinking of managers as less valuable than technical employees. I was wrong. So much local government work is about people, processes, and dealing with stakeholders; a manager can really make (or break) a small organization or department. Unfortunately, one of local government&amp;rsquo;s biggest problems is a lack of good managers (on all levels).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Old technology is good actually.&lt;/strong&gt; By &amp;ldquo;old&amp;rdquo; here I mean tech that&amp;rsquo;s 5-10 years old i.e. not brand new. Such technology is usually super stable, well-performing, and well-documented. Chasing the newest stack is for startup folks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The simplest possible solution is the best solution.&lt;/strong&gt; Someone after you will have to maintain your code. Moreover, if you&amp;rsquo;re producing public-facing work, it should be simple for the sake of transparency. Remove complexity (and technologies) whenever possible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Decision makers (rightly) do not care about the technical details.&lt;/strong&gt; This was a tough lesson. Decision-makers care about options, their implications, and their potential risks. They do not care about how a boosted tree model works.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#opinions-that-havent-changed&#34;&gt;&lt;h2 id=&#34;opinions-that-havent-changed&#34;&gt;Opinions that haven&amp;rsquo;t changed&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to opinions-that-havent-changed section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Avoid vendor lock-in, prefer open-source.&lt;/strong&gt; Local governments tend to prefer SaaS tools. They offload support costs to a third-party and (arguably) require less technical, less independent users. However, with the right team, open-source can be more transparent, cheaper, and can help build connections to the wider developer community. On a related note, open-source GIS tools &amp;gt; ESRI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The potential impact of a motivated, smart person is extremely high.&lt;/strong&gt; Local government is bereft of competent data people despite being awash in data and data-related problems. A sufficiently motivated person can accomplish &lt;em&gt;a lot&lt;/em&gt; in local government even with an average data science skill set. The first (and hardest) step is to find a team with the leverage and mandate to create change.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
                <link>https://sno.ws/local-gov/</link>
                <category domain="recommended">true</category>
                <pubDate>Mon, 24 May 2021 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/local-gov/</guid>
            </item><item>
                <title>Creating moving transit maps with R and GTFS feeds</title>
                <description>&lt;style media=&#34;screen&#34;&gt;
  :root { --add-media-width: 80px }
  .content .video-holder {
    margin: 2rem auto;
  }
&lt;/style&gt;
&lt;h4&gt;
&lt;a href=&#34;https://gist.github.com/dfsnow/6cef8184ed0dbccadc0cd56a0d22b8be&#34;&gt;GitHub gist for source code&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;ve been on a bit of a transit kick this month. I read &lt;a href=&#34;https://humantransit.org/&#34;&gt;Human Transit&lt;/a&gt; (the blog and the book) and have been playing a lot of &lt;a href=&#34;https://dinopoloclub.com/games/mini-metro/&#34;&gt;Mini Metro&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve also been playing around with &lt;a href=&#34;https://gtfs.org/&#34;&gt;GTFS feeds&lt;/a&gt;, which are a standardized data format for public transit systems. They provide schedules, stop locations, route shapes, and more.&lt;/p&gt;
&lt;p&gt;I wanted to see if I could take a GTFS feed and turn it into an animated map in the style of Mini Metro (I love its aesthetic). Turns out it&amp;rsquo;s actually pretty easy.&lt;/p&gt;


&lt;div class=&#34;video-holder&#34;&gt;
    &lt;video autoplay loop muted playsinline&gt;
        &lt;source src=&#39;https://content.sno.ws/videos/2021-03-03-chicago-gtfs.mp4&#39; type=&#34;video/mp4&#34;&gt;
        &lt;source src=&#39;https://content.sno.ws/videos/2021-03-03-chicago-gtfs.webm&#39; type=&#34;video/webm&#34;&gt;
        Your browser does not support the video tag.
    &lt;/video&gt;
&lt;/div&gt;



&lt;div class=&#34;video-holder&#34;&gt;
    &lt;video autoplay loop muted playsinline&gt;
        &lt;source src=&#39;https://content.sno.ws/videos/2021-03-03-dc-gtfs.mp4&#39; type=&#34;video/mp4&#34;&gt;
        &lt;source src=&#39;https://content.sno.ws/videos/2021-03-03-dc-gtfs.webm&#39; type=&#34;video/webm&#34;&gt;
        Your browser does not support the video tag.
    &lt;/video&gt;
&lt;/div&gt;

&lt;p&gt;These maps are made using &lt;a href=&#34;https://cloud.r-project.org/&#34;&gt;R&lt;/a&gt; and &lt;a href=&#34;https://ggplot2.tidyverse.org/&#34;&gt;ggplot2&lt;/a&gt;. Each frame of animation is a separate plot combined using &lt;a href=&#34;https://ffmpeg.org/&#34;&gt;ffmpeg&lt;/a&gt;. There are probably better/faster ways to animate besides rendering each frame, but this way is easy and flexible.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#walkthrough&#34;&gt;&lt;h2 id=&#34;walkthrough&#34;&gt;Walkthrough&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to walkthrough section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;You can find the code to make these maps at the GitHub gist at the top of the page. It only works for single feeds (so no New York, which has many separate feeds) and only for trains, though it could be easily adapted to other route types.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s relatively simple code, so rather than explain it step-by-step, I&amp;rsquo;ll walkthrough the general process of creating a map. Anything in &lt;code&gt;snake_case&lt;/code&gt; refers to an object in the code.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#create-the-data&#34;&gt;&lt;h3 id=&#34;create-the-data&#34;&gt;Create the data&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to create-the-data section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;First, we need to download a GTFS feed and convert it into a format useable in R. The map needs three data sets to work:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A spatial data frame of stop locations (&lt;code&gt;stop_shapes&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A spatial data frame of track shapes (&lt;code&gt;route_shapes&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A data frame of the point location of all trains at any time within the specified window (&lt;code&gt;final_df&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;100%&#34; height=&#34;100%&#34; viewBox=&#34;0 0 1277 634&#34; preserveAspectRatio=&#34;none&#34;&gt;
  &lt;style&gt;
    @media (prefers-color-scheme:dark) {
      .bb {fill: #fff}
    }
  &lt;/style&gt;
  &lt;path class=&#34;bb&#34; fill-rule=&#34;evenodd&#34; d=&#34;M840.25 53.99c3.16.01 7.21.6 9 1.33 1.79.72 4.26 2.75 5.5 4.5 1.3 1.83 2.25 4.66 2.25 6.68 0 1.92-.53 4.74-1.19 6.25-.65 1.51-2.68 4.33-7.83 9.75l3.03 3c2.43 2.4 3.01 3.8 2.94 7-.06 2.2-.68 5.58-1.38 7.5s-2.36 4.28-3.67 5.24c-1.44 1.04-5.2 1.98-16.4 2.96l-7-7.46 3 .73c1.65.4 5.02.94 7.5 1.2s5.74 0 7.25-.59c1.74-.68 3.48-2.64 4.73-5.33 1.09-2.34 1.99-5.26 2-6.5s-.54-2.59-1.23-3-4.85-.97-9.25-1.25c-6.16-.39-8-.84-8-1.98 0-.81 1.13-1.77 2.5-2.15 1.38-.37 4.51-1.28 6.97-2.02 3.18-.96 5.14-2.36 6.8-4.85 1.28-1.92 2.87-5.17 3.53-7.22.99-3.08.94-4.16-.3-6.26-.99-1.68-1.82-2.2-2.45-1.53-.52.55-2.77 1.01-5 1.01s-5.4.41-7.05.9c-1.65.5-3.5.61-4.12.25-.61-.36-1.4-1.66-1.75-2.9-.46-1.66-.04-2.64 1.62-3.76 1.36-.91 4.53-1.5 8-1.5zM427 75.03c.82-.06 2.8.93 4.38 2.19 2.71 2.14 2.84 2.59 2.19 7.28-.38 2.75-1.95 7.25-3.49 10-1.55 2.75-4.68 7.92-6.97 11.5s-4.15 6.72-4.13 7 4.87-.07 10.78-.76 10.97-1.02 11.24-.73c.27.3-.18 1.21-1 2.04-.89.9-6.35 2.26-13.5 3.37l-14.75 2.47c-2.05.45-2.75.23-2.75-.89 0-.83 3-4.99 6.66-9.25 3.67-4.26 7.48-9.55 8.48-11.75s1.83-6.14 1.84-8.75-.21-5.42-.48-6.25-1.18-1.5-2-1.5-4.65 2.03-8.5 4.5-7.45 4.5-8 4.5-1.01-.34-1.02-.75 1.22-1.92 2.75-3.35c1.52-1.43 4.79-3.98 7.27-5.66 2.48-1.69 5.63-3.53 7-4.09 1.38-.56 3.18-1.07 4-1.12zM44.11 88l-.31 15.14c-.18 9.04.1 15.68.7 16.47.55.73 2.69 2.01 4.75 2.86 2.06.84 3.75 2.09 3.76 2.78 0 .84-3.5 1.67-10.75 2.54L29 129.29c-1.93.16-2.56-.31-2.75-2.04-.2-1.76.46-2.47 3-3.27 1.79-.56 4.26-1.01 5.5-1s2.94-.99 3.79-2.23c1.2-1.75 1.47-4.6 1.25-12.92-.16-5.87-.63-10.93-1.04-11.25s-2.21-.13-4 .41c-1.79.55-3.37.89-3.51.75-.15-.13 1.58-2.38 3.83-4.99C37.9 89.47 39.92 88 44.11 88zm820.87 18c2.21 0 4.19.36 4.4.79.2.44-.47 2.69-1.5 5-1.04 2.32-2.55 4.21-3.38 4.21s-2.2-1.69-3.06-3.75-1.33-4.31-1.03-5c.3-.7 2.3-1.25 4.57-1.25zM454 113.02c.27.01 1.18.44 2 .97 1.17.74 1.25 1.35.38 2.73-.62.98-2.28 2.68-3.7 3.78-2.31 1.78-2.76 1.84-4.18.5-.87-.83-1.63-2.07-1.68-2.76-.05-.7 1.44-2.16 3.3-3.25s3.61-1.98 3.88-1.97zm505.75 1.07c.69-.05 2.04.33 3 .84s2.65 1.21 3.75 1.57c1.87.61 1.81.81-1 3.26-2.37 2.07-3.06 3.57-3.31 7.18-.17 2.51-.51 5.57-.75 6.81-.31 1.61-1.51 2.53-4.19 3.24-2.06.55-4.76 1-6 1-1.24.01-2.24-.55-2.22-1.24.01-.69 1.36-3.39 5.97-10.75l-3-2.5c-1.65-1.37-3-3.17-3-4s1.01-2.02 2.25-2.66a33.41 33.41 0 0 1 4.75-1.91c1.38-.42 3.06-.8 3.75-.84zm-4.87 6.41c.74.67 1.92.51 3.64-.5 1.39-.83 2.52-1.84 2.51-2.25-.02-.41-1.36-.75-2.98-.75s-3.25.56-3.61 1.25-.16 1.7.44 2.25zm70.12-6.39c1.92-.05 4.17.32 5 .81 1.3.77 1.22 1.34-2.68 7.58l2.34 1.75c1.29.96 2.34 2.65 2.34 3.75s-.45 2.22-1 2.5-1 1.63-1 3c0 1.38-1.01 3.41-2.25 4.52-1.3 1.17-3.63 2.01-5.5 2-1.79-.01-3.25-.47-3.25-1.02s1.13-1.22 2.5-1.5c1.8-.36 2.92-1.62 4-4.5.83-2.2 1.5-4.22 1.5-4.5s-2.36-.48-10.5-.41l3.75-4.54c2.06-2.5 3.75-4.77 3.75-5.05s-2.25-.5-5-.5c-3.09 0-4.73-.37-4.29-.98.39-.55 2.08-1.4 3.75-1.91s4.62-.96 6.54-1zm-103.12 3.96c1.44 1.05 3.29 2.47 4.12 3.16.83.7 2.06 2.06 2.75 3.02 1.01 1.41.95 3.05-.28 8.5-1.41 6.21-1.83 6.9-5.25 8.58-2.05 1.01-4.58 1.69-5.63 1.5-1.13-.19-2.43-1.77-3.18-3.83-.69-1.93-1.3-6.65-1.35-10.5-.06-4.26.4-7.64 1.17-8.63.7-.89 2.12-2.09 3.15-2.66 1.44-.79 2.5-.59 4.5.86zm76.48 1.36c1.73.36 4.6 1.76 6.39 3.11s3.25 3.36 3.25 4.46-.67 3.35-1.5 5c-.92 1.83-2.57 3.25-4.25 3.64-1.51.36-4.28.24-6.15-.25-1.88-.49-4.29-2.01-5.36-3.39-1.35-1.74-1.77-3.34-1.35-5.25.34-1.51 1.79-3.93 3.22-5.36 2.13-2.13 3.2-2.49 5.75-1.96zm-3.97 8.82c.34 1.51 1.51 3.2 2.61 3.75 1.51.76 2.49.57 4.03-.75 1.12-.96 2.02-2.31 2-3s-1.04-1.93-2.28-2.76-2.7-1.5-3.25-1.48c-.55.01-1.61.35-2.36.76-.9.48-1.15 1.67-.75 3.48zM977.61 121c.77 0 1.39.67 1.39 1.5s-1.01 1.75-2.25 2.07c-1.24.31-2.48.32-2.75.02s.11-1.23.86-2.07c.75-.83 1.99-1.52 2.75-1.52zm-911.83 6.02c.4 0 1.39.44 2.22.97 1.24.79 1.28 1.26.22 2.73-.7.98-1.6 2.58-2 3.56s-1.17 1.62-1.72 1.43c-.55-.2-1.11-1.34-1.25-2.54-.14-1.19.21-3.07.78-4.17.56-1.1 1.35-1.99 1.75-1.98zM978.12 134c1.04 0 1.89.34 1.91.75s-.77 1.57-1.75 2.56c-1.26 1.29-2.51 1.62-6.78.44l2.37-1.87c1.31-1.04 3.22-1.88 4.25-1.88z&#34;/&gt;
  &lt;path d=&#34;M481.62 138.75c-.27.96-.56 13.45-.66 27.75l-.16 36c0 5.5.45 20.8 1.01 34 .7 16.76 1.53 25.96 2.73 30.5l3.55 13.5c1.54 5.92 2.48 7.58 6.12 10.8a476.21 476.21 0 0 1 9.04 8.25c2.61 2.45 4.52 4.9 4.25 5.45s.74 1.63 2.25 2.41c1.51.77 5.34 3.69 8.5 6.5 3.16 2.8 6.2 5.09 6.75 5.09s1.67 1.35 2.5 3 4.02 5.59 7.1 8.75c3.97 4.08 5.66 6.62 5.82 8.75.11 1.65 1.72 5.25 3.57 8 1.86 2.75 7.23 8.84 11.94 13.52 4.71 4.69 11.72 11.9 15.57 16.02 3.85 4.11 12.17 11.88 18.5 17.25 10.18 8.64 12.13 9.89 17 10.83 3.63.71 10 .78 18.76.22 10.75-.68 13.25-1.12 13.23-2.34-.01-.82-.45-2.18-.97-3-.79-1.23-3.85-1.5-17.24-1.5-13.85 0-16.58-.25-18.28-1.69-1.1-.94-4.7-3.7-8-6.15-3.3-2.44-8.36-6.74-11.25-9.55s-5.26-5.67-5.28-6.36-3.29-5.07-7.27-9.75-9.72-11.65-12.75-15.5a462.6 462.6 0 0 1-10.2-13.5c-2.58-3.57-6.28-8.07-8.23-10-2.03-2-3.33-4.14-3.04-5 .33-1.01-1.04-2.31-4.23-4-2.6-1.37-5.18-3.46-5.74-4.64-.55-1.17-7.37-8.37-15.15-16-7.77-7.62-15.03-15.66-16.13-17.86s-2.78-7.82-3.73-12.5c-1.52-7.51-1.66-13.56-1.24-52 .29-26.38.96-46.85 1.7-52 1.07-7.4 1.01-9.27-.45-14.5-.91-3.3-2.31-7.01-3.09-8.25-.84-1.33-2.42-2.25-3.87-2.25-1.47 0-2.63.69-2.93 1.75z&#34; fill=&#34;red&#34;/&gt;
  &lt;path class=&#34;bb&#34; fill-rule=&#34;evenodd&#34; d=&#34;M920.46 152.09c.65.64.86 4.98.57 11.71l-.5 17.4c-.02 4.41.44 7.14 1.35 8 1.13 1.07 1.46 1.04 1.89-.2.29-.82 2.49-3.41 4.88-5.75s4.8-4.03 5.35-3.75 1 .95 1 1.5-2.36 3.53-5.25 6.62-6.37 6.02-7.75 6.52c-1.99.72-3.22.4-6-1.58-1.92-1.37-4.85-3.63-6.5-5.02-2.59-2.19-2.73-2.53-1-2.5 1.1.01 2.9.69 4 1.51s2.34 1.48 2.75 1.47.75-6.77.75-15.02.29-16.24.65-17.75 1.13-3.07 1.71-3.46 1.53-.25 2.1.3zM87.5 182.59c3.57.28 7.6 1.37 9.95 2.69 2.17 1.22 4.76 3.57 5.75 5.22 1.03 1.7 1.91 5.38 2.05 8.5.18 3.96-.33 6.62-1.81 9.5-1.41 2.74-3.45 4.71-6.5 6.26a20.75 20.75 0 0 1-9.44 2.23c-2.75-.02-6.8-.84-9-1.82s-4.79-2.88-5.76-4.23c-1.16-1.61-1.76-4.31-1.77-7.94-.02-4.37.73-6.98 3.62-12.68 2-3.95 4.38-7.42 5.27-7.7.9-.28 4.34-.29 7.64-.03zM76.85 196.5c-.99 2.2-1.82 5.69-1.83 7.75-.02 3.06.62 4.3 3.48 6.75 2.34 2 4.58 3 6.75 3 1.79-.01 4.6-.82 6.25-1.82s4.69-3.58 6.75-5.75c2.06-2.16 3.91-4.61 4.1-5.43s-.26-3.64-1-6.25c-1.22-4.3-1.85-4.99-6.6-7.26-2.89-1.38-6.22-2.51-7.4-2.5-1.23 0-3.56 1.62-5.42 3.76-1.8 2.06-4.09 5.55-5.08 7.75zm843.9 4.58c1.79-.04 3.44.48 3.67 1.17.24.69.69 4.96 1.58 17.75l-3.75 1.57c-2.06.87-4.65 1.43-5.75 1.25-1.52-.24-2.17-1.4-2.72-4.82l-1.4-9.5c-.66-4.84-.58-5.04 2.22-6.17 1.6-.65 4.36-1.21 6.15-1.25zm.8 28.92c.8 0 3.14 2.03 5.2 4.51 2.06 2.49 3.98 4.53 4.25 4.54.27.02 1.05-1.23 1.73-2.76.67-1.53 2.23-3.66 3.47-4.72 1.35-1.16 2.59-1.55 3.11-1 .49.53.2 3.09-.68 5.93-.84 2.75-2.42 6.13-3.5 7.5-1.67 2.13-2.78 2.5-7.52 2.5-3.06 0-5.69-.45-5.84-1s1.2-1.45 2.99-2 3.26-1.34 3.25-1.75-.46-.75-1.01-.75-1.45-1.12-2-2.5c-.55-1.37-1.9-2.72-3-3s-2.23-1.18-2.5-2-.25-1.95.05-2.5 1.2-1 2-1zm57.44 8.48c1.38.34 3.26.71 4.17.82s2.04.54 2.5.96-.41 1.99-1.93 3.5c-2.42 2.39-2.65 3.1-1.75 5.49.77 2.08.66 3.48-.48 5.75-.83 1.65-2.51 3.5-3.75 4.11s-3.49.84-5 .5c-1.99-.44-2.76-1.23-2.78-2.86-.02-1.24 1.11-3.94 2.5-6s2.53-4.2 2.53-4.75-.9-1.22-2-1.5-2.04-.92-2.1-1.43c-.05-.51 1.18-1.89 2.74-3.07 1.97-1.49 3.61-1.96 5.35-1.52zm-3.35 4.86c.47.47 2.1.58 3.61.25 2.33-.5 2.56-.83 1.5-2.13-.69-.85-2.02-1.53-2.95-1.5-.94.02-2 .6-2.36 1.29s-.27 1.63.2 2.09zm-2.74 12.38c.06.71.66 1.29 1.35 1.3s2.08-.56 3.09-1.25c1.02-.7 1.69-2.13 1.5-3.19-.19-1.05-.85-2.09-1.47-2.3-.61-.21-1.9.64-2.84 1.89-.95 1.25-1.68 2.85-1.63 3.55zm64.12-17.72c.54 0 1.02.56 1.08 1.25l.25 3.74c.12 1.92.82 2.6 3.11 3 2.42.42 3.09 1.15 3.7 4.01.41 1.93.55 4.29.3 5.25-.26.98-2.11 2.22-4.21 2.83-2.68.77-4.54.77-6.5 0-1.75-.69-2.98-2.08-3.38-3.83-.34-1.51-.07-4.55.61-6.75s1.87-5.24 2.65-6.75 1.85-2.75 2.39-2.75zm-2.52 16c.28.55 1.85 1 3.5 1s3.22-.45 3.5-1-.06-1.7-.75-2.54c-.69-.85-2.22-1.53-3.42-1.5-1.19.02-2.42.72-2.75 1.54-.32.82-.36 1.95-.08 2.5zm-20.96-15c.8 0 2.7.61 4.21 1.36s3.09 2.1 3.5 3 .75 3.89.75 6.64c0 4.11-.4 5.25-2.25 6.38-1.24.76-3.49 1.66-5 2s-3.76.24-5-.23-3.04-2.49-4-4.5-1.77-4.39-1.79-5.3 1.8-3.39 4.04-5.5c2.25-2.12 4.74-3.85 5.54-3.85zm-4.93 9.53c-.38 2.14-.13 4.08.64 5.07.89 1.14 2.11 1.41 4.25.95 1.65-.35 3.58-1.19 4.29-1.85.72-.66 1.28-2.44 1.25-3.95-.02-1.51-.71-3.43-1.54-4.25s-2.29-1.49-3.25-1.47-2.49.48-3.39 1.03-1.91 2.56-2.25 4.47zM993.55 241c.8 0 1.94 1.01 2.53 2.25.8 1.65.78 2.52-.07 3.25-.8.7-1.74.31-3.08-1.25-1.06-1.24-1.68-2.7-1.38-3.25s1.2-1 2-1zM940 248.39c.83.08 2.02 1.26 2.66 2.63.64 1.36 1.84 4.73 2.68 7.48 1.39 4.56 1.37 5.31-.16 8.5-1.44 3-2.17 3.5-5.12 3.5-2.89 0-3.78-.57-5.47-3.5-1.12-1.93-2.54-5.07-3.16-7s-.86-5.07-.52-7c.54-3.04 1.08-3.58 4.1-4.13 1.92-.34 4.16-.56 4.99-.48zM82.96 274c2.25 0 4.34 1.23 8.08 4.75 2.91 2.74 5.48 6.23 6.09 8.25.59 1.98.71 4.81.27 6.5-.43 1.65-1.74 4.13-2.93 5.5-1.31 1.53-4.65 3.24-8.56 4.4-5.69 1.68-6.79 1.74-9.74.5-2.06-.87-3.49-2.26-3.75-3.65-.23-1.24-.87-2.25-1.42-2.25s-1.47-1.91-2.05-4.25c-.72-2.89-.73-5.21-.05-7.25.56-1.65 3.26-5.14 6.01-7.75 3.72-3.53 5.78-4.75 8.05-4.75zm-8.31 9.8c-1.02.93-2.21 2.38-2.66 3.2-.49.92.04 3.55 1.35 6.76 1.19 2.89 2.83 5.69 3.66 6.23s2.96.99 4.75.99c2.27.02 4.34-.96 6.88-3.23 1.99-1.79 4.24-4.49 5-6 1-2 1.1-3.43.37-5.25-.55-1.37-2.69-3.63-4.75-5-2.06-1.38-3.97-2.48-4.25-2.43-.28.04-2.3.74-4.5 1.55s-4.83 2.24-5.85 3.18zm876.6-8.76c1.39.02 3.59 1.63 5.75 4.23 1.92 2.3 5.68 6.45 8.35 9.21 4.83 5.01 4.85 5.01 6.5 2.89.91-1.17 2.17-2.97 2.8-4 .79-1.29 1.49-1.56 2.26-.87.77.68.88 3.06-.41 14h-9c-7.31 0-9-.28-9-1.49 0-1.01 1.55-1.74 4.75-2.25 3.22-.51 4.75-1.24 4.75-2.26 0-.82-.56-1.52-1.25-1.54-.69-.03-4.97-3.74-9.52-8.25-4.56-4.52-8.27-8.55-8.25-8.96.01-.41 1.03-.73 2.27-.71zm34.65 23.95c.33 0 3.08 1.84 6.1 4.1s6.11 5.07 6.86 6.26c1.24 1.95 1 2.64-2.5 7.4-2.12 2.89-4.42 5.25-5.11 5.25s-1.99-.56-2.9-1.25c-.9-.69-3.81-3.27-6.46-5.75-2.93-2.74-4.83-5.38-4.85-6.75-.02-1.24.41-2.25.96-2.25s2.42-1.57 4.15-3.5c1.74-1.93 3.43-3.5 3.75-3.51zm62.5 9.28c.49.13 1.08.68 1.31 1.23.22.55-1.31 2.03-3.4 3.3-3.06 1.84-3.55 2.53-2.52 3.5 1.02.94 1.89.86 4-.37 1.49-.87 3.7-2.22 4.91-3 1.21-.79 2.56-1.09 3-.67s-.21 2.11-1.45 3.75c-1.69 2.24-2.11 3.81-1.68 6.24.43 2.38.02 3.99-1.5 6-1.68 2.24-2.75 2.7-5.72 2.5-2.16-.15-4.1-.96-4.75-1.99-.85-1.34-.67-2.48.78-5 1.86-3.22 1.86-3.29-.25-6.01-1.5-1.94-1.87-3.26-1.26-4.5.48-.96 2.39-2.53 4.25-3.48s3.78-1.62 4.28-1.5zm-4.39 19.73c.74 1.26 1.28 1.11 3.41-1 1.39-1.37 2.31-2.84 2.05-3.25s-1.36-.75-2.44-.75c-1.09 0-2.41.79-2.93 1.75-.57 1.03-.6 2.37-.09 3.25z&#34;/&gt;
  &lt;path d=&#34;M559.5 310c-1.65.42-9.86.82-18.25.88-9.42.07-15.25.5-15.25 1.12 0 .55 1.03 1.79 2.28 2.75 1.26.96 3.75 2.43 5.54 3.25s3.24 1.84 3.22 2.25.67.75 1.53.75c.87 0 2.26-.71 3.11-1.57 1.36-1.39 6.6-1.51 46.67-1.09l45.4.57c.14.05 1.12 2 2.17 4.34 1.06 2.34 2.42 7.85 3.03 12.25.6 4.4 1.36 13.4 1.69 20 .32 6.6 1.1 13.19 1.73 14.65.99 2.31.88 2.71-.87 3.19-1.68.47-1.86 1-1.15 3.36.47 1.54 1.07 6.85 1.34 11.8.39 7.45.19 9.26-1.15 10.5-.9.82-1.61 2.51-1.58 3.75.02 1.24.52 2.36 1.12 2.5.59.14 1.48 3.85 1.97 8.25s1.02 25.1 1.17 46l-.06 57.5c-.19 10.73-.75 21.98-1.26 25-.65 3.92-.44 10.09.76 21.5.92 8.8 1.81 16.23 1.98 16.5s1-.06 1.84-.75c1.05-.86 1.98-.94 3.02-.25 1 .67 1.67.67 2 0 .27-.55.05-4.37-.5-8.5-.55-4.12-.98-13.01-.96-19.75s.45-19.45.96-28.25l1.98-43 1.29-30c.2-2.58-.09-2.96-2.02-2.75-2.19.24-2.25 0-2.24-9 .01-5.41-.61-11.33-1.49-14.25-1.22-4.04-1.51-11.54-1.49-39 .01-25.07-.4-37.28-1.56-46.5-1.4-11.07-1.96-13.07-4.87-17.5-1.81-2.75-4.6-6.06-6.2-7.36l-2.9-2.35c-46.94 1.34-50.49 1.23-54-.2-2.27-.93-6.38-1.58-9.5-1.5-3.02.08-6.85.49-8.5.91z&#34; fill=&#34;#633600&#34;/&gt;
  &lt;path class=&#34;bb&#34; fill-rule=&#34;evenodd&#34; d=&#34;M1099.65 309c.74 0 2.48 1.13 3.85 2.5 1.38 1.38 2.5 3.4 2.5 4.5s-.5 3.01-1.12 4.25-2.53 3.72-4.25 5.52-3.92 3.26-4.88 3.25-1.74-.36-1.73-.77 1.25-1.99 5.48-6.26l-3.23-3.24c-1.78-1.79-3.29-3.78-3.35-4.43s1.13-2.11 2.64-3.25 3.35-2.07 4.09-2.07zm1.72 8.75c.9.14 1.64-.31 1.65-1s-.56-1.82-1.25-2.52c-.7-.69-2.15-1.26-3.24-1.25-1.84.02-1.86.16-.38 2.27.88 1.24 2.32 2.36 3.22 2.5zm-24.68-6.75c.17 0 2.34.9 4.81 2s4.79 2.56 5.15 3.25.7 2.67.75 4.4c.06 1.85-.72 4.07-1.9 5.39-1.1 1.23-3.46 2.85-5.25 3.6-2.79 1.17-3.75 1.15-6.75-.14-3.31-1.42-3.51-1.78-3.71-6.7-.18-4.73.11-5.51 3.2-8.5l3.7-3.3zm-3.89 10.7c.16 2.71.69 3.41 2.95 3.91 1.51.34 3.76.11 5-.5s2.53-2.35 2.88-3.86c.47-2.05.15-3.07-1.25-4.02-1.03-.69-3.03-1.26-4.43-1.25s-3.18.56-3.95 1.22-1.31 2.68-1.2 4.5zm-12.01-8.52c.93.17 1.8 1.11 1.94 2.07.15.96-.42 2.09-1.27 2.5-.86.42-2.07.22-2.75-.46-.73-.73-.89-1.86-.4-2.83.45-.88 1.56-1.46 2.48-1.28zm-57.46 11.05c1.73 1.25 5.63 4.42 8.66 7.05s5.85 4.77 6.26 4.75.75-1.15.75-2.53c0-1.37.45-2.73 1-3s1.71.06 2.57.75c1.18.93 1.5 2.65 1.25 6.74-.29 4.97-.6 5.63-3.32 6.95-1.65.8-5.02 1.48-7.5 1.51s-4.73-.36-5-.86c-.27-.51 1.61-1.63 4.18-2.5 2.57-.88 4.94-1.93 5.25-2.34s-3.68-4.46-8.88-9-9.21-8.6-8.91-9.02 1.96.25 3.69 1.5zm34.62 20.77c2.15 0 4.08 1.03 6.55 3.5 1.92 1.93 3.48 4.29 3.46 5.25s-1.03 2.96-2.25 4.43c-1.21 1.47-3.56 2.97-5.21 3.34-2.68.59-3.46.14-7.29-4.18-2.35-2.66-4.24-5.08-4.18-5.37.05-.29 1.4-1.97 2.98-3.75 2.06-2.3 3.76-3.22 5.94-3.22zm28.3 10.96c.69-.02 3.28 1.72 10.25 7.79l-4.13 4.13c-2.28 2.26-4.86 4.12-5.75 4.12s-1.63-.79-1.64-1.75.56-2.3 1.25-2.98c1.02-.98.87-1.36-.73-1.91-1.1-.38-4.47-1.79-7.5-3.14-3.36-1.49-4.92-2.64-4-2.94.83-.28 3.41 0 5.75.61s5.26 1.1 6.5 1.08c1.99-.03 2.05-.14.5-1-.96-.53-1.75-1.65-1.75-2.47s.56-1.52 1.25-1.54zm24.5.09c1.24-.03 3.15.85 4.25 1.95 1.11 1.11 2 3.33 2 5 0 1.65-.45 4.13-1 5.5-.55 1.38-2.35 3.18-4 4s-4.19 1.39-5.65 1.25-3.51-1.37-4.56-2.75c-1.6-2.08-1.78-3.3-1.1-7.27.71-4.2 1.22-4.93 4.31-6.19 1.92-.79 4.51-1.46 5.75-1.49zm40.61 8.95c.9 0 2.32 1.01 3.15 2.25s1.45 2.98 1.39 3.87c-.06.88.83 2.8 1.99 4.25s1.77 3.14 1.36 3.76c-.5.76-2.56.91-6.25.46-3.03-.38-10.22-1.83-16-3.22-5.78-1.4-11.17-3.17-12-3.93-.83-.77-1.16-1.71-.74-2.11.42-.39 5.59.5 11.5 1.98s11.98 2.69 13.49 2.69c2.4 0 2.69-.32 2.25-2.5-.28-1.37-.79-3.62-1.14-5-.49-1.91-.25-2.5 1-2.5zm19.18 0c.25 0 1.36.45 2.46 1s2.46 2.46 3.02 4.25 1.01 5.5 1 8.25c0 2.78-.67 6-1.51 7.25-.83 1.24-2.52 2.26-3.76 2.28s-3-.77-3.91-1.75-2.17-3.8-2.81-6.28-.9-5.62-.58-7c.31-1.37 1.71-3.74 3.1-5.25s2.74-2.75 2.99-2.75zm41.46 1.02c.28.01 1.75 1.25 3.27 2.75 1.53 1.5 2.76 3.29 2.75 3.98s-1.6 2.15-3.52 3.25-3.49 2.34-3.47 2.75.99 2.32 2.15 4.25c1.86 3.07 1.98 3.97.97 7.25-.63 2.06-1.86 4.43-2.72 5.25-.87.82-3.12 1.5-5 1.5-1.89 0-4.1-.68-4.93-1.5-1.33-1.33-1.22-2.25 3.6-15l-2.05-2.75c-1.13-1.51-2.06-3.09-2.08-3.5-.01-.41 1-1.73 2.25-2.93 1.26-1.2 3.63-2.89 5.28-3.75s3.22-1.55 3.5-1.55zm-7.19 9.29c.1.38.98.69 1.94.7.96 0 2.76-.67 4-1.5s2.25-2.19 2.25-3.01-.82-1.5-1.83-1.5-2.89 1.04-4.19 2.31c-1.3 1.28-2.28 2.63-2.17 3zm-.19 15.44c-.4 1.47-.18 2.24.63 2.23.69 0 1.75-.34 2.35-.75.61-.4 1.62-1.74 2.25-2.98s.93-2.7.65-3.25-.88-1-1.35-1-1.54.79-2.38 1.75c-.85.96-1.81 2.76-2.15 4zM1247 368.3c2.86.16 3.46.57 3.26 2.2l-.82 7.5c-.47 4.41-.17 6.29 1.5 9.5 1.14 2.2 2.07 4.56 2.07 5.25-.01.69-1.39 2.6-3.09 4.25-1.81 1.77-4.17 3.02-5.75 3.04-1.47.03-3.23-.65-3.92-1.5-.69-.84-1.03-1.99-.75-2.54s1.53-1 2.8-1c1.26 0 2.85-.56 3.52-1.25s1.22-1.7 1.23-2.25c0-.55-1.18-2.8-2.64-5-2.32-3.5-2.52-4.38-1.55-7 .62-1.65 1.12-3.79 1.13-4.75.01-1.41-.87-1.75-4.49-1.75-3.11 0-4.4-.39-4.16-1.25.18-.69 2.09-1.79 4.25-2.45 2.15-.65 5.49-1.1 7.41-1zm-19.72.7c.48 0 1.07 1.46 1.31 3.25s.43 7.41.42 12.5c-.01 8.24-.2 9.22-1.76 8.99-1.24-.19-1.95-1.57-2.43-4.75-.37-2.47-.8-7.44-.95-11.04-.19-4.65.14-6.9 1.13-7.75.77-.66 1.79-1.2 2.28-1.2zM127 373.06c1.93-.04 4.63.67 6 1.58 1.38.91 4.2 3.28 6.27 5.26s4.25 5.17 4.84 7.1.82 4.63.51 6c-.31 1.38-2.6 4.41-5.09 6.75s-6.22 4.7-8.28 5.24c-2.06.55-5.1 1-6.75 1s-4.46-.9-6.25-1.99c-1.79-1.1-4.14-3.46-5.23-5.25s-2.25-4.6-2.57-6.25c-.33-1.67.1-4.99.96-7.5.85-2.48 2.79-5.71 4.32-7.19 1.52-1.48 3.9-3.14 5.27-3.69 1.38-.55 4.08-1.03 6-1.06zm-8.96 10.31c-2.77 3.1-5.04 6.08-5.04 6.63s.61 2.46 1.36 4.25 2.21 4.04 3.25 5.01 3.69 2.03 5.89 2.34c3.39.49 4.65.11 8.25-2.51 2.34-1.7 4.54-3.88 4.9-4.84.37-.96 1.83-2.69 3.25-3.85l2.6-2.1c-3.74-5.27-5.99-8.05-7.41-9.57-1.58-1.69-3.57-2.74-5.09-2.69a18.71 18.71 0 0 0-4.71.89c-1.21.44-4.47 3.34-7.25 6.44zm1091.69-8.35c2.07 0 4.44.43 5.27.94s1.28 1.18 1 1.49-2.53 1.02-5 1.58c-2.96.67-4.84.68-5.5.03-.55-.54-.67-1.68-.27-2.52.46-.99 2.07-1.53 4.5-1.52zm-987.23 1c1.65-.04 4.53.95 6.41 2.2 1.87 1.25 4.23 3.41 5.24 4.78 1.01 1.38 2.12 4.52 2.45 7 .43 3.1.12 5.67-.99 8.25-1.24 2.88-2.71 4.24-6.36 5.86-3.09 1.37-5.8 1.9-7.75 1.53-1.65-.32-4.53-1.61-6.41-2.86-1.87-1.25-4.35-3.55-5.5-5.1-1.57-2.13-2.03-4.05-1.84-7.75.14-2.71.89-6.28 1.68-7.93s1.58-3.01 1.75-3.02c.18 0 2.12-.66 4.32-1.45s5.35-1.47 7-1.51zm-5.06 4.96c-1.14.01-3.16 1.17-4.5 2.57-2.15 2.25-2.36 3.11-1.73 7.25.48 3.19 1.6 5.59 3.5 7.47 1.53 1.53 4.14 3.05 5.79 3.38 1.94.39 4.41-.06 7-1.27 3.82-1.8 4.02-2.12 4.53-7.38.46-4.85.25-5.74-1.78-7.5-1.26-1.1-2.3-2.45-2.31-3s-.79-1.55-1.73-2.22-2.16-1.22-2.71-1.23-1.68.42-2.5.95-2.43.98-3.56.98zm915.81 1.04c.96-.01 1.97.43 2.25.98s-1.86 2.16-4.75 3.57c-2.89 1.42-5.81 2.32-6.5 2-.69-.31-1.31-1.04-1.38-1.62s1.85-1.92 4.25-2.98c2.41-1.06 5.17-1.94 6.13-1.95zm76.3 6.98c.8 0 1.65.56 1.89 1.25s-.21 2.26-1 3.5-2.11 2.25-2.94 2.25-1.7-.56-1.94-1.25.24-2.26 1.05-3.5c.82-1.24 2.14-2.25 2.94-2.25z&#34;/&gt;
  &lt;path d=&#34;M663.5 399.59c-2.93 1.06-5.68 1.24-10.26.68l-6.26-.77c.02 6.33.24 6.52 4.27 6.96 2.34.26 17.08.93 32.75 1.51 20.16.73 28.88 1.4 29.79 2.28 1.03 1 1.53 1 2.45 0 .64-.69 1.41-1.26 1.71-1.27.3-.02 1.09 1.67 1.74 3.75.66 2.07 1.66 7.37 2.23 11.77s1.51 16.77 2.08 27.5c.58 10.73 1.15 32.46 1.27 48.3.15 18.17-.14 29.17-.77 29.81-.55.55-1.11 3.68-1.25 6.95s.2 6.17.75 6.44c.61.3.65.99.1 1.75-.5.69-1.43 4.85-2.06 9.25-.64 4.4-.91 8.56-.6 9.25s-.11 1.92-.94 2.75c-.89.89-1.5 3.33-1.5 6 0 4.07.21 4.48 2.25 4.25 1.59-.18 2.25-.91 2.25-2.49 0-1.23.11-2.25.25-2.25.14-.01 1.18.55 2.31 1.24 1.76 1.07 2.27.96 3.52-.75 1.03-1.41 1.46-4.78 1.47-11.5.01-5.23.66-14.9 1.46-21.5s1.46-14.92 1.48-18.5c.01-3.58-.44-10.1-1.01-14.5s-1.48-24.43-2.04-44.5l-1.72-44.72c-.68-7.77-.91-8.39-4.22-11.26-1.92-1.68-4.85-3.76-6.5-4.64-2.06-1.09-4.09-1.37-6.5-.9-1.92.38-8.67.66-15 .63s-15.15-.74-19.6-1.58c-4.46-.84-8.51-1.5-9-1.46-.5.04-2.7.72-4.9 1.52z&#34; fill=&#34;red&#34;/&gt;
  &lt;path class=&#34;bb&#34; fill-rule=&#34;evenodd&#34; d=&#34;M1152.81 399.18c1.12.21 2.61 3.03 4.41 8.32 1.5 4.4 2.73 9.46 2.75 11.25s.48 3.25 1.03 3.25 2.01-.68 3.25-1.51c1.24-.84 3.04-1.29 4-1 .96.28 1.76.85 1.78 1.26.01.41-1.34 2.66-3 5-1.67 2.34-3.82 4.67-4.78 5.18-1.17.61-2.75.45-4.75-.48-1.65-.77-4.91-2.99-7.25-4.93-2.34-1.93-4.25-3.97-4.25-4.52s.56-1.02 1.25-1.03c.69-.02 2.49.88 4 2 1.51 1.11 3.09 2.03 3.5 2.04.41 0 .46-2.81.1-6.25s-1.63-8.51-2.83-11.26-1.9-5.6-1.54-6.32c.35-.73 1.4-1.18 2.33-1zm9.19 40.89c.83-.09 2.04.42 2.71 1.14.66.71 1.51 3.31 1.88 5.79.38 2.48.42 5.63.09 7-.32 1.38-1.96 3.29-3.63 4.25-1.68.96-4.06 1.77-5.3 1.79-1.24.03-3.28-.76-4.54-1.75-1.85-1.44-2.43-3.17-3.71-16.08l5.5-.98c3.03-.55 6.17-1.07 7-1.16zm-858.15 23.94c3.66 0 8.45.49 10.65 1.09 2.2.61 4.8 1.84 5.78 2.75 1.29 1.19 1.76 3.04 1.68 6.65-.06 2.75-.68 6.57-1.37 8.5-.77 2.15-2.9 4.66-5.52 6.5-3.35 2.36-5.57 3.08-10.41 3.38-4.2.26-7.27-.13-9.66-1.21-1.93-.88-4.06-2.74-4.75-4.13-.69-1.4-1.25-4.56-1.25-7.04s.45-5.62 1-7c.55-1.37 2.39-4.07 4.1-6 2.95-3.34 3.4-3.5 9.75-3.49zm-9.19 8.11c-1.38 1.75-1.78 3.6-1.52 7.01.22 2.87 1.12 5.42 2.36 6.73 1.1 1.16 3.13 2.3 4.5 2.54 1.38.24 3.85.15 5.5-.2 1.65-.34 5.36-2.78 8.25-5.41 4.1-3.74 5.25-5.45 5.25-7.79 0-2-.75-3.5-2.25-4.49-1.24-.82-4.5-1.69-7.25-1.94s-6.79-.08-8.99.36c-2.29.47-4.78 1.83-5.85 3.19zm-48.16-5.08c3.3.3 7.24 1.32 8.75 2.25 1.8 1.12 3.09 3.09 3.75 5.71.59 2.38.65 4.91.12 6.25-.48 1.24-2.95 4.16-5.5 6.5-2.54 2.34-6.4 4.81-8.59 5.5-3.17 1-4.47 1-6.5 0-1.39-.69-3.43-3.05-4.53-5.25s-2.21-6.02-2.46-8.5c-.38-3.61.03-5.26 2.06-8.42 1.42-2.22 3.48-4.07 4.71-4.26 1.21-.18 4.89-.08 8.19.22zm-12.13 9.71c-.35 1.51-.36 4.32-.03 6.25s1.63 4.31 2.88 5.29c1.25.99 3.52 1.78 5.03 1.75 1.51-.02 4.09-.83 5.74-1.79 1.64-.96 3.4-2.65 3.9-3.75s1.4-3.46 2.01-5.25c.84-2.47.8-3.65-.15-4.9-.69-.92-2.71-2.27-4.5-3-1.79-.74-4.74-1.35-6.55-1.35-1.91 0-4.24.85-5.5 2-1.21 1.1-2.48 3.24-2.83 4.75zm924.18-1.75c.8 0 1.9 1.13 2.45 2.5.55 1.38 1 6.1 1 10.5s.22 8.68.5 9.5 1.06 1.52 1.75 1.55c.69.02 2.83-1.67 4.75-3.77 1.92-2.09 4.06-4.14 4.75-4.54.69-.41 1.92-.51 2.75-.24s1.5 1.18 1.5 2-3.04 4.67-6.75 8.54c-4.12 4.3-7.53 7.02-8.75 6.99-1.1-.04-4.03-1.42-6.5-3.08-2.47-1.65-5.17-2.97-6-2.93s-1.99-.51-2.59-1.23c-.61-.71-1.36-1.97-1.67-2.79s-.19-2.18.26-3c.7-1.26 1.61-.98 5.67 1.69 2.65 1.75 5.17 2.99 5.58 2.75s.75-2.8.74-5.69c0-2.89-.43-7.95-.95-11.25s-.72-6.34-.44-6.75c.27-.41 1.15-.75 1.95-.75zm80.95 37.04c1.65-.04 3.9.55 5 1.31 1.92 1.34 1.94 1.54.34 5.27-.91 2.13-3.61 7.84-6 12.67-2.39 4.84-4.9 8.77-5.59 8.75s-1.25-.6-1.26-1.29c0-.69 1.51-4.85 3.36-9.25s3.65-9.01 4.01-10.25c.6-2.11.31-2.27-4.61-2.5-2.89-.14-5.18-.7-5.1-1.25.09-.55 1.66-1.54 3.5-2.19 1.84-.66 4.7-1.23 6.35-1.27zm-48.48 1.96c1.13 0 2.51 1.09 3.23 2.56 1.07 2.19.96 3.06-2.75 9.41l2 2.14c1.25 1.34 2.12 3.88 2.33 6.76.2 2.78-.2 5.34-1 6.4-.73.98-2.91 2.03-4.83 2.35-2.19.37-4.9-.01-11-2.62l3.25-6.46c3.18-6.31 3.22-6.55.25-14.76l3.27-2.89c1.79-1.59 4.16-2.89 5.25-2.89zm-5.22 7.7c.11.71.54 1.31.95 1.33s1.53-.77 2.47-1.75c.95-.98 1.74-2.12 1.75-2.53.02-.41-.56-.75-1.27-.75s-1.93.54-2.7 1.2-1.31 1.78-1.2 2.5zm-1.79 17.55c-.01 1.27.79 1.75 2.92 1.75 1.61 0 3.63-.67 4.5-1.5.86-.83 1.57-2.51 1.58-3.75 0-1.24-.67-3.26-1.5-4.5s-1.93-2.25-2.44-2.25-1.85 1.91-2.98 4.25c-1.14 2.34-2.07 5.04-2.08 6zm35.35-25.25c.9 0 2.09.9 2.64 2s.99 5.94.98 10.75c0 4.81-.43 9.42-.94 10.25s-1.29 1.12-1.73.67c-.45-.46-.83-4.74-.86-9.5-.03-4.77-.43-9.91-.89-11.42-.68-2.22-.53-2.75.8-2.75zm-57.36 5.04c.83-.07 2 .45 2.61 1.17.61.71 1.38 3.09 1.7 5.29.33 2.2.16 6.25-.38 9s-1.89 5.9-3.01 7c-1.9 1.87-2.11 1.89-3.23.29-.65-.94-1.75-1.73-2.44-1.75s-1.25-.49-1.25-1.04-.9-1.23-2-1.5c-1.66-.41-2.04-1.45-2.25-6l-.25-7.75c0-1.83.85-2.47 4.5-3.42 2.47-.64 5.17-1.23 6-1.29zm43.86 1.92c.35-.03 1.23.62 1.95 1.45.72.82 1.16 2.3.99 3.29-.18.99-1.17 1.8-2.2 1.8-1.04 0-2.38-.75-2.99-1.66-.84-1.26-.77-2.06.25-3.25.75-.88 1.65-1.61 2-1.63zm2.25 16.04c.49 0 1.23.7 1.64 1.55.45.92.15 2.15-.75 3.05-1.33 1.33-1.64 1.33-2.75-.05-.93-1.15-.96-1.94-.14-3.05.61-.83 1.51-1.5 2-1.5zM249.5 553.06c1.1 0 4.03.44 6.5.99 2.48.55 5.8 1.55 7.39 2.22 1.66.71 3.68 2.82 4.75 4.98 1.02 2.06 1.85 5.44 1.84 7.5s-.91 5.66-2 8-2.88 4.7-3.98 5.25-4.48 1-7.5 1c-4.96 0-5.9-.37-9.58-3.75-3.1-2.85-4.56-5.31-6.08-10.25-1.87-6.04-1.9-6.73-.42-9.75.87-1.79 2.82-3.91 4.33-4.71s3.65-1.47 4.75-1.48zm-7.69 11.75c.1 1.21.82 3.43 1.59 4.94.78 1.51 2.47 3.77 3.75 5.02 1.29 1.25 3.7 2.33 5.35 2.4 1.65.08 4.01-.38 5.25-1.01 1.24-.64 2.3-.82 2.37-.41.06.41.06 1.09 0 1.5-.07.41.44.77 1.13.79.69.03 1.93-.68 2.75-1.57 1.21-1.32 1.25-1.76.18-2.3-1.06-.54-1.08-1.44-.12-4.67.66-2.2.91-5.24.57-6.75-.35-1.51-1.42-2.95-2.38-3.2s-4.9-.74-8.75-1.1c-6.5-.6-7.17-.47-9.44 1.77-1.34 1.32-2.36 3.39-2.25 4.59z&#34;/&gt;
&lt;/svg&gt;
&lt;p&gt;The first two data sets are contained in the feed, but the third data set is not. In order to create it, we need locations and arrival times for not only stops, but also the &lt;em&gt;points between stops&lt;/em&gt;. GTFS feeds don&amp;rsquo;t contain that information, but they do contain data we can use to figure it out, mainly:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The geographic location of each stop (&lt;code&gt;stops_df&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Each train&amp;rsquo;s scheduled arrival time for a given stop (&lt;code&gt;stops_df&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The shape of the track between stops, which we can convert to waypoints for the train to follow. These waypoint don&amp;rsquo;t have arrival times (&lt;code&gt;waypoints_df&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;100%&#34; height=&#34;100%&#34; viewBox=&#34;0 0 1800 1057&#34; preserveAspectRatio=&#34;none&#34;&gt;
  &lt;style&gt;
    @media (prefers-color-scheme:dark) {
      .bb {fill: #fff}
    }
  &lt;/style&gt;
  &lt;path class=&#34;bb&#34; fill-rule=&#34;evenodd&#34; d=&#34;M486 38.03c.27.01 1.18.65 2 1.43 1.22 1.14 1.46 4.09 1.29 15.72-.11 7.88-.48 17.25-.81 20.82-.5 5.44-.28 6.91 1.3 9 1.04 1.38 3.09 2.84 4.56 3.25 1.55.44 2.68 1.48 2.7 2.5.03.96-.65 2.31-1.5 3-.93.75-2.83 1.01-4.79.66l-6.25-1.1c-2.02-.35-3.49.02-4.5 1.13-.82.91-1.95 1.61-2.5 1.56s-1.68.66-2.5 1.58c-.82.91-2.85 2.33-4.5 3.15s-4.12 1.53-5.5 1.59c-1.37.05-4.19-1.12-6.25-2.61s-4.27-3.72-4.91-4.96-1.09-4.05-.99-6.25c.11-2.69 1.23-5.54 3.41-8.69 1.78-2.58 4.14-5.23 5.24-5.89s4.59-1.47 7.76-1.81c5.05-.53 5.76-.4 5.75 1.14a13 13 0 0 1-.51 3.25c-.36 1.07-1.94 1.5-5.5 1.5-4.56 0-5.18.29-7.04 3.25-1.39 2.23-1.86 4.2-1.48 6.25.31 1.65 1.79 4.27 3.29 5.83 2.25 2.34 3.3 2.73 5.98 2.25 1.9-.34 4.29-1.83 5.75-3.58 1.38-1.65 2.5-4.24 2.5-5.75.01-1.67-.78-3.24-2-4-1.1-.69-1.99-1.81-1.97-2.5.01-.69.8-2.08 1.75-3.1 1.41-1.53 1.76-4.12 1.94-14.5.11-6.96.72-14.22 1.34-16.15.62-1.92 2.33-4.51 3.79-5.75 1.46-1.23 2.88-2.23 3.15-2.22zm44.97 2.13c1.94-.02 4.32.16 5.28.4s2.2 1.34 2.75 2.44c.76 1.51.57 2.49-.75 4.03-1.22 1.42-2.95 2.03-5.75 2.02-2.2-.01-5.8.61-8 1.37-2.69.94-4.21 2.16-4.65 3.74-.36 1.29-.68 4.14-.72 6.34s.48 4.74 1.15 5.65c.79 1.08 3.49 1.91 7.72 2.38 3.58.41 7.29 1.12 8.25 1.6s1.77 1.66 1.79 2.62c.03.96-.53 2.33-1.25 3.03-.71.7-4.38 1.6-8.15 2-4.52.47-7.12 1.23-7.62 2.22-.42.82-.87 5.32-.99 10-.13 5.22-.76 9.37-1.62 10.75-.95 1.52-2.38 2.25-4.41 2.25-1.86 0-3.33-.66-3.86-1.75-.51-1.05-.27-5.58.61-11.25 1.1-7.12 1.19-10.06.36-11.75-.65-1.32-2.78-2.77-5.16-3.5-2.68-.83-3.94-1.75-3.74-2.75.17-.82 1.95-2.4 3.96-3.5 3.01-1.65 3.83-2.82 4.73-6.75.61-2.61 1.1-5.87 1.1-7.25 0-1.37.79-3.84 1.75-5.48.96-1.65 2.88-3.44 4.25-3.99 1.38-.55 4.06-1.86 5.97-2.92 1.91-1.05 5.06-1.93 7-1.95zM259.02 43c1.09 0 2.57 1.01 3.28 2.25.72 1.24 1.87 4.28 2.56 6.75l3.64 12.5 7.21.5c5.71.4 7.69.97 9.5 2.75 2.19 2.15 2.22 2.32.51 4-1.34 1.31-3.07 1.68-7 1.45-2.87-.17-6.34.11-7.72.62-2.47.91-2.5 1.04-2.5 12.76 0 11.63-.04 11.85-2.5 13.05-1.47.71-3.32.88-4.5.42-1.73-.69-2.01-1.77-2.09-8.17l-.25-11.13c-.14-3.37-.57-3.93-4.19-5.5-2.22-.96-4.02-2.31-4-3s1.42-2.26 3.12-3.5c2.95-2.14 3.06-2.49 2.43-7.25-.36-2.75-1.19-6.85-1.84-9.11-1.02-3.55-.94-4.47.59-6.75.97-1.45 2.66-2.64 3.75-2.64zM1493.5 54.16c0-.11 1.58.43 3.5 1.2 1.92.78 4.07 2.03 4.77 2.78.71.75 1.16 2.7 1 4.34-.18 2-1.08 3.38-2.77 4.24-2.28 1.15-2.72.99-5-1.74-1.37-1.65-3.4-3.01-4.5-3.02s-2.7.78-3.56 1.76c-.85.98-2.09 3.02-2.75 4.53-.65 1.51-1.19 4.1-1.19 5.75 0 2.57.39 3.02 2.75 3.15l6.59.25c2.82.07 4.35.76 5.79 2.6 1.07 1.38 1.94 3.06 1.91 3.75-.02.69-.94 1.7-2.04 2.25-1.18.59-4.01.69-6.89.25-3.75-.57-5.28-.4-6.54.75-1.26 1.14-1.65 3.23-1.61 8.75.02 3.99-.18 7.93-.46 8.75-.3.89-1.72 1.5-3.5 1.5-1.85 0-3.34-.67-3.89-1.75-.48-.96-.71-5.24-.5-9.5.28-5.51.03-7.95-.86-8.43-.69-.37-2.15-.76-3.25-.87l-3.75-.32c-.96-.07-1.75-.81-1.75-1.63s1.46-2.11 3.25-2.85c1.79-.73 3.82-1.97 4.51-2.75.69-.77 1.51-3.43 1.82-5.9.32-2.47 1.09-5.62 1.72-7 .62-1.37 2.39-4.19 3.92-6.25 2.51-3.39 3.28-3.78 8.03-4.07 2.89-.17 5.25-.4 5.25-.52zM1449.65 56c1.29 0 2.77.79 3.28 1.75s.67 4.68.36 8.25c-.32 3.57-.53 9.2-.47 12.5s.75 7.8 1.54 10c1.19 3.31 2.18 4.28 5.79 5.63 3.44 1.3 4.35 2.13 4.35 3.99 0 1.57-.66 2.46-2 2.69-1.1.18-4.47-.45-7.5-1.4-3.03-.96-6.06-2.11-6.75-2.57-.86-.58-1.95.43-3.5 3.27-1.24 2.26-3.37 4.7-4.75 5.43-1.61.86-4.64 1.17-8.5.89-3.89-.29-6.62-1.06-7.77-2.19-1.07-1.05-2.01-3.96-2.37-7.33-.37-3.37-.16-6.44.52-7.75.62-1.19 3.15-3.51 5.62-5.16 2.86-1.9 5.78-3 8-3 1.92 0 3.72.45 4 1s-.06 1.7-.75 2.54c-.69.85-2.04 1.53-3 1.5-.96-.02-2.9 1.42-4.3 3.21-2.1 2.67-2.45 3.96-1.99 7.25.35 2.51 1.21 4.25 2.3 4.67.96.37 2.51.15 3.46-.5.94-.64 2.91-3.87 4.36-7.17 2.25-5.09 2.71-7.74 3.03-17.5.21-6.32.64-12.62.96-14 .32-1.37 1.29-3.29 2.16-4.25.86-.96 2.62-1.75 3.92-1.75zm-126.4 4.08c1.92-.06 3.2.68 4.25 2.42.83 1.38 1.72 3.63 2 5 .28 1.38 1.06 2.56 1.75 2.63.69.08 3.28.06 5.75-.04 2.69-.11 5.4.44 6.75 1.36 1.32.91 2.25 2.58 2.25 4.05 0 2.14-.5 2.54-3.5 2.75-1.92.14-4.74.28-6.25.33-1.51.04-3.54.37-4.5.75-1.54.59-1.72 1.95-1.5 11.14.2 8.18-.08 10.82-1.25 12.07-1.12 1.2-2.4 1.43-8.5.21l.65-7.62c.36-4.2.34-8.75-.04-10.13-.45-1.64-1.53-2.62-3.15-2.84-1.35-.19-3.26-1.09-4.24-2s-1.77-2-1.75-2.41 1.72-1.59 3.78-2.61c2.14-1.07 4.06-2.89 4.46-4.25.45-1.5.17-3.23-.75-4.64-.8-1.24-1.55-2.89-1.66-3.67s.45-1.64 1.25-1.92 2.69-.54 4.2-.58zM228.5 64.06c2.2-.05 5.46.36 7.25.92 2.24.71 3.25 1.64 3.25 3.02 0 1.6-1.34 2.4-6.75 4.02-3.71 1.11-7.2 2.02-7.75 2.02s-2.46 1-4.24 2.23c-1.79 1.23-3.25 2.79-3.25 3.48-.01.69 1.23 1.88 2.74 2.65 1.51.76 4.78 1.94 7.25 2.62 2.7.73 5.8 2.58 7.75 4.6 2.78 2.89 3.25 4.1 3.25 8.38 0 2.75-.39 6.01-.86 7.25-.48 1.24-2.62 3-4.75 3.93-2.14.92-6.14 2.03-8.89 2.47-2.75.43-9.16.69-14.25.57-8.38-.2-9.48-.45-11.75-2.72-1.37-1.37-2.28-2.95-2-3.5.31-.61 4.26-.82 10.25-.52 5.53.27 11.26.02 13.25-.59 1.93-.58 4.51-1.92 5.75-2.98 1.79-1.52 2.03-2.27 1.17-3.66-.59-.96-3.8-3.32-7.14-5.25s-7.13-4.29-8.43-5.25c-1.73-1.29-2.36-2.74-2.37-5.5-.02-2.94.97-5.05 4.57-9.75 3.29-4.29 5.65-6.33 8.28-7.17 2.02-.65 5.47-1.22 7.67-1.27zm1038.75.03c.96-.05 2.42 1.04 3.25 2.41.83 1.38 1.28 3.18 1 4-.29.87-2.29 1.76-4.75 2.11-2.34.34-5.26.34-6.5 0s-2.48-1.4-2.75-2.36c-.28-.96-.08-2.31.44-3 .53-.69 2.44-1.67 4.26-2.16 1.81-.5 4.09-.95 5.05-1zm-878.5 1.01c.14-.05 1.03.17 1.98.51.97.33 1.64 1.45 1.5 2.5-.12 1.04-1.8 3.24-3.73 4.89s-3.95 3-4.5 3-1 .56-1 1.25c-.01.69 2.47 3.16 5.5 5.5 4.33 3.34 5.5 4.84 5.48 7-.01 1.51-.8 4.9-1.75 7.53-1.21 3.35-2.55 5.14-4.48 6-1.52.67-2.75 1.56-2.75 1.97s-1.57.75-3.5.75-4.62-.45-6-1c-1.37-.55-2.84-1.7-3.25-2.55-.45-.93-.15-2.14.75-3.02.82-.81 3.75-1.66 6.5-1.89 2.75-.22 5.33-1 5.73-1.72.41-.73.75-1.88.75-2.57.01-.69-.78-2.04-1.76-3-.97-.96-4.13-3.55-7.01-5.75s-5.23-4.79-5.23-5.75c.01-.96 2.21-3.89 4.88-6.5s6.38-5.27 8.25-5.9l3.64-1.25zm-47 3.94c.69-.02 2.94.66 5 1.52s4.98 2.78 6.47 4.25c1.5 1.48 3.01 4.26 3.36 6.19s.06 5.51-.65 8c-.71 2.47-2.04 5.85-2.95 7.5-.92 1.65-2.75 3.29-4.07 3.65-1.33.36-4.55.7-7.16.75-3.44.07-5 .58-5.65 1.85-.5.96-.95 6.14-1 11.5-.06 5.36-.33 10.43-.6 11.25-.28.84-1.72 1.51-3.25 1.53-1.9.02-3.09-.68-3.84-2.25-.72-1.5-.79-3.65-.21-6.28.49-2.2 1.02-7.82 1.19-12.5.16-4.68-.2-11.5-.8-15.17-.93-5.73-.86-6.95.51-8.58.87-1.05 1.68-2.77 1.78-3.83s.96-2.89 1.9-4.07c.95-1.18 3.29-2.85 5.22-3.71s4.06-1.58 4.75-1.6zm-8.25 10.47c0 .54.63 3.24 1.4 5.99s2.12 5.8 3 6.78c.93 1.04 2.96 1.77 4.85 1.75 2.27-.02 3.67-.71 4.65-2.28.9-1.44 1.18-3.51.79-5.75-.34-1.93-1.87-4.74-3.4-6.25-1.54-1.51-3.35-2.7-4.04-2.63-.69.06-2.6.41-4.25.76s-3 1.09-3 1.63zM1372 71.66c1.38.28 3.06.69 3.75.92s1.25 1.55 1.25 2.92c0 1.38-.67 2.72-1.5 3s-3.3.5-5.5.5c-2.67 0-4.67.67-6 2-1.1 1.1-2 2.45-2 3s1.13 2.13 2.5 3.5c1.38 1.38 3.4 2.5 4.5 2.5s2.9.45 4 1c1.54.77 2 1.99 1.98 5.25-.02 3.03-.66 4.9-2.25 6.53-1.97 2-3.2 2.27-10.48 2.25-4.54-.02-9.39-.59-10.78-1.28s-2.51-1.81-2.5-2.5c.02-.69 1.04-1.76 2.28-2.39 1.3-.66 4.58-.93 7.75-.64 3.03.27 6.06.34 6.75.14S1367 97.1 1367 96c0-1.52-.66-2-2.75-1.99-1.51 0-3.76-.67-5-1.5s-2.92-2.86-3.75-4.51-1.5-3.9-1.5-5c0-1.11 1.67-3.34 3.75-5.01 2.06-1.66 5.55-3.87 7.75-4.93 2.24-1.07 5.1-1.69 6.5-1.4zm-325 .59c1.25.25 1.45 2.25 1.19 12.27-.28 10.7-.09 12.33 1.75 15.23 1.38 2.18 3.29 3.58 5.81 4.24 2.06.55 4.65 1 5.75 1.01 1.26.01 2.62-1.2 3.67-3.24.92-1.79 1.94-6.41 2.27-10.26.52-6.02.99-7.31 3.33-9.25 1.5-1.23 3.29-2.24 3.98-2.25.87 0 1.25 1.92 1.26 6.25 0 3.44.42 7.82.94 9.75.51 1.93 1.81 4.63 4.84 8.5l5.61-1.75c3.38-1.06 6-2.54 6.6-3.75.55-1.1.89-4.66.75-7.9-.2-4.75.14-6.32 1.75-8.03 1.1-1.18 2.34-2.12 2.75-2.1s1.65 1.6 2.75 3.53c1.44 2.52 1.84 4.55 1.44 7.25-.3 2.06-.73 4.65-.93 5.75-.21 1.1-1.76 3.46-3.45 5.25-1.68 1.79-5.2 4.17-7.81 5.3s-6.78 2.31-9.25 2.61c-3.59.44-5.05.12-7.25-1.56-1.51-1.15-2.97-2.1-3.25-2.1s-1.89 1.01-3.58 2.25c-2.5 1.82-4.35 2.24-9.75 2.18-4.06-.04-7.84-.69-9.67-1.66-1.65-.87-4.25-2.87-5.79-4.43-2.4-2.45-2.86-3.88-3.34-10.34-.3-4.12-.28-9.86.04-12.75.45-4 1.25-5.85 3.34-7.77 1.51-1.39 3.42-2.39 4.25-2.23zm162 2.85c1.92-.02 5.24.96 7.36 2.18s4.48 3.46 5.25 4.97c.76 1.51 1.39 3.43 1.39 4.25s-1.69 2.8-3.75 4.38c-2.06 1.59-5.78 3.83-12.75 7.09l-.63 10.77c-.35 5.92-1.13 11.77-1.75 13.01-.71 1.43-2.03 2.25-3.62 2.25-1.37 0-2.81-.56-3.19-1.25s-.59-9.57-.46-19.75c.18-14.68.53-18.81 1.69-20 .81-.82 1.13-1.83.71-2.23-.41-.4-.15-1.46.58-2.36.74-.9 2.31-2 3.5-2.46 1.2-.45 3.75-.84 5.67-.85zm-2.99 15.15a1.72 1.72 0 0 0 1.74 1.77c.96.01 2.76-.89 4-2 1.79-1.6 2.04-2.43 1.25-4.02-.55-1.1-1.9-2.45-3-3s-2.74-1-3.65-1c-1.34 0-1.53.62-.99 3.25.36 1.79.66 4.04.65 5zM302.25 77.07c.41-.04 1.93.49 3.37 1.18s3.24 2.49 4 4 2.73 3.43 4.38 4.25 3.45 2.4 4 3.5.73 3.01.39 4.25-2.02 3.75-3.75 5.58-4.71 3.98-6.64 4.77c-1.93.8-5.41 1.44-7.75 1.42-3.37-.01-4.99-.69-7.83-3.27-3.07-2.79-3.58-3.89-3.61-7.75-.02-2.47.77-6.07 1.75-8 .99-1.93 3.14-4.62 4.78-6 1.64-1.37 3.69-2.81 4.57-3.18.87-.37 1.93-.71 2.34-.75zm-5.11 12.2c-.63 1.5-1.14 3.63-1.14 4.73s.68 2.68 1.5 3.5 3.27 1.5 5.43 1.5 4.63-.68 5.5-1.5c.86-.82 1.57-1.95 1.57-2.5s-1.36-2.01-3.02-3.25-2.99-2.8-2.94-3.46c.04-.67-.79-1.65-1.86-2.19-1.06-.53-2.37-.65-2.91-.26-.55.39-1.51 1.93-2.13 3.43zm879.36-12.32c.55-.02 1.54.54 2.21 1.26.79.84 1.44 7.32 1.88 18.79.55 14.58.39 18.46-.96 23.25-.99 3.49-2.54 6.44-3.95 7.5-1.38 1.04-3.92 1.71-6.25 1.65-2.16-.06-5.28-.45-6.93-.87s-4.7-1.95-10.55-6.03l2.28-2.28c1.25-1.25 2.94-2.26 3.77-2.25.83 0 3.3.92 5.5 2.03s4.56 2.01 5.25 2.01c.69-.01 2.31-2.82 3.61-6.26 1.45-3.83 2.22-7.7 2-10-.21-2.17-.89-3.74-1.61-3.72-.69.02-2.15.7-3.25 1.52s-3.46 1.48-5.25 1.47-5.05-1.14-7.25-2.52c-3.04-1.9-4.11-3.28-4.45-5.75-.25-1.79-.63-5.5-.85-8.25-.32-3.92-.01-5.38 1.45-6.75 1.02-.96 2.52-1.75 3.35-1.75s2 1.01 2.61 2.25c.6 1.24 1.01 3.6.89 5.25-.11 1.65-.15 4.57-.09 6.5.07 1.93.53 4.18 1.04 5 .76 1.25 1.34 1.29 3.48.25 1.76-.86 3.2-2.99 4.57-6.75 1.1-3.03 1.94-7.05 1.87-8.94-.11-2.62.44-3.82 2.25-5.01 1.31-.86 2.83-1.58 3.38-1.6zm-50 1.11c1.1-.01 2.84.77 3.86 1.72 1.05.97 3.43 1.72 9.14 1.72l1 9c.98 8.85 1.06 9.03 4.29 10.5 1.98.9 3.17 2.1 2.97 3-.23 1.09-1.4 1.42-4.29 1.2-2.41-.19-5.84.5-8.72 1.75-2.61 1.13-6.33 2.05-8.25 2.05s-5.97-1.12-9-2.5c-4.28-1.95-5.63-3.11-6.1-5.25-.33-1.51-.97-4.1-1.43-5.75-.62-2.24-.33-4.01 1.15-7 1.09-2.2 2.96-4.68 4.16-5.5 1.19-.82 3.76-2.27 5.69-3.22 1.94-.94 4.43-1.72 5.53-1.72zm-7.88 11.69c-1.29 2.59-1.41 4.01-.59 7 .57 2.06 1.81 4.3 2.75 4.97.95.67 3.18 1.23 4.97 1.25 2.42.02 3.63-.61 4.75-2.47.83-1.37 1.51-3.96 1.52-5.75.02-1.79-.66-4.94-1.5-7-1.34-3.3-1.93-3.75-4.91-3.75-1.86 0-3.83.56-4.37 1.25-.55.69-1.72 2.71-2.62 4.5zm122.13-9.68c.69-.04 1.81 1.09 2.5 2.5s2.38 2.82 3.75 3.13c1.38.31 3.3 1.3 4.28 2.18.98.89 1.77 2.75 1.76 4.12-.02 1.38-.88 4.07-1.91 6s-3.17 4.25-4.76 5.18c-1.58.92-3.88 1.71-5.12 1.75s-3.94-.6-6-1.42c-2.79-1.1-4.33-2.64-6-6-1.24-2.48-2.25-5.63-2.25-7.01 0-1.37 1.01-3.62 2.25-5 1.24-1.37 4.05-3.14 6.25-3.93 2.2-.78 4.56-1.46 5.25-1.5zm-4.31 14.43c.76 2.72 1.75 4.1 3.09 4.31 1.3.21 2.39-.55 3.22-2.25 1.1-2.26.95-2.98-1.25-6.06-1.37-1.93-3.13-3.5-3.9-3.5-.78 0-1.61.79-1.85 1.75-.23.96.07 3.55.69 5.75zm29.05-11c1.11.68 2.4 2.54 2.87 4.12.47 1.59.58 5.35.24 8.38-.37 3.37-1.39 6.37-2.61 7.75-1.09 1.24-2.78 2.25-3.74 2.26-1.47 0-1.86-1.32-2.45-8.25-.38-4.54-.99-9.38-1.36-10.76-.55-2.1-.21-2.68 2.2-3.62 2.17-.86 3.33-.83 4.85.12zm33.01 2.49c1.1-.04 3.13.8 4.5 1.88 2.39 1.87 2.49 2.35 2.21 11.29-.16 5.14-.61 9.63-1 9.98-.39.36-2.15.36-3.91 0-3.02-.6-3.24-.95-3.88-6.14-.38-3.03-.4-6.06-.05-6.75s.18-1.93-.37-2.75c-.83-1.25-1.42-1.29-3.53-.25-1.39.69-2.78 2.38-3.08 3.75-.31 1.38-1.24 4.3-2.06 6.5-.83 2.2-2.03 4.58-2.67 5.29-.64.72-2.85 1.28-8.66 1.21l.63-9.25c.35-5.09 1.14-9.86 1.75-10.6.69-.83 2.46-1.2 4.62-.96 1.92.22 5.75-.39 8.5-1.36s5.9-1.8 7-1.84zm-868.75 9.16c1.79-.08 3.93.07 4.75.35s1.52 1.51 1.54 2.75c.03 1.24-.76 3.28-1.75 4.55-1.64 2.11-2.64 2.31-11.79 2.45-5.5.09-11.01-.16-12.25-.55-1.24-.38-2.24-1.49-2.22-2.45s.72-2.65 1.55-3.75c1.2-1.58 3.13-2.13 9.22-2.6l10.95-.75zM1398 101.1c1.92-.05 5.08.33 7 .85 2.34.63 3.72 1.71 4.17 3.25.37 1.26.49 2.86.25 3.55-.29.87-3.07 1.25-9.17 1.26-4.81.01-10.22-.33-12.02-.75-1.89-.44-3.29-1.4-3.3-2.26-.01-.82.56-2.02 1.28-2.66.71-.64 2.87-1.61 4.79-2.16s5.08-1.04 7-1.08zm-830.96 94.36c1.09.56 1.98 1.81 1.97 2.78 0 .97-1.75 4.35-3.87 7.51s-4.62 6.43-5.54 7.25c-.93.82-1.67 2.06-1.64 2.75.02.69-.75 2.02-1.71 2.97-.96.94-3.11 3.98-4.78 6.75s-4.14 6.71-5.5 8.76-3.71 4.19-5.22 4.75c-1.84.68-3.57.69-5.25.02-1.37-.55-3.11-2.24-3.86-3.75s-3.21-4.32-5.47-6.25-4.09-4.28-4.08-5.23 1.12-2.41 2.46-3.25c1.35-.83 3.24-1.3 4.2-1.03.96.28 3.77 2.29 10.75 8.47l5.26-8.23 8.5-13.62c1.78-2.96 4.37-6.62 5.74-8.13 1.38-1.51 3.3-2.92 4.27-3.15.98-.22 2.67.06 3.77.63zM408 206.11c1.93-.07 4.51.55 5.75 1.38s2.25 2.19 2.25 3.01-1.01 1.91-2.25 2.41-2.93.85-3.75.79c-.82-.07-4.09.2-7.25.59s-5.77.82-5.78.96c-.02.14-.63 3.63-1.36 7.75-.72 4.13-1.15 9.19-.96 11.25.32 3.39.09 3.81-2.4 4.38-1.51.35-3.43.19-4.25-.35-1.11-.73-1.63-3.66-2.5-21.64l-3-.83a55.65 55.65 0 0 0-6-1.25l-3.75-.49c-.41-.04-.75-.52-.75-1.07s.9-1.9 2-3c1.73-1.73 3.38-2.01 12.25-2.06 5.64-.03 12.05-.43 14.25-.88 2.2-.46 5.57-.89 7.5-.95zm13.36.87c.63-.01 2.04.63 3.14 1.42s1.62 1.81 1.15 2.27-2.15.94-3.75 1.08c-1.59.14-3.13-.2-3.4-.75s0-1.68.61-2.5 1.63-1.51 2.25-1.52zm71.89 7.02c2.95 0 4.29.64 6.25 3 1.38 1.65 2.5 3.68 2.5 4.5s-1.78 3.41-3.96 5.75-3.98 4.81-4 5.5 1.09 1.25 2.46 1.25c1.56 0 2.5.57 2.5 1.5 0 .82-.34 2.24-.75 3.14s-1.99 2.25-3.5 3-5.68 1.36-9.25 1.36c-6.1 0-6.72-.22-10-3.5-2.57-2.57-3.5-4.36-3.49-6.75 0-1.79.79-4.42 1.75-5.84s3.31-3.95 5.24-5.62 5.07-3.99 7-5.16 5.19-2.12 7.25-2.13zm-9.38 12.56c.07.79.92 1.43 1.88 1.41s2.45-.58 3.31-1.25 1.87-2.01 2.25-2.97c.5-1.26.2-1.75-1.06-1.76-.96 0-2.82.7-4.13 1.56-1.32.86-2.33 2.21-2.25 3.01zM337.5 215.81c1.65.25 4.51 1.64 6.35 3.07 1.84 1.44 4.54 3.42 6 4.39 1.46.98 4.36 4.36 6.45 7.5 2.08 3.15 4.22 7.3 4.74 9.23s.95 5.64.95 8.25c.01 2.82-1.03 7.29-2.56 11-1.41 3.44-3.82 7.82-5.37 9.75-1.54 1.93-5 4.71-7.68 6.19s-7.58 3.39-10.88 4.26c-3.3.86-8.93 1.6-12.5 1.64s-8.64-.41-11.25-1.01c-2.61-.59-6.21-1.82-8-2.73s-5.61-3.39-8.5-5.5c-3.86-2.83-5.98-5.37-8-9.6-2.2-4.59-2.75-7.17-2.75-12.79 0-5.98.38-7.53 2.5-10.28 1.38-1.78 3.4-4.27 4.5-5.54s5.15-4.13 9-6.35 8.03-4.35 9.3-4.73c1.26-.38 2.27-1.11 2.25-1.63-.03-.51 2.09-1.21 4.7-1.56 2.61-.34 5.65-1.11 6.75-1.7s4.02-1.36 6.5-1.7 5.85-.42 7.5-.16zm-17.75 12.51c-.56 1.99-1.39 2.68-3.25 2.68-1.58 0-2.4-.51-2.24-1.37.17-.85-.5-1.28-1.75-1.13-1.1.13-3.58 1.02-5.51 1.98-1.93.97-4.81 3.16-6.42 4.89-1.6 1.72-3.74 4.48-4.75 6.13-1.03 1.7-1.83 4.95-1.85 7.5-.02 2.48.66 6.19 1.5 8.25.83 2.06 3.21 5.38 5.27 7.38s6 4.75 8.75 6.12c4.15 2.07 6.54 2.52 14 2.6 7.78.09 9.74-.25 14.5-2.52 3.78-1.81 6.63-4.14 9.12-7.48 1.99-2.67 4.35-6.31 5.25-8.1s1.62-4.49 1.62-6c-.01-1.51-.74-4.77-1.61-7.25-.88-2.48-2.78-6.02-4.24-7.89-1.45-1.86-4.89-5.14-7.64-7.28-4.19-3.27-5.73-3.89-9.5-3.83-2.48.04-5.85.65-7.5 1.36-1.82.78-3.29 2.33-3.75 3.96zM459 215.99c1.38-.02 3.46.98 4.63 2.23 1.16 1.26 2.63 3.29 3.25 4.53.61 1.24 1.13 3.71 1.14 5.5s-.53 3.81-1.2 4.5-2.03 1.25-3.02 1.25-2.22-1.01-2.73-2.25-1.19-3.49-1.5-5-.91-2.77-1.32-2.79-1.76 2.23-3 5c-2.09 4.68-2.48 5.02-5.5 4.79-3.06-.24-3.28-.51-3.75-4.75-.35-3.11-.96-4.5-2-4.5-.82 0-2.62 2.25-4 5-2.17 4.33-2.9 5-5.5 5-2.23 0-3.08-.51-3.3-2-.17-1.1 1.41-4.59 3.5-7.75s4.97-6.26 6.41-6.88c1.53-.66 4.65-.87 7.52-.5 2.71.34 5.58.18 6.39-.36.82-.54 2.61-1 3.98-1.02zm-39.18 2.98c.37-.02 1.47.77 2.44 1.75 1.13 1.14 2.11 4.49 2.72 9.28.72 5.64.66 7.82-.26 8.79-.67.72-2.12 1.3-3.22 1.3s-2.53-.58-3.18-1.3c-.65-.71-1.49-4.66-1.88-8.79-.6-6.35-.45-7.77.99-9.25.94-.96 2.02-1.76 2.39-1.78zM124 223.17c.28-.08 1 .19 1.62.6.61.4 1.4 1.74 1.75 2.98.38 1.37 1.41 2.25 2.63 2.25 1.1 0 2.68 1.01 3.51 2.25s1.5 3.49 1.5 5c-.01 1.51.44 3.65.99 4.75.6 1.2 2 2 3.5 2 1.38 0 3.51.52 4.75 1.15s2.58 1.64 2.98 2.25c.41.6.75 1.66.75 2.35.02.88-1.25 1.11-4.23.8-2.72-.29-5.06.07-6.5 1-1.72 1.1-2.25 2.4-2.25 5.45 0 2.2-.45 4.9-1 6s-1.45 2-2 2-1.45-1.35-2-3-.72-3.56-.38-4.25.34-2.26 0-3.5-1.86-2.82-3.37-3.51c-1.51-.7-2.75-1.93-2.75-2.74s1.31-2.15 2.9-2.99c2.76-1.43 2.86-1.74 2.15-6.01l-1-6.5c-.21-1.6-.93-1.96-3.65-1.81-1.87.1-4.41.44-5.65.75s-3.64 1.8-5.33 3.31c-2.3 2.05-2.93 3.32-2.5 5 .32 1.24 2.44 3.49 4.71 5 2.67 1.78 4.85 4.34 6.16 7.25 1.33 2.95 1.85 5.71 1.52 8-.28 1.93-1.25 4.74-2.16 6.25-1.63 2.72-1.75 2.75-11.9 2.67-7.02-.05-10.96-.52-12.5-1.5-1.27-.8-2.24-2.4-2.22-3.67.01-1.24.8-3.05 1.75-4.03.94-.98 2.17-1.79 2.72-1.79s1.9.93 3 2.07c1.57 1.63 3.22 2.06 7.75 2.03 5.24-.03 5.76-.23 5.91-2.28.08-1.24.07-3.37-.03-4.75-.11-1.59-2.12-4.32-5.5-7.5-2.92-2.75-5.84-6.01-6.47-7.25-.89-1.73-.87-2.75.09-4.39.69-1.18 2.15-3.15 3.25-4.38s4.03-3.17 6.5-4.3c2.47-1.14 5.85-2.26 7.5-2.48s3.22-.46 3.5-.53zM1179.07 228c1.06 0 2.43 1.01 3.05 2.25.82 1.66.82 4.75-.01 11.75-.62 5.23-.91 14.45-.64 20.5.26 6.05.95 11.45 1.53 12s1.33 4.15 1.65 8c.37 4.31 1.23 7.7 2.23 8.83 1.33 1.5 1.49 3.04.89 8.5-.52 4.65-1.27 7.04-2.5 7.89-.98.66-2.22 1.59-2.77 2.06-.59.49-.79 3.82-.5 8.05.28 3.97.14 12.72-1.1 31.67l3.8 3.76c3.5 3.46 3.74 4.05 3.05 7.5-.42 2.06-2.09 5.08-6.74 9.74l-.08 14c-.05 7.7.26 20.07 1.45 41l3.56 3.11c1.96 1.7 3.78 4.32 4.06 5.81s.01 3.47-.6 4.4c-.6.92-2.85 2.54-8.9 5.5l.86 18.59c.47 10.23 1.03 28.04 1.23 39.59.21 11.55.8 24.15 1.33 28 .6 4.39.6 8.86.01 12-.51 2.75-.74 5.67-.5 6.5s.73 10.5 1.09 21.5l.57 31.25c-.05 6.19-.52 15.41-1.05 20.5s-1.06 15.55-1.19 23.25c-.19 11.68.05 14.46 1.46 16.75 1.52 2.48 2.11 2.7 5.94 2.22 2.66-.33 4.9-.05 6 .75 1.08.79 1.76 2.62 1.77 4.78.02 1.92-.1 5.41-.25 7.74-.25 3.92.06 4.52 3.98 7.75 2.34 1.93 5.83 4.18 7.75 5.01s3.5 1.95 3.5 2.5 1.01 1.24 2.25 1.53 3.38 2.34 4.75 4.56c1.38 2.21 4.08 5.23 6 6.7 1.92 1.48 7.33 6.63 12 11.46 6.67 6.89 8.93 8.65 10.5 8.17 1.15-.35 2.63.02 3.5.87.84.82 2.71 1.3 4.25 1.09 1.9-.26 3.39.31 4.84 1.87 1.15 1.24 3.44 4.05 5.08 6.25 2.58 3.44 2.91 4.59 2.41 8.25-.34 2.48-.09 5.19.6 6.5.64 1.24 4.08 5.17 7.64 8.75 3.55 3.58 9.88 9.35 14.07 12.83s9.07 8.1 10.86 10.25c2.34 2.82 3.09 4.55 2.67 6.17-.4 1.5-.06 2.5 1 3 .87.41 2.91 3.11 4.53 6s5.33 7.3 8.25 9.81c2.91 2.51 6.5 6.56 7.98 9 1.47 2.44 2.93 6.35 3.25 8.69.48 3.58.26 4.41-1.43 5.25-1.19.59-2.92.65-4.25.15-1.24-.47-3.83-2.67-5.75-4.88s-4.17-5.28-5-6.82-2.85-4.39-4.5-6.33-4.31-4.68-5.92-6.08c-1.6-1.4-4-3.66-5.32-5.04-1.9-1.97-2.29-3.19-1.84-5.75.43-2.41 0-4.09-1.67-6.5-1.24-1.78-3.83-5.1-5.75-7.36s-5.75-5.84-8.5-7.94c-2.75-2.11-5.77-4.76-6.72-5.89-.94-1.13-1.74-2.51-1.78-3.06-.03-.55-1.73-2.46-3.78-4.25s-4.17-3.29-4.72-3.35c-.55-.05-2.86-.17-5.14-.25-2.36-.08-4.95-.89-6-1.87-1.02-.95-2.31-1.73-2.86-1.73s-2.51-1.7-4.36-3.78c-3.16-3.55-3.37-4.23-3.5-11.52-.08-4.26-.48-7.74-.89-7.75-.41 0-4.93-4.16-10.03-9.25-5.11-5.09-11.07-10.85-13.25-12.8-2.19-1.95-4.98-4.76-6.22-6.25-1.24-1.48-2.92-2.7-3.75-2.7s-1.5-.45-1.5-1-.79-1.22-1.75-1.49-2.95-1.28-4.41-2.25c-1.47-.97-5.18-3.22-8.25-5.01-4.58-2.66-6.27-3.14-9.34-2.65-2.36.38-4.62.11-6.11-.75-1.3-.74-3.22-3.15-4.26-5.35-1.05-2.2-1.9-5.91-1.89-8.25.01-3.22.74-5.16 3.03-8 2.76-3.43 3.03-4.43 3.13-11.75.06-4.4-.4-9.91-1.02-12.25-.66-2.47-.77-4.77-.26-5.5.48-.69 1.15-5.86 1.5-11.5.6-9.69.52-10.28-1.37-10.75-1.1-.27-2-.95-2-1.5s.99-2.01 2.21-3.25c2.19-2.23 2.21-2.52 2-32-.12-16.36-.43-30.2-.71-30.75s-.7-8.09-.94-16.75L1174 510c-.06-1.37-.09-8.8-.06-16.5s-.44-17.6-1.03-22c-.66-4.87-.77-10.94-.29-15.5.44-4.12.69-8.62.56-10-.14-1.4-1.77-3.82-3.71-5.5-2.55-2.21-3.46-3.79-3.43-6 .01-1.65.58-3.97 1.25-5.17.66-1.19 2.51-3.21 6.98-6.83l-.89-11.5c-.48-6.32-.74-17.57-.57-25s.06-14.51-.25-15.75-1.12-2.26-1.81-2.28-2.18-.81-3.32-1.75c-1.14-.95-2.6-2.73-3.25-3.97s-1.19-3.26-1.2-4.5 1.38-3.6 3.1-5.25 4.09-3.46 5.27-4.03c2.03-.97 2.18-1.89 2.65-17 .28-8.78.1-17.77-.39-19.97s-1.46-4.68-2.15-5.5-2.2-3.19-3.36-5.25c-1.15-2.06-2.09-5.21-2.08-7 .01-1.99.88-4.13 2.25-5.53 1.23-1.25 2.79-2.26 3.48-2.25.69.02 1.54-1.21 1.9-2.72s.1-5.45-.57-8.75c-.81-3.98-.99-9.54-.54-16.5l.93-17.5.31-8.18c.04-.65.82-1.88 1.72-2.75.9-.86 2.51-1.57 3.57-1.57zm-959.71 2.05c1.47.45 2.51 2.04 3.33 5.05.69 2.57 1.1 9.97 1 17.74-.11 7.51-.63 13.65-1.19 14.07-.55.4-2.24.81-3.75.91-1.77.12-3.05-.45-3.58-1.57-.45-.96-.67-7.26-.5-14 .18-6.74-.01-12.24-.42-12.23-.41.02-1.09-1.33-1.5-3-.48-1.92-.3-3.74.5-5 .69-1.1 1.86-2.13 2.61-2.31.76-.17 2.33-.02 3.5.34zm-57.46 19.51l6.6 2.08c2.3.71 3.94.48 7-.97 2.75-1.31 5.1-1.71 7.5-1.29 1.93.33 4.54 1.62 5.81 2.86 1.48 1.46 2.48 3.86 2.8 6.76.35 3.17-.03 5.53-1.31 7.98-1.37 2.65-3 3.93-6.8 5.33-2.75 1.02-5.22 2.07-5.5 2.35-.28.27-.72 4.4-1 9.17-.49 8.45-.56 8.67-5.5 8.67v-12.67c0-6.96-.37-13.04-.81-13.5-.45-.45-3.29.52-6.32 2.17-3.99 2.18-6.84 3-10.41 3-3.54 0-5.48-.55-6.99-2-2.06-1.98-2.06-2.06-.28-7.38 1-2.96 2.39-5.89 3.1-6.5.72-.62 1.26-1.57 1.22-2.12s.73-1.74 1.71-2.65c.98-.9 2.63-1.83 3.68-2.05 1.04-.23 3.51.11 5.5.76zm-9.03 11.69c-.48.96-.66 2.31-.41 3 .26.69 1.16 1.59 2 2 .92.45 2.52.05 3.99-1 1.35-.96 3.04-3.02 3.75-4.58 1.1-2.41 1.07-2.97-.2-3.74-.82-.49-2.26-.91-3.18-.91-.92-.01-2.44.77-3.38 1.73-.93.96-2.09 2.54-2.57 3.5zm25.38 3.28c.69 1.39 1.93 2.53 2.75 2.54s2.18-.71 3-1.6c1.18-1.27 1.28-2.29.47-4.79-.83-2.56-1.65-3.24-4.18-3.49-2.78-.28-3.16-.02-3.22 2.25-.04 1.41.49 3.7 1.18 5.09zm377.83-13.55c.78-.01 1.99.56 2.69 1.25.69.7 1.24 2.4 1.21 3.77-.04 1.67-1.92 4.33-5.65 8-3.08 3.02-6.54 6.85-7.7 8.5-1.15 1.65-3.23 4.34-4.61 5.98-1.39 1.63-4.77 5.36-7.52 8.28-3.59 3.81-5.99 5.47-8.5 5.9-3.42.58-3.6.43-8.02-6.28-2.49-3.79-5.13-8-5.88-9.38-.74-1.37-1.07-3.29-.72-4.25.34-.96 1.63-1.76 2.87-1.78s3.02.77 3.96 1.75 2.74 3.8 4 6.28 2.96 4.64 3.79 4.8c.86.17 4.27-3.01 8.03-7.5 3.59-4.29 7.87-9.78 9.5-12.19 1.63-2.42 4.8-6.36 7.05-8.75 2.24-2.4 4.71-4.37 5.5-4.38zM391 260.01c1.98-.01 2.79.77 3.91 3.74.78 2.06 1.3 6 1.16 8.75l-.57 14 4.5.34c2.48.18 6.98-.19 10-.83 4.66-.98 5.73-.92 7 .37 1.33 1.35 1.33 1.7 0 3.1-.82.87-3.75 2.03-6.5 2.56-2.75.54-9.27 1.02-14.5 1.08-8.19.08-9.68-.16-10.77-1.76-.71-1.03-.98-2.54-.61-3.36s1.03-4.2 1.48-7.5.5-8.84.11-12.3c-.57-5.07-.42-6.49.79-7.24.82-.51 2.63-.94 4-.95zm958.25 5.05c.41-.03.99.42 1.28 1s.31 2.04.05 3.25c-.27 1.2-2.87 5.44-5.78 9.41-2.92 3.97-6.76 9.82-8.55 13s-4.61 7.47-6.25 9.53c-1.67 2.08-3.89 3.75-5 3.75-1.19 0-3.75-2.12-6.35-5.25-2.39-2.89-4.81-6.6-5.36-8.25-.6-1.78-.66-3.92-.15-5.25.5-1.3 2.02-2.5 3.61-2.83 1.51-.32 2.77-.44 2.79-.25.02.18.93 2.58 2.03 5.33 1.12 2.81 2.64 5 3.46 5 .8 0 2.59-2.05 3.97-4.56 1.37-2.51 4.53-7.24 7.01-10.5 2.48-3.27 5.34-7.2 6.35-8.74 1.01-1.55 2.81-3.2 3.99-3.69s2.49-.91 2.9-.95zM470.31 267c1.89 0 2.69.52 2.7 1.75 0 .96-.78 2.88-1.74 4.25a30.08 30.08 0 0 1-4 4.5c-1.25 1.1-2.5 3.46-2.77 5.25-.36 2.32-.07 3.39 1 3.75.82.27 3.75-.62 6.5-2 2.75-1.37 6.01-2.52 7.25-2.54 1.24-.03 2.81.65 3.5 1.5.69.84 1.02 2.44.75 3.54s-1.74 2.49-3.25 3.08c-1.51.6-5.45 1.52-8.75 2.06-3.3.53-7.57.72-9.5.41-2.76-.43-3.8-1.24-4.89-3.8-1.18-2.77-1.18-3.9 0-7.69.81-2.6 3.28-6.43 5.95-9.25 3.24-3.43 5.33-4.81 7.25-4.81zM435 272.11c2.67-.02 6.33.87 9 2.18 3.12 1.53 4.69 3.01 5.12 4.82.34 1.43.49 3.68.33 5-.16 1.36-1.94 3.67-4.12 5.37-3.05 2.37-5.05 3.05-9.83 3.36-5.29.35-6.38.09-9.25-2.22-1.93-1.56-3.45-3.84-3.75-5.62-.32-1.95.24-4.34 1.6-6.81 1.16-2.1 3.07-4.32 4.25-4.94 1.18-.61 4.17-1.13 6.65-1.14zm-4.1 11.71c.02.37.95 1.47 2.07 2.43 1.84 1.59 2.3 1.61 5.03.25 1.65-.82 3.23-1.95 3.5-2.5s.27-1.68 0-2.5c-.31-.94-1.77-1.5-3.93-1.5-1.88 0-4.17.71-5.07 1.57-.9.87-1.63 1.88-1.6 2.25zm776.35-5.78c.41-.02 1.26 1.65 1.87 3.71.78 2.6.81 4.36.1 5.75-.56 1.1-1.41 6.66-2.72 22.73l5.5-.57 9.75-1.12c4-.51 4.28-.38 4.84 2.21.34 1.55.1 3.19-.54 3.75-.62.55-4.87 1.47-9.43 2.04s-10.21.79-16.82-.04l.22-13c.12-7.15.48-15.15.81-17.77.47-3.71 1.17-5.09 3.14-6.21 1.39-.79 2.87-1.46 3.28-1.48zm-711.5 2.04c.69-.04 1.93.6 2.75 1.42s1.49 2.06 1.47 2.75c-.01.69-.8 2.05-1.75 3.03-.94.98-2.73 1.77-3.97 1.75s-2.93-.71-3.75-1.53-1.51-1.84-1.52-2.25.56-1.49 1.25-2.38c.7-.9 1.95-1.88 2.77-2.18.82-.29 2.06-.57 2.75-.61zM1243 294.67c1.92.3 5.08 1.59 7 2.87s4.16 3.45 4.98 4.82c1.01 1.71 1.22 3.37.66 5.31-.44 1.56-2.79 4.74-5.22 7.08-4.11 3.95-4.81 4.25-9.92 4.25-4.39 0-6.05-.49-8.25-2.42-2.36-2.07-2.8-3.33-3.1-8.75-.33-6.01-.19-6.47 2.75-9.08 1.71-1.51 4.11-3.17 5.35-3.68 1.24-.52 3.83-.69 5.75-.4zm-6.5 12.88c0 4.94.01 4.95 3.5 5.23 2.56.21 4.11-.33 5.78-2 1.25-1.25 2.26-3.29 2.25-4.53-.02-1.31-1.07-2.87-2.53-3.75-1.37-.82-2.84-1.46-3.25-1.4-.41.05-1.87.41-3.25.79-2.24.63-2.5 1.22-2.5 5.66zm37.77-12.64c.47.32.72 1.45.54 2.51-.17 1.05-1.66 2.67-3.31 3.58-1.68.94-3.66 3.28-4.5 5.33-.83 2.01-1.13 4-.67 4.41.46.42 3.43.76 6.6.76 3.67 0 6.4-.54 7.52-1.5 1.59-1.35 1.91-1.3 3.18.5.77 1.1 1.4 2.79 1.39 3.75s-1.03 2.45-2.27 3.3c-1.69 1.16-4.29 1.47-10.39 1.25-6.47-.24-8.61-.71-10.36-2.3-1.88-1.71-2.15-2.83-1.85-7.69.28-4.6.93-6.37 3.41-9.28 1.8-2.11 4.46-3.92 6.46-4.4 1.87-.45 3.78-.55 4.25-.22zm25.6 9.34c1.02.22 1.39 1.39 1.2 3.79-.14 1.9-.67 4.25-1.17 5.21-.49.96-1.69 1.77-2.65 1.79-.96.03-2.31-.53-3-1.25-.7-.72-.97-2.17-.61-3.29.36-1.1 1.58-3.03 2.71-4.28 1.13-1.26 2.71-2.14 3.52-1.97zm51.88 32.14c.84.67 1.18 2.01.83 3.36-.32 1.24-3.05 4.73-6.08 7.75s-6.74 7.36-8.25 9.64-3.42 5.39-4.25 6.92c-.83 1.52-2.74 4.16-4.25 5.86-1.51 1.69-3.42 3.08-4.25 3.08s-2.17-.23-3-.5-1.51-1.06-1.52-1.75-1.25-3.12-2.75-5.4c-1.5-2.29-3.74-5.55-7.23-10.35l2.75-2.53c1.51-1.4 3.09-2.52 3.5-2.5.41.01 2.39 2.62 4.4 5.78l3.97 6.25c.18.27 1.06-.18 1.95-1s2.14-2.46 2.77-3.63c.64-1.17 2.8-4.54 4.81-7.5 2-2.95 4.76-6.49 6.13-7.87 1.36-1.37 3.39-3.23 4.51-4.12 1.11-.89 2.59-1.84 3.29-2.11.7-.26 1.9.01 2.67.62zm-147.38 11.88c.62.21 1.66 2.37 2.3 4.8.64 2.44 1.21 7.92 1.25 12.18s.19 7.76.33 7.77 1.71-.66 3.5-1.5c2.72-1.27 4.11-1.33 8.5-.33 2.89.65 5.83 1.66 6.54 2.25.72.58 1.28 1.62 1.25 2.31-.02.69-.83 1.98-1.79 2.88-1.38 1.29-2.9 1.5-7.25.99-4-.47-6.59-.2-9.5.97-2.33.95-5.15 1.37-9.5.41l.17-10.75c.1-5.91-.16-12.32-.57-14.25-.62-2.87-.36-3.91 1.44-5.8 1.21-1.27 2.71-2.14 3.33-1.93zm68.14 5.42c.77.29 1.42 1.38 1.44 2.42.03 1.04-.85 3.69-1.95 5.89s-1.78 4.45-1.5 5c.3.61 2.96.76 6.75.39 4.42-.43 6.92-.21 8.53.75 1.31.78 2.26 2.31 2.25 3.61-.02 1.24-.59 2.55-1.28 2.92s-4.85.76-9.25.86c-6.06.14-8.91-.27-11.75-1.67-2.12-1.05-4.01-2.84-4.34-4.11-.33-1.24.12-4.16 1-6.5.87-2.34 3.19-5.56 5.15-7.17 1.96-1.6 4.19-2.68 4.95-2.39zm-24.26 7.32c4.23-.01 5.88.39 6.25 1.49.28.82.16 2.92-.25 4.65s-1.87 4.23-3.25 5.55c-1.37 1.31-3.96 3.05-5.75 3.85s-3.92 1.45-4.75 1.45-2.85-.68-4.5-1.5-3.5-2.51-4.1-3.75c-.84-1.71-.78-2.79.25-4.5.74-1.23 2.25-2.71 3.35-3.28 1.1-.58 3.13-1.7 4.5-2.49 1.38-.8 5.08-1.46 8.25-1.47zm-9.25 8.46c-1.27.71-1.2 1.04.5 2.2 1.1.75 2.56 1.36 3.25 1.35s2.15-.92 3.25-2.02 1.78-2.45 1.5-3-.84-.96-1.25-.91c-.41.04-1.87.41-3.25.82-1.37.4-3.17 1.1-4 1.56zm61.62-4.47c.76 0 1.6.68 1.88 1.5s.16 2.24-.25 3.14-1.42 2.01-2.25 2.47c-1.01.57-2.15.17-5.5-3.3l2.37-1.91c1.31-1.04 3-1.9 3.75-1.9zm60.35 42.21c2 .23 2.59.92 2.82 3.29.22 2.21-.47 3.79-2.62 6-1.6 1.65-4.74 6.15-6.98 10l-6.38 10.81c-1.27 2.09-3.43 4.5-4.81 5.35-1.44.89-3.46 1.29-4.75.95-1.48-.4-3.61-3.09-6.22-7.86-2.18-3.99-3.98-8.04-4-9s1.14-2.31 2.58-3c2.4-1.15 2.84-.99 5.5 2 1.59 1.79 2.89 3.93 2.89 4.75 0 .83.56 1.49 1.25 1.47s1.96-1.03 2.83-2.25 3.52-5.59 5.89-9.72c2.36-4.12 5.46-8.76 6.89-10.29 1.77-1.92 3.39-2.71 5.11-2.5zM1209.08 419c1.06 0 2.23.56 2.6 1.25s.6 6.54.5 13c-.16 10.75-.03 11.71 1.57 11.27.96-.26 6.81-.94 13-1.5s11.92-.79 12.75-.52 1.5.05 1.5-.5 1.46-2.35 3.25-3.99c1.79-1.65 5.72-4.33 8.75-5.97s6.51-2.99 7.75-3.01 2.92.65 3.75 1.47c.83.83 1.5 3.28 1.5 5.5 0 2.54-.89 5.37-2.43 7.75-1.33 2.06-4.14 4.98-6.25 6.48-2.71 1.95-5.05 2.74-8.07 2.75-3.51.02-4.69-.5-6.75-2.98-1.86-2.23-2.73-2.68-3.39-1.75-.5.69-3.98 1.8-7.75 2.47s-11.02 1.46-16.11 1.75c-7.74.44-9.45.27-10.5-1.08-.98-1.26-1-2.94-.1-7.75.64-3.38.91-7.94.61-10.14-.29-2.2-1.15-5.01-1.9-6.25-1.22-2.02-1.09-2.56 1.22-5.25 1.42-1.65 3.45-3 4.5-3zm41.17 21.03c-.69-.02-1.68.76-2.22 1.72-.65 1.19-.57 2.35.25 3.61.88 1.34 1.87 1.67 3.54 1.19 1.27-.37 3.18-1.99 4.25-3.61 1.06-1.62 1.82-3.69 1.68-4.61-.14-.91-.73-1.83-1.32-2.02-.59-.2-1.94.57-3 1.7s-2.49 2.04-3.18 2.02zm36.75-16.02c.28-.05 1.06.6 1.75 1.45.8.98.94 2.17.38 3.29-.48.96-2.28 2.99-4 4.5-1.81 1.59-3.11 3.7-3.09 5 .02 1.24.81 2.8 1.75 3.47s3.17 1.23 4.96 1.25 4.49-.89 6-2.01 3.54-1.79 4.5-1.5c1.23.38 1.75 1.58 1.75 4.04 0 2.66-.66 3.99-2.75 5.53-2.24 1.66-4.22 2.03-10.75 1.99-7.87-.05-8.06-.11-11.77-3.78-2.33-2.32-3.77-4.69-3.78-6.24-.01-1.37 1.57-4.65 3.51-7.28s5.22-5.86 7.28-7.19c2.07-1.33 3.98-2.46 4.26-2.52zm26.36 13.26c.63.21 1.25 1.36 1.39 2.56.14 1.19-.65 3.52-1.75 5.17s-2.67 3-3.5 3-2.06-1.17-2.75-2.61c-1.15-2.41-.99-2.84 2.11-5.56 1.85-1.62 3.87-2.77 4.5-2.56zm-468.11 20.75c.41-.01 1.69 1.22 2.84 2.73 1.87 2.47 2.02 3.62 1.46 11.25-.37 5.1-.22 9.1.38 10 .76 1.14 3.49 1.57 11.28 1.79 8.74.24 10.55.58 12.04 2.25 1.67 1.87 1.66 2.05-.25 3.96-1.78 1.78-3.14 1.97-22.5 1.5l.37 6.5c.21 3.6-.13 7.5-.75 8.75-.9 1.82-1.84 2.2-4.86 2-2.44-.16-3.81-.77-3.94-1.75-.11-.83-.48-4.87-1.44-16.5l-11.19-.28c-6.15-.15-11.31-.38-11.45-.5-.15-.12.19-1.46.75-2.97.85-2.32 1.76-2.85 5.76-3.38 2.61-.35 7.34-.35 16.25.63l-.02-7.75c-.01-4.46.62-9.56 1.5-12 .84-2.34 1.18-4.26.77-4.27-.41 0-.08-.45.75-.98s1.84-.98 2.25-.98zM567.17 527c.46 0 1.28.9 1.83 2s1 3.01 1.01 4.25c0 1.24-1.61 4.73-3.59 7.75s-5 8.42-6.72 12c-1.73 3.58-3.82 8.49-4.67 10.92-1.21 3.48-2.16 4.58-4.53 5.23-1.72.48-4.38.4-6.25-.16-1.83-.56-4.22-2.41-5.46-4.24-1.21-1.79-3.01-3.81-4-4.5-.98-.69-1.79-1.7-1.79-2.25s.9-1.9 2-3c1.46-1.46 2.74-1.83 4.75-1.37 1.51.35 3.65 1.45 4.75 2.45 1.1 1.01 2.49 1.51 3.08 1.12.59-.38 1.88-2.28 2.86-4.2l4.82-9.5c1.68-3.3 3.98-7.35 5.13-9 1.14-1.65 2.95-4.01 4.01-5.25 1.07-1.24 2.31-2.25 2.77-2.25zM409.5 539.13c2.75-.06 6.05.23 7.32.63 1.87.59 2.26 1.33 2 3.74-.32 2.95-.42 3-6.82 3.32-3.57.17-7.08.84-7.79 1.5-.72.65-1.28 2.31-1.25 3.68.03 1.38.61 5.09 1.3 8.25 1.13 5.25 1.06 6.06-.76 9.3-1.1 1.94-2.79 3.74-3.75 3.99s-2.2.23-2.75-.04-1-2.64-.99-5.25-.27-7.45-.62-10.75-1.14-6.58-1.76-7.29c-.69-.79-3.37-1.28-6.88-1.25-3.65.02-5.97-.42-6.36-1.21-.34-.69 0-1.76.75-2.37.75-.62 5.41-2.07 10.36-3.22l11-2.51c1.1-.23 4.25-.46 7-.52zm98.75 3.91c.41-.02 1.88.41 3.25.96 1.82.73 2.57 1.85 2.75 4.15.14 1.78-.51 4.16-1.5 5.5-.96 1.29-1.74 2.69-1.73 3.1s-1.22 1.94-2.75 3.4c-1.52 1.46-3.63 2.81-4.69 3-1.05.19-2.06.91-2.25 1.6-.18.69.56 1.25 1.67 1.25 1.1 0 2.23.45 2.5 1s1.74 1.02 3.25 1.04c1.51.03 3.42-.67 4.25-1.54s2.06-1.57 2.75-1.54c.75.02 1.15 1.14 1 2.79-.18 2.02-1.18 3.22-3.75 4.52-1.93.97-4.85 1.81-6.5 1.87s-4.91-.39-7.25-1.01c-3.06-.82-4.81-2.04-6.25-4.38-1.09-1.79-1.98-4.6-1.97-6.25.02-1.65 1.01-4.58 2.2-6.5a105.91 105.91 0 0 1 4.85-6.98c1.47-1.92 4.19-4.04 6.05-4.71 1.85-.68 3.71-1.25 4.12-1.27zm-7.43 11.99c.1.53.41.97.68.97s1.29-.39 2.25-.86c.96-.48 2.03-1.6 2.37-2.5s.57-1.62.5-1.6-1.44.71-3.05 1.53-2.85 1.93-2.75 2.46zm-68.6-8.03c.43 0 1.07.56 1.42 1.25.36.7-.4 2-1.75 2.98-1.31.95-1.94 1.72-1.39 1.71s1.65 1.46 2.45 3.27 1.35 5.09 1.23 7.29-.78 5.27-1.45 6.83c-.74 1.71-2.22 3.03-3.73 3.33-1.37.28-2.62.36-2.76.17-.15-.18-.37-4.3-.5-9.14-.2-7.37.05-9.05 1.51-10.25 1.08-.89 1.5-2.11 1.1-3.19-.42-1.13.01-2.19 1.22-3 1.04-.69 2.23-1.25 2.65-1.25zm44.03 1.14c.96-.08 2.43.99 3.25 2.36.82 1.38 1.8 4.64 2.16 7.25.56 4.04.33 5.09-1.5 7-1.19 1.24-2.5 2.24-2.91 2.23-.41 0-1.31-.34-1.99-.75-.69-.4-1.59-3.12-2-6.04-.72-5-.9-5.27-3.18-4.65-1.33.36-3.24 1.63-4.25 2.81-1 1.18-2.19 3.5-2.64 5.15-.48 1.81-1.88 3.5-3.5 4.25-1.48.69-3.03 1.08-3.44.87s-1.09-2.24-1.5-4.5c-.41-2.27-1.2-4.35-1.75-4.62s-2.8 2.42-5 6c-2.96 4.81-4.71 6.65-6.75 7.08-1.51.32-2.98.32-3.25-.01-.27-.32 1.45-4.3 3.84-8.83s5.31-9.25 6.5-10.49c1.19-1.23 3.17-2.47 4.41-2.75 1.24-.27 3.49.23 5 1.11 2.56 1.5 2.99 1.49 6.25-.25 1.93-1.02 5.07-2.13 7-2.47 1.93-.33 4.29-.67 5.25-.75zm1355.32.86c.23 0 .42 4.39.41 9.75-.01 6.72-.31 9.28-.99 8.25-.54-.83-.95-3.98-.91-7 .03-3.02.29-6.74.56-8.25s.69-2.75.93-2.75zM344.5 550.17c3.09-.12 5.31.69 9.76 3.59 3.17 2.05 5.74 4.19 5.71 4.74-.02.55 1.76 3.7 3.96 7 2.96 4.44 4.01 7.04 4.04 10 .02 2.2-.66 6.7-1.52 10s-2.97 8.25-4.67 11c-1.71 2.75-4.05 5.81-5.19 6.81-1.15 1-4.11 2.74-6.59 3.87-2.48 1.14-7.2 2.48-10.5 2.99-4.02.62-8.48.54-13.5-.22-4.12-.63-7.95-1.53-8.5-1.99s-2.91-1.54-5.25-2.4-5.82-2.8-7.75-4.31c-1.94-1.52-3.49-3.64-3.48-4.75.01-1.1-.56-2.58-1.25-3.3-.85-.86-1.19-3.78-1.02-8.75.14-4.1.67-8.46 1.17-9.7.51-1.24 2.89-4.27 5.28-6.75 2.4-2.48 6.14-5.87 8.33-7.55 2.18-1.67 5.54-3.95 7.47-5.05 1.93-1.11 5.52-2.55 8-3.19 2.48-.65 6.07-1.34 8-1.54 1.93-.19 5.3-.42 7.5-.5zm-15.83 10.15c-3.4-.53-4.61-.07-10.5 3.97-3.67 2.51-7.79 6.06-9.17 7.89-2.09 2.77-2.5 4.43-2.5 10 0 5.18.46 7.31 2.07 9.5 1.14 1.55 4.74 4.26 8 6.01 3.47 1.87 8.84 3.69 12.93 4.38 3.85.64 9.36.89 12.25.55 3.05-.36 6.53-1.56 8.32-2.87 1.68-1.24 4.39-4.27 6.01-6.75 2.09-3.17 3.14-6.27 3.58-10.5.55-5.3.31-6.52-2.01-10.5-1.45-2.48-3.33-5.85-4.19-7.5-.95-1.82-3.4-3.89-6.26-5.26-2.58-1.24-5.82-2.24-7.2-2.23-1.37.02-3.62.91-5 1.97-1.9 1.48-3.42 1.8-6.33 1.34zm-184.17-3.05c2.47.19 3 .67 3 2.72 0 1.96-.95 2.93-4.5 4.63-2.47 1.17-5.32 2.98-6.33 4.01-1.19 1.22-1.65 2.75-1.32 4.37.38 1.82 1.64 2.91 4.61 4 2.25.83 4.07 1.73 4.04 2-.02.27 1.54 1.29 3.48 2.25s4.25 3.21 5.14 5c1 1.99 1.38 4.31 1 6-.34 1.51-1.44 3.54-2.44 4.5-1.01.96-3.14 2.91-4.75 4.33-1.76 1.55-5.73 3.27-9.93 4.31-3.85.96-8.24 1.49-9.75 1.18-1.51-.32-3.04-1.36-3.4-2.32s-.2-2.42.36-3.25c.7-1.04 2.83-1.52 6.9-1.56 3.94-.04 6.88-.68 8.89-1.93 1.65-1.04 4.02-2.81 5.28-3.94 1.25-1.14 2.26-2.74 2.24-3.57s-1.5-2.72-3.28-4.2c-1.78-1.49-4.97-3.29-7.08-4-2.11-.72-4.86-2.42-6.12-3.8-1.26-1.37-2.53-3.84-2.82-5.48s.06-4.12.78-5.5c.72-1.39 2.37-3.51 3.65-4.71 1.29-1.21 3.92-2.89 5.85-3.74s4.85-1.43 6.5-1.3zm109 2.34c2.56.31 4.98 1.46 6.71 3.19 2.47 2.47 2.7 3.35 2.66 10.2-.04 5.86-.47 8.05-1.99 10-1.07 1.38-1.93 3.4-1.9 4.5s.38 2.61.79 3.35c.53.98 1.95 1.17 5.23.7 3.64-.53 5.03-.26 7.25 1.4 1.51 1.13 2.75 2.95 2.75 4.05s-.56 2.29-1.25 2.65-5.75.82-11.25 1.02l-11.86.6c-1.03.13-2.38-.52-3-1.45-.92-1.35-.15-3.63 4.06-12 4.57-9.07 5.11-10.79 4.5-14.21-.39-2.14-1.48-4.39-2.43-5-1.26-.81-2.73-.81-5.5.01-2.07.61-4.33.84-5.02.5-.94-.46-1.01-1.44-.25-3.87.58-1.89 2.15-3.85 3.75-4.69 1.67-.87 4.32-1.24 6.75-.95zm-82.45.39c1.07 0 2.63.67 3.45 1.5s2.18 4.09 3.02 7.25 2.16 6.88 2.94 8.25c.79 1.38 2.69 2.85 4.23 3.28 1.55.42 3.32 1.55 3.94 2.5 1.07 1.62 1.32 1.62 4.5.02 2.94-1.49 3.56-1.53 4.87-.26 1.21 1.17 1.26 1.69.23 2.7-.69.69-1.26 2.5-1.25 4.01s.47 2.75 1.02 2.75 1.45-1.35 2-3c.66-1.97 1.59-2.91 2.71-2.75.94.14 2.36 1.38 3.15 2.75 1.23 2.15 1.24 2.92.04 5.46-1.05 2.23-2.39 3.19-5.4 3.86-2.2.48-4.9.63-6 .33-1.1-.31-2.73-1.81-3.63-3.35-.94-1.6-1.47-4.2-1.25-6.05.38-3.22.34-3.25-3.87-3.22-2.76.02-5.04.73-6.5 2-1.61 1.41-2.24 3.04-2.21 5.72.03 2.22-.58 4.26-1.5 5-.84.69-2.22 1.02-3.04.75-1.14-.38-1.38-1.57-1-5 .42-3.79.18-4.66-1.5-5.5-1.1-.55-3.12-1-4.5-1-1.37 0-2.76-.56-3.09-1.25-.32-.69-.09-2.26.5-3.5.6-1.24 1.77-2.25 2.59-2.25s2.67-.56 4.1-1.25c2.32-1.11 2.54-1.66 2-5-.33-2.06-1.28-5.77-2.1-8.25s-1.25-4.95-.95-5.5 1.43-1 2.5-1zm396.42 17.21c1.53.22 2.1 1.14 2.3 3.79.21 2.85-.44 4.27-3.5 7.63l-6.25 7c-1.36 1.58-3.03 3.77-3.71 4.87s-1.55 2.67-1.95 3.5c-.39.83-2.66 3.64-5.04 6.25-2.37 2.61-4.32 5.31-4.31 6 0 .69-.78 1.94-1.75 2.78-.97.83-3.11 2.12-4.76 2.86-1.65.73-3.79 1.06-4.75.72-.96-.33-1.75-1.51-1.75-2.61s-.34-2.17-.75-2.37c-.41-.21-1.42-2.52-2.25-5.13s-1.84-4.92-2.25-5.13c-.41-.2-.77-1.38-.79-2.62-.03-1.24.69-2.92 1.58-3.75 1.24-1.13 2.04-1.23 3.3-.41.91.6 2.39 2.62 3.29 4.5.89 1.88 2.41 4.08 3.36 4.91 1.58 1.36 1.97 1.22 4.2-1.5 1.35-1.65 3.66-4.75 5.13-6.9l3.68-5.48c.55-.87 2.98-4.29 5.41-7.6s5.56-7.28 6.97-8.81c1.52-1.66 3.38-2.67 4.59-2.5zM218.48 580c.84 0 3.17.79 5.19 1.75 2.01.96 4.71 3.33 6 5.25s2.34 4.96 2.33 6.75c0 2.37-1.01 4.33-3.75 7.25-2.22 2.36-4.67 4-6 4-1.24 0-3.15.9-4.25 2-1.14 1.14-1.94 3.19-1.87 4.75.08 1.51-.15 3.54-.5 4.5-.34.96-.18 1.98.37 2.25.65.33.6 1.62-.15 3.75-.62 1.79-1.52 3.81-2 4.5-.47.69-1.3 1.02-1.85.75-.62-.31-.94-7.66-.7-38.36l2.83-4.57c1.56-2.51 3.52-4.57 4.35-4.57zm-.73 15.52c.43 2.56 1.29 4.5 2 4.5.69-.01 2.15-.92 3.25-2.02s2.01-3.01 2.03-4.25-.77-3.03-1.75-3.97c-.98-.95-2.53-1.74-3.45-1.75-.91-.02-1.92.64-2.25 1.47-.32.83-.24 3.53.17 6.02zM405.48 594c1.62 0 3.21.99 4.44 2.75 1.24 1.77 2.04 4.89 2.58 14.75h8.1c5.77 0 8.58.43 9.79 1.5.94.83 1.68 2.29 1.65 3.25-.02.96-1.05 2.17-2.29 2.68s-6.3 1.44-11.25 2.06l-11.87 1.32c-2.06.14-3.08-.37-3.62-1.81-.42-1.1-.36-3.01.12-4.25s.87-3.6.87-5.25-.71-5.14-1.59-7.75c-1.19-3.58-1.32-5.3-.51-7 .69-1.45 1.96-2.25 3.58-2.25zm47.39 5.99c1.45 0 4.43.9 6.63 2.01s4.79 2.01 5.75 2.01c.96-.01 2.43 1.12 3.25 2.49.82 1.38 1.5 4.08 1.5 6 0 2.11-.95 4.79-2.38 6.75-1.31 1.79-4.01 4.04-6 5s-6.37 1.86-9.73 2c-5.89.24-6.22.12-9.01-3.25-1.67-2.01-2.9-4.67-2.89-6.25 0-1.51.87-4.44 1.92-6.5s3.36-5.21 5.12-7c1.99-2.02 4.2-3.25 5.84-3.26zm-4.89 13.76c-.01 1.51.89 3.76 2 5S452.45 621 453 621s2.01-.52 3.25-1.16l3.75-1.85c.82-.38 1.61-1.88 1.75-3.34.19-1.98-.57-3.28-3-5.12-1.79-1.36-3.93-2.47-4.75-2.47s-2.51.89-3.75 1.97c-1.3 1.14-2.26 3.14-2.27 4.72zM485.66 601c1.29 0 3.02.23 3.84.5s1.49 1.29 1.48 2.25-1.81 2.99-4 4.5-4.26 3.76-4.6 5-.34 2.81 0 3.5c.42.84 1.85 1.05 4.37.66 2.06-.33 5.21-1.12 7-1.75 2.65-.95 3.53-.89 4.85.34 1.08 1.01 1.4 2.4 1 4.25-.33 1.51-1.39 3-2.35 3.3s-4.9.83-8.75 1.17c-5.01.45-7.96.22-10.38-.8-1.86-.78-3.77-2.21-4.25-3.17S473 618.1 473 617s.79-3.67 1.75-5.72c.96-2.04 3.28-5.19 5.16-7 1.87-1.81 4.45-3.28 5.75-3.28zm25.01 12c.18 0 1.11.27 2.06.61 1.03.35 1.66 1.48 1.54 2.75-.11 1.18-1.12 3.38-2.24 4.89-1.11 1.51-2.93 2.75-4.03 2.75s-2.05-.56-2.12-1.25c-.06-.69-.02-2.15.09-3.25.12-1.1 1.14-3.01 2.29-4.25 1.14-1.24 2.23-2.25 2.41-2.25zm851.58 15.06c.96-.03 1.75.61 1.75 1.44s.24 2.06.53 2.75-.95 2.86-2.75 4.82c-1.81 1.96-4.63 6.18-6.28 9.38s-4.46 7.1-6.25 8.68-3.24 3.21-3.22 3.62-.89 1.65-2.03 2.75-2.05 2.45-2.03 3c.03.55-1.23 2.58-2.79 4.5s-4.15 3.85-5.76 4.28c-2.35.63-3.37.33-5.2-1.5-1.25-1.25-2.26-2.73-2.24-3.28.01-.55-.87-2.69-1.98-4.75-1.1-2.06-2-4.31-2.01-5 0-.69-.7-2.6-1.56-4.25-1.52-2.91-1.48-3.07 1.25-5.36 2.72-2.28 2.87-2.29 4.14-.5.72 1.02 2.64 4.67 4.25 8.11 2.07 4.42 3.37 6.1 4.43 5.75.83-.27 1.5-.95 1.5-1.5s2.92-5.5 6.5-11 6.95-10 7.5-10 1-.56 1-1.25c-.01-.69 1.16-2.96 2.59-5.06s3.57-4.21 4.75-4.69c1.19-.48 2.95-.9 3.91-.94zm-143.88 12.9c.62-.02 1.77 1.44 2.55 3.25 1.11 2.55 1.27 5.64.7 13.79-.52 7.59-1.13 10.71-2.17 11.25-.8.41-1.47 1.31-1.49 2-.04.89.41.82 1.54-.25 1.42-1.34 1.58-1.31 1.54.25-.03 1.33.5 1.61 2.21 1.16 1.24-.32 6.08-.8 10.75-1.07 8.49-.48 8.5-.48 11.5 2.67 2.61 2.74 2.87 3.5 1.98 5.82-.74 1.94-1.83 2.75-4 2.96-1.64.16-4.78-.45-6.98-1.35-2.89-1.19-5.39-1.46-9-.98-2.75.37-6.35.78-8 .91s-3.56.56-4.25.94c-.75.41-1.44-.01-1.71-1.06-.25-.96-.52-8.05-.59-15.75l-.16-17.4c-.02-2.34.68-3.99 2.22-5.25 1.23-1.02 2.74-1.87 3.36-1.89zm69.13 12.03c.55-.05 1.67.64 2.5 1.51 1.34 1.42 1.27 1.88-.6 4.29-1.15 1.49-2.83 4.17-3.75 5.96-.91 1.79-1.65 3.7-1.65 4.25s1.58 1 3.5 1c2.07 0 5.04-1.02 7.25-2.5 3.03-2.02 4.01-2.26 5.08-1.25.81.76 1.08 2.22.7 3.75-.35 1.38-2.07 3.75-3.83 5.29-2.78 2.42-4.02 2.78-9.45 2.75-4.63-.03-6.68-.49-7.89-1.79-.9-.96-2.03-2.76-2.5-4s-.5-3.94-.05-6c.44-2.06 2.06-5.45 3.6-7.53 1.55-2.08 3.54-4.2 4.45-4.72.9-.52 2.09-.97 2.64-1.01zm-22.63 1.75c2 .32 4.66 1.29 5.92 2.17 1.27.87 2.73 2.83 3.25 4.34.53 1.51.62 3.36.21 4.11s-2.95 3.79-5.65 6.75c-4.11 4.52-5.56 5.46-9 5.82-3.55.37-4.53 0-7.35-2.75-2.85-2.79-3.18-3.64-2.67-6.93.33-2.06 1.68-5.25 3.02-7.09 1.33-1.83 3.83-4.15 5.54-5.16 2.18-1.29 4.19-1.66 6.73-1.26zm-6.87 16.34c1.11.68 2.34.02 4.75-2.58 1.79-1.92 3.25-4.17 3.25-5s-.89-1.5-1.99-1.5c-1.21 0-3.07 1.6-4.75 4.08-2.35 3.47-2.54 4.21-1.26 5zm55-6.79c1.63.14 2.62.91 2.83 2.21.21 1.25-.81 3.03-2.75 4.75-1.69 1.51-3.53 2.75-4.08 2.75s-1.67-1.12-2.5-2.5c-.83-1.37-1.19-3.19-.82-4.02.38-.84 1.62-1.95 2.75-2.46 1.14-.52 3.2-.84 4.57-.73zm108.85 28.9c1.75.21 2.75.99 2.94 2.31.17 1.1-.64 4.02-1.8 6.5-1.15 2.48-3.42 6.52-5.04 9-1.63 2.48-3.81 6.3-4.86 8.5l-3.48 7.5c-.86 1.92-1.99 4.17-2.5 5s-1.65 3.64-2.52 6.25c-1.22 3.63-2.53 5.34-5.59 7.25-2.2 1.38-4.45 2.5-5 2.5s-2.28-2.81-3.84-6.25-3.36-7.71-4-9.5c-.9-2.52-.88-3.59.09-4.79.69-.85 2.04-1.53 3-1.5.96.02 2.65 1.39 3.75 3.04s2 3.67 2 4.5.56 1.35 1.25 1.18c.69-.18 1.98-2.55 2.86-5.25.89-2.71 2.8-6.95 4.25-9.43 1.46-2.48 4.78-8.71 7.39-13.86s5.58-10.24 6.6-11.31c1.15-1.2 2.87-1.83 4.5-1.64zm-131.14 24.82c.87-.01 1.2 2.39 1.15 8.24-.04 4.54-.72 10.05-1.51 12.25s-1.19 5.01-.89 6.25c.29 1.24 1.12 2.25 1.84 2.25.71 0 1.73-.38 2.25-.84s3.42-1.36 6.45-2.01c3.03-.64 7.3-1.28 9.5-1.41 3.74-.22 4.02-.45 4.25-3.49.18-2.29 1.28-4.13 3.75-6.25 1.92-1.65 4.29-3.05 5.25-3.12.96-.06 2.42-.04 3.25.05s2.74-.31 4.25-.89c2.48-.94 2.95-.74 4.75 1.96 1.1 1.65 2 3.9 2 5s-.67 3.35-1.5 5-1.95 3-2.5 3-2.24 1.4-3.75 3.1c-1.51 1.71-4.21 3.73-6 4.5s-4.04 1.09-5 .71-2.26-1.39-2.88-2.25c-.93-1.29-1.62-1.36-4-.39-1.58.64-6.47 1.43-10.87 1.74-4.68.33-8.62 1.14-9.5 1.95-.83.76-2.76 1.55-4.3 1.76s-3.22-.18-3.75-.87c-.59-.78-.61-3.05-.04-6 .49-2.61.99-6.55 1.11-8.75.11-2.2.26-7.36.34-11.47.13-6.89.33-7.56 2.64-8.73 1.38-.7 3.05-1.28 3.71-1.29zm29.79 26.49c.28 1.38.95 2.5 1.5 2.5s2.08-1.46 3.41-3.25 2.56-4.15 2.75-5.25c.26-1.53-.29-2.07-2.32-2.31-2.11-.25-2.99.32-4.25 2.75-.88 1.68-1.37 4.19-1.09 5.56zm35.75-21.44c.96-.03 1.75.39 1.75.94s-.64 2.24-1.42 3.75c-.79 1.51-2.35 4.77-3.49 7.25-1.13 2.48-2.07 4.84-2.08 5.25 0 .41.89.75 1.99.75s3.46-.9 5.25-2c1.79-1.09 4.26-1.99 5.5-2 1.73 0 2.25.57 2.25 2.5 0 1.38-.45 3.4-1 4.5s-1.67 2-2.5 2-1.49.34-1.48.75-1.79 1.54-4 2.5c-2.22.97-5.03 1.48-6.27 1.15-1.26-.33-3.78.16-5.75 1.12-3.35 1.63-3.55 1.62-4.66-.16-.92-1.47-.75-3.12.8-7.86 1.08-3.3 3.61-8.84 5.62-12.31 2.01-3.48 4.57-6.71 5.7-7.19 1.12-.48 2.83-.9 3.79-.94zm23 15.08c.41-.08.75 1.32.76 3.11 0 1.79-.67 4.26-1.5 5.5-.95 1.41-2.35 2.16-3.76 2-1.8-.2-2.3-.96-2.52-3.75-.15-1.92.22-4.04.81-4.69.6-.65 2.07-1.38 3.27-1.61l2.94-.56zm-654.5 62.98c.14-.07.92.55 1.75 1.38 1.33 1.33 1.02 2.31-2.85 8.75L717.18 822c-1.17 1.92-3.21 5.75-4.53 8.5s-3.92 6.43-5.77 8.18c-1.86 1.75-4.5 3.47-5.88 3.83-2.08.54-2.71.18-3.75-2.18-.69-1.56-1.65-5.08-2.15-7.83-.49-2.75-.56-5.9-.15-7s1.6-2.34 2.65-2.75c1.14-.46 2.43-.26 3.22.5.72.69 1.62 2.95 2 5.02.37 2.07 1.05 3.65 1.5 3.5s2.71-3.87 5.03-8.27c2.31-4.4 5.91-11.01 8.01-14.68 2.09-3.67 4.55-6.88 5.47-7.13s1.78-.51 1.92-.57zm508.5 1.03c.41-.08 1.8.86 3.08 2.1 1.57 1.52 2.9 4.84 4.12 10.25.98 4.4 3.09 11.71 4.67 16.25s2.9 8.81 2.92 9.5c.03.69-.65 1.81-1.5 2.5-.84.69-2.33 1.04-3.29.78s-2.71-2.4-3.88-4.75c-1.18-2.35-2.47-6.98-2.88-10.28s-1.25-7.02-1.87-8.27c-1.01-2.05-1.35-1.46-3.53 6-1.32 4.55-3.28 10.07-4.36 12.27s-2.53 4.67-3.22 5.5-2.05 3.98-3.02 7-2.83 7.64-4.13 10.25c-2.09 4.21-2.36 6.15-2.37 17-.01 10.95.24 12.78 2.42 17.25 1.34 2.75 3.57 6.13 4.97 7.5 1.4 1.38 5.37 4.2 8.83 6.27 4.5 2.69 7.43 3.76 10.29 3.75 2.2 0 5.58.42 7.5.94s5.53 1.19 8 1.49 5.06 1.1 5.74 1.8c.99.99.99 1.94-1.24 7.98l-6.75-.61c-3.71-.34-7.54-1.02-8.5-1.51-.96-.5-4.67-1.34-8.25-1.87-4.44-.67-8-1.96-11.25-4.11-2.61-1.72-5.2-3.13-5.75-3.13s-2.84-1.69-5.09-3.75c-2.24-2.06-4.66-4.87-5.36-6.25l-2.83-5.5c-1.16-2.24-1.57-6.31-1.62-16-.05-9 .41-14.69 1.5-18.5.87-3.02 3.16-8.87 5.09-13 1.94-4.12 4.55-8.85 5.81-10.5s3.17-5.25 4.26-8 2.26-7.14 2.61-9.75c.46-3.46.29-4.76-.62-4.78-.69-.02-2.88 1.44-4.87 3.25l-6.75 6.03c-1.72 1.51-3.92 2.76-4.88 2.77s-2.65-.64-3.75-1.44c-1.77-1.29-1.83-1.62-.5-2.9.83-.79 3.97-3.11 7-5.15 3.03-2.05 8.11-6.8 11.31-10.56 3.94-4.65 6.67-6.98 8.5-7.26l3.44-.56zm-648.75 7.93c2.75-.03 6.13.52 7.5 1.21 1.38.69 2.61 2.26 2.75 3.49.16 1.4-.58 2.75-2 3.65-1.66 1.05-3.44 1.21-6.75.62-2.48-.44-5.29-.63-6.25-.43-1.36.3-1.72 1.33-1.63 4.63.07 2.34-.14 6.95-.47 10.25-.43 4.43-1.18 6.58-2.87 8.2-1.25 1.2-2.73 1.99-3.28 1.73-.57-.26-1-4.89-1-10.86 0-5.72-.23-10.67-.5-10.98-.27-.32-2.86-.02-5.75.66-4.48 1.07-5.48 1.03-6.84-.25-1.25-1.18-1.36-1.97-.5-3.75.74-1.52 2.79-2.73 6.34-3.73l10.75-2.93c3.02-.8 7.75-1.48 10.5-1.51zm19.66 9.92c.46 0 .83 1.01.81 2.25-.01 1.24-.8 3.05-1.75 4.04-1.51 1.56-1.56 2.25-.45 5.5 1.06 3.08 1.02 4.73-.21 9.71-.82 3.3-2.07 6.32-2.77 6.71-.71.39-1.57.39-1.92 0s-.86-3.86-1.14-7.71c-.41-5.68-.16-7.47 1.29-9.5.98-1.37 1.6-3.06 1.38-3.75s.57-2.6 1.76-4.25c1.2-1.65 2.55-3 3-3zM524 822.74c1.92.26 4.85 1.11 6.5 1.89s3.45 1.39 4 1.36 3.25 1.18 6 2.68 5.53 3.43 6.17 4.28 1.96 4.25 2.92 7.55c.97 3.3 2.11 6.45 2.55 7 .43.55.34 3.7-.2 7-.53 3.3-2.03 7.8-3.33 10-1.29 2.2-4.1 5.54-6.23 7.41-2.14 1.88-5.9 4.26-8.38 5.3-2.48 1.03-7.2 2.27-10.5 2.75s-9.5.57-13.78.21c-4.28-.37-8.11-1.12-8.5-1.67-.4-.55-1.91-1.67-3.35-2.5-1.45-.83-4.72-3.98-7.27-7-3.73-4.43-4.63-6.23-4.62-9.25.01-2.06.94-5.89 2.07-8.5 1.19-2.74 4.89-7.62 8.75-11.53 4.88-4.94 6.7-7.51 6.7-9.44 0-1.98.88-3.15 3.5-4.65 1.93-1.09 5.75-2.3 8.5-2.68s6.58-.48 8.5-.21zm-5.69 14.69c-1.82 1.25-4.22 1.86-6.81 1.72-3.44-.17-4.71.41-9 4.16-3.26 2.84-5.43 5.73-6.23 8.28-.68 2.15-1.25 4.81-1.26 5.91s1.93 4.25 4.31 7c3.29 3.8 5.64 5.44 9.76 6.81 4.46 1.5 6.81 1.67 13.28 1 4.32-.44 8.04-1.15 8.25-1.56.22-.41 1.18-.75 2.14-.75.96.01 3.45-1.46 5.52-3.25s4.37-4.37 5.1-5.75c.74-1.37 1.48-3.4 1.65-4.5s-.04-3.8-.46-6-1.51-5.74-2.41-7.86c-1.3-3.04-2.83-4.46-7.15-6.62-3.02-1.51-7.14-3.05-9.15-3.41-2.99-.55-3.75-.35-4.19 1.11-.3.98-1.8 2.65-3.35 3.71zm152.55-15.47c2.12-.03 4.16.59 4.89 1.5.72.88 1 2.71.66 4.29-.33 1.51-1.45 3.99-4.41 8.25h2.5c1.38 0 2.79.56 3.14 1.25.36.7-.41 2.03-1.75 3.03-1.31.98-3.97 2.45-5.89 3.27-1.92.83-5.08 1.48-7 1.45-2.23-.03-4.33-.85-5.78-2.27-1.25-1.23-2.26-3.02-2.25-3.98.02-.96 1.47-3.89 3.23-6.5 1.75-2.61 4.5-5.99 6.11-7.5 2.04-1.93 3.99-2.76 6.55-2.79zM663.71 832c-.32.83-.05 2.07.6 2.76.95 1.01 1.85.49 4.41-2.5 1.77-2.07 3.01-4.1 2.75-4.51s-1.03-.74-1.72-.73-2.2.8-3.36 1.75c-1.15.95-2.36 2.4-2.68 3.23zm-21.46-8.92c2.13-.06 3.14.66 4.45 3.17.94 1.79 1.85 5.5 2.04 8.25.27 3.92-.05 5.27-1.45 6.27-.98.69-2.58 1.26-3.54 1.25-1.33-.02-1.75-.86-1.75-3.52 0-1.92-.45-4.62-1-6-.88-2.19-1.28-2.36-3.25-1.38-1.24.62-3.28 2.09-4.53 3.25-1.26 1.17-2.77 3.71-3.38 5.63-.6 1.92-1.82 4.3-2.72 5.28-.89.98-2.41 1.77-3.37 1.75-1.45-.02-1.75-.97-1.75-5.53 0-3.02-.45-6.4-1-7.5s-1.45-2-2-2-1.29 1.91-1.63 4.25c-.35 2.34-1.25 5.26-2 6.5-.76 1.24-2.04 2.25-2.87 2.25s-1.76-.56-2.07-1.25-.03-3.95.63-7.25c.93-4.61 1.99-6.75 4.57-9.25 2.53-2.44 3.93-3.09 5.62-2.62 1.24.35 3.49 1.47 5 2.5 2.72 1.85 2.8 1.84 6.5-.47 2.06-1.29 4.42-2.61 5.25-2.92.83-.32 2.74-.62 4.25-.66zm-221.75 5.96c1.65-.02 4.46.87 6.25 1.96 3.2 1.97 3.24 2.1 2.75 8-.4 4.76-1.23 7.04-7.5 16l2.5 1.5c1.38.83 3.18 1.5 4 1.5s2.46 1.01 3.63 2.25c1.65 1.73 1.98 2.94 1.46 5.25-.37 1.65-1.44 3.84-2.38 4.86s-3.96 2.98-6.71 4.35a24.98 24.98 0 0 1-10.5 2.65c-5.17.13-5.52-.01-5.8-2.36-.17-1.37.2-2.95.81-3.5.62-.55 3.9-1.32 7.3-1.71 3.41-.39 6.79-1.29 7.52-2 .76-.74 1.08-2.26.75-3.54-.41-1.6-2.03-2.76-5.59-4-2.76-.96-5.02-1.98-5.02-2.25.01-.27 1.58-3.42 3.5-7 1.91-3.58 3.48-7.62 3.48-9 0-1.37-.78-3.3-1.73-4.28-.94-.98-2.28-1.77-2.97-1.75s-2.04.91-3 1.98c-.96 1.08-2.87 2.09-4.25 2.25-2.09.25-2.54-.16-2.75-2.45-.14-1.51.17-2.75.68-2.75s1.63-.67 2.5-1.5c.86-.83 3.03-2.16 4.82-2.96s4.6-1.48 6.25-1.5zm-111.75 2.07c.14-.06 1.15.34 2.25.89s2.02 1.56 2.04 2.25-1.22 1.78-2.75 2.42a40.57 40.57 0 0 1-5.79 1.82c-1.65.35-4.01 1.29-5.25 2.08-1.52.96-2.25 2.41-2.25 4.43 0 1.65.45 3 1 3s2.24 1.12 3.75 2.5c1.51 1.37 5.11 4.3 8 6.5 3.6 2.74 5.25 4.71 5.24 6.25 0 1.46-2.19 4.3-6.25 8.1-3.43 3.21-7.93 6.7-9.99 7.75-2.06 1.04-4.87 1.9-6.25 1.9-1.52 0-3.87-1.37-6-3.5-1.93-1.92-3.51-4.06-3.52-4.75s.64-2.15 1.45-3.25c1.44-1.98 1.5-1.97 6.76.75 2.92 1.51 5.87 2.74 6.56 2.75.69 0 3.28-1.69 5.76-3.75 2.49-2.06 4.51-4.31 4.5-5 0-.69-2.71-3.27-6.01-5.75s-6.68-4.5-7.5-4.5-2.42-1.24-3.53-2.75c-1.12-1.51-2.02-3.42-1.99-4.25s1.28-3.23 2.79-5.35c1.5-2.12 4.3-5.03 6.23-6.47s5.07-2.91 7-3.28 3.61-.72 3.75-.79zm18.4 5.89c1.02 0 2.53 1.13 3.35 2.5.82 1.38 1.5 3.06 1.51 3.75 0 .69.45 2.94 1 5 .89 3.37 1.32 3.75 4.24 3.72 2.06-.02 3.89.71 5 2 .96 1.12 1.58 2.37 1.37 2.78s-1.89 1.11-3.75 1.54c-1.85.44-4.17 1.56-5.15 2.5-.99.94-2.03 3.06-2.32 4.71s-1.28 4.08-2.21 5.39c-1.19 1.68-2.11 2.12-3.08 1.5-1.03-.66-1.23-2.12-.75-5.64.5-3.74.32-4.86-.86-5.25-.82-.27-2.62-.5-4-.5-1.37 0-2.5-.45-2.5-1s.56-1.44 1.25-1.98c.69-.53 2.5-1.99 6.8-5.52l-2.06-5.5c-1.13-3.02-2.27-5.73-2.53-6-.25-.27.28-1.29 1.19-2.25.9-.96 2.48-1.75 3.5-1.75zm52.25 16.27c1.7.27 5.24 1.9 7.85 3.61 3.16 2.08 4.8 3.87 4.9 5.37.08 1.24.03 3.83-.11 5.75-.13 1.92-.88 4.17-1.65 5-.78.83-2.19 2.54-3.15 3.82-.96 1.27-3.31 2.64-5.24 3.03-3.44.71-3.5.81-3.76 6.19-.14 3-.48 6.47-.75 7.71s-1.39 2.7-2.49 3.25-2.68.77-3.5.5c-1.23-.41-1.48-2.61-1.37-12.25.08-6.46-.15-13.21-.5-15-.34-1.79-1.08-3.25-1.62-3.25-.55 0-2.68 1.83-4.75 4.06-2.14 2.3-5.27 4.46-7.26 4.99-1.93.52-4.29.94-5.25.94-.96.01-2.02-.78-2.35-1.74-.32-.96-1.29-3.1-2.13-4.75-.88-1.7-1.29-4.08-.95-5.5.32-1.37 2.3-4.19 4.38-6.25 2.09-2.06 4.59-3.75 5.55-3.75s1.73.56 1.71 1.25-1.37 2.71-3 4.5c-2.34 2.56-2.91 4.04-2.71 6.99.19 2.87.72 3.82 2.25 4.05 1.1.17 2.72-.45 3.6-1.39.96-1.02 1.67-3.66 1.75-6.55.08-2.67.6-5.08 1.15-5.35s1.72-.16 2.6.25c.87.41 2.46 2.33 3.53 4.25 1.87 3.38 2 3.44 3.9 1.75 1.08-.96 2.42-1.52 2.97-1.25s.98 1.29.97 2.25c-.02.96 1.1 2.99 2.5 4.5 1.39 1.51 3.27 2.64 4.17 2.5.91-.14 2.09-.92 2.64-1.75.54-.83.7-2.62.35-4-.36-1.37-2.44-3.74-4.64-5.25-2.19-1.51-4.67-2.75-5.49-2.75s-1.5-.45-1.5-1 .97-1.95 2.15-3.11c1.57-1.55 2.98-1.98 5.25-1.62zm339.75 7.8c1.08.55 1.95 1.77 1.93 2.72-.02.94-1.84 5.65-4.06 10.46-2.21 4.81-4.47 8.98-5.02 9.25s-1.46 1.51-2.02 2.75c-.57 1.24-2.26 4.49-3.75 7.23-1.5 2.74-4.19 6-5.98 7.25s-3.7 2.04-4.25 1.77-2.8-4.33-5-9-4.01-8.84-4.03-9.25.88-1.65 4.05-4.75l2.51 2.5c1.38 1.38 3.06 3.76 3.74 5.29s1.46 2.79 1.73 2.79c.27.01 1.02-.57 1.65-1.29.63-.71 3.91-6.69 7.3-13.29 3.38-6.6 6.84-12.77 7.69-13.72 1.17-1.31 2.01-1.48 3.51-.71zm-142.71 8.14c1.84.26 2.04.93 1.89 6.29-.09 3.3-.43 8.81-.75 12.25s-.35 6.7-.08 7.25c.32.63 1.51.5 3.25-.36 1.51-.75 4.44-1.65 6.5-2s4.42-.41 5.25-.14 1.49 1.29 1.48 2.25-1.03 2.77-2.25 4.03c-1.23 1.25-3.24 2.26-4.48 2.25-1.24-.02-4.16.88-6.5 1.98-2.34 1.11-5.37 2.03-6.75 2.05-1.37.02-3.08-.55-3.78-1.27-.87-.88-1.12-3.05-.77-6.79.28-3.02.77-9.77 1.1-15 .42-6.68 1.08-10.03 2.22-11.29.89-.99 2.54-1.67 3.67-1.5zm71.21 6.79c1.29 0 2.53.56 2.74 1.25.22.69-.15 2.6-.81 4.25s-2.15 3.67-3.3 4.5c-1.16.83-2.59 2.74-3.19 4.25s-.86 3.76-.58 5 1.51 2.87 2.75 3.63c1.75 1.09 2.89 1.15 5.24.27 1.65-.62 4.35-2.46 6-4.1 2.33-2.31 3.39-2.76 4.75-2.01.96.53 1.74 1.97 1.72 3.21-.02 1.35-1.72 3.76-4.25 6.04-2.32 2.09-5.8 4.22-7.72 4.73a13.84 13.84 0 0 1-7-.03c-1.92-.53-4.96-2.32-6.75-3.98-1.83-1.69-3.24-4-3.24-5.26.01-1.24.53-3.83 1.16-5.75s1.97-5.41 2.98-7.75c1.02-2.34 3.04-5.15 4.5-6.25s3.71-2 5-2zm-34.9 3.01c.14-.01 2.39 1.13 5 2.51 2.61 1.39 5.54 2.52 6.5 2.5.96-.01 2.42 1.11 3.25 2.48.83 1.38 1.5 4.08 1.5 6 0 2.11-.95 4.79-2.38 6.75-1.31 1.79-4.01 4.04-6 5s-6.37 1.86-9.73 2c-5.89.24-6.22.12-9.01-3.25-1.67-2.01-2.9-4.67-2.89-6.25 0-1.51.9-4.44 1.99-6.5 1.08-2.06 2.77-4.71 3.75-5.89.97-1.17 3.12-2.86 4.77-3.74s3.11-1.61 3.25-1.61zm-5.77 14.74c-.01 1.51.89 3.76 2 5S611.45 901 612 901s2.01-.52 3.25-1.16l3.75-1.85c.83-.38 1.61-1.88 1.75-3.34.19-1.98-.57-3.28-3-5.12-1.79-1.36-3.92-2.47-4.75-2.47s-2.51.89-3.75 1.97c-1.3 1.14-2.26 3.14-2.27 4.72zm67.24-2.75c1.23 0 1.78.77 1.78 2.5 0 1.38-.71 3.17-1.57 4-.87.83-2.67 1.5-4 1.5-2.12 0-2.36-.35-1.88-2.75.31-1.51 1.31-3.31 2.23-4s2.47-1.25 3.44-1.25zm734.76 16c1.11 0 3.26.63 4.77 1.4 1.51.78 3.75 2.47 4.96 3.75 1.54 1.64 2.36 4.03 2.7 7.85l.54 6.25c.03.41.95 1.2 2.05 1.75 1.42.71 3.37.56 6.75-.51 2.61-.83 5.76-1.51 7-1.5 1.24 0 3.6.91 5.25 2.01 1.82 1.21 2.8 2.59 2.5 3.5-.28.83-2.3 1.95-4.5 2.5-2.87.72-3.86 1.42-3.5 2.5.28.83 1.06 1.48 1.75 1.46.69-.03 2.32.76 3.62 1.75 2.3 1.73 2.32 1.89.75 5.04-1.1 2.21-3.14 3.93-6.37 5.37-3.44 1.54-6.96 2.16-12.75 2.25-7.99.13-8 .13-7.65-2.37.19-1.37.57-2.72.83-3 .27-.28 3.59-.5 7.37-.5 5.01 0 7.36-.45 8.66-1.65 1.7-1.57 1.49-1.84-3.96-5.25-3.16-1.98-6.31-3.61-7-3.62-.69-.02-2.24 2.12-3.44 4.75-1.26 2.75-3.28 5.3-4.75 6.02-1.41.69-3.23 1.25-4.06 1.25-1.16 0-1.44-1.08-1.25-4.75.22-4.21.02-4.73-1.75-4.59-1.1.08-3.01-.25-4.25-.75s-2.25-1.58-2.25-2.41 2.14-2.46 4.75-3.63 5.08-2.63 5.48-3.25c.41-.62.74-2.92.75-5.12.01-2.33-.82-5.25-1.97-7-1.09-1.65-2.51-3.67-3.15-4.5s-.88-2.29-.54-3.25c.35-.96 1.54-1.75 2.66-1.75zm60.25 4.96c1.8-.03 3.86.53 4.58 1.25.97.96 1.14 3.44.04 18.29l6.07 1.25c3.51.72 7.24 2.25 8.83 3.62 1.51 1.3 3.42 3.57 4.25 5.03s2.06 2.64 2.75 2.63c.69-.02 1.25-.37 1.24-.78s1.23-2.27 2.75-4.12 3.49-4.1 4.39-5 2.7-2.44 4-3.42c1.3-.99 3.27-2.04 4.37-2.35s3.01-.07 4.25.54c1.44.7 2.25 2 2.25 3.6 0 1.38-.63 3.74-1.4 5.25-.78 1.51-2.47 3.73-3.75 4.92-1.29 1.19-3.7 2.32-5.35 2.5-2.35.26-3.06.87-3.29 2.83-.16 1.4.5 3.28 1.5 4.28.98.98 2.46 1.76 3.29 1.72.83-.03 3.86-1.4 6.75-3.03s5.25-3.42 5.25-3.97 1.13-1 2.5-1c1.56 0 2.5-.57 2.5-1.5 0-.83.67-1.72 1.5-2s1.72-.05 2 .5-.51 2.49-1.75 4.31c-1.24 1.81-3.6 4.68-5.25 6.36s-4.8 3.57-7 4.19-5.46 1.13-7.25 1.13c-1.79.01-4.71-.68-6.5-1.53-1.91-.91-4.28-3.36-8.25-10.37l-3 1.93c-1.65 1.05-3.92 1.93-5.05 1.95s-2.48.49-3 1.05-4.32 1.04-8.45 1.08c-5.97.04-8.01-.34-10-1.89-2.06-1.6-2.47-2.73-2.32-6.33.1-2.41.42-6.63.71-9.38s.8-8.6 1.13-13 .79-8.56 1.01-9.25c.23-.69 1.89-1.27 3.7-1.29zm3.15 29.86c-.41 2.55-.17 3.91.77 4.41.74.41 2.59.75 4.1.75 1.51.01 3.42-.2 4.25-.48s1.49-1.51 1.47-2.75-.58-2.99-1.25-3.9-2.34-1.89-3.72-2.19c-1.37-.3-3.07-.31-3.77-.03s-1.53 2.17-1.85 4.19zM1343.91 915c2.38 0 3.03.4 2.83 1.75-.17 1.12-1.15 1.75-2.74 1.75-1.55 0-2.6-.65-2.83-1.75-.27-1.37.33-1.75 2.74-1.75zm201.7 1c1.62 0 2.71.81 3.39 2.5.55 1.38 1.01 3.51 1.02 4.75s1.02 4.85 2.25 8.03c2.17 5.64 2.33 5.79 5.98 5.75 2.36-.02 4.03.53 4.5 1.47s0 2.28-1.25 3.6c-1.1 1.15-3.46 2.72-5.25 3.5-2.37 1.02-3.57 2.42-4.42 5.15-.64 2.06-1.81 4.42-2.61 5.25-1.1 1.14-1.83 1.24-3.08.39-.9-.61-1.89-2.63-2.19-4.5-.3-1.86-.86-3.95-1.25-4.64-.38-.69-1.6-1.25-2.7-1.25s-3.29-1.01-4.88-2.25c-2.19-1.72-2.67-2.67-2-4 .55-1.08 2.02-1.75 3.88-1.75 1.65 0 3.22.45 3.5 1s.95 1 1.5 1c.62 0 .78-2.36.42-6.25-.32-3.44-.69-8.27-.83-10.75-.13-2.48.18-5.06.7-5.75.51-.69 2.01-1.25 3.32-1.25zM1292 919.99c2.2-.01 5.26 1.1 8.25 3 3.94 2.5 4.75 3.52 4.75 6.01 0 1.65-.39 4.01-.86 5.25s-2.39 3.75-4.25 5.59-5.75 4.43-13.89 8.16v11.5c0 6.33-.22 12.17-.5 13s-1.4 1.5-2.5 1.5-3.01-.52-4.25-1.16c-2.2-1.14-2.24-1.4-1.53-12.75.42-6.75.3-14.3-.29-18.09l-1.47-9.75c-.41-2.91-.03-3.54 3.67-6l6.75-4.49c1.44-.96 4.2-1.76 6.12-1.77zm-4.5 11.16c-2.09.24-2.87.8-2.58 1.85.23.83.57 3.19.75 5.25s.55 3.75.83 3.75 1.4-.45 2.5-1 3.35-2.46 5-4.25c1.91-2.07 2.91-4.13 2.75-5.67-.14-1.34-.71-2.58-1.28-2.76s-1.92.3-3 1.07-3.32 1.56-4.97 1.76zm37-5.84c1.91.12 3 .73 3.01 1.69.01 1.11 1.18 1.5 4.5 1.5 4.35 0 4.5.1 4.74 3.25.14 1.83-.59 4.67-1.68 6.5-1.06 1.79-3.2 4.45-4.75 5.92-1.92 1.81-4.34 2.85-7.57 3.25-4.46.54-4.99.35-8.71-3.17-3.45-3.27-3.96-4.32-3.98-8.25-.02-2.48.3-5 .71-5.6.4-.61 1.86-1.69 3.23-2.41 1.38-.72 3.63-1.66 5-2.09 1.38-.42 3.85-.69 5.5-.59zm-5.27 15.46c.7.69 2.06 1.26 3.02 1.25.99-.01 2.2-1.22 2.77-2.77.75-2 .68-3.5-.25-5.5-.94-2.03-1.99-2.75-4.02-2.75-2.57 0-2.75.28-2.77 4.25-.01 2.34.56 4.82 1.25 5.52zm62.77-15.02c.83.15 2.85 1.54 4.5 3.09s3.36 4.13 3.79 5.74c.45 1.66.34 4.32-.25 6.17-.57 1.79-1.94 3.7-3.04 4.25s-2.56.79-3.25.52c-.69-.26-1.81-1.61-2.5-3-.69-1.38-1.25-3.42-1.25-4.52 0-1.29-.58-1.91-1.64-1.75-.91.14-3.29 3.4-5.29 7.25-2.67 5.15-4.22 7.07-5.85 7.25-1.61.18-2.51-.5-3.29-2.5-.59-1.51-1.51-4.78-2.03-7.25l-1.67-8.18c-.67-3.35-.49-3.79 2.03-5 2.23-1.06 3.01-1.08 4-.05.68.69 2.14 1.28 3.24 1.29 1.1.02 2.62-.64 3.38-1.46s2.78-1.63 4.5-1.8 3.79-.19 4.62-.05zm-34.75 2.37c.41-.07 2.1 1.23 3.75 2.88 2.26 2.26 3 3.93 3.02 6.75.01 2.06-.44 5.21-1 7-.9 2.87-1.4 3.22-4.22 3-3.14-.25-3.22-.38-4.42-7.25l-1.54-9.18c-.23-1.51.29-2.31 1.67-2.63 1.09-.25 2.33-.51 2.74-.57zm282.75 2.94c.83-.01 2.52.99 3.78 2.21 1.25 1.23 2.26 3.02 2.25 3.98-.02.96-.93 3.55-2.03 5.75s-2.45 4.22-3 4.5-1 1.17-1 2 .56 1.49 1.25 1.47c.69-.01 2.71-1.14 4.5-2.5s3.92-2.25 4.75-1.97 1.5 1.17 1.5 2-1.29 2.96-2.87 4.75c-2.64 2.99-3.5 3.31-11 4-5.8.54-8.91.39-10.84-.5-1.48-.69-3.91-3.05-8.09-9.25l2.94-1.5c1.62-.83 2.91-1.72 2.87-2s1.5-2.68 3.41-5.35c1.96-2.72 4.94-5.45 6.79-6.21 1.81-.75 3.96-1.37 4.79-1.38zm74.25.06c.96-.07 2.65.33 3.75.88s2.73 2.46 3.62 4.25c1 1.99 1.6 5.58 1.56 9.25-.04 3.49-.62 6.56-1.38 7.35-.78.81-2.3 1.11-3.8.76-1.37-.33-3.09-.93-3.8-1.35-.72-.42-1.62-2.9-2-5.52-.48-3.27-1.17-4.76-2.2-4.76-.83.01-2.06.91-2.75 2.02-.69 1.1-1.81 2-2.5 2.01-.69 0-2.37 1.63-3.75 3.62-1.37 1.99-3.4 4.08-4.5 4.65s-4.76 1.08-8.14 1.13c-4.65.07-6.69.58-8.36 2.09-1.72 1.56-3.85 2.06-9.61 2.25-7.03.24-7.54.1-10.39-2.75-2-2-3-4-3-6 0-2.16 1.2-4.27 4.25-7.51 2.34-2.48 4.59-4.5 5-4.5.41.01 1.99-.91 3.5-2.02 1.51-1.12 3.42-2.04 4.25-2.05.83 0 2.63.85 4 1.91 2.4 1.83 2.44 2.04 1.02 5.29-.81 1.86-2.95 5.07-4.75 7.13-3.22 3.69-3.23 3.76-1.02 4.25 1.24.27 2.92.35 3.75.17s3.01-1.19 4.86-2.25 4.25-2.59 5.33-3.42c1.34-1.02 2.02-2.84 2.14-5.66.09-2.29.52-4.54.94-5 .43-.46 2.46-.22 4.5.54 3.34 1.23 4.05 1.18 6.73-.44 1.65-.99 3.9-2.58 5-3.52 1.1-.95 2.9-1.94 4-2.2a25.96 25.96 0 0 1 3.75-.6zM1572.52 934c1.71 0 2.79.77 3.48 2.5.58 1.45.69 4.6.25 7.51-.47 3.18-.38 5.02.25 5.04.55.01 1.72-.79 2.6-1.77s1.89-2.57 2.25-3.53 1.66-2.02 2.9-2.36c1.24-.33 3.49-.33 5 0 1.51.34 2.74 1.17 2.73 1.86s.56 1.81 1.25 2.49c1.01.98 1.63.88 3.05-.5.98-.96 1.76-2.19 1.73-2.74-.04-.55 1.05-1.67 2.41-2.5 2.23-1.35 2.72-1.33 5.03.25 1.47 1.01 2.55 2.7 2.54 4 0 1.24-1.8 5.06-4 8.5-3.65 5.72-4.29 6.25-7.49 6.25-1.92 0-5.3-.9-7.5-2s-4.11-2.01-4.25-2.03-1.6 1.11-3.25 2.49c-1.7 1.43-3.76 2.31-4.75 2.03-.96-.27-1.75-.04-1.75.51s-1.12 1-2.5 1c-1.48 0-3.12-.92-4.01-2.25-1.02-1.53-1.52-4.9-1.57-10.55-.04-5.78.43-9.2 1.53-11.25s2.35-2.95 4.07-2.95zm-236.05 29.54l8.24 1.84c2.86.62 6.01 1.92 7 2.91 1.56 1.56 1.6 1.91.29 2.75-.83.54-3.86.75-6.75.47-5.09-.49-5.27-.42-5.8 2.24-.31 1.51-.31 3.99 0 5.5.38 1.9 1.17 2.75 2.55 2.75 1.1 0 2.11-.08 2.25-.17s1.26.36 2.5 1 2.25 1.84 2.25 2.67-1.46 2.18-3.25 3.02-3.81 1.51-4.5 1.5c-.88-.01-1.25 1.98-1.24 6.73 0 4.37-.53 7.54-1.5 9-.89 1.33-2.53 2.25-4.01 2.25-1.47 0-2.77-.72-3.15-1.75-.35-.96-.2-4.45.34-7.75.55-3.3.73-7.09.4-8.43-.37-1.5-1.82-2.93-3.84-3.75-1.79-.72-3.36-1.77-3.5-2.32s-.25-1.56-.25-2.25 1.58-1.47 7-2.25l-.29-7c-.18-4.6.15-7.46.97-8.34.85-.89 2.25-1.1 4.29-.62zm71 3.88c1.11.72 2.15 2.16 2.29 3.19.14 1.04-.09 2.49-.5 3.22-.51.89-1.84 1.14-4.01.75-2.75-.49-3.28-1.04-3.42-3.53-.12-1.99.44-3.27 1.72-3.94 1.32-.7 2.49-.61 3.92.31zm53.36-.45c.92-.02 2.4.77 3.29 1.75s1.84 2.45 2.11 3.28c.28.83.11 2.29-.37 3.25-.47.96-1.87 1.76-3.11 1.77s-2.82-.56-3.52-1.25c-.69-.7-1.26-2.28-1.25-3.52s.28-2.92.6-3.75c.33-.83 1.34-1.51 2.25-1.53zm-87.28 2.03c1.35 0 3.69.54 5.2 1.2s3.99 2.01 5.5 3 2.75 2.47 2.75 3.3-1.12 1.72-2.5 2c-1.37.28-3.4.05-4.5-.5-1.43-.71-2.29-.64-3.02.25-.57.69-.91 2.6-.75 4.25.19 2.15.84 3.07 2.27 3.23 1.1.13 2.56.92 3.25 1.75 1 1.22 1 1.83 0 3.06-.69.85-1.92 1.54-2.75 1.53s-2.3.76-3.28 1.71c-.98.94-1.77 2.96-1.75 4.47s-.87 4.78-1.97 7.25c-1.6 3.6-2.5 4.5-4.5 4.5-1.49 0-3.09-.91-3.97-2.25-1.32-2.02-1.28-2.55.47-5.25 1.07-1.65 1.95-4.46 1.97-6.25.02-2.29-.71-3.84-2.47-5.25-1.56-1.25-2.41-2.84-2.25-4.25.2-1.77.89-2.26 3.25-2.28 2.92-.03 3.03-.22 4-6.5.55-3.56 1.36-7.03 1.8-7.72s1.9-1.25 3.25-1.25zm150.5 0c.52 0 1.68.79 2.58 1.75s2.31 3.1 3.14 4.75c1.14 2.29 1.34 4.77.82 10.5l-1.18 15.5c-.29 4.62-1.22 9.41-2.21 11.33-1.21 2.36-2.27 3.23-3.69 3-1.1-.18-2.52-1.45-3.17-2.83-.84-1.79-.92-4.93-.3-11 .48-4.67 1.11-13.6 1.39-19.84.28-6.23.77-11.74 1.09-12.25.32-.5 1.01-.91 1.53-.91zm93.06 1c.49 0 1.74 1.24 2.78 2.75s2.43 4.78 3.09 7.25c.65 2.47 1.09 6.08.96 8-.12 1.92-.17 4.17-.1 5 .06.83 1.7 2.29 3.64 3.25s3.74 2.42 4.02 3.25-.06 2.18-.75 3.01c-.69.84-2.36 1.63-3.71 1.75-1.72.17-3.53 1.82-6 5.48-1.95 2.88-3.99 5.09-4.54 4.92-.55-.18-1.34-2.65-1.75-5.49-.67-4.65-1-5.17-3.25-5.17-1.37 0-2.5-.22-2.5-.5s.56-1.64 1.25-3.04 2.04-2.75 3-3 1.86-1.19 2-2.08.01-6.4-.28-12.25c-.3-5.85-.14-11.19.36-11.88.49-.69 1.29-1.25 1.78-1.25zm-311.86 11.04c.96-.02 2.7 1.2 3.86 2.71 1.17 1.51 3.08 3.21 4.25 3.77 1.18.57 2.27 2.14 2.43 3.5.16 1.44-.89 4.25-2.5 6.69-1.54 2.32-3.91 4.86-5.29 5.64-1.37.78-4.41 1.7-6.75 2.04-3.19.46-5.06.14-7.5-1.28-1.79-1.04-3.58-2.95-3.99-4.25-.4-1.3-.74-3.82-.75-5.61-.01-2.29.95-4.3 3.24-6.79 1.79-1.95 5.05-4.18 7.25-4.96s4.79-1.43 5.75-1.46zm-7.86 17.21c.37 1.69 1.28 2.77 2.36 2.79.96.03 2.73-.76 3.92-1.75 1.19-.98 2.43-3.25 2.75-5.04l.58-3.25c-7.35.3-8.58.84-9.29 2.42-.52 1.14-.66 3.32-.32 4.83zM1710 981.99c.83-.04 2.17.64 3 1.52 1.24 1.32 1.29 2.01.25 4.04-.69 1.35-2.16 2.79-3.27 3.2-1.12.41-2.25 1.42-2.52 2.25s.3 2.63 1.26 4c.96 1.38 2.33 3.63 3.04 5 .72 1.38 1.3 3.4 1.3 4.5 0 1.17-1.57 3.13-3.78 4.71-2.08 1.49-5.13 3.46-6.78 4.37-1.89 1.05-4.02 1.43-5.75 1.04-1.51-.34-2.97-1.29-3.25-2.12s.06-2.2.75-3.04c.69-.85 2.26-1.53 3.5-1.5 1.24.02 3.39-.97 7.34-4.46l-3.63-5c-2.82-3.88-3.5-5.62-3.05-7.75.33-1.51 1.6-3.62 2.84-4.67l4.75-3.97c1.38-1.12 3.17-2.08 4-2.12zM1432.05 983c1.07 0 2.85.45 3.95 1s2.01 1.56 2.02 2.25-1.32 3.28-2.95 5.75c-1.64 2.47-3.34 5.97-3.78 7.77-.75 3.1-.64 3.28 1.96 3.25 1.62-.01 4.08-1.23 6-2.98 1.79-1.63 3.81-2.98 4.5-3s1.7.86 2.25 1.96 1 2.67 1 3.5-1.35 2.85-3 4.5c-1.99 1.99-4.59 3.3-7.75 3.88-2.87.54-6.13.51-8.25-.06-1.92-.52-4.31-1.94-5.29-3.14-.99-1.2-1.76-3.53-1.72-5.18s1.41-5.81 3.04-9.25 3.42-6.25 3.97-6.25 1.25-.9 1.55-2c.32-1.12 1.41-2 2.5-2zm160.95 2.07c.83-.08 2.4.84 3.5 2.02 1.95 2.11 1.96 2.19.11 3.29-1.05.61-3.01 2.02-4.37 3.12-1.82 1.47-2.31 2.6-1.86 4.25.34 1.24 2.21 3.94 4.15 6 2.53 2.69 3.36 4.32 2.91 5.75-.33 1.1-1.81 3.01-3.28 4.25-1.46 1.23-3.11 2.22-3.66 2.2s-1.67.68-2.5 1.55-2.96 1.57-4.75 1.54c-1.79-.02-4.39-.6-5.78-1.29-1.49-.74-2.5-2.07-2.47-3.25.04-1.1.95-3.01 2.03-4.25s2.64-2.25 3.47-2.25 1.5.45 1.5 1 1.01.89 2.24.75c1.24-.14 2.36-1.03 2.5-2 .14-.96-.75-3.14-1.99-4.83-1.68-2.31-2.15-4.07-1.84-6.97.23-2.13 1.34-4.91 2.47-6.16 1.12-1.26 2.96-2.81 4.08-3.44 1.12-.64 2.71-1.21 3.54-1.28zm-191.69 1.48c1.2.38 3.03 1.42 4.05 2.32 1.62 1.41 1.78 2.59 1.25 8.88-.33 3.99-1.06 8.26-1.61 9.5-.56 1.24-2.02 2.87-3.25 3.62-1.24.76-2.81 1.09-3.5.75-.94-.47-1.11-3.39-.67-11.87.32-6.19.8-11.84 1.06-12.57.31-.86 1.25-1.08 2.67-.63zm91.44.47c1.24-.01 3.6 1.33 5.25 2.98 2.33 2.33 3 3.89 3 7 0 2.2.22 4.67.5 5.5s1.17 1.5 2 1.5 1.72.45 2 1 .05 1.9-.5 3c-.63 1.26-2.01 2.01-3.75 2.02-1.51.01-3.76-.89-5-2-2.25-2.02-2.25-2.02-3.5-.02-.81 1.3-2.31 2-4.25 1.98-1.73-.01-3.96-.97-5.28-2.25-1.25-1.23-2.26-3.24-2.25-4.48.02-1.24.58-3.49 1.25-5s2.35-4.33 3.74-6.25 2.98-3.83 3.53-4.23c.56-.41 2.02-.75 3.26-.75zm-35.02 1.02c1.53.02 3.69 1.03 4.84 2.25 1.13 1.22 2.41 4.01 2.84 6.21.42 2.2.5 5.46.18 7.25-.36 1.99-1.56 3.83-3.09 4.75-2.04 1.23-2.87 1.27-4.54.25-1.77-1.09-1.95-1.9-1.38-6.25.48-3.71.21-5.9-1.04-8.5-.94-1.92-1.45-4.06-1.14-4.75.3-.69 1.8-1.23 3.33-1.21zm226.01 1.92c1.41.3 3.84 2 5.41 3.79s2.85 4.15 2.85 5.25-1.48 3.46-3.29 5.25-5.08 4.2-7.25 5.35c-2.18 1.16-5.08 2.38-6.46 2.71-2.46.6-2.5.77-2.5 10.61 0 8.23-.31 10.32-1.77 11.79-1.38 1.4-2.15 1.55-3.5.69-1.06-.67-1.83-2.62-2-5-.14-2.15.19-4.35.73-4.9.62-.62.8-5.81.48-13.5-.39-9.18-.18-13.14.77-14.9.71-1.33 2.42-3.27 3.79-4.33 1.38-1.05 4.23-2.24 6.34-2.63 2.1-.4 4.98-.47 6.4-.18zM1673 1003c0 2.6.37 3 2.75 3.03 1.55.01 3.76-.97 5.06-2.25 1.27-1.26 2.16-3.18 1.99-4.28-.25-1.56-1.22-2.07-4.42-2.3-2.97-.22-4.28.13-4.74 1.25-.35.85-.64 2.9-.64 4.55zm-20.77-9.37c4.04.39 6.72 1.19 7.54 2.24.74.95 1.27 4.54 1.28 8.63.02 6.33-.24 7.27-2.76 9.82-1.54 1.55-3.91 3.06-5.29 3.37-1.37.3-3.96.27-5.75-.07s-4.6-1.74-6.25-3.12c-1.99-1.66-3-3.43-3.01-5.25a37.61 37.61 0 0 1 .53-5.75c.3-1.65 2.1-4.68 4-6.74 3.44-3.72 3.46-3.73 9.71-3.13zm-8.6 12.24c-.07 1.56.38 3.47 1 4.23.62.77 2.42 1.7 4 2.06 1.7.39 3.4.19 4.16-.5.72-.64 1.28-2.85 1.25-4.91-.02-2.06-.6-3.95-1.29-4.2s-2.74-.66-4.55-.91c-1.82-.26-3.57-.05-3.88.46s-.62 2.2-.69 3.77z&#34;/&gt;
&lt;/svg&gt;
&lt;p&gt;Combining these two data sets gives us the position and arrival time of stops &lt;em&gt;and&lt;/em&gt; the position (but not time) of waypoints between stops. We can then use &lt;a href=&#34;https://pages.uoregon.edu/dgavin/software/stineman.pdf&#34;&gt;Stineman interpolation&lt;/a&gt; to fill in the missing times.&lt;/p&gt;
&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;100%&#34; height=&#34;100%&#34; viewBox=&#34;0 0 1584 949&#34; preserveAspectRatio=&#34;none&#34;&gt;
  &lt;style&gt;
    @media (prefers-color-scheme:dark) {
      .bb {fill: #fff}
    }
  &lt;/style&gt;
  &lt;path class=&#34;bb&#34; fill-rule=&#34;evenodd&#34; d=&#34;M422.25 28.03c.41-.02 1.43.2 2.25.47s1.51 1.06 1.53 1.75c.01.69-1.68 4.62-3.75 8.73-2.08 4.11-5.26 9.06-7.06 11-1.81 1.94-3.27 4.31-3.25 5.27s-1.32 2.88-2.97 4.25c-1.65 1.38-3.79 2.31-4.75 2.08-.96-.24-2.2-.45-2.75-.48s-2.24-1.86-3.75-4.07C396.24 54.81 395 52.55 395 52s1.24-1.42 2.75-1.94c2-.68 3.3-.55 4.75.47 1.1.77 2.34 1.42 2.75 1.44s2.49-2.56 4.62-5.72c2.12-3.16 4.93-8.17 6.25-11.13 1.31-2.95 3.06-5.75 3.88-6.21.82-.47 1.84-.86 2.25-.88zm-115.4 5.18c3.82.2 5.77.8 6.55 2.01.73 1.15.77 2.05.1 2.7-.55.54-3.48 1.23-6.5 1.55-3.02.31-5.63.67-5.78.8s-.38 4.38-.5 9.44c-.16 6.62-.64 9.64-1.72 10.72-.83.84-2.5 1.3-3.75 1.04-1.47-.31-2.3-1.25-2.38-2.72-.08-1.24-.07-4.05.02-6.25s-.42-5.11-1.12-6.46c-.8-1.56-2.74-2.88-5.27-3.59-2.38-.67-4.1-1.8-4.25-2.79-.17-1.1.68-1.86 2.5-2.24a47 47 0 0 0 5.25-1.49c1.38-.5 4.3-1.18 6.5-1.52 2.2-.33 4.21-.8 4.46-1.05s2.9-.32 5.89-.15zm661.65 2.81c1.1 0 4.43.79 7.4 1.74 3.5 1.13 6.22 2.79 7.73 4.74 1.29 1.65 3.03 5.25 3.87 8s1.52 7.36 1.51 10.25c0 2.89-.89 8.06-1.96 11.5-1.53 4.88-2.79 6.89-5.75 9.18-2.09 1.61-5.55 3.41-7.69 4-3.34.92-4.05 1.63-5.07 5.07-.68 2.27-1.29 11.56-1.42 21.5-.12 9.63.28 20.88.88 25 .6 4.13 1.12 9.3 1.15 11.5.04 2.89-.53 4.49-2.05 5.75-2.05 1.71-2.1 2.45-2.1 34.25 0 21.34.37 33.27 1.09 34.75.65 1.36 1.84 2.15 3 2 1.24-.16 2.26.63 2.91 2.25.55 1.38 1 3.63 1 5 0 1.52-1.37 3.87-7 9.5l.51 7.75 1.57 24.75c.59 9.35 1.27 17.34 1.5 17.75s.38 6.26.34 13l.02 15.25c.05 1.65 1.21 4.46 2.58 6.25 1.36 1.79 2.48 4.26 2.47 5.5 0 1.24-.45 3.94-1 6-.54 2.06-1.89 4.2-2.99 4.75-1.28.64-1.99 1.99-1.98 3.75.01 1.51.64 6.35 1.41 10.75.83 4.75 1.3 13.28 1.16 21-.13 7.15-.09 13.56.09 14.25.19.76 1.99 1.24 4.57 1.22 2.79-.01 6.14.97 9.75 2.87 3.21 1.68 6.65 4.5 8.27 6.77 1.52 2.14 3.71 5.69 4.85 7.89 1.33 2.56 2.1 5.97 2.14 9.5.03 3.02-.73 7.75-1.7 10.5-.96 2.75-2.45 6.35-3.3 8s-2.5 4.02-3.65 5.28c-1.16 1.25-2.78 2.27-3.61 2.27s-2.17.65-3 1.45c-.83.79-3.52 1.71-6 2.04l-7 .9-3.75.43c-.88.09-1.06 1.23-.61 3.88.35 2.06.76 28.5.9 58.75.15 32.7.74 60.07 1.44 67.5.66 6.88.93 16.21.61 20.75-.53 7.37-.38 8.46 1.41 10.25 1.1 1.1 2.45 2.9 3 4s.99 3.24.97 4.75c-.03 2.62.05 2.67 1.75 1.03.98-.95 2.12-1.74 2.53-1.75.41-.02.52 1.43.23 3.22-.43 2.7.01 3.76 2.61 6.25 1.73 1.65 4.15 4.58 5.39 6.5s6.38 8.67 11.43 15 12.64 15.22 16.88 19.77 8.38 8.51 9.21 8.8 3.3 2.81 5.5 5.62c2.2 2.8 5.35 6.62 7 8.47 2.73 3.07 3.44 3.35 7.89 3.11 4.74-.26 4.98-.14 8.19 4.23 2.38 3.24 3.17 5.2 2.79 7-.4 1.92.46 3.66 3.72 7.5l5.64 6.5c.76.83 3.53 3.75 6.15 6.5l21.36 22.5c9.14 9.63 18.08 19.52 19.87 22 1.8 2.48 4.87 6.27 6.83 8.43l5.06 5.55c.83.89 4.54 5.09 8.25 9.32 3.71 4.24 7.42 7.7 8.25 7.7s2.96-1.28 4.75-2.86c2.68-2.35 4.04-2.81 7.75-2.62 2.47.13 6.3.59 8.5 1.01 2.2.43 6.81 2.06 10.25 3.63 3.69 1.67 8.2 4.83 11 7.68 2.95 3.01 5.64 7.09 7.1 10.75 1.88 4.75 2.25 7.19 1.88 12.41-.38 5.43-.87 6.83-2.96 8.5l-4.39 3.56c-1.03.85-2.89 2.09-4.13 2.75-1.24.65-3.04 1.18-4 1.16-.96-.01-4.45 1.15-7.75 2.58s-8.7 2.85-12 3.15c-3.93.36-8.24-.02-12.5-1.09-3.92-.99-8.68-3.16-12-5.48-5.02-3.51-5.66-4.4-7.38-10.24-1.75-5.96-1.77-6.76-.31-11.89.97-3.43 3.09-7.29 5.63-10.25 2.23-2.61 4.08-5.09 4.1-5.5.03-.41-5.52-6.6-12.31-13.75-6.8-7.15-13.61-15.02-15.14-17.5-1.52-2.48-5.77-7.59-9.43-11.36l-15.66-16.11-14.1-14.64c-2.8-2.96-6.37-7.19-7.94-9.39s-4.68-5.9-6.91-8.23c-3.12-3.26-4.8-4.23-7.3-4.25-1.79-.01-4.38-.81-5.76-1.77-1.71-1.19-2.71-3.03-3.11-5.75-.53-3.58-2.54-5.95-19.23-22.57-10.26-10.21-21.91-22.7-25.9-27.75S987 649.55 987 649s-1.36-2.91-3.03-5.25c-1.66-2.34-3-4.7-2.98-5.25.03-.55-1.34-2.35-3.04-4-2.09-2.04-4.27-3.09-6.77-3.27-2.02-.14-4.47-.25-5.43-.25-.96.01-1.75-.43-1.75-.98s-.67-.77-1.5-.5c-.83.28-2.83-.83-4.5-2.5-1.65-1.65-3-3.67-3-4.5s.67-2.85 1.5-4.5 2.74-3.57 4.25-4.27c2.69-1.25 2.75-1.46 2.7-9.75-.03-4.67-.41-14.1-.85-20.98l-1.17-24c-.21-6.33-.42-22.3-.47-35.5-.04-13.2.21-26.25.56-29s.17-7.02-.4-9.5c-.7-3.03-.72-7.76-.07-14.5L963 452l-3.75.3c-2.73.22-5.51-.63-10.25-3.12-3.58-1.88-7.74-4.27-9.25-5.3-1.53-1.04-3.26-3.55-3.89-5.63-.88-2.86-.85-6.13.12-13.75 1.11-8.76 1.66-10.5 4.46-14 1.96-2.44 6-5.46 10.38-7.75 3.95-2.06 7.97-3.73 8.93-3.71.96.03 2.42-.71 3.25-1.64 1.27-1.43 1.39-4.22.77-18.29-.41-9.14-1.18-20.88-1.73-26.11l-1.01-10.25c-.02-.41-.7-.75-1.53-.75s-1.95-1.12-2.5-2.5c-.55-1.37-1.01-2.84-1.02-3.25s1.44-3 6.48-10.75l-.31-11.5-.6-15.5-.97-16-1.64-25c-.95-12.8-1.01-13.03-3.95-15.25-1.77-1.33-3.19-3.48-3.49-5.25-.35-2.12.35-4.53 2.42-8.25 1.64-2.97 2.99-6.99 3.09-9.25.1-2.2.14-18.06.09-35.25-.09-28.83-.24-31.29-1.85-31.82-.96-.31-2.54-2.11-3.5-4-1.53-3-1.58-3.77-.37-6.18.76-1.51 2.17-3.43 3.13-4.25s2.23-2.62 2.82-4c.58-1.37 1.32-11.05 1.63-21.5.43-14.32.94-19.57 2.06-21.31 1.35-2.11 1.3-2.44-.52-3.77-1.1-.8-2.45-1.44-3-1.41-.55.02-3.02-.84-5.5-1.91s-5.22-2.77-6.1-3.77c-.88-1.01-2.32-4.08-3.19-6.83-1.15-3.6-1.39-6.54-.87-10.5.39-3.02 1.77-7.3 3.05-9.5s3.29-4.76 4.47-5.68c1.18-.93 5.52-3.96 9.64-6.74 4.13-2.79 8.4-5.06 9.5-5.06zm-7.25 10.96c-1.24.01-3.68 1.26-5.42 2.77-1.75 1.51-3.99 4.55-4.98 6.75s-1.82 6.14-1.83 8.75.69 6.21 1.56 8 2.67 4.04 4 5 4.56 2.15 7.17 2.63c2.95.55 6.07.51 8.25-.11 1.92-.55 4.74-1.85 6.25-2.88 1.94-1.33 3.23-3.59 4.38-7.64 1.12-3.97 1.44-7.61 1.02-11.75-.39-3.88-1.4-7.13-2.87-9.19-1.26-1.76-3.52-3.9-5.03-4.75-1.51-.86-3.31-1.55-4-1.54s-2.37.9-3.75 1.98c-1.37 1.08-3.51 1.97-4.75 1.98zm3.5 358.05c-.72-.56-2.52-.63-4.25-.17-1.65.44-4.8 1.83-7 3.08-2.2 1.26-5.33 3.93-6.96 5.92-2.51 3.08-3.08 4.86-3.7 11.64-.7 7.7-.63 8.13 1.96 11.45 1.54 1.96 5.07 4.51 8.2 5.91 4.26 1.91 6.97 2.43 12 2.29 3.58-.1 9.2-.88 12.5-1.72s6.9-2.11 8-2.81 3.01-3.38 4.25-5.95 2.77-6.81 3.4-9.42c.89-3.71.86-5.52-.14-8.25-.71-1.93-3.14-5.68-5.4-8.33-2.26-2.66-5.91-5.69-8.11-6.74s-5.16-1.91-6.59-1.92c-1.73-.01-3.29.98-4.75 2.99-1.54 2.14-2.52 2.72-3.41 2.03zM1150.5 809.5c-.83-.27-2.51.39-3.75 1.47l-6.38 5.75c-2.59 2.37-4.54 5.27-5.24 7.78-.62 2.2-1.12 5.46-1.12 7.25-.01 1.79.6 4.49 1.36 6 .75 1.51 2.66 3.9 4.25 5.31 1.58 1.4 5.58 3.36 8.88 4.35 4.31 1.3 7.62 1.64 11.75 1.2 3.16-.34 8.11-1.47 11-2.51 2.89-1.05 6.49-2.17 8-2.5s3.88-1.72 5.25-3.1c1.83-1.83 2.5-3.57 2.5-6.5 0-2.2-1.1-6.36-2.45-9.25s-3.94-6.7-5.75-8.47c-2.13-2.08-6.32-4.29-11.8-6.23-4.67-1.66-8.95-3.02-9.5-3.04-.55-.01-2.01.65-3.25 1.48s-2.92 1.28-3.75 1.01zM321.75 37.08c.14-.04 1.03.19 1.98.53.96.33 1.63 1.23 1.5 2-.13.83-1.44 1.39-3.23 1.39-1.83 0-3.08-.55-3.2-1.42-.11-.78.45-1.64 1.25-1.92l1.7-.58zM1027 38.49c2.47.31 5.51 1.23 6.75 2.04 1.62 1.06 2.25 2.44 2.25 4.97 0 2.8-1 4.6-10 14.5l2.5 3.5c2.19 3.06 2.38 3.97 1.53 7.25-.53 2.06-1.99 4.5-3.25 5.43-1.25.92-3.86 2.15-5.78 2.73s-4.96 1.06-6.75 1.07c-2.02.01-4.39-.93-6.25-2.48-1.65-1.37-3-3.4-3-4.5s1.46-3.27 3.25-4.81c1.79-1.55 4.04-3.8 5-5 1.7-2.12 1.66-2.27-1.22-4.94-1.63-1.51-3.22-4.1-3.54-5.75-.38-2 .05-4 1.29-6 1.02-1.65 4.3-4.26 7.29-5.79 4.43-2.28 6.26-2.69 9.93-2.22zm-11.61 11.3c-.69 1.07-.79 2.55-.25 3.96.47 1.24 1.71 2.25 2.75 2.25s3.74-1.8 6-4 4.11-4.67 4.11-5.5c0-.99-.94-1.48-2.75-1.44-1.51.04-4.1.73-5.75 1.55-1.65.81-3.5 2.24-4.11 3.18zm-2.89 23.71c.27.83 1.17 1.5 2 1.5s2.85-.67 4.5-1.5 3.49-2.51 4.09-3.75c.89-1.83.74-2.58-.78-4.01-1.79-1.69-2.03-1.6-6.09 2.25-2.51 2.39-4.02 4.62-3.72 5.51zM237 42.65c4.13.28 10.88 1.4 15 2.49 4.31 1.13 8.67 3.01 10.25 4.42 1.51 1.34 3.2 2.44 3.75 2.44s1.66 2.36 2.46 5.25c.81 2.89 1.92 9.53 2.47 14.75.75 7.04.69 10.96-.21 15.12-.98 4.51-2.3 6.83-6.72 11.82-4.84 5.46-6.28 6.44-12 8.15-3.57 1.08-7.51 1.94-8.75 1.93-1.48-.01-2.25.58-2.25 1.73 0 .96.71 5.35 1.58 9.75.88 4.47 1.65 14.02 1.92 35.29l3.25 4.11c1.79 2.25 3.72 5.34 4.29 6.85.74 1.95.71 3.62-.09 5.75-.63 1.65-1.88 3.59-2.79 4.3-.91.72-3.01 1.92-7.66 4.03l-.17 39.84c-.16 38.29-.09 39.98 1.88 43.83 1.56 3.08 1.91 5.16 1.49 9-.3 2.77-1.47 6.23-2.62 7.75-1.96 2.59-2.09 4.12-2.21 26.5l.01 41.75.15 21c.01 2.4.66 3.3 3.24 4.5 1.78.82 3.79 2.74 4.48 4.25 1.03 2.26.99 3.37-.25 6.25-.82 1.93-3.06 4.96-4.96 6.75-2.78 2.61-3.48 4.04-3.54 7.25l-1 49.5 3.75.65c2.06.36 5.55 1.42 7.75 2.37 2.2.94 5.26 3.01 6.8 4.6 1.53 1.58 3.41 4.23 4.18 5.88.76 1.65 1.93 4.35 2.6 6 .68 1.65 1.35 3.68 1.5 4.5.16.82.52 3.07.81 5s.11 5.3-.4 7.5c-.52 2.2-2.39 6.02-4.17 8.5-1.77 2.48-4.59 6.2-6.27 8.27-1.68 2.08-5.08 5.04-7.55 6.59s-6.86 3.56-9.75 4.48c-2.89.91-5.47 2.11-5.75 2.66s-.61 8.92-.75 18.59c-.14 9.68.09 17.78.5 18 .41.23.61 6.15.44 13.16s-.02 15.9.32 19.75c.36 3.99.14 9.8-.52 13.5-.64 3.58-1.33 11.45-1.53 17.5s-.32 13.25-.27 16l.24 12c.09 4.98.59 7.43 1.73 8.5.87.83 2.66 3.64 3.96 6.25 1.31 2.61 2.39 5.31 2.41 6 .01.69 2.26 3.61 5 6.5 2.73 2.89 6.26 6.04 7.85 7 1.58.96 7.96 6.48 14.16 12.25l13.88 13.1 13.58 13.83c10.74 10.96 11.08 11.22 14.5 10.56 1.93-.37 4.51-.41 5.75-.08 1.24.32 3.15 2.17 4.25 4.09s1.99 5.19 1.97 7.25c-.03 3.51.74 4.47 11.75 14.84 6.48 6.1 14.48 13.31 17.78 16.02s7.24 5.71 8.75 6.66 5.55 4.32 8.98 7.48l16 15c5.37 5.09 11.01 10.02 12.52 10.96 1.51.93 4.1 2.91 5.75 4.39l9.25 8.3c3.44 3.08 8.16 6.78 10.5 8.23 2.34 1.44 8.41 6.84 13.5 12 5.09 5.15 9.93 9.37 10.75 9.37s1.49-.34 1.47-.75 2.69-3.45 6.02-6.75c3.34-3.3 7.18-6.56 8.54-7.25s4.67-1.59 7.35-2c3.18-.49 5.36-.36 6.25.36.75.61 3.62 1.42 6.37 1.79 2.77.37 6.34 1.69 8 2.96 1.65 1.25 4.83 5.4 7.06 9.21 2.24 3.81 4.62 9.18 5.3 11.93 1.06 4.3.99 5.78-.5 10.5-.96 3.02-2.6 6.85-3.66 8.5-1.05 1.65-4.12 4.46-6.81 6.25s-6.8 3.92-9.14 4.74c-2.34.81-7.74 1.49-12 1.5-5.73.01-8.86-.52-12-2.01-2.34-1.11-5.89-3.48-7.91-5.25-2.01-1.78-4.66-5.48-5.88-8.23-1.86-4.17-2.13-6.04-1.6-11.25.62-6.08.57-6.29-2.11-7.66-1.51-.78-7.25-5.88-12.75-11.34-6.05-6.01-12.07-10.98-15.25-12.59-2.89-1.46-5.46-3.22-5.72-3.91-.25-.69-3.85-4.06-8-7.5-4.14-3.44-7.87-6.24-8.28-6.23s-4.09-3.48-8.18-7.75-8.22-8.22-9.18-8.77-4.82-3.96-8.57-7.59c-3.75-3.62-9.3-8.31-12.32-10.41s-5.73-4.08-6-4.41c-.27-.32-2.52-2.15-5-4.06s-5.39-4.61-6.47-6c-1.09-1.39-6.04-6.48-11-11.31-4.97-4.83-9.82-8.77-10.78-8.75-.96.01-1.98.48-2.25 1.03s-2.07 1-4 1c-2.4 0-4.29-.79-6-2.5-2.18-2.18-2.47-3.26-2.25-8.42.24-5.66.07-6.11-3.75-10.27-2.2-2.39-5.55-5.46-7.45-6.83-1.91-1.36-5.45-4.5-7.87-6.98l-10.05-10.27c-3.1-3.17-5.97-5.76-6.38-5.75s-.75-.65-.75-1.48-.56-1.51-1.25-1.51c-.69-.01-3.27-1.96-5.75-4.34l-20.5-19.44-4.25 1.39c-4.01 1.32-4.43 1.27-7.5-.92-2.78-1.99-3.21-2.86-3-6 .16-2.42 1.45-5.23 3.75-8.18 2.04-2.62 3.3-5.23 3.03-6.25l-2.16-8.25c-.93-3.58-1.73-8.52-1.77-11s.25-7.42.64-11l1.39-13c.38-3.58.66-10.55.63-15.5s-.31-15.3-.62-23l-.66-22.5c-.05-4.67.16-13.56.47-19.75.54-10.98.5-11.27-1.7-12.15-1.24-.49-4.25-1.5-6.7-2.25-2.44-.74-6.04-2.63-8-4.19-1.95-1.56-4.77-4.71-6.27-7-2.47-3.79-2.74-5.1-2.92-14.66-.15-7.82.24-11.77 1.54-15.5.96-2.75 2.73-6.55 3.92-8.43 1.2-1.89 4.21-4.95 6.68-6.79s6.75-3.98 9.5-4.75c2.75-.76 6.32-1.54 7.93-1.71 2.31-.25 3.11-.96 3.72-3.32.43-1.65.68-12.38.56-23.84-.11-11.47.01-20.98.29-21.13.28-.16.86-2.48 1.3-5.16.74-4.54.6-5.07-2.12-7.87-1.61-1.65-3.2-4.46-3.55-6.25-.5-2.58-.07-4.02 2.12-7 2.68-3.65 2.74-4.03 2.35-14.75a680.71 680.71 0 0 1-.38-23l.68-59-2.69-4.5c-1.48-2.48-2.68-5.18-2.68-6s1.27-2.85 2.82-4.5 3.33-4.8 3.96-7c.73-2.54.86-6 .36-9.5-.43-3.03-.7-15.62-.59-28 .11-12.72.68-24.24 1.3-26.5.61-2.2 1.12-6.25 1.14-9 .02-4.77-.19-5.16-4.52-8.5-3.47-2.67-4.54-4.15-4.52-6.25.01-1.51.42-3.76.9-5 .49-1.24 2.54-4.05 8.24-10.25l-.77-10c-.42-5.5-.78-15.71-.85-35.38l-6.5-1.15c-3.57-.63-8.97-2.08-12-3.22s-6.85-2.96-8.5-4.04-4.3-4.05-5.89-6.59c-2.57-4.11-2.9-5.55-2.97-13.12-.04-4.67.25-10.08.64-12 .5-2.46 2.86-5.72 7.97-11 3.99-4.12 9.27-9.08 11.72-11 2.46-1.92 5.83-4.03 7.5-4.68 1.86-.72 5.92-.98 10.53-.67zm-10.75 8.68c-1.84.95-3.23 2.43-3.21 3.42.03.96-.53 2.25-1.25 2.86-.71.61-2.41 1.38-3.79 1.7-1.37.33-3.96 2.08-5.75 3.89-2.05 2.09-3.81 5.32-4.76 8.8-.96 3.51-1.26 6.95-.82 9.5.39 2.2.62 4.56.52 5.25-.11.69 1.05 3.26 2.56 5.72 2 3.25 4.18 5.16 8 7 2.9 1.4 7.6 2.69 10.5 2.88 2.89.2 8.63.01 12.75-.42 4.13-.43 9.19-1.6 11.25-2.61 2.06-1 5.35-3.85 7.31-6.32s3.83-5.62 4.15-7c.33-1.37.34-7 .04-12.5-.44-7.77-1.06-10.89-2.8-14-1.23-2.2-2.95-4.67-3.82-5.5-.86-.83-4.06-2.24-7.1-3.15-3.04-.9-7.56-1.89-10.03-2.18-2.47-.3-5.85-.19-7.5.23s-4.46 1.52-6.25 2.43zm2 407.23c-2.61.32-5.76.77-7 1-1.24.24-4.3 2.35-6.81 4.69-2.98 2.78-5.23 6.07-6.5 9.5-1.4 3.8-1.94 7.8-1.93 14.5 0 7.1.41 9.87 1.75 11.92.96 1.48 2.75 3.61 3.99 4.75 1.24 1.15 3.82 2.76 5.75 3.58s4.74 1.5 6.25 1.5c1.51.01 6.13-1.21 10.25-2.71 6.25-2.26 8.61-3.8 14.11-9.25 5.13-5.07 6.98-7.72 8.25-11.79 1.51-4.83 1.51-5.75.04-11.5-.88-3.44-2.27-7.6-3.11-9.25-.83-1.65-2.47-3.81-3.65-4.8-1.18-.98-3.26-2.27-4.64-2.85-1.37-.59-3.72-1.42-5.22-1.86-1.84-.54-3.37-.35-4.75.6-1.12.78-4.17 1.66-6.78 1.97zm232.35 389.4c-2.42 1.63-6.09 5.34-8.17 8.25-2.91 4.07-3.81 6.33-3.93 9.79-.08 2.48.64 6.3 1.6 8.5s3.58 5.69 5.82 7.75c3.7 3.4 4.76 3.81 11.33 4.4 6.92.63 7.54.5 13.68-2.75 4.12-2.17 7.46-4.84 9.28-7.4 2.23-3.13 2.84-5.08 2.82-9-.02-3.41-.86-6.59-2.64-10-1.44-2.75-4.25-6.67-6.25-8.71-2.28-2.32-4.89-3.89-6.98-4.21-1.84-.27-4.2-.07-5.25.46-1.42.72-2.04.58-2.41-.54-.27-.83-1.15-1.5-1.95-1.5s-1.7.45-2 1-2.53 2.33-4.95 3.96zM353.25 42.03c1.51-.02 3.65.42 4.75.97 1.56.78 2 2 2 5.5 0 2.48-.45 5.4-1 6.5-.6 1.2-2 2-3.5 2-1.65 0-2.56-.6-2.67-1.75-.1-.96-.21-2.61-.25-3.67-.04-1.05-.64-2.06-1.33-2.25-.69-.18-2.71 1.26-4.5 3.19-2.22 2.41-4.12 3.52-6 3.5-1.77-.01-2.75-.56-2.75-1.52 0-.83-.34-1.51-.75-1.53-.41-.01-1.65 1.9-2.75 4.25-1.57 3.36-2.59 4.33-4.75 4.53-1.66.15-2.75-.24-2.76-1-.01-.69.67-3.5 1.5-6.25 1.16-3.87 2.43-5.65 5.57-7.87 3.42-2.42 4.77-2.79 8.5-2.38 2.86.32 5.05.02 6.19-.84.96-.74 2.99-1.36 4.5-1.38zM378 43.1c.82-.03 2.3.73 3.28 1.68.98.94 1.77 2.73 1.75 3.97-.02 1.37-1.42 3.33-3.58 5-1.95 1.51-3.52 3.09-3.5 3.5.03.41 1.18.98 2.55 1.25 1.38.27 3.51-.18 4.75-1.01s2.81-1.5 3.5-1.5c.87.01.72.8-.5 2.64-.96 1.45-2.99 3.25-4.5 4s-3.99 1.36-5.5 1.34-4.21-.92-6-2c-2.06-1.25-3.56-3.16-4.1-5.22-.59-2.24-.43-4.1.5-6 .74-1.51 2.59-3.55 4.1-4.53 1.52-.98 3.43-2.07 4.25-2.42.83-.36 2.18-.67 3-.7zm726.62 2.9c3.51 0 7.05.23 7.88.5s1.5 1.63 1.5 3c0 1.53-1.76 4.53-9.11 13l4.06.75c2.89.53 4.41 1.47 5.3 3.25 1 2 1 3 0 5-.69 1.38-3.28 3.85-5.75 5.5s-6.1 3.34-8.05 3.75c-3.16.67-3.59.51-4-1.5-.25-1.24-.44-2.59-.43-3 .02-.41 1.26-.62 2.75-.46 1.91.21 3.79-.64 6.23-2.8 1.92-1.71 3.05-3.3 2.5-3.55-.55-.24-2.58-1.23-4.5-2.19-2.24-1.12-3.59-2.56-3.75-4-.14-1.24.88-3.6 2.25-5.25 1.38-1.65 2.5-3.45 2.5-4s-1.69-1.24-3.75-1.54-4.42-.98-5.25-1.52c-1.28-.83-1.15-1.28.87-2.96 1.82-1.52 3.86-1.98 8.75-1.98zM320.5 47.09c1.1-.03 2.6.27 3.33.68.96.53 1.16 2.1.73 5.73-.46 3.8-1.14 5.28-2.83 6.16-1.23.64-2.72.86-3.33.5-.6-.36-1.49-3.22-1.98-6.35-.72-4.68-.61-5.78.6-6.17.82-.27 2.38-.51 3.48-.55zm753.25 2.95c1.35-.02 2.25.56 2.25 1.46 0 .89.61 1.3 1.5 1 .83-.27 2.63.17 4 1 1.38.83 3.4 2.96 4.5 4.75 1.17 1.9 1.99 5.01 2 7.5 0 3.36-.58 4.78-2.75 6.78-1.51 1.4-3.2 2.51-3.75 2.47s-2.24.85-3.75 1.97c-1.51 1.11-4.21 2.04-6 2.05s-4.71-.44-6.5-1c-2.39-.75-3.78-2.14-5.26-5.27-1.11-2.34-2.01-5.26-2-6.5 0-1.24.86-3.94 1.9-6 1.05-2.06 2.73-4.48 3.75-5.37 1.02-.9 3.21-2.34 4.86-3.21 1.65-.88 4.01-1.61 5.25-1.63zM1066 63.7c-1.23 3.38-1.27 4.59-.25 6.71.85 1.76 2.05 2.59 3.75 2.59 1.38 0 4.19-.87 6.25-1.93 2.06-1.07 4.08-2.98 4.49-4.25.5-1.59.03-3.72-1.5-6.73-1.23-2.43-2.72-4.57-3.31-4.77-.58-.2-2.61.67-4.5 1.94-2.15 1.44-3.99 3.85-4.93 6.44zm-17.75-9.71c.41.01.75 1.36.75 3.01s-.45 3.23-1 3.5-1.9.27-3 0-2.06-1.15-2.13-1.94c-.08-.8.93-2.15 2.25-3.01 1.31-.86 2.72-1.56 3.13-1.56zm-908 5.99c.69-.01 1.82.56 2.52 1.25.69.7 1.24 3.3 1.2 5.77-.03 2.47-.88 9-1.89 14.5s-1.55 10.82-1.21 11.82c.38 1.11.04 2.19-.87 2.74-.82.5-2.74.92-4.25.92-2.01.02-2.91-.58-3.35-2.23-.33-1.24-.12-3.83.47-5.75.58-1.92 1.46-6.87 1.95-11 .48-4.12.64-9 .36-10.84-.4-2.59-.03-3.78 1.65-5.25 1.19-1.05 2.73-1.92 3.42-1.93zm-97.75 6.1c.55-.03 1.67.37 2.5.89 1.18.74.65 1.28-2.5 2.53-2.2.87-5.08 2.13-6.39 2.79-1.32.67-3.12 2.25-4 3.52-1.57 2.25-1.45 2.47 4.63 8.5 3.47 3.44 6.25 7.08 6.26 8.19.01 1.1-1.34 3.69-2.99 5.75-1.97 2.46-4.13 3.95-6.26 4.34-1.79.32-4.82.33-6.75.01s-4.77-1.6-6.33-2.84c-2.57-2.05-2.68-2.4-1.23-3.76 1.32-1.25 2.28-1.31 5.82-.32l5.99 1.75c1.18.38 2.24-.25 3.25-1.93 1.2-2 1.26-2.95.32-4.75-.65-1.24-1.89-2.95-2.75-3.8s-2.81-2.32-4.32-3.25C25.6 82.37 25 81.24 25 78.5c0-2.14.73-4.18 1.88-5.25 1.04-.96 3.63-2.49 5.75-3.39L39 67.18c1.38-.57 2.95-1.07 3.5-1.1zm14.42 4.88c.87-.03 2.12.53 2.78 1.25.65.71 1.57 3.09 2.04 5.29.68 3.16 1.74 4.58 5.06 6.75 2.31 1.51 3.98 3.2 3.7 3.75s-2.19.99-4.25.98c-3.53-.03-3.83.22-5.18 4.25-.79 2.35-1.91 4.85-2.5 5.57-.59.71-1.47 1.16-1.97 1-.49-.17-1.39-2.33-2-4.8-.86-3.53-1.58-4.55-3.35-4.75-1.51-.17-2.16-.83-1.98-2 .14-.96 1.57-2.42 3.16-3.25 2.86-1.48 2.88-1.57 2.01-7.11-.51-3.27-.51-5.88 0-6.25.49-.35 1.61-.66 2.48-.68zm358.96 1.25c.89.17 1.73 1.32 1.87 2.55.16 1.45-1.14 3.74-3.69 6.49a351.88 351.88 0 0 0-8.19 9.25l-5.81 6.76c-.86.97-2.91 1.76-4.56 1.76s-4.1-.8-5.44-1.76c-1.35-.97-3.25-3.56-4.23-5.76s-1.8-4.79-1.81-5.75.77-1.98 1.73-2.25c.96-.28 2.36.06 3.09.75.74.69 1.87 2.33 2.5 3.66.64 1.32 1.97 2.9 2.97 3.5 1.49.9 2.26.56 4.35-1.91l7.69-8.92 6.53-7.3c.76-.76 2.11-1.24 3-1.07zm631.37-.19c1.51-.01 3.03.54 3.37 1.23s-.55 2.38-1.97 3.75c-2.3 2.22-2.86 2.36-5.12 1.25-1.82-.9-2.34-1.74-1.85-3 .37-.96 1.16-2.08 1.75-2.48.59-.41 2.31-.75 3.82-.75zm-756.89 5.96c.63-.01 2.04.64 3.14 1.43 1.77 1.28 1.97 2.43 1.5 18.59l2.75-.58c1.51-.32 4.21-.32 6 0 1.89.34 3.46 1.31 3.76 2.33.28.96.39 1.86.25 1.99s-4.31 1.18-9.26 2.33c-7.5 1.75-9.22 1.87-10.34.76s-1.08-2.6.25-9.08c1.42-6.92 1.43-8.15.09-11.5-1.1-2.77-1.2-4.08-.38-5 .61-.69 1.62-1.26 2.24-1.27zM107.19 81c4.08 0 5.12.42 6.86 2.75 1.53 2.05 1.87 3.52 1.36 5.75-.38 1.65-1.19 3.77-1.8 4.72-.61.94-2.23 2.26-3.61 2.91-1.37.66-3.17 1.34-4 1.5-.83.17-2.06.54-2.75.84-.69.29-1.06 1.09-.82 1.78s-.32 3.45-1.25 6.14c-.92 2.69-2.45 5.39-3.4 6-1.15.74-2.09.78-2.83.11-.81-.72-.82-1.62-.03-3.25.59-1.24 1.08-5.17 1.08-8.75s-.22-7.17-.5-8-1.2-1.5-2.05-1.5c-.86 0-2.77 1.37-4.25 3.05-2.43 2.74-3.2 3.02-7.66 2.75-4.64-.28-5.06-.53-6.37-3.8-1.26-3.14-1.21-3.91 2.33-11.5l6 .29c5.17.24 6.29.66 10.22 5.71l4.34-3.75c3.71-3.21 5.02-3.75 9.13-3.75zm-5.23 10.25c.83 2.19 1.6 2.7 3.79 2.5 1.86-.17 2.86-.9 3.08-2.25.19-1.1-.37-2.79-1.25-3.75-.87-.96-2.49-1.75-3.6-1.75-1.12 0-2.26.56-2.55 1.25-.28.69-.04 2.49.53 4zm-20.21 1.3c.41.85 1.09 1.41 1.5 1.25.41-.17.75-.64.75-1.05V90c0-1.1-.41-2-.92-2-.5 0-1.17.67-1.5 1.5-.32.83-.24 2.2.17 3.05zM321.5 87c.82 0 3.41.82 5.75 1.83 2.34 1 4.59 2.58 5 3.5.46 1.01.07 2.75-.99 4.42-.95 1.51-2.41 3.3-3.25 3.97-.83.67-3.2 1.23-5.26 1.25s-4.49-.31-5.4-.72-2.04-1.76-2.5-3c-.5-1.32-.44-3.29.15-4.75.55-1.37 1.9-3.4 3-4.5s2.68-2 3.5-2zm24.65 0c1.57 0 2.85.45 2.85 1s-.92 2.24-2.03 3.75c-1.12 1.51-2.02 3.31-2 4 .01.69.48 1.47 1.03 1.75s3.14-.67 5.75-2.09c2.61-1.43 5.1-2.22 5.53-1.75.42.46.31 2.08-.25 3.59-.63 1.68-2.4 3.34-4.53 4.25-1.93.83-5.19 1.49-7.25 1.47-2.17-.01-4.5-.75-5.53-1.75-.98-.94-1.77-2.73-1.75-3.97s.54-3.26 1.16-4.5 1.81-3.04 2.65-4c.83-.96 2.8-1.75 4.37-1.75zm21.09 5.75c1.57.31 2.49 1.24 2.61 2.62.1 1.17-.36 2.69-1.03 3.38s-2.03 1.25-3.02 1.25-2.49-1.01-3.33-2.25c-1.4-2.06-1.37-2.39.41-3.87 1.13-.94 2.96-1.42 4.36-1.13zm987.74 31.49c.82.14 1.61 1.05 1.75 2.01.15.96-1.64 4-3.98 6.76-2.34 2.75-5.04 5.23-6 5.5-1.07.3-1.75 1.46-1.75 2.99 0 2 .5 2.5 2.5 2.5 1.38 0 4.13 1.24 6.12 2.75s3.99 3.43 4.43 4.25c.48.9.13 2.86-.87 4.9-.93 1.88-3.59 4.69-5.93 6.25-3.26 2.19-5.42 2.85-9.25 2.85-2.75 0-5.67-.22-6.5-.5s-1.5-1.18-1.5-2 1.13-2.18 2.5-3c1.69-1.01 3.07-1.2 4.25-.59 1.13.58 2.82.46 4.75-.36 1.65-.7 3.9-2.28 7-5.75l-3-2.39c-1.65-1.32-3.56-2.4-4.25-2.41-.69 0-2.6-.9-4.25-2-2-1.33-3-2.83-3-4.5 0-1.37.63-3.74 1.4-5.25s3.13-4.31 5.25-6.21c2.12-1.91 4.98-4.05 6.35-4.76 1.38-.71 3.17-1.18 3.98-1.04zm-160.48.71c.55-.02 1.51.54 2.13 1.26.63.71 1.41 2.64 1.75 4.29.33 1.65.86 7.5 1.16 13l1.26 21.5c.38 6.32.66 18.93.61 28l-.24 29.5c-.09 7.15-.65 17.5-1.25 23-.9 8.22-.82 11.69.46 19.5.86 5.23 2.03 16.02 2.6 24s.85 16.3.62 18.5.03 12.32.57 22.5l.97 20c-.01.82.18 2.51.42 3.75s.89 2.25 1.44 2.25.98-.56.96-1.25 2.8-4.29 6.25-8c4.16-4.46 7.05-6.74 8.54-6.75 1.49 0 2.46.76 2.87 2.25.46 1.69-1.03 4.8-6 12.5-5.37 8.31-7.23 10.43-9.87 11.22-1.79.53-5.31.87-7.84.75-2.52-.12-5.38-.9-6.35-1.72s-3.1-3.52-4.74-6-4.29-5.29-5.9-6.25c-1.98-1.19-2.92-2.55-2.92-4.25 0-1.48.92-3.12 2.25-4.01 1.24-.83 3.71-1.5 5.5-1.5 2.26.01 3.38.54 3.69 1.76.24.96 1.59 2.54 3 3.5 1.52 1.04 2.76 1.34 3.06.75.28-.55.01-3.59-.58-6.75-.6-3.16-1.24-10.25-1.44-15.75l-1-23c-.36-7.15-.9-13.45-1.21-14-.3-.55-.67-5.5-.81-11-.16-6.06-.9-11.77-1.88-14.5-1.46-4.06-1.48-5.77-.2-17.5.77-7.15 1.5-18.85 1.6-26l.29-18.5c.06-3.03-.2-13.6-.57-23.5s-1.11-19.8-1.64-22-.76-6.47-.51-9.5c.33-3.88.02-6.16-1.04-7.75-.83-1.24-1.57-4.25-1.64-6.69-.11-3.66.28-4.72 2.25-6.01 1.31-.86 2.83-1.58 3.38-1.6zm-183.19 2.27c.54.15 1.17.73 1.39 1.28.21.55-.3 1.34-1.15 1.75s-2 .53-2.55.25c-.64-.32-.58-1.05.16-2.03.64-.85 1.6-1.41 2.15-1.25zm10.8 1.31c.49.26.67 1.03.4 1.72s-2.52 2.26-5 3.5-4.52 2.81-4.54 3.5.87 2.15 3.97 5.25l1.93-3.5c1.07-1.93 3.22-4.33 4.79-5.34 2-1.29 3.14-1.52 3.84-.76.68.73-.04 2.51-2.25 5.58-2.83 3.93-3.17 5.07-2.66 8.77.46 3.36.2 4.59-1.25 5.87-1.01.9-3.42 1.92-5.34 2.29-1.92.36-4.74.19-6.25-.38s-2.76-1.59-2.77-2.28 1.34-2.26 3-3.5 3.02-2.93 3.02-3.75-.61-1.84-1.35-2.25c-.75-.41-1.87-1.76-2.5-3-.93-1.81-.82-2.72.53-4.63.93-1.32 3.9-3.55 6.62-4.98 2.71-1.42 5.33-2.37 5.81-2.11zm46.94 3.47c1.07 0 2.25.56 2.61 1.25s.59 3.16.5 5.5c-.16 4.22-.14 4.25 3.34 4.25 2.22 0 3.68-.55 4-1.5.28-.82.5-2.62.5-4 0-1.37.22-3.18.5-4s1.4-1.5 2.5-1.5 2.06.56 2.13 1.25l.35 3.75c.13 1.38-.29 5.2-.93 8.5s-1.92 7.24-2.85 8.75c-.94 1.51-2.15 2.75-2.7 2.75s-1.16-.56-1.35-1.25.01-2.37.44-3.75c.43-1.37.48-2.85.1-3.28s-2.04-.77-3.69-.76c-1.65 0-3.9.67-5 1.49s-2.79 1.5-3.75 1.52c-1.52.03-1.66-.59-1.05-4.72.38-2.61.72-6.32.75-8.25s.41-4.06.85-4.75 1.68-1.25 2.75-1.25zm171.45.02c.55-.06 1.57.47 2.27 1.19.71.71 1.27 2.42 1.26 3.79-.02 1.38-.23 4.75-.49 7.5-.25 2.75-.03 6.69.5 8.75.86 3.38 1.28 3.75 4.21 3.72 1.79-.02 3.93-.58 4.77-1.25.83-.67 2.33-3.02 3.33-5.22 1.31-2.89 1.72-5.79 1.48-10.47-.32-6.24-.24-6.5 2.38-7.5 1.49-.57 2.96-.81 3.25-.53.3.28.96 2.3 1.47 4.5.57 2.46.57 4.67 0 5.75-.51.96-.93 3.55-.93 5.75s-.62 5.24-1.38 6.75-2.18 3.43-3.16 4.25-3.84 2.04-6.37 2.69c-3.03.79-5.78.88-8.09.29-1.92-.5-4.51-1.82-5.75-2.94-1.52-1.38-2.25-3.18-2.25-5.54 0-1.93-.45-3.72-1-4s-1.08-3.89-1.18-8.03c-.17-7.14-.06-7.58 2.25-8.44 1.34-.5 2.88-.95 3.43-1.01zm132.7-.02c1.25 0 2.08 1.15 2.72 3.75a142.92 142.92 0 0 1 1.5 7c.44 2.44 1.2 3.37 3.08 3.75 1.67.33 2.5 1.17 2.5 2.5 0 1.11-1.33 2.89-3 4-1.85 1.23-3 2.86-3 4.25-.01 1.24-1.02 3.56-2.25 5.16-1.32 1.7-2.77 2.63-3.5 2.25-.69-.37-1.21-2.34-1.15-4.41.05-2.06.05-4.31 0-5-.06-.74-1.52-1.25-3.6-1.25-2.44 0-3.5-.45-3.5-1.5 0-.82 1.01-1.89 2.25-2.37s2.92-1.66 3.75-2.63c1.23-1.43 1.32-2.8.51-7.53-.81-4.71-.73-5.98.45-6.87.79-.61 2.25-1.1 3.24-1.1zm17.6.96c.93-.03 2.37.68 3.2 1.57 1.33 1.45 1.33 1.73 0 2.53-.83.5-1.72.92-2 .94s-1.36-.54-2.4-1.23c-1.09-.73-1.6-1.8-1.2-2.52.38-.69 1.46-1.27 2.4-1.29zM1038.7 135c.71 0 1.3.68 1.3 1.5s-.79 1.94-1.75 2.47c-.96.54-2.09.76-2.5.5s-.21-1.37.45-2.47 1.78-2 2.5-2zm16.55 2.65c.53.26.91 1.12.85 1.91-.05.79-1.68 2.34-3.6 3.44-2.65 1.51-3.51 2.67-3.53 4.75-.02 1.51.88 3.65 1.99 4.75 1.67 1.65 2.09 1.74 2.42.5l1.6-6c.67-2.47 1.56-5.18 1.98-6 .41-.82 1.38-1.5 2.15-1.5 1.03 0 1.3 1.16 1.05 4.5-.19 2.47-1.32 6.3-2.51 8.5-1.69 3.1-2.84 4.07-5.16 4.29-2.28.23-3.77-.49-6.26-3-1.94-1.95-3.27-4.31-3.27-5.79 0-1.44 1.18-3.62 2.77-5.13 1.52-1.45 4.08-3.32 5.67-4.16 1.6-.84 3.33-1.31 3.85-1.06zm225.75 2.31c.28-.03 1.06.53 1.75 1.25.69.71 1.03 2.08.75 3.04-.27.96-1.62 1.97-3 2.25-1.37.28-2.5 1.18-2.5 2s.57 2.06 1.26 2.75c.7.69 1.76 2.38 2.37 3.75.6 1.38.82 4.01.48 5.86-.33 1.85-1.17 3.77-1.86 4.25-.73.52-4.15.48-8.25-.11-3.85-.55-7-1.45-7-2s1.01-1.29 2.25-1.64c1.24-.36 3.83-.74 5.75-.84 3.29-.19 3.5-.4 3.43-3.61-.04-1.95-1.11-4.82-2.5-6.7-1.9-2.58-2.2-3.67-1.36-5 .6-.94 2.62-2.5 4.5-3.46 1.89-.96 3.65-1.77 3.93-1.79zm198.89 3.07c.34.02 1.32.58 2.2 1.25.87.67 2.11 2.23 2.75 3.47s1.16 3.82 1.16 5.75.22 3.5.5 3.5 2.86-2.44 5.75-5.43c3.07-3.17 6.5-5.7 8.25-6.09 1.71-.38 3.43-.22 4 .38.67.71.63 1.49-.12 2.35-.62.71-2.42 1.85-4 2.54s-3.67 2.6-4.63 4.25-1.53 3.68-1.25 4.5 1.06 1.49 1.75 1.47 2.26-.92 3.5-2 2.25-2.65 2.25-3.47 1.01-2.18 2.25-3.01c1.24-.84 2.92-1.28 3.75-.99s2.29 1.87 3.25 3.52c.96 1.64 1.75 4.11 1.75 5.48 0 1.38-.56 2.66-1.25 2.85s-2.6-.09-4.25-.62c-2.29-.73-3.83-.56-6.5.73-3.07 1.49-4.03 1.54-7.83.37-2.38-.73-4.96-2.34-5.75-3.58-1.31-2.07-1.56-2.12-3.17-.67-.96.88-2.61 1.44-3.67 1.25-1.57-.27-1.93-1.22-2-5.24-.05-3.03-.56-5.04-1.33-5.25-.69-.19-2.83 2.36-4.75 5.66-3.46 5.92-3.55 5.99-7.25 5.44-3.13-.46-4.16-.13-6.25 2.03-1.37 1.42-3.29 2.57-4.25 2.56-.96-.02-1.89-.59-2.07-1.28s.46-3.28 1.41-5.75c.96-2.47 2.34-5.7 3.07-7.17.74-1.46 2.06-3.38 2.94-4.25.87-.87 2.45-1.6 3.5-1.62 1.04-.03 2.46.65 3.15 1.5 1.11 1.37 1.89 1.2 6.89-1.46 3.1-1.65 5.91-2.99 6.25-2.97zm55.45.92c1.74.38 3.72.99 4.41 1.37.69.37 2.14 2.59 3.23 4.93s1.99 5.26 2 6.5-.99 2.93-2.23 3.76-3.71 1.5-5.5 1.5c-1.79-.01-3.25-.23-3.25-.51s.5-1.51 1.11-2.75c.8-1.64.8-2.86 0-4.5-.61-1.24-1.58-2.25-2.16-2.25-.57 0-2.11 1.01-3.41 2.25-1.31 1.24-3.65 3.3-5.21 4.58-1.73 1.42-3.8 2.2-5.33 2-2.31-.3-2.54-.83-3.07-6.83-.31-3.57-.44-6.95-.28-7.5.15-.55 1.08-1.37 2.06-1.81 1.33-.61 2.38-.1 6.4 4.81l2.2-2.11c1.2-1.17 3.02-2.57 4.03-3.12s3.26-.69 5-.32zm-234.84.04c1.1-.01 2.57.55 3.27 1.24.69.7 1.26 2.28 1.25 3.52s-.47 3.15-1.02 4.25-2.58 2.68-4.5 3.5-3.5 2.18-3.5 3c0 1.08 1.11 1.5 4 1.5 2.45 0 5.07-.79 6.75-2.03 1.77-1.3 3.11-1.68 3.75-1.07.66.63.27 2-1.14 4.03-1.17 1.69-3.08 3.52-4.25 4.07-1.16.55-3.57.99-5.36.99-1.79-.01-4.37-.59-5.75-1.28-1.37-.7-3.23-2.83-4.11-4.74-1.2-2.56-1.39-4.38-.75-6.97.48-1.93 1.29-4.14 1.8-4.93.52-.79 2.43-2.25 4.25-3.25s4.21-1.82 5.31-1.83zm117.61 1.01c1.04 0 3 1.24 4.36 2.75s2.48 3.76 2.5 5c.03 2.02.42 2.2 3.78 1.77 2.48-.33 4.94-1.64 7.25-3.89 1.92-1.86 4.51-3.9 5.75-4.51 1.77-.88 2.57-.8 3.75.38.97.97 1.29 2.48.92 4.25-.32 1.51-.77 3.31-1 4s-1.88 2.13-3.67 3.21c-2.44 1.48-2.88 2.12-1.75 2.59.83.34 2.51.13 3.75-.46 1.24-.6 2.7-1.99 3.25-3.09s1.67-2 2.5-2c1.05 0 1.5 1.06 1.5 3.5 0 2.87-.59 3.87-3.25 5.53-2.63 1.64-4.21 1.91-8.25 1.39-2.75-.35-6.46-1.27-8.25-2.03-2.14-.92-3.08-1.9-2.75-2.89.31-.92-.27-1.69-1.5-2-1.1-.28-2.7.06-3.54.75-.85.69-1.52 1.93-1.49 2.75.04.82-.51 2.03-1.2 2.69-.7.65-1.83.99-2.52.75-.93-.33-1.06-2.02-.5-6.62.64-5.26.53-6.1-.75-5.68-.83.27-3.3 3.06-5.5 6.2-3.07 4.38-4.58 5.7-6.5 5.68-2.46-.02-2.5-.13-2.33-7.77.14-6.42.48-7.9 2-8.64 1.16-.56 2.47-.47 3.58.25 1.09.71 2.41.81 3.5.26.96-.49 2.36-1.61 3.11-2.5s2.21-1.62 3.25-1.62zm-1141.83 1.28c7.22.09 8.61.42 11.44 2.66 1.76 1.41 4.35 3.35 5.75 4.31 1.39.96 3.71 4.11 5.15 7 2.23 4.47 2.55 6.22 2.19 11.75-.25 3.69-1.39 8.66-2.66 11.5-1.22 2.75-2.72 5.9-3.34 7-.61 1.1-2.19 4.93-3.51 8.5l-6.03 17c-.34.82-.76 2.4-.94 3.5s-.59 6.72-1.48 23l6.62 6c4.71 4.27 6.46 6.5 6.07 7.75-.3.96-.09 2.43.46 3.25s.77 2.18.5 3-1.62 1.95-3 2.5c-1.37.55-4.55 3.81-7.06 7.25-2.5 3.44-4.91 7.6-5.34 9.25-.44 1.65-.63 6.82-.42 11.5l.74 12.5c.19 2.2 1.79 10.98 3.55 19.5l3.47 17.5 1.01 8c.45 3.62.24 9.77-.52 15.5-.7 5.23-1.86 10.96-2.6 12.75-.73 1.79-3.02 5.12-5.08 7.41-2.07 2.29-6.44 5.43-9.75 7-3.3 1.56-7.46 2.84-9.25 2.84s-3.25-.45-3.25-1 1.24-1.51 2.75-2.14 5-2.16 7.75-3.4c3.83-1.73 5.88-3.57 8.75-7.86 3.13-4.67 3.93-6.97 4.82-13.85.6-4.57.74-10.7.33-13.75-.41-3.02-.8-7.07-.86-9-.07-1.93-.62-5.3-1.24-7.5-.61-2.2-1.39-7.6-1.72-12-.38-5.02-1.4-9.68-2.74-12.5-1.85-3.89-2.13-6.19-2.06-17 .06-10.01.46-13.39 2.01-17 1.07-2.48 3.88-6.98 6.26-10 2.37-3.02 4.58-5.73 4.92-6 .33-.27.58-2.02.56-3.87-.02-2.69-.87-4.09-4.24-7-2.51-2.16-4.76-5.25-5.56-7.63-.74-2.2-1.47-6.93-1.6-10.5-.14-3.67.67-11.08 1.86-17 1.57-7.82 3.47-13.31 7.45-21.5 2.93-6.05 5.81-12.57 6.4-14.5.58-1.93 1.36-5.75 1.73-8.5.56-4.21.25-5.83-1.95-10.25-1.44-2.89-3.41-5.46-4.37-5.71s-2.65-1.39-3.75-2.53c-1.73-1.8-3.18-2.07-10.75-2.04-6.01.02-8.96-.36-9.41-1.22-.36-.7.31-1.98 1.54-2.91 1.66-1.26 4.17-1.64 10.4-1.56zm1118.07-.01c.47.12 1.52 1.8 2.34 3.73 1.28 3 1.3 4.14.15 8-1.11 3.72-1.76 4.5-3.76 4.5-2.35 0-2.41-.2-2.3-7.49.08-4.99.55-7.73 1.42-8.23.71-.41 1.68-.64 2.15-.51zm-355.26 5.47c.53.15.49 1.1-.09 2.26-.55 1.1-1.56 2.28-2.25 2.62s-2.37.33-3.75-.02c-2.42-.62-2.44-.7-.7-2.57.99-1.05 2.72-2.06 3.84-2.23s2.45-.2 2.95-.06zm-439.36 21.44c.88.18 1.75.88 1.94 1.57.18.69-.81 2.04-2.2 3-1.38.96-2.85 1.41-3.25.99-.39-.42-.13-1.92.6-3.32.75-1.47 2-2.43 2.91-2.24zm-28.26.84c.53-.01 1.54 1.11 2.25 2.48.7 1.38 1.57 4.86 1.93 7.75s1.15 5.58 1.75 5.98c.61.41 2.11.75 3.35.75 1.33.01 2.25.64 2.25 1.52 0 .82-.56 1.51-1.25 1.52s-2.27 1.03-3.53 2.25c-1.38 1.36-2.26 3.41-2.25 5.23.01 1.65-.88 4.46-1.97 6.25-1.1 1.79-2.45 3.25-3 3.25s-.99-1.69-.99-3.75c.01-2.06-.33-5.22-.75-7.02-.55-2.36-1.32-3.27-2.76-3.27-1.1.01-2.61-.32-3.35-.73-1.04-.56-1.1-1.24-.25-2.98.61-1.24 2.23-2.93 3.6-3.75 2.38-1.43 2.46-1.79 1.75-7.55-.6-4.87-.46-6.23.75-6.98.83-.52 1.94-.95 2.47-.95zM477.72 179c.16 0 .92 1.24 1.7 2.75 1.03 2 1.43 7.02 1.58 34.25l-2.51 1.25c-1.67.83-2.82.91-3.42.25-.49-.55-1.05-8.8-1.23-18.33-.32-16.32-.22-17.41 1.63-18.75 1.09-.78 2.1-1.42 2.25-1.42zm142.21 7.99c.31-.01 2.1 1.23 3.96 2.75 2.92 2.37 3.4 3.4 3.46 7.26.05 2.62-.64 5.65-1.64 7.25-1.35 2.18-2.7 2.87-6.46 3.34-3.64.45-5.1.21-6.25-1.03-.98-1.05-1.39-3.09-1.18-5.84.18-2.32.8-5.12 1.38-6.22.57-1.1 2.2-3.24 3.61-4.75 1.4-1.51 2.81-2.76 3.12-2.76zM360.05 188c1.07 0 2.86 1.01 3.97 2.25 1.49 1.66 2 3.57 1.95 7.25-.04 2.75-.39 8-.77 11.66-.39 3.66-.93 6.96-1.2 7.33s-1.74.41-3.25.09c-2.26-.48-2.75-1.12-2.75-3.58 0-2.26-.55-3.15-2.25-3.61-1.24-.34-4.16-.34-6.5 0S344.1 210.9 343 212s-2.56 3.86-3.25 6.14-1.83 4.42-2.55 4.75c-.71.34-1.94-.07-2.74-.89-1.12-1.16-1.22-2.28-.45-5 .55-1.93.99-6.76.99-10.75s-.45-8.37-1-9.75c-.55-1.37-.77-3.18-.5-4s1.18-1.5 2-1.5 2.29.75 3.25 1.67c.96.91 2.44 3.5 4.82 9.83l14.93-.32.3-3.34c.16-1.84-.18-4.58-.75-6.09-.58-1.51-.8-3.2-.5-3.75s1.43-1 2.5-1zm240.06 0c.49 0 1.15.79 1.46 1.75.32.96.99 2.54 1.5 3.5s.94 2.54.96 3.5-.65 3.1-1.49 4.75-1.52 3.68-1.52 4.5c.01.82-.53 2.06-1.2 2.75s-2.03 1.25-3.02 1.25c-1.45 0-1.68-.53-1.16-2.75.35-1.51.73-5.81.86-9.56.12-3.75.78-7.46 1.47-8.25s1.65-1.44 2.14-1.44zm51.39 1.26c2.2.2 4.96 1.23 6.13 2.3s2.4 2.95 2.75 4.19c.34 1.24.19 3.71-.34 5.5-.56 1.87-2.05 3.78-3.5 4.5-1.4.69-2.71.91-2.91.5s-.65-2.44-1-4.5c-.42-2.51-1.45-4.24-3.13-5.25-2.22-1.33-2.83-1.33-5.5 0-2.56 1.28-2.93 1.94-2.5 4.5s.06 3.22-2.5 4.5c-1.65.82-3.45 1.28-4 1-.61-.31-.76-3.13-.39-7.25.33-3.71 1.2-7.43 1.93-8.25 1.16-1.33 1.5-1.3 2.89.25 1.49 1.66 1.73 1.65 4.82-.29 2.25-1.42 4.48-1.94 7.25-1.7zm770.75 3.77c.96-.02 2.53 1.21 3.47 2.72 1.32 2.11 1.8 5.56 2.06 14.75.29 10.38.06 12.64-1.72 16.75-1.13 2.61-2.73 4.97-3.56 5.25s-2.06.08-2.75-.44c-1-.75-1-2.7 0-9.75.69-4.84.96-9.93.6-11.31-.36-1.37-.55-3.62-.42-5 .13-1.37-.5-3.18-1.39-4-.9-.82-1.71-2.58-1.81-3.89a4.23 4.23 0 0 1 1.79-3.72c1.09-.73 2.77-1.34 3.73-1.36zM523.58 195c.78 0 1.65.68 1.92 1.5s-.17 2.85-1 4.5-1.5 4.35-1.5 6c0 1.72.54 3.01 1.25 3.03.69.02 3.05-1.34 5.25-3.03s4.34-3.05 4.75-3.03c.41.01.98.48 1.25 1.03s.05 2.01-.51 3.25c-.55 1.24-2.24 3.18-3.75 4.33-1.51 1.14-4.32 2.61-6.24 3.26-1.92.66-4.06 1.19-4.75 1.18s-1.92-.7-2.75-1.52c-.85-.85-1.58-3.58-1.68-6.33-.14-3.99.39-5.64 3.08-9.5 1.79-2.57 3.9-4.67 4.68-4.67zm770.17.14c.14-.08.87 1.1 1.63 2.61s1.66 5.11 2 8c.57 4.86.9 5.38 4.37 7 2.06.96 4.06 2.2 4.43 2.75.38.55.55 1.22.37 1.5-.17.28-2.17.84-4.43 1.25-3.2.58-4.45 1.42-5.62 3.75-.83 1.65-1.5 3.9-1.5 5s-1.01 2.68-2.25 3.51-2.59 1.5-3 1.5c-.41-.01-.75-2.71-.75-6.01 0-5.47-.22-6.09-2.5-7-1.37-.55-2.5-1.45-2.5-2s1.35-1.79 2.99-2.75c1.65-.96 3-2.43 3.01-3.25s-.43-3.86-.99-6.75-.68-5.9-.28-6.69 1.64-1.63 2.75-1.87c1.11-.23 2.13-.48 2.27-.55zm-746.17.86c.78 0 1.65.68 1.92 1.5s-.62 2.63-2 4c-1.37 1.38-2.5 3.63-2.5 5 0 1.38.34 2.51.75 2.52s1.54-1.56 2.5-3.5 2.43-3.86 3.25-4.27c.92-.46 2.18-.08 3.25.97.96.95 2.54 1.74 3.5 1.75.99.02 1.54.57 1.26 1.28-.28.69-2.19 1.88-4.25 2.64-2.07.77-4.77 2.46-6.01 3.75-1.63 1.71-3.35 2.36-6.25 2.36-2.67 0-4.17-.5-4.5-1.5-.27-.82-.55-2.79-.6-4.36-.08-2.04 1.1-4.19 4.08-7.5 2.3-2.55 4.82-4.64 5.6-4.64zm691.22 2.38c1.48.76 3.26 2.11 3.95 3s1 2.41.7 3.37c-.45 1.47-1.22 1.63-4.75 1.01-2.31-.4-5.02-1.53-6.03-2.5-1.78-1.7-1.75-1.83.8-4.01 2.38-2.04 2.88-2.12 5.33-.87zm-742.22.62c.78 0 1.61.34 1.84.75s1.7.58 3.25.38c2.25-.3 3.29.27 5.08 2.75 2 2.77 2.11 3.48 1.04 6.37-.67 1.79-2.13 4.24-3.25 5.44-1.12 1.21-3.28 2.67-4.79 3.25s-3.76 1.07-5 1.09c-1.24.01-3.28-1-4.54-2.25-1.82-1.81-2.17-3-1.73-5.78.31-1.93 1.94-5.41 3.62-7.75s3.69-4.25 4.48-4.25zm-1.31 13.83c1.37 1.29 2.16 1.42 3.5.57.95-.61 1.76-2.22 1.8-3.59.04-1.36-.45-3.02-1.1-3.69-.92-.93-1.72-.51-3.58 1.92-2.28 2.98-2.31 3.2-.62 4.79zM417.67 200c.73 0 1.56.68 1.83 1.5s.5 2.4.5 3.5-.61 2.34-1.36 2.75c-.76.41-2.04 2.1-2.87 3.75s-2.91 4.24-4.64 5.75c-2.86 2.51-3.39 2.64-6.09 1.5-2.62-1.11-3.3-1-9.04 3.25l-4.25-2.07c-2.48-1.21-5.19-1.84-6.5-1.5-1.24.31-2.26 1.13-2.28 1.82s-1.14 2.04-2.5 3c-1.74 1.23-3.25 1.53-5.13 1-1.47-.41-3.51-1.87-4.54-3.25-1.03-1.37-1.85-3.96-1.83-5.75.01-1.79.48-4.37 1.03-5.75.55-1.37 2.05-3.23 3.33-4.12 1.79-1.23 3.66-1.47 8-1 5.14.56 5.82.92 7.28 3.87.88 1.79 2.57 3.99 3.75 4.9 1.72 1.33 2.58 1.42 4.41.5 1.49-.75 2.09-1.75 1.75-2.9-.29-.96-.75-2.65-1.02-3.75-.32-1.26.15-2.34 1.25-2.93.96-.51 2.2-.63 2.75-.25.55.37 1.79 2.37 2.75 4.43s2.2 3.75 2.75 3.75 1.9-1.35 3-3 1.91-3.31 1.81-3.69c-.11-.37.87-1.72 2.17-3 1.3-1.27 2.96-2.31 3.69-2.31zm-41.92 16.3c.41.98 1.2 1.62 1.75 1.41s1.14-1.24 1.31-2.29c.18-1.06-.07-2.28-.55-2.71-.47-.44-1.4-.21-2.06.5-.7.75-.89 2.04-.45 3.09zM437 199.99c1.38-.04 3.06.62 3.75 1.47.79.97.97 2.5.5 4.13-.42 1.44-2.08 3.22-3.75 4.02-1.65.79-3.56 1.42-4.25 1.41s-1.25.43-1.25.98 1.46 1.01 3.25 1.03 4.82-1.01 6.75-2.29 4.06-2.64 4.75-3.03c.82-.47 1.25-.02 1.25 1.29 0 1.1-1.46 3.61-3.25 5.58-2.86 3.14-3.91 3.62-8.75 3.91-3.02.19-6.74-.07-8.25-.58-1.61-.53-2.75-1.64-2.74-2.66 0-.96-.65-2.65-1.45-3.75-1.28-1.75-1.28-2.28-.01-4.25.8-1.24 2.35-2.25 3.45-2.25s3.24-1.11 4.75-2.47 3.88-2.5 5.25-2.54zm1027.31 4.6c.66.39 2.21 1.65 3.47 2.81 1.25 1.15 2.24 3 2.2 4.1s.51 2.54 1.23 3.19c.71.66 3.88 1.56 7.05 2 3.17.45 5.78 1.03 5.8 1.31.01.28-.55 1.01-1.27 1.62-.71.62-3.09 1.73-5.29 2.46-2.2.74-4.58 1.81-5.29 2.38-.72.57-1.21 1.94-1.1 3.04s.13 3.01.05 4.25c-.09 1.24-1.17 3.14-2.41 4.22s-2.65 1.65-3.14 1.25c-.48-.4-.6-2.41-.25-4.47s.26-4.76-.21-6c-.46-1.24-1.7-2.59-2.75-3.01-1.23-.5-2.43-.22-3.4.78-.83.85-3.75 1.74-6.5 1.98-2.75.25-5.45.86-6 1.38-.55.51-2.35 1.07-4 1.25-1.65.17-3.96-.35-5.14-1.16-1.17-.81-2.29-2.37-2.48-3.47s.4-3.57 1.31-5.5 2.71-4.5 3.99-5.73c1.27-1.22 3.78-2.68 5.57-3.25 2.16-.68 3.42-.68 3.75-.02.28.55-.29 1.79-1.25 2.76s-2.74 2.43-3.95 3.25-2.56 2.96-3 4.76c-.58 2.39-.46 3.27.45 3.25.69-.01 2.19-1.37 3.33-3.02s3.05-3.51 4.25-4.13c1.85-.97 2.5-.75 4.42 1.5 1.5 1.75 2.92 2.46 4.25 2.13 1.1-.28 2.92-1.74 4.03-3.25 1.12-1.51 2.02-3.54 2-4.5-.01-.96-.55-2.54-1.18-3.5s-.83-2.57-.44-3.56c.42-1.06 1.21-1.52 1.9-1.1zm-196.56 6.4c.69.01 2.49.95 4 2.1 2.05 1.56 3.04 3.54 3.88 7.75.69 3.41.79 6.36.25 7.41-.48.96-1.89 2-3.13 2.32-1.24.31-2.3.42-2.36.25-.07-.18-1-3.02-2.09-6.32-1.47-4.49-2.44-6-3.84-6-1.05 0-3.07 1.75-4.63 4-1.52 2.2-2.79 4.9-2.82 6s-.84 2.8-1.79 3.78c-.94.98-2.73 1.77-3.97 1.75-1.9-.02-2.27-.61-2.4-3.78l-.25-5.48c-.05-.95-.55-1.75-1.1-1.78-.55-.02-1.22 2.1-1.5 4.71-.4 3.82-.99 4.99-3 5.96-1.64.79-3.1.89-4.25.27-.96-.51-1.81-1.72-1.89-2.68-.07-.96-.07-3.44 0-5.5.08-2.06-.53-5.1-1.36-6.75-1.36-2.73-1.34-3.19.25-5.03.96-1.12 2.76-2.02 4-2 1.3.02 2.75.98 3.42 2.28.65 1.24 1.77 2.81 2.5 3.5 1.07 1 1.64.95 2.9-.25.87-.82 2.67-1.5 4-1.5 1.34 0 2.65.45 2.93 1s2.86-.58 5.75-2.51c2.89-1.92 5.81-3.5 6.5-3.5zm56.45.19c2.57.25 3.36.82 3.55 2.57.14 1.24-.59 3.94-1.61 6-1.08 2.18-3.19 4.38-5.04 5.25-1.75.82-3.16 2.06-3.14 2.75s1.28 1.26 2.79 1.28c1.51.01 4.63-1.23 6.92-2.75 2.3-1.53 5.11-4.02 6.25-5.53s2.64-2.73 3.33-2.71 2.6 1.11 7.25 4.82l2.5-1.96c1.38-1.08 3.29-1.95 4.25-1.93 1.55.03 1.46.51-.77 4.28-1.38 2.34-3.74 5.03-5.25 5.99-1.5.96-3.52 1.75-4.48 1.75-.96.01-1.75-.67-1.75-1.49s.9-1.95 2-2.5 2-1.45 2-2c0-.59-1.35-.75-3.25-.39-1.79.33-4.37 1.61-5.75 2.85-1.37 1.23-4.53 3.2-7 4.36-2.47 1.17-5.85 2.41-7.5 2.77-1.65.35-4.01.14-5.25-.47-1.24-.62-3.6-3.15-8.25-10.12l2.75-1.89c1.51-1.03 4.87-3.99 7.45-6.56 3.99-3.97 5.22-4.64 8-4.37zm44.55 2.88c1.24-.03 3.38.39 4.75.94 2.23.89 2.47 1.51 2.25 5.72-.22 4.15-.67 4.99-3.75 7.05-1.92 1.29-4.51 3.21-5.75 4.28-1.83 1.59-2.26 3.02-2.31 7.7-.03 3.16-.59 7.32-1.25 9.25-.93 2.74-1.79 3.55-6.69 4l.21-15.75c.2-15.37.26-15.82 2.75-18.44 1.4-1.48 3.67-3.14 5.04-3.69 1.38-.55 3.51-1.02 4.75-1.06zM1364 225c.74 1.47 1.53 1.8 2.98 1.25 1.1-.41 2.22-1.65 2.49-2.75.28-1.1.51-2.34.52-2.75 0-.41-1.57-.75-3.49-.75-2.44 0-3.5.45-3.5 1.5 0 .82.45 2.4 1 3.5zm145.37-11c.9 0 1.63.68 1.63 1.5s1.58 2.18 3.5 3c3.05 1.31 3.5 1.95 3.5 5 0 1.93-.79 4.85-1.75 6.5s-2.87 3.42-4.25 3.94c-1.37.52-4.3 1.22-6.5 1.56-3.11.49-4.4.22-5.81-1.19-1.71-1.7-1.72-2.15-.25-7.56 1.02-3.76 2.73-6.96 4.93-9.25 1.86-1.93 4.11-3.5 5-3.5zm-5.27 15.57c-.07.96.76 1.35 2.55 1.18 1.46-.14 3.14-1.04 3.75-2 .8-1.27.8-2.23-.01-3.5-.61-.96-1.81-1.9-2.68-2.07-.96-.2-1.96.7-2.54 2.31-.54 1.45-1.01 3.29-1.07 4.08zm23.55-15.57c.74 0 1.8.9 2.35 2 .8 1.61 1.64 1.88 4.25 1.4 2.26-.42 4.55.04 7.5 1.5 2.51 1.24 4.5 3.02 4.86 4.35.34 1.24.11 3.82-.51 5.75s-1.11 4.4-1.07 5.5c.03 1.1-.68 2.68-1.59 3.5-1.48 1.34-1.81 1.29-3.07-.5-.77-1.1-1.39-4.03-1.37-6.5s-.54-5.07-1.23-5.77c-.7-.69-2.06-1.26-3.02-1.25-.98.01-2.21 1.23-2.79 2.77-.57 1.51-.8 3.31-.5 4s-.02 1.66-.71 2.17c-.69.5-2.49 1.18-4 1.5-2.69.57-2.75.48-2.81-4.17-.03-2.61-.24-6.55-.46-8.75-.27-2.73.11-4.56 1.21-5.75.88-.96 2.21-1.75 2.96-1.75zm-129.9 1.08c2.63-.06 3.63.54 5.25 3.17 1.09 1.79 1.99 4.49 2 6 0 1.51-.79 3.49-1.75 4.39s-2.76 2.03-4 2.5-4.16.88-6.5.9c-2.59.03-5.18-.65-6.63-1.75-1.97-1.49-2.27-2.38-1.78-5.29.32-1.93 1.56-4.4 2.73-5.5 1.18-1.1 3.34-2.53 4.79-3.17s4.1-1.2 5.89-1.25zm-6.92 9.09c.09.46.84 1.51 1.67 2.33s1.95 1.5 2.5 1.5 1.11-1.08 1.23-2.39c.15-1.52-.39-2.62-1.5-3-.95-.34-1.88-.61-2.06-.61-.19 0-.71.3-1.17.67-.46.36-.76 1.04-.67 1.5zm98.7-9.17c1.96 0 2.64.67 3.27 3.25.43 1.79.69 5.05.56 7.25s-.55 6.25-.93 9c-.39 2.75-1.21 5.58-1.82 6.29-.61.72-1.9 1.28-2.86 1.25-.96-.02-2.2-.94-2.75-2.04-.64-1.28-.68-4.41-.1-8.75.49-3.71.66-7.87.38-9.25-.28-1.37.01-3.51.63-4.75.72-1.42 2.06-2.25 3.62-2.25zm-470.78 6.08c.69-.04 1.25.82 1.25 1.92 0 1.33-1.17 2.5-3.5 3.5-2.67 1.14-3.5 2.1-3.5 4 0 1.38.45 2.72 1 3s1 .16 1-.25 1.61-2.1 3.59-3.75c2.37-1.99 3.91-2.66 4.56-2 .64.65.51 1.52-.37 2.5-.74.82-2.34 2.96-5.78 8l2 2c1.1 1.1 1.77 2.68 1.5 3.5s-.05 1.72.5 2c.62.31.43 1.63-.5 3.5-.83 1.65-2.4 3.45-3.5 4-1.17.59-3.93.69-6.65.25-3.17-.51-4.96-1.39-5.63-2.75-.76-1.58-.31-3.01 2.16-6.75 1.71-2.61 3.11-5.31 3.09-6s-.7-2.15-1.52-3.25-1.49-2.9-1.5-4 .79-2.96 1.77-4.13c.98-1.18 3.36-2.83 5.28-3.67 1.92-.85 4.06-1.57 4.75-1.62zm-7.24 28.17c2.02 1 2.76 1 3.75-.01.9-.92.96-2 .24-3.92-.55-1.46-1.47-2.81-2.04-3-.58-.19-1.81 1.02-2.75 2.67-1.68 2.97-1.67 3.03.8 4.26zm70.49-20.97c.83.13 1.64 1.36 1.81 2.73s-.4 4.4-2.81 10.99l5.01-.75c4.4-.66 5.01-.53 5 1 0 .96-1.13 3.55-2.51 5.75-1.37 2.2-3.51 4.7-4.75 5.56-1.46 1-3.4 1.36-5.5 1-1.79-.31-3.47-1.01-3.75-1.56s-.06-4.04.48-7.75l1.59-10.72c.34-2.19 1.37-4.54 2.28-5.23.91-.7 2.32-1.16 3.15-1.02zm-3.09 21.15c.05.87.43 1.58.84 1.6s1.47-.77 2.35-1.75 1.89-2.34 2.25-3.03c.4-.77-.15-1.41-1.44-1.66-1.3-.26-2.46.28-3.09 1.43-.55 1.02-.96 2.55-.91 3.41zm-41.66-18.4c1.21-.02 1.75.74 1.75 2.47 0 1.38-.45 2.72-1 3s-2.12.28-3.5 0c-1.37-.28-2.58-1.15-2.67-1.95s.69-1.91 1.75-2.47 2.71-1.03 3.67-1.05zm21.25-.07c.55-.02 3.25 1.44 6 3.25 3.76 2.47 5.06 3.97 5.25 6.04.18 1.97-.67 3.68-3 6.04-2.56 2.59-4.42 3.45-8.75 4.05-5.04.69-5.64.56-7.18-1.54-.93-1.27-1.86-3.42-2.08-4.8-.23-1.37.08-4.07.68-6 .76-2.45 2.13-4.02 4.58-5.25 1.92-.96 3.95-1.76 4.5-1.79zm-3.93 14.79c.24.69.88 1.25 1.43 1.25s2.35-.68 4-1.5 3.01-2.06 3.03-2.75c.01-.69-1-2.25-2.25-3.48-1.26-1.22-2.78-2.24-3.39-2.25-.62-.01-1.6 1.67-2.18 3.73-.59 2.06-.88 4.31-.64 5zm-537.71-.73c.35 0 1.14.34 1.74.75.61.4 1.71 1.86 2.45 3.23.74 1.38 1.59 4.3 1.9 6.5.57 3.99.58 4 5.06 4 2.47 0 5.05.34 5.74.75 1 .6 1 1.06 0 2.3-.69.85-3.39 2.2-6 3-3.86 1.18-4.86 1.97-5.34 4.2-.32 1.51-1 4.21-1.5 6-.64 2.27-1.44 3.17-2.66 2.99-1.42-.22-1.75-1.29-1.75-11.12l-4.99-1.06c-3.47-.74-5.06-1.59-5.25-2.81-.14-.96.64-2.2 1.74-2.75s3.13-.77 4.5-.5c1.77.35 2.69-.01 3.16-1.25.37-.96.14-3.89-.5-6.5-.85-3.49-.87-5.15-.05-6.25.61-.82 1.4-1.49 1.75-1.48zm519.45.2c.54.15 1.17.73 1.39 1.28.21.55-.3 1.34-1.15 1.75s-2 .53-2.55.25c-.64-.32-.58-1.05.16-2.03.64-.85 1.6-1.41 2.15-1.25zm-494.7.78c.77 0 1.39.68 1.39 1.5s-.67 1.72-1.5 2-1.95.28-2.5 0c-.65-.32-.61-1.03.11-2 .61-.82 1.74-1.5 2.5-1.5zm75.39 7.22c2.6.21 3.58.79 3.82 2.28.18 1.14-1.52 4.63-3.94 8.1-2.69 3.84-5.49 6.61-7.59 7.5-1.83.77-3.32 1.74-3.31 2.15s.58 1.01 1.27 1.34c.69.32 3.5-.13 6.25-1 2.94-.93 6.75-3.23 9.25-5.59 2.34-2.2 4.5-3.89 4.82-3.75.31.14.23 1.38-.18 2.75-.41 1.38-2.35 4.21-4.32 6.3-1.96 2.08-4.27 3.77-5.12 3.75-.85-.03-1.98.4-2.5.96s-3.73 1.12-7.12 1.25c-5.4.21-6.5-.07-8.78-2.26-1.68-1.62-2.6-3.56-2.59-5.5.02-1.96.97-3.9 2.78-5.61 1.52-1.43 4.12-4.13 5.77-6 1.66-1.86 4.14-4.19 5.5-5.17 1.53-1.1 3.83-1.68 5.99-1.5zm-10.13 11.23c.07.85.58 1.55 1.13 1.55s2.11-1.46 3.47-3.25 2.49-3.59 2.5-4c.02-.41-.35-.75-.82-.75-.46 0-2.1 1.1-3.63 2.45s-2.72 3.15-2.65 4zM393.43 254.3c.59.2 2.08 2.12 3.3 4.28 1.23 2.15 2.26 5.05 2.29 6.42.03 1.38.78 2.95 1.67 3.5 1 .62 1.36 1.66.96 2.75-.36.96-1.77 2.2-3.15 2.75-1.82.73-2.64 1.95-3 4.5-.31 2.15-1.37 4.06-2.75 4.96-1.24.8-2.59 1.25-3 1s-.33-2.15.18-4.21.74-4.09.5-4.5-2-1.2-3.93-1.75c-2-.57-3.5-1.64-3.5-2.5 0-.92 1.56-1.89 4-2.5 3.33-.83 4-1.42 4-3.5 0-1.37-.46-3.74-1.02-5.25-.8-2.19-.67-3.11.68-4.52.93-.98 2.18-1.62 2.77-1.43zM582 257c.27-.03 1.85 1.29 3.49 2.92 2.73 2.7 2.95 3.4 2.44 7.77-.32 2.83-1.56 6.16-2.99 8.08-1.34 1.8-2.78 3.26-3.19 3.25s-.68-2.16-.59-4.77.09-5.99 0-7.5-.61-2.75-1.16-2.75-1.67 1.57-2.5 3.5-2.4 3.95-3.5 4.5-2.9 1-4 1-2.18-.56-2.41-1.25c-.26-.8-1.24-.29-2.75 1.41-1.29 1.47-3.8 3.38-5.59 4.25-2.01.98-3.44 1.21-3.75.59-.27-.55.5-2.69 1.73-4.75s3.14-5.55 4.25-7.75c1.19-2.36 3.25-4.55 5.02-5.34 2.28-1.03 3.66-1.09 5.75-.25 2.26.9 3.32.74 6-.89 1.79-1.09 3.48-2 3.75-2.02zm-247.89 1c2.45 0 3.12.6 4.39 4 .82 2.2 1.5 4.9 1.5 6s.23 2 .5 2 2.3-.9 4.5-2 5.24-2.02 6.75-2.03c1.51-.02 3.99.88 5.5 2 1.72 1.27 2.75 2.96 2.75 4.53 0 1.38-1.29 4.41-2.88 6.75-1.58 2.34-4.39 5.44-6.25 6.9-1.85 1.46-5.39 3.59-7.87 4.73s-5.85 2.08-7.5 2.08c-1.65.01-3.53-.32-4.19-.73-.65-.4-1.26-2.53-1.36-4.73-.09-2.2.42-7.15 1.14-11 1.17-6.2 1.12-7.52-.36-11.5-1.23-3.28-1.39-4.84-.59-5.75.59-.69 2.38-1.25 3.97-1.25zm4.14 16.01c-.14-.01-.51 2.58-.83 5.74s-.21 6.09.25 6.5 2.18.52 3.83.23c1.65-.28 4.69-2.08 6.75-4 2.37-2.19 3.89-4.6 4.12-6.52.21-1.67-.13-3.72-.75-4.55-.61-.82-1.35-1.46-1.62-1.42-.27.05-2.98.97-6 2.05-3.02 1.09-5.61 1.97-5.75 1.97zm206.92-14.38c.46.2 1.5 1.94 2.33 3.87s1.5 5.52 1.5 8c0 3.73-.43 4.76-2.5 6-1.37.82-2.84 1.32-3.25 1.1s-.86-2.25-1-4.5c-.14-2.26-.7-5.22-1.25-6.6-.55-1.37-1.09-3.33-1.21-4.35-.12-1.11.74-2.25 2.17-2.87 1.31-.57 2.75-.86 3.21-.65zm763.85.29c2.04.32 4.68 1.48 5.87 2.58 1.2 1.1 2.16 3.01 2.14 4.25s-.48 3.15-1.03 4.25-1.56 2.01-2.25 2.02-1.92-1.45-2.75-3.25c-.97-2.1-2.21-3.27-3.5-3.27-1.75 0-2.03.75-2.26 6-.14 3.3.08 6.6.5 7.33.42.72 3.17 1.62 6.11 2 2.95.37 5.76 1.23 6.25 1.92.61.84.17 1.74-1.35 2.76-1.24.83-3.49 1.5-5 1.5-1.51-.01-3.42.22-4.25.49-1.04.35-1.5 1.89-1.5 5 0 3.42-.42 4.63-1.75 5.03-.96.28-2.54.28-3.5 0-1.3-.39-1.81-1.76-2-5.27-.2-3.84-.63-4.81-2.25-5.12-1.1-.21-3.12-.78-4.5-1.27-2.5-.89-2.5-.89-.5-2.88 1.1-1.1 3.13-2.11 4.5-2.24 2.45-.24 2.5-.45 2.72-9.25.12-4.95.72-9.61 1.33-10.36.62-.75 2.05-1.69 3.2-2.09 1.14-.39 3.74-.46 5.77-.13zm33.67.08c2.44 0 2.51.21 2.85 8.25.19 4.54.26 13.15.15 19.14-.15 8.41-.53 11.12-1.69 11.9-.83.56-2.29.72-3.25.36-1.54-.57-1.69-1.71-1.26-9.4L1340 280c.02-.82-.15-4.2-.37-7.5s-.18-7.46.09-9.25c.39-2.67.93-3.25 2.97-3.25zm-894.44 2.04c1.19-.03 2.07 1.15 2.74 3.71.55 2.06 1.02 5.55 1.05 7.75.03 2.45-.55 4.48-1.5 5.25-.84.69-2.1 1.08-2.79.88-.72-.21-1.36-2.35-1.5-5-.14-2.55-.48-5.08-.75-5.63s-1.29-1.01-2.25-1.03c-.96-.01-2.9 1.68-4.31 3.75-1.4 2.08-2.9 5.13-3.33 6.78s-1.3 3.58-1.94 4.29c-.64.72-1.96 1.28-2.92 1.25-1.4-.03-1.69-.78-1.45-3.79.17-2.06-.27-6.23-.98-9.25-1.16-4.96-1.11-5.62.45-6.77.95-.69 1.96-1.27 2.23-1.28s1.29.9 4 4.05l5.75-2.46c3.16-1.35 6.54-2.47 7.5-2.5zm987.95.96c.99 0 2.02.45 2.3 1s-.21 1.68-1.07 2.5c-.87.82-1.88 1.52-2.25 1.54-.37.03-1.23-.53-1.91-1.25-.94-.99-.95-1.58-.05-2.54.65-.69 1.99-1.25 2.98-1.25zm-973.3 1a1.96 1.96 0 0 1 1.6 1c.28.56 2.13.74 4.25.41 3.18-.49 4.09-.19 6 2 1.25 1.44 1.8 2.81 1.25 3.09-.55.27-1 1.4-1 2.5s-.45 2-1 2-2.43 1.24-4.19 2.75c-2.51 2.16-4.05 2.7-7.25 2.52-2.23-.13-4.59-.81-5.23-1.5-.64-.7-1.26-2.17-1.36-3.27-.11-1.1-.1-2.74.02-3.64.13-.91 1.49-3.05 3.02-4.75 1.54-1.71 3.29-3.11 3.89-3.11zm-.89 10.75c0 .69 1 1.27 2.24 1.29 1.24.03 2.81-.65 3.5-1.5 1.03-1.26.89-1.9-.75-3.54-1.1-1.1-2.41-2-2.9-2-.5 0-1.17 1.01-1.49 2.25s-.59 2.81-.6 3.5zm896.4-10.55c1.14.17 2.75 1.65 3.57 3.3.83 1.65 1.51 5.55 1.51 8.67.01 4.31-.48 6.23-2.05 8-1.13 1.28-2.61 3.68-3.29 5.33-.86 2.1-.91 3.3-.17 4 .58.55 1.05 2.24 1.04 3.75s-.71 3.09-1.56 3.5c-.88.43-2.05.2-2.75-.55-.66-.72-1.18-3.19-1.14-5.5s.43-5.1.88-6.2c.44-1.1.99-5.15 1.21-9s-.06-8.35-.62-10c-.72-2.14-.69-3.37.14-4.3.63-.71 2.08-1.16 3.23-1zm36.74-.2c.47 0 .85.68.85 1.5s-.79 2.2-1.75 3.06c-1.21 1.08-2.06 1.24-2.75.53-.67-.7-.38-1.71.9-3.07 1.04-1.11 2.28-2.02 2.75-2.02zm-157.18.97c.29-.02 1.77.88 3.28 2 1.86 1.38 2.83 3.08 3 5.28.24 3.07.45 3.23 3.75 2.95 1.92-.17 4.36.28 5.4 1 1.23.84 1.67 1.92 1.25 3.05-.37 1-2.8 2.39-10.65 4.75l-.75 7.01c-.61 5.73-1.07 7.01-2.5 7-.96 0-2.44-1.02-3.29-2.26-.96-1.41-1.42-3.93-.96-11.25l-3.75-.25c-2.93-.2-3.69-.63-3.49-2 .15-.96 1.95-2.54 4-3.5 2.06-.96 3.74-2.2 3.74-2.75s-.79-2.63-1.75-4.63c-1.7-3.51-1.69-3.66.22-5 1.09-.75 2.22-1.39 2.5-1.4zm256.03 1c.83-.03 2.06.64 2.75 1.49.69.84 1.03 1.99.75 2.54s-1.85 1-3.5 1c-1.76 0-3.31-.66-3.75-1.59-.47-.99-.19-1.92.75-2.48.83-.5 2.17-.93 3-.96zm-166.88 2.07c1.1.57 1.97 1.69 1.94 2.5-.03.8-1.07 1.72-2.31 2.04-1.28.33-2.82.01-3.57-.75-1.1-1.1-1.04-1.63.31-3.08 1.27-1.35 2.09-1.51 3.63-.71zm89.67 2.94c1.49 0 4.62 1.35 11.21 6.02l-.52 5.75c-.29 3.16-.97 6.2-1.52 6.75s-.97 1.9-.93 3c.03 1.1-.52 2.56-1.24 3.25-.71.69-1.96 1.04-2.79.77s-1.85-1.96-2.28-3.75c-.44-1.82-.36-4.38.18-5.77.7-1.82.55-3.32-.53-5.5-.82-1.65-1.88-3.45-2.35-4-.51-.61-1.26.38-1.88 2.5-.57 1.93-1.4 5.24-1.84 7.37-.44 2.14-1.14 4.05-1.55 4.25-.41.21-.73 1.17-.72 2.13.02.96-.99 2.93-2.25 4.37-1.64 1.88-2.98 2.49-4.78 2.17-2.14-.38-2.45-.9-2.17-3.62.19-1.74.94-4.52 1.67-6.17.78-1.74 1.06-4.17.67-5.79-.38-1.56-1.55-3.04-2.67-3.36-1.3-.37-2.44.08-3.27 1.29-.69 1.02-1.26 3.43-1.26 5.36s.57 4.08 1.26 4.78c1.03 1.03.76 1.7-1.41 3.5-1.47 1.22-2.83 3.12-3.01 4.22-.2 1.2-1.22 2.1-2.57 2.25-1.88.21-2.24-.24-2.24-2.75 0-1.65-.46-4.24-1.02-5.75-.78-2.13-.67-3.09.49-4.25.82-.82 1.95-3.19 2.51-5.25.64-2.34 2.24-4.64 4.27-6.12 1.79-1.3 4.6-2.6 6.25-2.89 1.65-.28 3.9-.18 5 .23 1.46.56 2.88-.01 5.29-2.11 1.86-1.62 4.46-2.87 6-2.88zm60.71.08c.55-.02 1.57.3 2.28.71.7.4 1.04 1.41.75 2.23s-2.1 2.4-4.03 3.5c-3.34 1.91-3.42 2.08-1.75 3.79.96.99 2.42 1.98 3.25 2.21.83.22 1.8 1.22 2.18 2.21.41 1.09.02 2.47-1 3.53-.93.96-3.48 2.4-5.68 3.21-2.2.8-6.14 1.48-8.75 1.51-2.61.02-4.97.49-5.25 1.04s-2.3 1-4.5 1-5.58-.68-7.5-1.5-3.84-2-4.25-2.61-.08-1.51.75-1.99 3.19-.88 5.25-.88c2.32-.01 3.75-.5 3.75-1.27.01-.69-1.12-2.94-2.5-5-1.37-2.06-2.5-4.2-2.5-4.75s1.46-1.9 3.25-3c1.79-1.09 4.49-1.99 6-2 1.94 0 2.76.52 2.79 1.75.03.96-.53 2.27-1.25 2.91-.71.65-1.74 1.32-2.29 1.5a1.04 1.04 0 0 0-.64 1.34c.19.55 1.54 2.57 2.99 4.5s3.09 3.84 3.64 4.25c.56.41 2.36.47 4.01.14s3.45-1 4-1.48c.65-.57.24-1.69-1.14-3.15-1.17-1.24-2.41-3.16-2.76-4.26-.34-1.1-.05-2.78.64-3.73s3.06-2.62 5.26-3.71 4.45-1.99 5-2zm-1109.07 1.25c.59.19 1.11 1.22 1.15 2.27.04 1.06.15 2.71.25 3.67.09.96.96 1.98 1.92 2.25.96.28 2.32-.06 3.01-.75.7-.69 1.38-2.37 1.5-3.74.16-1.61.95-2.61 2.24-2.82 1.1-.19 2.33.26 2.73.99.41.72.75 2.56.75 4.07.02 1.94-.94 3.48-3.23 5.22-2.25 1.72-4.55 2.48-7.5 2.5-2.48.02-4.88-.6-5.75-1.47-.82-.82-1.58-3.15-1.68-5.17-.12-2.43.45-4.3 1.68-5.53 1.02-1.01 2.34-1.69 2.93-1.49zm899.07 3.08c.55.15 1.16 1.14 1.37 2.19.2 1.06.66 2.15 1.03 2.42s1.75 1.8 3.07 3.38c1.31 1.59 2.31 3.62 2.21 4.5-.11.89-1.65 3.23-3.43 5.2-2.43 2.67-4.39 3.76-7.75 4.31-3.53.58-5.25.33-8-1.16-1.92-1.05-3.5-2.43-3.5-3.07s.11-2.51.25-4.16c.2-2.37 1.68-4.15 7-8.44 3.71-2.99 7.2-5.32 7.75-5.17zm-10.72 14.11c-.3 1.1-.15 2.79.34 3.75.48.96 1.67 1.75 2.63 1.76.96 0 2.76-.67 4-1.5 1.57-1.05 2.17-2.34 2-4.26-.21-2.26-.78-2.8-3.25-3.01-1.65-.14-3.49.08-4.09.5s-1.33 1.66-1.63 2.76zm240.2-12.27c1.33.8 1.57 2.31 1.28 8.13-.2 3.93-.9 7.74-1.56 8.46-.66.73-2.32 1.18-3.7 1-1.9-.24-2.4-.8-2.1-2.32.22-1.1.31-4.7.21-8-.17-5.29.07-6.13 2.02-7.12 1.48-.76 2.75-.8 3.85-.15zm26.77-1.19c.69-.02 2.15 1.31 3.25 2.96s2.29 5.59 2.64 8.75c.5 4.57.3 6.11-1 7.5-.9.96-2.15 1.64-2.77 1.5-.61-.14-1.87-3.18-2.78-6.75-1.27-4.98-2.12-6.57-3.62-6.81-1.09-.17-2.75.51-3.71 1.5-.96 1-2.38 3.61-3.16 5.81s-2.02 4.41-2.76 4.9c-.74.5-2.01.67-2.84.39-.99-.34-1.75-2.6-2.25-6.65-.41-3.38-.53-6.82-.25-7.64.36-1.09 1.45-1.36 4-1 2.01.29 4.22-.03 5.2-.75.94-.69 3.3-1.79 5.25-2.46 1.95-.66 4.11-1.22 4.8-1.25zm21 2.1c.69-.08 1.47.54 1.75 1.36.29.86 1.67 1.49 3.25 1.47 1.51-.02 3.5.77 4.41 1.75s2.01 4.03 2.44 6.78 1.6 6.57 2.6 8.5 1.79 4.4 1.76 5.5.53 2.51 1.25 3.14c.71.62 1.67 2.65 2.14 4.5s.92 5.03 1 7.08c.11 2.65-.5 4.37-2.09 6-2.13 2.16-2.52 2.21-7.25 1.03-2.76-.69-7.72-3.16-11.04-5.5-4.18-2.95-5.7-4.56-4.96-5.25.6-.55 2.98-.93 5.29-.86 2.31.08 5.89.87 7.95 1.75 2.91 1.25 3.87 1.33 4.27.36.28-.69-.63-4.62-2.03-8.75-1.4-4.12-3.09-8.74-3.77-10.25-.67-1.52-1.78-2.75-2.47-2.75s-1.47.9-1.75 2c-.29 1.17-1.64 2.25-3.25 2.6-1.51.33-3.87.11-5.25-.48-1.37-.6-2.83-2.1-3.24-3.35-.4-1.25-.74-3.84-.74-5.77-.01-1.93.92-4.93 2.05-6.67 1.14-1.75 3.05-3.37 4.25-3.62 1.2-.24 2.74-.5 3.43-.57zm-3.11 13.61c.52 1.39.94 1.04 2.06-1.75.78-1.93 1.39-3.73 1.36-4s-.4-.61-.82-.74c-.41-.14-1.31.88-2 2.25-.68 1.37-.95 3.28-.6 4.24zm-212.82-11.57c2.15.26 2.75.92 3.02 3.32.18 1.65-.13 4.57-.69 6.5-.63 2.13-2.03 3.99-6.15 6l.46-6.25.57-8.07c.09-1.36.79-1.73 2.79-1.5zm108.9-.18c.71 0 1.7.79 2.22 1.75s.69 3.55.36 5.75c-.32 2.2-.97 4.79-1.44 5.75-.51 1.04-1.78 1.65-3.11 1.5-1.99-.22-2.31-.94-2.74-6.22-.42-5.15-.22-6.15 1.47-7.25 1.09-.7 2.54-1.28 3.24-1.28zm-418.47 40.05c.98-.03 2.62 1.48 3.75 3.45 1.1 1.93 1.89 4.06 1.75 4.75s.42 1.1 1.25.92c.88-.19.38.83-1.23 2.5-1.5 1.56-2.74 3.62-2.75 4.58s.37 1.86.85 2 1.15 1.26 1.5 2.5c.44 1.57-.08 3.09-1.72 5-1.59 1.86-3.77 2.98-6.75 3.47-2.42.4-5.98.39-7.9-.03-2.42-.53-3.89-1.61-4.75-3.48-1.02-2.21-.99-3.22.15-5.46.76-1.51 2.34-3.54 3.5-4.5 1.83-1.52 1.95-2.1.93-4.5-.99-2.31-.87-3.19.72-5.54 1.04-1.54 3.48-3.42 5.42-4.2 1.94-.77 4.32-1.43 5.28-1.46zm-4.75 9.45c.3.89 1.72 1.5 3.5 1.5 2.79 0 2.89-.12 1.43-1.75-.87-.96-1.32-2.31-1-3 .31-.69-.05-1.25-.82-1.25-.76 0-1.89.68-2.5 1.5s-.88 2.18-.61 3zm-8.46 12.9c-.04.6.5 1.67 1.19 2.37.7.69 3.07 1.25 5.27 1.23s4.67-.44 5.5-.94c1.33-.81 1.33-1.34-.04-4.73-1.17-2.92-2.17-3.9-4.21-4.15-1.9-.22-3.41.48-5.16 2.4-1.37 1.49-2.51 3.21-2.55 3.82zm76.21-20.38c.41-.01.77.54.8 1.23.02.69-.86 1.93-1.96 2.75s-2.24 2.74-2.54 4.25c-.41 2.02-.15 2.75.95 2.75.83 0 3.25-1.91 5.39-4.25 2.58-2.81 4.1-3.83 4.5-3 .34.69 1.28 1.02 2.11.75 1.11-.37 1.5.28 1.5 2.5 0 2.29-.94 3.77-4.01 6.25-2.72 2.21-3.84 3.81-3.5 5 .28.96 1.41 1.98 2.51 2.25s2.01.84 2.03 1.25-.77 1.54-1.75 2.51c-1.19 1.18-3.93 1.93-8.28 2.26-4.68.35-7.06.09-8.5-.94-1.96-1.41-1.95-1.49 4-7.56l-1.7-3.76c-.93-2.07-1.55-4.88-1.38-6.26.18-1.37.32-2.86.33-3.3 0-.44 1.97-1.67 4.37-2.73 2.41-1.06 4.72-1.94 5.13-1.95zm-7 22.56c.14.32 1.49.32 3 0s2.53-1.03 2.25-1.58-1.38-1-2.45-1-2.2.45-2.5 1-.44 1.26-.3 1.58zM1038.56 328c.79 0 1.46.56 1.47 1.25.02.69-.88 2.49-2 4-1.11 1.51-2.03 3.43-2.03 4.25 0 .89-.61 1.3-1.5 1-.83-.27-1.95-.5-2.5-.5s-.76-1.22-.46-2.75c.29-1.51 1.67-3.76 3.06-5s3.17-2.25 3.96-2.25zm20.69.1c.41-.05 1.76.85 2.99 2.02 1.94 1.83 2.14 2.71 1.5 6.5-.45 2.65-2.08 6.06-4.12 8.63-2.09 2.62-4.58 4.54-6.5 5-2.1.5-4.1.26-6.12-.75-1.89-.94-3.36-2.7-3.98-4.75-.83-2.73-.59-3.97 1.48-7.75 1.36-2.48 3.49-5.09 4.73-5.81 1.25-.72 3.85-1.68 5.77-2.14 1.92-.47 3.84-.89 4.25-.95zm-8.59 8.9c-.95 1.38-1.6 3.85-1.44 5.5.2 2.11.87 3.09 2.28 3.31 1.1.17 2.75-.51 3.66-1.5.91-1 1.75-3.16 1.86-4.81.1-1.65.14-4.01.09-5.25-.06-1.24-.67-2.23-1.36-2.21s-1.73.58-2.31 1.25c-.58.66-1.84 2.34-2.78 3.71zm249.81-8.54c1.67.35 3.25.86 3.53 1.14.28.27 0 1.27-.6 2.2-.61.94-1.96 1.85-3 2.03-1.05.19-2.69-.37-3.65-1.25-1.42-1.28-1.52-1.88-.53-3.17.87-1.12 2.09-1.4 4.25-.95zm-28.72 2.07c.69.26 1.7.47 2.25.47s2.01 2.03 3.25 4.52c2.17 4.36 2.41 4.51 6.75 4.49 3.16-.01 5.61.72 8.25 2.49 2.06 1.37 3.77 2.84 3.79 3.25.03.41-.53 1.34-1.25 2.06-.81.82-2.51 1.1-4.54.75-1.79-.31-4.49-.83-6-1.16-1.71-.37-3.22-.09-4.01.75-.69.74-1.54 3.37-1.88 5.85-.35 2.48-1.02 5.29-1.5 6.25-.51 1.04-1.78 1.65-3.11 1.5-2.06-.23-2.25-.76-2.25-12.46l-3.93-.89c-2.16-.5-4.08-1.46-4.25-2.15-.18-.69 1.48-2.15 3.68-3.25s4-2.56 4-3.25c-.01-.69-.91-2.71-2-4.5-1.89-3.06-1.9-3.31-.25-4.22.96-.54 2.31-.76 3-.5zm131.25 5.75c1.63.14 2.61.92 2.82 2.22.23 1.5-.64 2.4-3.5 3.61-2.53 1.07-3.31 1.79-2.32 2.14l6.25 2.14c4.46 1.51 4.75 1.83 4.75 5.11 0 2.51-.79 4.28-2.8 6.25-1.54 1.51-4.24 3.09-6 3.5s-5.34.27-7.95-.32-5.32-1.6-6.01-2.25c-1.02-.95-1.02-1.43 0-2.47.78-.8 3.66-1.28 7.51-1.25 4.15.03 6.39-.38 6.66-1.21.24-.73-1.88-2.28-5.12-3.75-3.34-1.51-5.87-3.39-6.4-4.75-.49-1.24-.96-2.89-1.05-3.68-.1-.88 1.93-2.22 5.25-3.47 2.97-1.12 6.54-1.94 7.91-1.82zm-56.25.8c.69-.04 2.17 1.16 3.28 2.67 1.12 1.51 2.02 3.88 2 5.25-.02 1.38-.49 4.19-1.04 6.25-.72 2.72-1.75 4.03-3.74 4.76-1.85.67-3.16.67-4 0-.93-.75-1-1.98-.27-4.76.53-2.06.98-4.31 1-5 .01-.7-1.19-1.25-2.73-1.26-1.51 0-3.65.64-4.75 1.42-1.24.88-1.88 2.31-1.69 3.76.17 1.28-.29 3.06-1.03 3.95-.73.9-1.99 1.74-2.81 1.87-.81.14-2.26.19-3.22.13-1.33-.09-1.81-1.14-2-4.37-.2-3.45-.61-4.25-2.18-4.25-1.43 0-2.4 1.32-3.67 5-.95 2.75-2.4 5.45-3.23 6-1.03.69-1.99.61-3.08-.25-1.2-.94-1.35-1.74-.59-3.25.55-1.1 1-2.9 1-4s.83-3.24 1.85-4.75c1.01-1.51 3.71-3.54 6-4.5 2.28-.96 5.05-1.75 6.15-1.75s2.88.56 3.95 1.25c1.62 1.04 2.66.9 6.25-.89 2.36-1.17 4.97-2.37 5.8-2.67.83-.29 2.06-.57 2.75-.61zm29-.04c.69-.02 2.38 1.09 3.75 2.46 1.38 1.38 2.49 3.29 2.47 4.25-.01.96-1.14 3.21-2.5 5s-3.82 3.93-5.47 4.75-2.78 1.95-2.5 2.5 1.29 1 2.25 1 3.1-1.14 4.75-2.53 3.34-2.52 3.75-2.5.97.48 1.25 1.03-1.41 3.04-3.75 5.54c-3.39 3.63-4.91 4.54-7.5 4.5-2.43-.03-4.26-1.05-7.25-4.04-2.2-2.2-4-4.68-4-5.5s-.56-2.43-1.25-3.57c-1.09-1.79-.93-2.32 1.25-4.07l5-4.11c1.38-1.16 3.85-2.68 5.5-3.39 1.65-.7 3.56-1.3 4.25-1.32zm-73.39 2.93c.63-.02 1.98 1.44 3 3.25 1.58 2.79 1.73 4.25 1 9.78-.84 6.36-.92 6.5-6.86 6.5l-.26-8.5c-.15-5.21.18-8.98.87-9.75.61-.69 1.63-1.26 2.25-1.28zm-263.35 4.8c.96.25 1.8.86 1.87 1.35.06.48-1.23 1.56-2.88 2.38s-3.45 1.5-4 1.5-1.11-.62-1.25-1.38.83-2.04 2.14-2.85 3.17-1.26 4.12-1zm-1.76 55.27c.41-.02 1.42.19 2.25.46s1.5 1.4 1.5 2.5c0 1.11.67 2 1.5 2s2.4 1.57 3.5 3.5 1.78 4.4 1.5 5.5-1.96 2.7-3.75 3.55-3.81 2.42-4.5 3.5c-.97 1.51-.99 2.57-.08 4.7.93 2.2.85 3.55-.38 6.75-.88 2.27-2.79 4.74-4.42 5.72-1.58.94-4.9 2.02-7.37 2.38-2.47.37-5.74.39-7.25.04-1.7-.4-2.98-1.5-3.35-2.89-.33-1.24-.01-4.27.71-6.75.73-2.48 2.13-5.29 3.11-6.25 1.71-1.68 1.7-1.88-2.2-8.25l3.24-5.22c1.78-2.87 4.37-6.01 5.74-6.97 1.38-.96 4.08-2.3 6-2.98s3.84-1.26 4.25-1.29zm-5.23 7.96c-1.29 0-2.86 1.5-4.45 4.25-2.28 3.94-2.33 4.34-.76 5.52.93.69 2.59 1.27 3.69 1.27s3.24-1.24 4.76-2.77c1.52-1.52 3.14-4.34 3.6-6.27.75-3.2.62-3.52-1.49-3.73-1.27-.13-2.54.2-2.84.75-.29.54-1.42.98-2.51.98zm-10.1 23.97a8.33 8.33 0 0 0 .85 2.88c.58 1.07 1.5 1.13 4.48.25 2.14-.63 4.4-2.18 5.25-3.6 1.21-2.02 1.26-2.8.25-4.04-.69-.85-2.69-1.53-4.45-1.5-2.11.02-3.76.8-4.85 2.26-.9 1.22-1.59 2.91-1.53 3.75zM1126.04 407c1.08 0 3.14.56 4.57 1.25 2.5 1.19 2.6 1.55 2.2 7.75-.22 3.6-1.27 8.29-2.35 10.5-1.07 2.2-3.75 5.87-5.95 8.15-2.21 2.28-5.59 4.6-7.51 5.16s-4.53.71-5.78.35c-1.26-.36-2.13-1.11-1.93-1.66s2.71-2.57 5.58-4.5c2.88-1.93 6.11-4.96 9.13-10l-2.25-1.16c-1.24-.63-3.71-2.21-5.5-3.5-2.88-2.08-3.11-2.57-2.01-4.39.68-1.13 2.37-2.57 3.75-3.2 1.38-.64 3.31-1.97 4.3-2.95.98-.99 2.67-1.8 3.75-1.8zm-42.29 5.03c1.24-.02 4.39 1.68 7 3.77s5.72 5.12 6.9 6.75c1.18 1.62 2.46 4.52 2.84 6.45.59 2.99.21 4.14-2.65 7.93-1.93 2.56-4.6 4.8-6.34 5.32-1.65.49-4.58 1.27-6.5 1.73-2.14.52-4.47.44-6-.19-1.37-.57-3.55-1.55-4.83-2.16-1.28-.62-3.21-3.15-4.28-5.63s-1.94-5.18-1.94-6 .88-3.52 1.96-6 3.23-5.68 4.78-7.12c1.54-1.44 3.71-3.11 4.81-3.72 1.1-.6 3.01-1.11 4.25-1.13zm-7.59 13c-.65 2.23-.83 5.15-.41 6.67.41 1.48 2.1 3.5 3.75 4.49s3.9 1.81 5 1.82 3.58-1.3 5.5-2.91l3.5-2.92c-3.1-5.84-5.35-8.81-7-10.36-1.65-1.54-3.67-2.8-4.5-2.78-.83.01-2.21.47-3.09 1.02-.87.56-2.11 2.79-2.75 4.97zM1058.15 413c1.02 0 2.07.9 2.35 2s.05 2.9-.5 4c-.69 1.39-1.84 1.92-3.74 1.75-1.86-.17-2.84-.89-3.05-2.25-.17-1.1.45-2.79 1.39-3.75.93-.96 2.53-1.75 3.55-1.75zm-1.19 18.48c1.2 1.19 1.32 2.12.52 4.27-.72 1.96-1.8 2.82-3.75 3-2.17.2-2.77-.2-2.92-1.94-.11-1.2.89-3.23 2.21-4.52 2.16-2.09 2.57-2.17 3.94-.81zm-746.21 9.55c.69-.02 1.93.65 2.75 1.47s1.27 1.95 1 2.5-2.07 1-4 1c-2.22 0-3.68-.55-4-1.5-.27-.82.29-1.94 1.25-2.47s2.31-.98 3-1zM298 442.12c2.48-.09 5.3.42 6.28 1.11 1.5 1.07 1.58 1.55.5 3.04-.81 1.12-3.65 2.15-7.78 2.82-3.57.57-6.81 1.58-7.18 2.23-.38.65-.76 4.33-.84 8.18l-.09 9.5c.04 1.38-.71 3.3-1.66 4.28s-2.52 1.77-3.48 1.75c-1.6-.03-1.69-.92-1-10.58.63-8.85.51-10.69-.75-11.48-.82-.52-3.41-.95-5.75-.95-2.75-.01-4.82-.64-5.86-1.77-1.49-1.61-1.47-1.85.25-3.04 1.02-.71 2.76-1.47 3.86-1.68s5.82-1.03 10.5-1.82 10.52-1.51 13-1.59zm124.75-.09c.69-.02 1.52.76 1.85 1.72s-.19 3.32-1.16 5.25-4.05 6.16-6.85 9.41c-2.8 3.24-6.51 7.29-8.24 9-1.73 1.7-4.35 3.77-5.83 4.59-2.53 1.42-2.79 1.36-4.54-1-1.03-1.37-2.45-4.38-3.17-6.68-1.12-3.59-1.1-4.42.19-5.8.82-.88 2.06-1.59 2.75-1.56.69.02 1.93 1.61 2.75 3.54s1.84 3.49 2.25 3.49c.41-.01 2.71-2.15 5.1-4.75 2.39-2.61 5.72-6.62 7.38-8.92 1.67-2.3 2.9-4.64 2.73-5.2-.16-.56.56-1.48 1.62-2.04s2.48-1.03 3.17-1.05zm-92.5 9.96c.41.01 2.32 1.36 4.25 3.01 3.09 2.64 3.65 2.82 4.75 1.46.74-.92 2.78-1.53 5-1.5 2.58.03 4.38.74 5.77 2.29s2.02 3.66 2.03 6.75c.01 3.19-.57 5.08-2 6.5-1.65 1.64-2.29 1.77-3.53.75-1.16-.95-1.34-2.2-.77-5.21.65-3.43.48-4.05-1.25-4.67-1.54-.54-2.69.13-5 2.95-2.04 2.48-3.96 3.73-6 3.91-2.87.26-3.01.09-3.25-3.98-.14-2.34-.59-4.25-1-4.25s-1.87 2.14-3.25 4.74c-1.56 2.96-3.52 5.12-5.21 5.75-1.49.55-3.07.65-3.5.21s-.23-1.57.45-2.5c.69-.94 2.6-4.29 4.25-7.45 1.66-3.16 4.02-6.43 5.26-7.26s2.59-1.5 3-1.5zm47 .05c.41-.02 1.03.75 1.37 1.71s.34 2.76 0 4-1.98 3.71-3.65 5.5c-1.66 1.79-2.67 3.63-2.25 4.1.43.47 2.35.32 4.28-.32s4.85-2.28 6.5-3.64 3.11-2.23 3.25-1.93-.66 2.23-1.77 4.29-3.36 4.54-5 5.5-4.89 1.77-7.23 1.79c-3.22.03-5.47-.78-9.25-3.34-3.65-2.46-5.07-4.1-5.25-6.04-.15-1.55.27-2.71 1-2.78.69-.06 1.81-.06 2.5 0 .69.07 2.91-1.12 4.93-2.63 2.03-1.51 5.07-3.52 6.75-4.46 1.69-.94 3.41-1.73 3.82-1.75zm-68.5 7.04c.69-.04 1.7.82 2.25 1.92s.89 3.91.75 6.25c-.22 3.7-.57 4.29-2.75 4.56-1.37.17-2.83-.28-3.23-1-.41-.72-.84-3.41-.95-5.98-.16-3.32.2-4.81 1.23-5.17.8-.28 2.01-.54 2.7-.58zm-271.28 7.24c.57.19 1.14 1.31 1.28 2.51.19 1.62-.57 2.5-3 3.49-1.79.73-4.5 2.42-6.02 3.75-1.8 1.57-2.77 3.4-2.75 5.18.01 1.93 1.29 3.93 4.27 6.71l8.46 7.75c3.79 3.42 4.21 4.25 4.29 13.29l-5.5 2.5c-3.02 1.38-6.17 2.5-7 2.5-.82 0-2.4.45-3.5 1-1.41.7-2.59.63-4-.25-1.43-.89-2.01-2.33-2-5 0-2.44.52-3.92 1.5-4.25.82-.27 2.29.45 3.25 1.61 1.44 1.73 2.46 2 5.75 1.51 2.2-.33 4.56-1.27 5.25-2.11.78-.94.97-2.41.5-3.9-.41-1.31-2.77-4.01-5.25-6s-5.72-4.85-7.21-6.36-3.25-4.77-3.9-7.25c-1.05-3.96-.96-4.9.71-7.79 1.25-2.16 3.94-4.29 7.87-6.25 3.29-1.64 6.44-2.82 7-2.64zM138 469c1.38-.01 3.58.78 4.9 1.74 2.27 1.66 2.36 2.14 1.68 8.26-.61 5.47-1.27 7.09-4.15 10.25-1.89 2.06-4.11 5.1-6.43 9.75h5.5c3.03 0 6.18.23 7 .5s1.51 1.29 1.53 2.25c.01.96-1 2.29-2.25 2.96-1.26.66-5.21 1.41-8.78 1.67s-7.74.73-9.25 1.05c-1.51.31-3.42.12-4.25-.43-1.2-.8-1.28-1.55-.41-3.75.59-1.51 2.51-4.08 4.25-5.71s4.86-5.23 6.93-8c2.58-3.45 3.76-6.07 3.75-8.29-.01-2.24-.64-3.56-2.02-4.25-1.1-.55-3.35-.77-5-.5s-3.19.16-3.41-.25c-.23-.41.12-1.53.78-2.48.65-.95 2.52-2.41 4.16-3.24 1.63-.84 4.1-1.52 5.47-1.53zm1048.9 2.97c.33-.02 1.73.81 3.1 1.85 1.38 1.04 4.93 5.67 7.9 10.28l7.25 11.15c1.02 1.51 1.85 3.09 1.85 3.5s1.79 3.23 3.98 6.25l8.89 12.5c2.69 3.85 5.74 7.98 6.77 9.17 1.02 1.2 2.88 3.45 4.12 5 1.25 1.56 5.3 7.06 9 12.23l9.49 13.25c1.51 2.12 2.8 4.21 2.86 4.65s2.09 3.59 4.5 7 4.84 6.43 5.39 6.7 2.2 2.41 3.66 4.75c1.47 2.34 6.08 8.49 10.25 13.66l12.59 16.07 7.81 10.08 10.83 13.44c4.41 5.5 9.92 12.02 12.24 14.5s5.3 6.08 6.61 8c1.32 1.92 5.21 6.42 8.64 10 3.44 3.58 6.62 6.12 7.06 5.66.45-.45.7-5.74.56-11.75-.2-8.86.04-11.14 1.3-12.16 1.24-1 2.04-1 4 0 2.44 1.24 2.45 1.31 2 13.5-.36 9.75-.77 12.4-2 13-.89.43-1.55 2.03-1.55 3.75 0 2.16-.77 3.52-2.75 4.85-1.51 1.02-5.45 2.33-8.75 2.92-3.3.58-8.7.95-12 .81s-7.46-1-9.25-1.92c-1.79-.91-3.47-2.11-3.75-2.66s-.28-1.9 0-3c.46-1.85 1.14-1.97 9.25-1.56l12.22.75c2.46.22 3.58-.13 3.81-1.19.19-.83-1.6-3.64-3.97-6.26s-5.52-5.55-6.99-6.5c-1.48-.96-4.55-4.22-6.83-7.24s-5.01-6.06-6.07-6.75-1.93-1.81-1.95-2.5c-.01-.69-2.82-4.24-6.25-7.9-3.42-3.66-8.69-9.93-11.72-13.95l-27.5-35.49-8.28-10.78c-1.8-2.27-5.51-7.17-8.25-10.88-2.73-3.71-4.97-6.98-4.97-7.25s-1.37-2.41-3.05-4.75l-9.47-13.25-12.2-17.38c-3.18-4.61-6.23-8.66-6.79-9-.55-.34-2.17-2.2-3.6-4.12-1.43-1.93-3.57-5.41-4.75-7.75s-3.6-6.24-5.39-8.68a361.44 361.44 0 0 1-5.75-8.08c-1.37-2.02-3.72-5.09-5.21-6.83s-2.81-3.8-2.93-4.58.6-2.25 1.61-3.25c1-1.01 2.1-1.85 2.43-1.86zM54.3 475.03c.66.02 1.93.58 2.83 1.25.89.67 2.12 3.02 2.74 5.22.61 2.2 1.23 5.32 1.37 6.94.21 2.4.86 3.09 3.51 3.75 1.86.47 3.25 1.45 3.25 2.31 0 .82-1.58 2.4-3.5 3.5s-4.14 3.46-4.93 5.25c-.78 1.79-1.68 4.04-2 5-.31.96-1.02 1.75-1.57 1.75s-.99-2.36-.98-5.25c.02-5.02-.13-5.33-3.5-7-2.98-1.48-3.33-1.99-2.27-3.29.69-.85 1.81-1.53 2.5-1.5.69.02 1.7-1.08 2.25-2.46.55-1.37.78-3.51.5-4.75-.27-1.24-.95-3.71-1.5-5.5s-.75-3.7-.45-4.25 1.09-.99 1.75-.97zM412.72 484c.71 0 1.57.79 1.93 1.75s.25 2.27-.25 2.9c-.49.64-3.71 4.58-7.15 8.75-3.44 4.18-7.55 9.74-9.14 12.35s-4.07 5.54-5.5 6.5c-1.44.96-3.29 1.75-4.11 1.75-.92 0-2.3-2.23-3.57-5.75-1.15-3.16-2.91-7.55-3.93-9.75-1.13-2.45-1.58-4.88-1.17-6.27.37-1.26 1.23-2.49 1.92-2.75.69-.27 2.15.42 3.25 1.52s2.79 4.25 3.75 7c.96 2.76 2.31 5.01 3 5 .69 0 2.01-1.24 2.94-2.75s4.38-6.12 7.67-10.25c3.29-4.12 6.68-8.06 7.53-8.75.86-.69 2.13-1.25 2.83-1.25zM79 491.01c.28-.02.95.34 1.5.8s2.8 1.44 5 2.17c3.63 1.2 4.39 1.12 8.28-.84 4.15-2.08 4.39-2.09 7.38-.39l5.47 3c1.69.89 2.37 2.11 2.37 4.25 0 1.65-.6 4.24-1.33 5.75l-3 6c-.92 1.79-1.66 3.81-1.64 4.5s-1.56 2.15-3.52 3.25c-1.95 1.1-3.76 2.79-4.03 3.75-.26.96-.93 1.75-1.48 1.75s-.98.79-.96 1.75c.03.96-.71 2.42-1.64 3.25-1.56 1.38-1.63 1.29-.87-1 .45-1.37.94-4.08 1.07-6a89.67 89.67 0 0 1 .96-7.5c.39-2.28.21-5.61-.43-7.75-.83-2.74-1.68-3.75-3.18-3.75-1.12 0-3.03 1.03-4.25 2.29-1.24 1.3-4.59 2.85-7.7 3.58-3.03.7-5.72.99-6 .63s-.35-2.76-.17-5.33 1.26-6.33 2.39-8.37c1.14-2.03 2.79-4.15 3.67-4.72.89-.56 1.83-1.04 2.11-1.07zm-5.17 12.03c.09 1.63.73 3.22 1.42 3.55.69.32 2.26.09 3.5-.5 1.24-.6 2.7-1.99 3.25-3.09.73-1.45.59-2.68-.5-4.5-.83-1.37-1.86-2.5-2.3-2.5-.45 0-1.87.92-3.17 2.04-1.61 1.39-2.32 2.98-2.2 5zm22.97 2.17c.16 2.36.84 4.9 1.5 5.65s1.76 1.09 2.45.75c.69-.33 1.03-1.06.75-1.61s-.05-1.23.5-1.5 1-1.62 1-3c0-1.37-.45-3.4-1-4.5s-1.34-1.99-1.75-1.98c-.41 0-1.42.44-2.25.95-1.04.66-1.41 2.26-1.2 5.24zM287.61 491c.77 0 1.84.9 2.39 2 .56 1.11.78 5.56 0 18l4.75-.63c2.61-.35 6.44-.35 8.5 0 2.06.34 3.98 1.31 4.25 2.13.27.83-.06 2.08-.75 2.79-.69.72-3.73 1.63-6.75 2.04-3.02.4-7.75 1.39-10.5 2.2-3.96 1.16-5.17 1.21-5.81.22-.45-.69-.55-6.86-.23-13.72.33-6.86 1.08-13.05 1.68-13.75s1.71-1.28 2.47-1.28zm32.39 9.03c.27.02 2.3 1.28 4.5 2.79 2.92 2.02 4.08 3.56 4.28 5.72.17 1.8-.41 3.68-1.5 4.81-.98 1.01-3.24 2.47-5.03 3.25-1.79.77-4.26 1.16-5.5.87s-2.83-1.07-3.54-1.75c-.72-.67-1.28-2.23-1.25-3.47.02-1.24.83-3.89 1.79-5.9s2.65-4.27 3.75-5.01c1.1-.75 2.23-1.34 2.5-1.31zm23.54.97c.8 0 1.69.45 1.96 1s-.02 2.01-.65 3.25c-.64 1.24-2.21 3.26-3.5 4.5s-2.35 2.92-2.35 3.75c0 .97.97 1.5 2.75 1.5 1.51.01 4.44-.89 6.5-2 3.06-1.63 4.04-1.77 5.29-.75.85.69 1.53 1.81 1.5 2.5-.02.69-1.28 2.04-2.79 3s-4.1 2.32-5.75 3.02c-1.65.71-4.35 1.27-6 1.26s-3.9-.62-5-1.37c-1.1-.74-2.34-2.55-2.75-4.01-.51-1.78-.18-3.84 1-6.31.96-2.01 3.23-4.93 5.04-6.5 1.81-1.56 3.94-2.84 4.75-2.84zm21.66 9.57c.55.3.97 1.53.93 2.74-.03 1.2-.98 3.09-2.1 4.19-1.27 1.26-2.59 1.72-3.53 1.25-.82-.41-1.54-1.62-1.6-2.68-.05-1.06 1.12-2.85 2.61-3.98 1.48-1.14 3.14-1.82 3.69-1.52zm686.55 79.44c.69-.01 1.47.44 1.75.99s-.62 2.24-1.98 3.75c-1.37 1.51-2.48 3.2-2.48 3.75s-1.5 2.35-3.34 4-3.61 4.35-3.94 6c-.34 1.7-.1 3.68.57 4.56.64.86 1.96 1.87 2.92 2.25s1.75 1.25 1.74 1.94c0 .69-1.91 2.38-4.25 3.75-2.33 1.38-5.36 2.88-6.74 3.34-1.52.52-3.58.42-5.25-.25-2.34-.93-2.66-1.5-2.12-3.84.35-1.51 1.21-3.42 1.91-4.25.71-.83 1.4-2.17 1.54-3s-.1-3.3-.52-5.5c-.43-2.2-.51-5.46-.17-7.25.43-2.3 1.61-3.84 4.02-5.25 1.87-1.1 4.69-1.99 6.25-1.97s4.19-.65 5.84-1.49 3.56-1.53 4.25-1.53zm-13.42 12.73c.46.42 1.48-.14 2.27-1.24s1.43-2.56 1.42-3.25-.48-1.25-1.04-1.25-1.57 1.12-2.25 2.49-.86 2.83-.4 3.25zm61.92-10.68c.41-.03.97.61 1.25 1.44s-.85 3.52-2.5 6-3.28 6.41-3.63 8.75c-.37 2.48-.16 5.19.5 6.5.72 1.43 2.04 2.25 3.63 2.25 1.67 0 3.17-1 4.5-3 1.1-1.65 1.99-3.56 1.98-4.25s.56-1.81 1.25-2.49c1.02-.99 1.02-1.73.02-3.75-.69-1.38-1.25-3.18-1.25-4.01 0-.88.93-1.51 2.25-1.53 1.24-.02 3.49.88 5 2 1.51 1.11 2.76 2.59 2.77 3.28.02.69-.88 3.39-2 6-1.11 2.61-3.71 6.33-5.77 8.25-3.53 3.3-4.07 3.48-9.25 3.06-4.25-.34-6.07-1.03-8-3.03-1.43-1.48-2.6-3.97-2.73-5.81-.12-1.77.24-5.24.81-7.72s2.03-5.75 3.24-7.27c1.22-1.53 3.33-3.18 4.7-3.69 1.36-.5 2.82-.94 3.23-.98zm-20.45.9c.93-.03 2.37.72 3.2 1.65.83.94 1.47 3.32 1.44 5.3-.03 1.97-.37 5.61-.75 8.09-.39 2.48-1.26 5.76-1.94 7.29-.69 1.53-1.47 2.76-1.75 2.72s-1.17-.62-2-1.29c-1.15-.94-1.5-3.54-1.5-11.22 0-5.5.36-10.56.8-11.25s1.56-1.27 2.5-1.29zm-18.8 1.09c.28.01 1.27.56 2.21 1.23s1.73 2.01 1.75 2.97.49 1.75 1.04 1.75.89.96.75 2.14c-.14 1.17-1.15 2.75-2.25 3.51-1.76 1.21-2.34 1.11-4.83-.89-2.48-1.98-2.75-2.69-2.13-5.76.39-1.92 1.22-3.83 1.84-4.23.61-.41 1.34-.73 1.62-.72zm3.75 17.99c.69-.02 1.5.52 1.82 1.21.31.69-.82 3.39-2.5 6-1.69 2.61-3.74 4.75-4.57 4.75-1.16 0-1.44-1.06-1.23-4.62.22-3.73.74-4.87 2.75-5.96 1.36-.74 3.04-1.37 3.73-1.38zm44.06 74.16c2.32.21 3.84 1.1 5.01 2.94 1.67 2.64 1.66 2.67-4.02 9-4.52 5.05-5.45 6.63-4.5 7.65.66.72 1.54 1.28 1.95 1.25.41-.02 2.55 1.09 4.75 2.46 2.2 1.38 4.02 3.29 4.03 4.25.02.96-.88 2.99-2 4.5-1.83 2.48-2.64 2.75-8.28 2.78-4.76.03-6.91-.45-9-2-1.51-1.11-2.75-2.59-2.75-3.28-.01-.69.84-2.83 1.87-4.75 1.52-2.82 1.78-4.86.85-17.5l4.37-3.8c3.5-3.03 5.05-3.73 7.72-3.5zm-6.19 9.03c-.4.7-.6 2.38-.43 3.74.3 2.35.46 2.27 3.56-1.75 1.79-2.32 2.87-4.39 2.41-4.6s-1.73.01-2.82.48c-1.08.47-2.31 1.43-2.72 2.13zM1101.5 714c.28.55 2.08 1 4 1s3.5-.45 3.5-1-1.12-1.67-2.5-2.5c-1.37-.83-2.96-1.5-3.52-1.5-.57 0-1.24.67-1.5 1.5-.27.83-.26 1.95.02 2.5zm69.75-27.03c.69-.02 2.15.93 3.25 2.1 1.75 1.87 2 3.52 2 12.96s-.27 11.18-2.11 13.65c-1.15 1.55-2.73 2.94-3.5 3.09-1.15.23-1.35-2.39-1.19-15l.25-16.02c.03-.41.61-.76 1.3-.78zm-18.64 3.03c.22 0 1.29.79 2.4 1.75 1.17 1.03 2.09 3.2 2.21 5.25.11 1.92-.23 7.93-.76 13.35-.55 5.7-1.49 10.23-2.21 10.75-.75.54-2.05.5-3.25-.1-1.45-.73-1.86-1.68-1.5-3.5.28-1.37.54-7.56.59-13.75s.55-11.81 1.11-12.5 1.2-1.25 1.41-1.25zm-18.47 6.28c1.3-.09 2.94.37 3.65 1.03.72.65 1.28 1.53 1.25 1.94-.02.41-1.62 1.65-3.54 2.75s-4.17 1.77-5 1.5-1.53-1.37-1.57-2.43.58-2.53 1.39-3.27c.8-.75 2.52-1.43 3.82-1.52zm-2.09 14.72c1.41 0 1.95.69 1.95 2.5 0 1.38-.56 2.69-1.25 2.91-.69.23-1.85.12-2.59-.25-.85-.42-1.1-1.48-.7-2.91.39-1.34 1.43-2.25 2.59-2.25zm96.88 94.98c.86-.01 2.14.56 2.84 1.25.69.7 1.26 2.06 1.25 3.02s.34 1.75.78 1.75 1.23-.48 1.75-1.08c.52-.59 1.96-.81 3.2-.5 1.24.32 2.47 1.48 2.75 2.58s-.17 3.13-1 4.5c-.83 1.38-3.53 3.51-6.01 4.75s-4.73 2.81-5 3.5 1.3 2.71 3.49 4.5c2.8 2.28 4.16 4.29 4.59 6.75.49 2.85.17 3.91-1.73 5.68-1.29 1.19-4.37 2.87-6.84 3.73s-5.85 1.58-7.5 1.59c-1.65.02-3.85-.54-4.89-1.23-1.65-1.11-1.76-1.77-.85-5.27.57-2.2 2.05-6.25 5.52-14l-2.25-4.5c-2.16-4.31-2.18-4.65-.6-8 .91-1.92 3.29-4.74 5.29-6.25 2.01-1.51 4.35-2.76 5.21-2.77zM1227 816.4c.28.31 1.73.01 3.24-.67s2.75-1.57 2.75-1.98c.01-.41-.56-.75-1.27-.75-.7 0-2.16.64-3.25 1.42-1.08.78-1.75 1.67-1.47 1.98zm-4.1 21.82c.07 1.21.91 1.78 2.6 1.78 1.38 0 3.4-.45 4.5-1s2-1.67 2-2.5-1.01-2.18-2.25-3.01-2.57-1.5-2.95-1.5c-.39.01-1.44 1.01-2.35 2.23-.9 1.22-1.6 3.02-1.55 4zm55-24.98c.88.69 2.15 1.93 2.82 2.76.68.84 1.24 4.56 1.27 8.5.03 3.85-.67 9.48-1.54 12.5-.88 3.02-2.14 6.63-2.81 8-.66 1.38-2.09 2.62-3.17 2.76-1.09.14-2.64-.18-3.47-.7-1.32-.83-1.26-1.66.48-6.75 1.43-4.19 1.99-8.49 2-15.41.01-6.72.44-10.09 1.42-11.26 1.14-1.37 1.68-1.44 3-.4zm25.6-.14c.55-.06 2.01.56 3.25 1.39 1.88 1.26 2.25 2.42 2.25 7.01 0 4-.75 7.01-2.75 11.01-1.84 3.69-2.42 5.85-1.75 6.53.55.55 2.5 1.11 4.34 1.23 1.83.13 4.19 1.02 5.25 1.98 1.05.96 1.79 2.54 1.64 3.5-.14.96-1.38 2.28-2.75 2.93-1.76.83-3.92.89-7.48.21-2.75-.52-6.58-.67-8.5-.32s-4.51.14-5.75-.47c-1.24-.6-2.25-1.55-2.25-2.1s2.17-3.14 4.83-5.75c2.65-2.61 5.62-6.77 6.6-9.25 1.07-2.69 1.54-5.61 1.18-7.25-.54-2.43-1.05-2.74-4.36-2.65-2.06.05-4.54.05-5.5 0-.96-.06-1.76-.66-1.78-1.35s.77-2.03 1.75-2.98 3.81-2.14 6.28-2.64 4.95-.96 5.5-1.03zm-50.72 4.93c.95.01 2.52.8 3.5 1.75.98.94 1.79 2.39 1.79 3.22s-.81 2.26-1.79 3.2c-.98.93-2.26 1.38-2.84 1-.58-.39-1.8-1.82-2.7-3.2-1.19-1.8-1.38-2.99-.67-4.25.54-.96 1.76-1.74 2.71-1.72zm-585.29 4.18c1.49.22 2.1 1.19 2.35 3.79.2 2.08-.24 4.11-1.09 5-.78.83-3.7 6.23-6.49 12s-5.4 11.63-5.81 13c-.41 1.38-1.46 3.5-2.34 4.72-.89 1.22-2.4 2.23-3.36 2.25s-2.7-.98-3.87-2.22c-1.16-1.24-2.71-3.6-3.44-5.25-.74-1.65-2.5-4.35-3.92-6s-2.57-3.23-2.57-3.5c.01-.27.56-1.06 1.23-1.75s1.81-1.25 2.52-1.25 2.82 1.46 4.69 3.25c1.86 1.79 3.6 3.92 3.85 4.75.27.84 3.35-4.26 6.95-11.5l7.88-15.29c.86-1.39 2.2-2.17 3.42-2zm-154.02 5.22c1.67.33 8.99.59 16.28.58 11.93-.01 13.45.19 15.25 1.99 1.1 1.1 2 2.45 2 3 0 .56-2.72.98-6.25.96-4.67-.04-6.63.38-7.75 1.65-.99 1.13-1.62 4.46-1.85 9.8-.2 4.45-.99 9.33-1.75 10.84-.77 1.51-2.41 3.24-3.65 3.83-1.24.6-2.62.71-3.07.25s-.28-3.31.38-6.33c.68-3.13.92-8.01.56-11.34-.34-3.22-1.18-6.25-1.87-6.74s-2.15-.9-3.25-.91-3.69-.47-5.75-1.02c-2.06-.54-3.98-1.66-4.25-2.49s.05-2.21.72-3.09c.86-1.11 2.12-1.4 4.25-.98zm38.14 1.57c.22 0 1.17.27 2.12.61.97.33 1.64 1.45 1.5 2.5-.14 1.19-.79 1.7-1.73 1.39l-3-1c-1.15-.38-1.24-.85-.39-2 .61-.83 1.29-1.5 1.5-1.5zm67.33 7c.58 0 1.56 1.01 2.18 2.25.92 1.86.71 2.89-1.25 5.94-1.3 2.03-3.38 4.4-4.62 5.25-1.24.86-2.72 2.8-3.31 4.31-.87 2.28-.74 2.97.75 4.02 1 .69 4.06 1.24 6.81 1.22 2.78-.03 5.89-.71 7-1.54 1.1-.82 2.34-1.48 2.75-1.47s.76.81.78 1.77c.01.96-1 2.71-2.25 3.88-1.37 1.27-4.29 2.4-7.28 2.8-3.01.4-6.4.2-8.5-.5-1.92-.65-4.52-2.13-5.78-3.3-1.25-1.17-2.27-2.8-2.26-3.63s.68-3.52 1.5-6c.99-3.03 3.27-6.22 6.95-9.75 3-2.89 5.94-5.25 6.53-5.25zm-28.19 1.03c.14-.02 1.49.59 3 1.35 1.86.93 3.21 2.79 4.18 5.75.78 2.4 1.31 5.27 1.16 6.37-.14 1.1-.78 2.6-1.42 3.33-.68.77-2.12 1.09-3.42.75-1.83-.47-2.25-1.29-2.27-4.33 0-2.06-.43-4.42-.93-5.25-.8-1.29-1.21-1.23-3.05.5-1.16 1.1-3.1 3.98-4.31 6.39-1.2 2.42-2.53 4.56-2.94 4.75-.41.2-1.65.13-2.75-.14-1.17-.29-2-1.33-2-2.5 0-1.1-.45-2.9-1-4s-1.45-2-2-2-1.5 1.69-2.11 3.75-1.74 4.76-2.5 6c-.77 1.24-2.29 2.25-3.39 2.25s-2.23-.67-2.5-1.5.43-3.86 1.57-6.75c1.13-2.89 2.82-6.81 3.75-8.72 1.34-2.78 2.33-3.53 4.93-3.75 2.62-.23 3.69.31 7.75 5.73l3-2.87c1.65-1.58 3.9-3.37 5-3.98 1.1-.6 2.11-1.11 2.25-1.13zm661.17.17c1.75.21 2.86 1.19 3.56 3.14.86 2.4.7 3.07-.98 4.29-1.1.8-2.85 1.32-3.9 1.16-1.04-.16-2.39-1.05-3-1.98-.83-1.27-.74-2.34.34-4.3 1.07-1.92 2.11-2.53 3.98-2.31zm-699.91 4.64c1.24.36 2.93 2.01 3.75 3.66.98 1.98 1.28 4.37.88 7-.34 2.2-1.41 4.8-2.38 5.78s-2.77 1.77-4.01 1.75c-1.94-.03-2.16-.41-1.6-2.78.36-1.51.76-5.45.89-8.75l.22-6.66c0-.36 1.01-.36 2.25 0zm-285.62 6.41c.5.14 1.07.81 1.26 1.5s-2.31 3.16-5.56 5.5-6.4 5.04-7 6c-.87 1.4-.54 2.5 1.66 5.46 1.51 2.05 4.06 4.41 5.66 5.25 1.6.85 4.23 2.67 5.85 4.04 1.82 1.54 2.95 3.46 2.95 5-.01 1.38-.44 3.63-.96 5-.58 1.52-2.78 3.39-5.6 4.75-2.95 1.43-6.57 2.27-9.9 2.29-2.89.03-6.6-.34-8.25-.81-2.32-.67-3.08-1.52-3.34-3.8-.21-1.85.34-3.64 1.5-4.87 1.82-1.91 1.84-1.91 2.09.25.14 1.21 1.04 2.58 2 3.05.96.48 3.66 1.15 6 1.5 3.81.57 4.56.33 7.25-2.36 1.65-1.65 3-3.9 3-5s-.56-2.01-1.25-2.03c-.69-.01-2.71-1.14-4.5-2.5s-3.59-2.48-4-2.49-1.87-1.21-3.25-2.67c-1.58-1.68-2.64-4.16-2.89-6.74-.36-3.71-.01-4.45 4-8.35 2.41-2.35 6.19-5.17 8.38-6.25 2.2-1.08 4.4-1.86 4.9-1.72zm95.61 2.74c.82 0 4.09.68 7.25 1.5 3.16.83 6.65 1.51 7.75 1.51 1.24 0 2.22.86 2.58 2.25.45 1.73-.36 3.18-3.49 6.25-2.23 2.2-4.08 4.67-4.11 5.5-.02.83.64 2.85 1.48 4.5s1.53 4.13 1.54 5.5c.01 1.38-1 4.52-2.24 7-1.5 2.98-3.61 5.24-6.26 6.73-2.83 1.58-5.68 2.24-9.75 2.25-4.45.02-5.75-.32-5.75-1.48 0-.83.68-2.17 1.5-3s3.86-1.78 6.75-2.12c2.89-.33 6.04-1.01 7-1.5.96-.48 2.02-2.34 2.35-4.13.34-1.79.34-4.26 0-5.5-.33-1.24-1.39-2.26-2.35-2.27-.96-.02-3.44.66-5.5 1.5-2.06.83-4.43 1.29-5.25 1.02s-1.51-1.06-1.51-1.75c-.01-.69 2.8-2.91 6.25-4.93 3.44-2.02 7.16-4.61 8.26-5.75s1.73-2.63 1.4-3.32-2.35-1.61-4.5-2.04c-2.14-.44-5.16-1.34-6.69-2-1.53-.67-2.83-1.52-2.88-1.9-.06-.38.97-1.4 2.29-2.26 1.31-.86 3.06-1.56 3.88-1.56zm-75.27 2.98c.97-.02 2.55.77 3.49 1.75.95.98 2.25 4.48 2.88 7.78.64 3.3 1.33 6.56 1.53 7.25s1.5 1.25 2.87 1.25c1.56 0 2.5.57 2.5 1.5 0 .83-1.57 2.17-3.5 3s-3.51 1.61-3.53 1.75c-.01.14-.85 2.73-1.85 5.75-1.23 3.71-2.44 5.63-3.72 5.89-1.75.36-1.83.01-1-4.5.49-2.69.94-5.79 1-6.89.08-1.59-.62-2.06-3.4-2.29-1.93-.16-4.18-.5-5-.76-1.25-.38-1.16-.8.5-2.47 1.1-1.11 3.24-2.23 4.75-2.5 1.51-.26 2.8-1.04 2.87-1.73.06-.69.02-2.15-.09-3.25-.12-1.1-.89-3.35-1.72-5s-1.26-3.79-.94-4.75 1.38-1.76 2.36-1.78zM676.11 866c1.06 0 2.11.88 2.39 2 .3 1.21-.59 3.53-2.25 5.88l-6.25 8.6c-1.92 2.6-4.62 6.02-6 7.61-1.37 1.58-5.87 8.71-10 15.85-5.26 9.1-8.4 13.47-10.5 14.63-1.65.92-3.9 1.42-5 1.13-1.19-.32-3.31-3.1-5.25-6.87-1.78-3.48-3.24-7.57-3.25-9.08 0-1.51.45-2.98 1-3.25s1.74-.16 2.65.25c.9.41 2.7 2.89 4 5.5 1.29 2.61 2.91 4.6 3.6 4.41s4.17-5.26 7.75-11.25c3.58-6 8.75-14.12 11.5-18.05 2.75-3.92 6.96-9.43 9.36-12.25 2.4-2.81 5.22-5.11 6.25-5.11zm-367.89 4c.43 0 .78.45.78 1s-.49 2.24-1.09 3.75-1.28 4.89-1.5 7.5c-.23 2.61-.07 4.76.34 4.78s1.55-.77 2.54-1.75c1.29-1.29 1.7-3.01 1.5-6.28-.26-4.02-.08-4.46 1.71-4.15 1.1.18 2.58.86 3.29 1.5.72.63 1.28 1.94 1.25 2.9-.02.96-.72 3.33-1.54 5.25a9.21 9.21 0 0 1-5 5c-2.21.95-4.44 1.22-6.05.75-1.5-.44-2.32-1.26-2-2 .3-.69.1-1.48-.45-1.75s-1-1.85-1-3.5.69-4.69 1.53-6.75c.85-2.06 2.3-4.31 3.23-5s2.04-1.25 2.46-1.25zm24.53 1.08c1.24-.04 3.38.93 4.76 2.17 1.81 1.63 2.6 3.49 2.84 6.75.19 2.48-.03 5.74-.5 7.25-.48 1.54-2.17 3.41-3.85 4.25-1.65.83-4.57 1.5-6.5 1.5-2.08 0-3.54.51-3.61 1.25-.05.69-.01 2.38.11 3.75.11 1.38-.52 4.19-1.4 6.25s-2.28 3.75-3.1 3.75c-1.07 0-1.5-1.08-1.5-3.75 0-2.06.45-5.21 1-7 .67-2.17.67-3.42 0-3.75-.56-.28-.89-3.47-.75-7.19.23-6.11.55-7 3.75-10.37 1.93-2.02 4.18-3.93 5-4.23s2.51-.59 3.75-.63zm-7.07 9.42c-.46 2.2-.1 3.6 1.35 5.25 1.15 1.32 2.9 2.15 4.22 2 1.79-.2 2.31-.96 2.53-3.75.15-1.93-.41-4.51-1.25-5.75s-2.09-2.24-2.78-2.23c-.69 0-1.74.34-2.34.75-.6.4-1.38 2.08-1.73 3.73zm202.24.07c.32.33.71 2.48.86 4.77.16 2.29.43 9.11.61 15.16s.84 12.24 1.47 13.75c1.12 2.7 1.29 2.75 16.44 2.25l1.62-5c.89-2.75 2.55-6.35 3.7-8s3.06-3.34 4.23-3.75c1.22-.43 2.37-.32 2.65.25.27.55 1.51.73 2.75.39 1.59-.42 2.92.09 4.52 1.75 1.35 1.4 2.26 3.58 2.25 5.36-.01 1.65-.81 4.39-1.77 6.09s-2.65 4.51-3.75 6.25c-1.36 2.14-2.8 3.15-4.5 3.17-1.37.01-3.85-.47-5.5-1.07-2.43-.89-3.66-.76-6.5.69-2.72 1.38-5.39 1.72-12 1.49-4.67-.16-9.07-.82-9.76-1.46s-1.47-3.86-1.72-7.16l-.93-12.5c-.25-3.58-.77-8.98-1.15-12-.66-5.34-.59-5.58 2.61-8.26 1.8-1.53 3.55-2.5 3.87-2.17zm27.44 33.18c-.4 2.36-.21 4.03.5 4.5.63.41 1.93.36 2.89-.12s2.34-2.16 3.05-3.75c.72-1.58 1.17-4.42 1-6.3-.16-1.89-.78-3.58-1.36-3.77s-2.04 1.01-3.25 2.67c-1.2 1.66-2.48 4.71-2.83 6.77zm28.82-10.06c1.73 1.7 1.74 1.96.18 4.31l-3.02 4.5c-.75 1.1-1.35 3.01-1.35 4.25.01 1.28.77 2.47 1.76 2.76.96.29 2.88-.23 4.25-1.15 1.38-.92 4.19-2.95 6.25-4.51 2.06-1.57 4.42-2.85 5.25-2.85s1.73.45 2 1-.62 2.8-2 5c-1.7 2.72-4.02 4.69-7.25 6.14-2.61 1.18-5.87 2.31-7.25 2.51-1.37.2-3.96-.54-5.75-1.64-1.79-1.11-3.76-3.02-4.39-4.26-.89-1.76-.8-3.23.43-6.75.91-2.6 3.16-5.9 5.31-7.81 3.61-3.2 3.79-3.25 5.58-1.5zm29.07 9.35c.69.02 1.77.81 2.41 1.75.75 1.1.83 2.33.25 3.46-.5.96-1.81 2.2-2.91 2.75s-2.67.77-3.5.5-1.5-1.4-1.5-2.5.9-2.9 2-4 2.56-1.98 3.25-1.96z&#34;/&gt;
&lt;/svg&gt;
&lt;p&gt;The final data set (&lt;code&gt;final_df&lt;/code&gt;) is what creates the actual animation. It contains a list of geographic points and corresponding arrival times for each train.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#generate-the-animation-frames&#34;&gt;&lt;h3 id=&#34;generate-the-animation-frames&#34;&gt;Generate the animation frames&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to generate-the-animation-frames section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;Finally, we create a &lt;code&gt;ggplot2&lt;/code&gt; object and add animation with &lt;code&gt;gganimate&lt;/code&gt;. There are two important components here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;transition_components(time)&lt;/code&gt;, which tells &lt;code&gt;gganimate&lt;/code&gt; to cycle through the window of time defined in &lt;code&gt;final_df&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;geom_point()&lt;/code&gt; with a &lt;code&gt;group = trip_id&lt;/code&gt; aesthetic, which tells &lt;code&gt;gganimate&lt;/code&gt; to treat each train as a single point that moves along through time&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The resulting object is passed to the &lt;code&gt;animate()&lt;/code&gt; function, which then generates the inidividual frames. &lt;code&gt;gganimate&lt;/code&gt; will use the &lt;code&gt;tweenr&lt;/code&gt; package to further interpolate point locations for smoother animations.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#convert-to-video&#34;&gt;&lt;h3 id=&#34;convert-to-video&#34;&gt;Convert to video&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to convert-to-video section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h3&gt;&lt;/a&gt;&lt;p&gt;The output of &lt;code&gt;animate()&lt;/code&gt; is a folder of individual &lt;code&gt;.png&lt;/code&gt; plots. These can be combined into a single video using ffmpeg. I used the following settings:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -framerate &lt;span class=&#34;m&#34;&gt;60&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -pattern_type glob -i &lt;span class=&#34;s1&#34;&gt;&amp;#39;./gganim_plot*.png&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -c:v libx264 -profile:v main -preset fast &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -strict experimental -movflags +faststart -pix_fmt yuv420p &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  output.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then one more pass to create a WebM file as a fallback for HTML &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tags:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i output.mp4 -b:v &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; -crf &lt;span class=&#34;m&#34;&gt;45&lt;/span&gt; -an -f webm output.webm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Overall, this method works fairly well. It takes awhile to generate the individual frames, but the resulting animation is crisp, smooth, and beautiful. Pretty good for less than 200 lines of code.&lt;/p&gt;
</description>
                <link>https://sno.ws/transit-maps/</link>
                <category domain="recommended">true</category>
                <pubDate>Wed, 03 Mar 2021 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/transit-maps/</guid>
            </item><item>
                <title>Hello (again) world</title>
                <description>&lt;p&gt;I think I&amp;rsquo;ve made a personal website 3-4 times now. Each one sat on the internet dusty and unused. I made them out of a sense of obligation to have a site, not out of genuine interest in creating content.&lt;/p&gt;
&lt;p&gt;Well, now I finally feel like making some stuff and need a place to put it. So this site is my attempt at creating that space. It has five main purposes. It is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;An outlet for rare creative impulses (photos, writing, or otherwise)&lt;/li&gt;
&lt;li&gt;A place to put coding projects and other technical work/thoughts&lt;/li&gt;
&lt;li&gt;A way to keep track of books I read and which ones I like the most&lt;/li&gt;
&lt;li&gt;An occasional diary and place to keep track of goals, life events, or whatever I&amp;rsquo;m consuming at the time&lt;/li&gt;
&lt;li&gt;A way for me to learn modern web design and best practices&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Plus, this site is just a way for me to document my own life. I have awful long-term memory, so I want a way to look back at what I was up to during a given time.&lt;/p&gt;
&lt;p&gt;I plan to post something roughly every other week. Hopefully I can contribute at least a small bit to the vast pool of knowledge and content that is the modern internet.&lt;/p&gt;
</description>
                <link>https://sno.ws/hello-world/</link>
                <category domain="recommended">false</category>
                <pubDate>Sat, 27 Feb 2021 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/hello-world/</guid>
            </item><item>
                <title>Visualizing America&#39;s rural physician shortage</title>
                <description>&lt;p&gt;&lt;em&gt;Note: This is adapted from an essay I wrote as a research assistant during graduate school. You can see the &lt;a href=&#34;https://dfsnow.github.io/ama_viz/exploratory_plots.html&#34;&gt;original essay here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;div style=&#34;max-width:600px;display:flex;margin:-3rem auto;&#34;&gt;
    
    
    
    
    
    
    
    
    
    
    
    
      
        
        
      
    
    &lt;picture&gt;
        &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-colorbar.png&#34; type=&#34;image/png&#34;&gt;
        &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-colorbar.png&#34; alt=&#39;Post color palette&#39; width=&#39;1696&#39;
            height=&#39;44&#39; loading=&#34;lazy&#34;&gt;
    &lt;/picture&gt;
    

&lt;/div&gt;
&lt;p&gt;Rural America is facing a massive and growing shortage of physicians. For the past few decades, doctors have flocked to cities seeking better career opportunities, higher pay, and urban amenities. As a result, only 10% of physicians now live in rural areas, compared to 20% of the overall U.S. population. This maldistribution has potentially disastrous consequences: studies have shown that having physical access to a doctor is an important determinant of health. For many rural Americans, getting this access requires a long drive and a potentially longer wait, resulting in potential health consequences such as a higher likelihood of infant mortality, obesity, and disability. The shortage and its effects are likely to get worse in the coming decades, as an increasing percentage of physicians choose to practice in urban areas.&lt;/p&gt;
&lt;p&gt;In response to this crisis, policymakers have implemented two primary measures designed to stem the flow of physicians moving to urban areas. First, the Department of Health and Human Services and others have created wage incentives for doctors practicing in shortage areas. These incentives are designed to attract new doctors to rural areas by offering them a slight wage premium, and to keep rural doctors rural by offsetting their opportunity costs. Second, many medical schools have opened rural branch campuses or programs, ostensibly designed to accustom students to rural life and erode their preference for urban areas.&lt;/p&gt;
&lt;p&gt;The assumption of these policies is that doctors live in urban areas simply because they prefer higher density and urban amenities. Unfortunately, this assumption is incomplete and misinterprets the nature and causes of the rural doctor shortage. The rural doctor shortage is not a result of rurality per se, but rather of the urban/rural education and class divide. In short, doctors have an overriding preference for urban areas because urban areas, like doctors, tend to be richer and more highly educated than rural areas. Current policies aimed at changing this preference have been unsuccessful because class is largely an immutable characteristic. Paying doctors more in rural areas will not override their desire to be around other doctors and highly educated people. Instead, policymakers concerned about the rural doctor shortage should focus on recruiting doctors with pre-developed preferences for rural areas and on finding appropriate doctor substitutes, such as nurse practitioners.&lt;/p&gt;
&lt;p&gt;Maintaining current policies will waste millions of dollars and do little to ameliorate the rural doctor shortage or improve rural health. Policymakers should pivot toward a new set of policy solutions based on a more nuanced understanding of the shortage and its causes. To that end, the rest of this document is split into three parts: first, describing where the shortage is and what its causes are; second, discussing why current policies have failed; and third, offering new potential solutions.&lt;/p&gt;
&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#mapping-the-us-doctor-shortage&#34;&gt;&lt;h2 id=&#34;mapping-the-us-doctor-shortage&#34;&gt;Mapping the U.S. doctor shortage&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to mapping-the-us-doctor-shortage section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;Effective policy responses begin by correctly identifying the problem they’re trying to solve. Policymakers, health professionals, and academics have spent decades studying the spatial distribution of physicians. As early as the 1960s, academics such as Rimlinger and Steele (1961) lamented the shortage of rural U.S. physicians and its potential impact on rural health. Since then, countless academics have updated the methods used for quantifying the shortage, but their shared description of the shortage as being rural has remained the same (where rural typically means lower population density).&lt;/p&gt;
&lt;p&gt;Unfortunately, this definition is incomplete. While it’s generally true that rural areas have fewer doctors, there are also rural areas with a high number of doctors relative to their population. These oversupplied areas aren’t just small anomalies, they often encompass entire regions of the United States. The map below shows the physician-to-population ratio (physicians per 100K people) of each U.S. state. The ratio is grouped into quantiles for easier viewing. Most rural southern states (Mississippi and Arkansas) and plain states (Iowa, Nebraska) do have a low number of doctors relative to their population. However, notably rural regions such as the Pacific Northwest (Washington, Oregon) and the far Northeast (Maine, Vermont) are oversupplied.&lt;/p&gt;
&lt;p&gt;This distribution indicates that the rural doctor shortage is not driven entirely by rurality, but rather by a combination of rurality and other factors such as educational attainment level. Research shows that educational attainment explains over 40% of the variation in physician supply, while population density (rurality) explains less than 10%. In other words, the rural doctor shortage may be better characterized as a doctor shortage in less-educated areas. Rural areas do have doctor shortages, but they’re largely caused by rural areas being less-educated, rather than by rurality itself. Thus, policymakers have misidentified the cause of the shortage, attributing it to rurality when the truth is likely more nuanced.&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-doc-population.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-doc-population.png&#34; alt=&#39;Rural states have a shortage of doctors relative to their population&#39; width=&#39;1728&#39;
        height=&#39;1344&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;p&gt;The true nature of the doctor shortage can be seen more clearly at the county level. The map below shows an index of the relative level of primary care accessibility for every county in the United States. This index is calculated using a new technique which minimizes the driving time and cost of congestion for each patient. In other words, it allows patients to make a trade-off between distance and crowdedness, with patients moving farther to avoid extremely crowded providers. This method adds to previous literature on spatial accessibility, which is often measured simply as the patient-to-provider ratio of a given space.&lt;/p&gt;
&lt;p&gt;Since the algorithm is applied to the entire U.S., the index number it yields is nationally relative and can be used to compare regional or county-level variation in accessibility. In highly accessible (purple) areas, patients drive only a short distance to their doctor and the doctor’s office is unlikely to be crowded when they arrive. In inaccessible (pink) areas, patients may drive for hours to their doctor, only to find themselves competing for attention with the many other patients that doctor serves.&lt;/p&gt;
&lt;p&gt;The results from this new method support the hypothesis that physicians prefer to live in highly educated areas. On the map, this can be seen most clearly in the New England region. Maine, Vermont, and New Hampshire have excellent primary care accessibility despite being relatively rural states. Similarly, states in the upper Midwest such as Minnesota, Wisconsin, and Iowa are highly accessible despite being mostly rural. All of these states contain a large number of highly educated people relative to their population. Conversely, Texas and much of the South have poor accessibility despite being relatively more urban. These areas have lower average educational attainment than the rest of the U.S.&lt;/p&gt;
&lt;p&gt;Nonetheless, framing the problem as a rural shortage can still be useful. Certain regions notwithstanding, the U.S. generally has a large overlap between rurality and low educational attainment, and areas with the most severe shortages tend to be both very rural and very undereducated. As such, rurality can serve as a useful heuristic, capturing the educated/undereducated area divide in a way that is more intuitive to most people. However, this characterization becomes a problem when used as a basis for policy, where misidentification of the underlying problem can yield ineffective and costly results.&lt;/p&gt;
&lt;p&gt;(For the remainder of the article, “rural” is used as a shorthand for “rural and/or undereducated”.)&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-pc-access.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-pc-access.png&#34; alt=&#39;Rural counties have poor access to primary care&#39; width=&#39;1728&#39;
        height=&#39;1344&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;p&gt;Age is also an important aspect of the rural doctor shortage story. In the past three decades, more and more young doctors have settled in cities, while very few have moved to rural areas. This sorting is likely driven by homophily (the desire to interact with and live among people like yourself) and existing demographic shifts in American society. Put bluntly, young, educated people like to live around other young, educated people, most of whom live in cities. Doctors follow this same trend.&lt;/p&gt;
&lt;p&gt;Unfortunately, these young, urban doctors tend to stay put rather than move to rural areas as they get older. As a result, rural doctors tend to be an average of 18 years older than their urban peers. In the plot below, the bulk of the distribution of rural doctors is around 60 years old. Many of these doctors will retire in the next few decades and will not be replaced, severely exacerbating the existing crisis.&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-doc-age.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-doc-age.png&#34; alt=&#39;Rural doctors are scarcer and older&#39; width=&#39;1728&#39;
        height=&#39;1344&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;p&gt;The rise in specialist physicians has also contributed to the rural doctor shortage. As more medical students choose high-paying specialties, the proportion of primary care physicians trained each year has decreased, particularly since 2001. The plot below shows this trend.&lt;/p&gt;
&lt;p&gt;Specialists are much more likely to practice in urban areas than primary care physicians. Rural areas rarely produce the demand needed to support a specialist. Even if rural demand was sufficient, most rural hospitals do not have the infrastructure, equipment, or funds necessary to support full-time specialists. As a result, specialists are much more likely to live and practice in urban areas.&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-pc-v-spec.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-pc-v-spec.png&#34; alt=&#39;More doctors are becoming specialists&#39; width=&#39;1728&#39;
        height=&#39;1344&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#doctor-preferences-and-the-current-policy-response&#34;&gt;&lt;h2 id=&#34;doctor-preferences-and-the-current-policy-response&#34;&gt;Doctor preferences and the current policy response&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to doctor-preferences-and-the-current-policy-response section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;Policymakers have spent millions of dollars trying to solve the rural doctor shortage. Unfortunately, current policies are misguided and focus on the wrong problem, relying on the assumption that geographic variation in physician supply is driven by rurality itself. These policies have each attempted to change physician preferences for rurality but have ignored physicians’ homophily and preference for educated areas. As a result, these policies have largely failed and the rural doctor shortage persists.&lt;/p&gt;
&lt;p&gt;One of the most well-known policies designed to address the rural shortage is increasing rural doctor pay. Health and Human Services (HHS) and other healthcare payers reimburse doctors practicing in shortage areas at a higher rate, typically around 10%. The goal of these payments is to incentivize physicians to move to rural areas by offsetting their input and opportunity costs. However, these payments have not worked as intended.&lt;/p&gt;
&lt;p&gt;The plot below shows the median wage of urban and rural doctors over time. Since 2000, the wage gap between urban and rural doctors has expanded dramatically, with rural doctors now making roughly $40K more than their urban counterparts. Yet the rural doctor shortage has only worsened, indicating that such payment policies have mostly subsidized already-rural doctors while inducing few urban doctors to move.&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-wage.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-wage.png&#34; alt=&#39;Rural doctors make more money than urban doctors&#39; width=&#39;1728&#39;
        height=&#39;1152&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;p&gt;By ignoring wage incentives, urban doctors display an overriding hidden preference for urban areas. Previous research (Lombardo et al.) suggests this preference is a combination of doctors’ preferences for urban amenities and their preference for being around other highly educated people. This partially explains the maldistribution visible in the previous maps. Places such as New England have a high level of educational attainment and nice urban amenities, they therefore have a large number of doctors. Places like Mississippi have low average educational attainment and few urban amenities, they therefore have fewer doctors.&lt;/p&gt;
&lt;p&gt;Doctors have this preference for urban areas regardless of their birthplace. The plot below shows the rurality of where different cohorts of physicians end up attending medical school, doing their residency, and practicing. Each line represents a cohort of physicians born in 1 of 10 core-based statistical area (CBSA) deciles. For example, the pink line represents the most rural-born cohort of doctors, while the purple line represents the most urban-born. Each shaded region represents a different level of rurality.&lt;/p&gt;
&lt;p&gt;All of the doctor cohorts, regardless of their birthplace rurality, end up practicing in urban/suburban areas. After being mechanically forced to urban areas for school (almost all medical schools are in cities), doctors never return to the same rurality level as their birthplace. This indicates that doctors’ preferences for urban areas may develop as a result of training in those areas. Based on this assumption, some medical schools have developed rural programs intended to give doctors a taste of rural life. However, there is little evidence to indicate that such programs increase rural practice retention.&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-cohort.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-cohort.png&#34; alt=&#39;Doctors move to urban areas regardless of birthplace&#39; width=&#39;1728&#39;
        height=&#39;1344&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;p&gt;Medical schools also play a role in determining where a doctor chooses to practice. The plot below shows the average MCAT score of each medical school compared to the rurality of the average graduate’s practice location. Graduates of medical schools with higher average MCAT scores tend to end up practicing in more urban areas.&lt;/p&gt;
&lt;p&gt;The reason for this is two-fold. First, better medical schools tend to be located in large cities. Doctors at these schools likely develop preferences for big city amenities as well as business and social networks that make leaving undesirable. Second, graduates of better medical schools are more likely to be matched with their preferred residency programs, i.e. they are unlikely to be forced to attend less competitive rural programs.&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-med-school.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-med-school.png&#34; alt=&#39;Competitive medical schools send their graduates to urban areas&#39; width=&#39;1728&#39;
        height=&#39;1344&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;a class=&#34;header-link hover-icon&#34; role=&#34;none&#34; href=&#34;#how-do-we-fix-the-rural-doctor-shortage&#34;&gt;&lt;h2 id=&#34;how-do-we-fix-the-rural-doctor-shortage&#34;&gt;How do we fix the rural doctor shortage?&lt;svg version=&#34;1.2&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; role=&#34;img&#34; aria-hidden=&#34;true&#34; class=&#34;header-link-icon&#34; viewBox=&#34;0 0 32 32&#34; width=&#34;0.7em&#34; height=&#34;0.7em&#34; fill=&#34;currentcolor&#34;&gt;&lt;title&gt;Link to how-do-we-fix-the-rural-doctor-shortage section&lt;/title&gt;&lt;path d=&#34;M14 21h-5a4.8 4.8 90 010-10h5v-3h-5a1 1 0 000 16h5ZM18 11h5a4.8 4.8 270 010 10h-5v3h5a1 1 180 000-16h-5ZM8 14.5h16v3h-16Z&#34; /&gt;&lt;/svg&gt;&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;The current state of rural American medicine is bleak. Doctors are overwhelmingly clustered in urban and highly educated areas. The existing cohort of rural doctors is rapidly aging and is unlikely to be replaced. More and more doctors are becoming specialists who can only viably practice in cities. Solving the rural doctor shortage seems like an impossible task.&lt;/p&gt;
&lt;p&gt;Previous solutions have focused on increasing the compensation of rural doctors, yet this strategy seems to be ineffective. Doctors have such a strong preference for urban areas that it overrides any incentives created by relatively small rural wage premiums. Given this preference, the high earnings of most physicians, and the marginal utility of money, it would likely take a massive wage premium to begin attracting marginal doctors to rural areas.&lt;/p&gt;
&lt;p&gt;Instead, two solutions should be implemented. First, medical schools should recruit more students from rural areas. The sixth plot shows that such students are the most likely to practice in rural areas. These students have pre-existing preferences for rurality, i.e. they are not as prone to developing strong preferences for urban areas because they already prefer rural ones. Additionally, students from rural areas are already invested in and familiar with rural communities. Recruiting more of these students would undoubtedly bolster the number of rural physicians.&lt;/p&gt;
&lt;p&gt;Second, states should focus on training and licensing more nurse practitioners (NPs). The plot below shows that nurse practitioners already serve as substitutes in states with relatively few doctors. NPs can perform the same basic tasks as a primary care physicians but are cheaper and easier to train and license. Substituting NPs in rural areas could reduce the impact of the rural physician shortage and improve basic health outcomes for rural Americans.&lt;/p&gt;












  
    
    
  

&lt;picture&gt;
    &lt;source srcset=&#34;https://content.sno.ws/posts/2019-04-10-nps.png&#34; type=&#34;image/png&#34;&gt;
    &lt;img src=&#34;https://content.sno.ws/posts/2019-04-10-nps.png&#34; alt=&#39;Nurses serve as substitutes in states with few doctors&#39; width=&#39;1728&#39;
        height=&#39;1536&#39; loading=&#34;lazy&#34;&gt;
&lt;/picture&gt;


&lt;p&gt;The worsening maldistribution of U.S. physicians has potentially devastating health consequences for millions of Americans. States and the medical community should act quickly to implement practical solutions that increase the recruitment of rural medical students and NPs.&lt;/p&gt;
</description>
                <link>https://sno.ws/rural-docs/</link>
                <category domain="recommended">false</category>
                <pubDate>Wed, 10 Apr 2019 00:00:00 +0000</pubDate>
                <guid isPermaLink="true">https://sno.ws/rural-docs/</guid>
            </item></channel>
</rss>