Jon-Michael Deldin | BMX, bike trials, and software2020-03-29T22:22:58-07:00http://www.jmdeldin.comJon-Michael Deldinjm+blog@jmdeldin.com0 A.D. Map Reviews2020-03-29T00:00:00-07:00http://www.jmdeldin.com/posts/2020/0ad-map-review<p>We have played <a href="https://play0ad.com/">0 A.D.</a> for about four years now, and this past fall, we
decided to play all the biome variants of each map. We finally finished!</p>
<h3>Strategy</h3>
<p>Our general strategy was build a wonder inside Iberian walls, and then
the other player would launch attacks but also be able to mount a large
response to protect the wonder. We still have not figured out how to
dispatch with elephants efficiently – they can wipe us out quickly,
especially if the enemies have 150 people. Cavalry archers seem to do a
decent job, as do British dogs, but it’s never fast enough. Naturally,
when we play as elephant civilizations, the enemy crushes our elephants
immediately. Furthermore, the AI swordsman decimate us, even when our
infantry and cavalry units are fully upgraded.</p>
<p>We’re still not good enough to go against three AI enemies without a
third player, so when we didn’t have a third human, we had a random
behavior, random civilization AI as a sacrificial lamb. Sometimes, it
worked and they were attacked early instead of us, but not always. We
usually were an Iberian+Roman human team.</p>
<h3>Setup</h3>
<ul>
<li>Wife: 2012 Macbook Pro is the host, shares WiFi over ethernet</li>
<li>Me: 2016 Thinkpad T460 running Ubuntu, plugged into MBP</li>
<li>Stepson: Steam box running Windows 10, connected over WiFi or ethernet
to router</li>
</ul>
<h3>Game Settings</h3>
<ul>
<li>3 AI enemies on random behavior and very hard</li>
<li>Large map</li>
<li>Wonder Victory (60 min)</li>
<li>Teams Locked</li>
<li>Conquest</li>
<li>No treasures</li>
<li>Unexplored</li>
<li>Unrevealed</li>
<li>Pop 100</li>
<li>Very high resources</li>
<li>Disable spies</li>
<li>Insane 2x</li>
</ul>
<h3>Top maps</h3>
<ul>
<li>Lion’s Den</li>
<li>Persian Highlands</li>
<li>Sahel Watering Holes</li>
<li>Snowflake Searocks</li>
</ul>
<h3>Worst maps</h3>
<ul>
<li>Lake (too much lag)</li>
<li>Wild Lake (so hard to move and to build)</li>
</ul>
<h3>Statistics</h3>
<table>
<tr><th>Victory</th><th>Count</th></tr>
<tr><td>Win: Wonder</td><td>50</td></tr>
<tr><td>Win: Survival</td><td>1</td></tr>
<tr><td>Win: Conquest</td><td>110</td></tr>
<tr><td>Skip</td><td>2</td></tr>
<tr><td>Quit</td><td>21</td></tr>
<tr><td>Lost</td><td>13</td></tr>
<tr><td><b>Total</b></td><td>197</td></tr>
</table>
<h3>Game Notes</h3>
<p>We live in the Northwest, so there are a lot of long rainy days, i.e., 0
A.D. killing days.</p>
<table>
<tr><th>Date</th><th>Map</th><th># human</th><th># AI Allies</th><th># AI Enemies</th><th>Wood</th><th>Metal</th><th>Stone</th><th>Meat</th><th>Fish</th><th>Would play again?</th><th>Win?</th><th>Iberian walls?</th><th>AI Ally Play</th></tr>
<tr><td><2019-09-11 Wed></td><td>African Plains</td><td>3</td><td>0</td><td>3</td><td>H</td><td>M</td><td>M</td><td>H</td><td>L</td><td>Y / hard</td><td>Wonder, almost destroyed all</td><td>Y</td><td>N/A</td></tr>
<tr><td><2019-09-12 Thu></td><td>Alpine Lakes</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>H</td><td>L</td><td>L</td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Strong</td></tr>
<tr><td><2019-09-12 Thu></td><td>Alpine Valley</td><td>2</td><td>1</td><td>3</td><td>M</td><td>H</td><td>H</td><td>H</td><td></td><td>Y / hard</td><td>Wonder, almost killed</td><td>Y</td><td>Meh</td></tr>
<tr><td><2019-09-14 Sat></td><td>Ambush</td><td>3</td><td>0</td><td>3</td><td>H</td><td>M</td><td>L</td><td>M</td><td></td><td>Y / medium</td><td>Wonder, almost killed</td><td>Y</td><td>N/A</td></tr>
<tr><td><2019-11-19 Tue></td><td>Ambush - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td></td><td>Y / medium</td><td>Wonder, needed more time to kill</td><td>Y</td><td>Medium</td></tr>
<tr><td><2019-11-20 Wed></td><td>Ambush - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>N / not as good as alpine</td><td>Wonder, no chance of getting conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-11-20 Wed></td><td>Ambush - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>L</td><td></td><td></td><td>N / better than autumn</td><td>Wonder</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-11-23 Sat></td><td>Ambush - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Medium</td></tr>
<tr><td><2019-11-23 Sat></td><td>Ambush - Savanna</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / not as good as medit</td><td>Wonder, needed more time for conquest</td><td>N</td><td>Medium</td></tr>
<tr><td><2019-11-23 Sat></td><td>Ambush - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2019-11-24 Sun></td><td>Ambush - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun, narrow corridors for fighting</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2019-11-25 Mon></td><td>Ambush - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / very fun, easy conquest</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-09-15 Sun></td><td>Anatolian Plateau</td><td>2</td><td>1</td><td>3</td><td>L</td><td>H</td><td>L</td><td>2L</td><td></td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Meh</td></tr>
<tr><td><2019-09-15 Sun></td><td>Arctic Summer</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y / medium</td><td>Wonder, almost killed</td><td>Y</td><td>SUCKED</td></tr>
<tr><td><2019-09-15 Sun></td><td>Ardennes Forest</td><td>3</td><td>0</td><td>3</td><td>H</td><td>L</td><td>L</td><td>L</td><td></td><td>Y / very hard</td><td>Wonder (backup), almost died</td><td>Y</td><td>N/A</td></tr>
<tr><td><2019-09-16 Mon></td><td>Atlas Mountains</td><td>3</td><td>0</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>N / very hard, basically open</td><td>Wonder, probably needed 20 min to kill all</td><td>Y</td><td>N/A</td></tr>
<tr><td><2019-09-16 Mon></td><td>Belgian Uplands</td><td>3</td><td>0</td><td>3</td><td>H</td><td>VL</td><td>VL</td><td>VH</td><td></td><td>N / fake resources, sucks</td><td>LOST</td><td>N</td><td>N/A</td></tr>
<tr><td><2019-09-16 Mon></td><td>Botswanan Haven</td><td>3</td><td>0</td><td>3</td><td>M</td><td>M</td><td>M</td><td>H</td><td></td><td>N / too much lag</td><td>QUIT too much lag</td><td>Y</td><td>N/A</td></tr>
<tr><td><2019-09-16 Mon></td><td>Caledonian Meadows</td><td>3</td><td>0</td><td>3</td><td>M</td><td>M</td><td>M</td><td>M</td><td></td><td>N / too much lag</td><td>QUIT too much lag</td><td>Y</td><td>N/A</td></tr>
<tr><td><2019-09-16 Mon></td><td>Cantabarian Highlands</td><td>3</td><td>0</td><td>3</td><td>H</td><td>H</td><td>H</td><td>H</td><td>L</td><td>Y / easy and fun</td><td>Wonder, probably needed 10 min to kill all</td><td>Y</td><td>N/A</td></tr>
<tr><td><2019-09-20 Fri></td><td>Canyon</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>M</td><td>L</td><td></td><td>Y / easy and fun</td><td>Conquest</td><td>Y</td><td>Meh</td></tr>
<tr><td><2019-11-25 Mon></td><td>Canyon - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / nice conquest</td><td>Conquest</td><td>Y</td><td>Good</td></tr>
<tr><td><2019-11-25 Mon></td><td>Canyon - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun conquest</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-11-30 Sat></td><td>Canyon - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun easy conquest</td><td>Conquest, singlehanded</td><td>Y</td><td>SUCKED, almost died</td></tr>
<tr><td><2019-11-30 Sat></td><td>Canyon - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>N / not as fun, was placed in middle so further to attack therefore harder</td><td>Conquest</td><td>Y</td><td>SUCKED, had to defend constantly</td></tr>
<tr><td><2019-12-02 Mon></td><td>Canyon - Savanna</td><td>2</td><td>1</td><td>3</td><td>L</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / trivial</td><td>Conquest</td><td>Y</td><td>SUCKED, did nothing</td></tr>
<tr><td><2019-12-02 Mon></td><td>Canyon - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / depends on location for difficulty</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-12-02 Mon></td><td>Canyon - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>H</td><td></td><td>Y / pretty easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-12-02 Mon></td><td>Canyon - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>L</td><td>L</td><td></td><td>N / lagged, two elephant bad guys + british</td><td>Wonder</td><td>Y</td><td>Weak, lost civ center</td></tr>
<tr><td><2019-09-21 Sat></td><td>Continent</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>M</td><td>Y / hard until you conquer one</td><td>Conquest</td><td>Y</td><td>Poor</td></tr>
<tr><td><2019-12-07 Sat></td><td>Continent - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>H</td><td>L</td><td>M</td><td>Y / can be hard until you start conquering the map</td><td>Conquest</td><td>Y</td><td>Strong!</td></tr>
<tr><td><2019-12-07 Sat></td><td>Continent - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>M</td><td>N / alpine more fun</td><td>Conquest</td><td>Y</td><td>Good</td></tr>
<tr><td><2019-12-07 Sat></td><td>Continent - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>M</td><td>Y / very easy conquest if you start early</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2019-12-07 Sat></td><td>Continent - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>M</td><td>Y equivalent to desert</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2019-12-07 Sat></td><td>Continent - Savanna</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>M</td><td>Y / equivalent to desert</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2019-12-07 Sat></td><td>Continent - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>N / not as fun</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2019-12-07 Sat></td><td>Continent - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y / easy conquest</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2019-12-07 Sat></td><td>Continent - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y / ok conquest</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2019-09-21 Sat></td><td>Corinthian Isthmus</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>L</td><td>Y / easy if you block the isthmus</td><td>Wonder, nowhere near conquest, should have infiltrated via boat</td><td>N</td><td>Poor</td></tr>
<tr><td><2019-09-21 Sat></td><td>Deep Forest</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td></td><td>Y / hard till you take out one</td><td>Conquest</td><td>Y</td><td>Poor</td></tr>
<tr><td><2019-09-22 Sun></td><td>Empire</td><td>2</td><td>1</td><td>3</td><td>M</td><td>H</td><td>H</td><td>M</td><td></td><td>Y / hard, dual civ</td><td>Wonder, probably needed 20 min to kill all</td><td>N</td><td>SUCKED</td></tr>
<tr><td><2019-12-09 Mon></td><td>Empire - Alpine</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>N / hard, annoying, sucks</td><td>LOST</td><td>N</td><td>SUCKED</td></tr>
<tr><td><2019-12-11 Wed></td><td>Empire - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>Y / worked much better (less lag), no enemy siege weapons?</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2019-12-12 Thu></td><td>Empire - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>N / lost wonder, way overpowered by enemy siege at all towns</td><td>QUIT</td><td>N</td><td>Poor, absolutely useless</td></tr>
<tr><td><2019-12-12 Thu></td><td>Empire - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>N / lost my wonder, but overall better game than desert</td><td>Wonder</td><td>N</td><td>Mediocre</td></tr>
<tr><td><2019-12-16 Mon></td><td>Empire - Savanna</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>N / better than last</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2019-12-18 Wed></td><td>Empire - Snowy</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>N / about the same as savanna, not very fun</td><td>Wonder</td><td>N</td><td>Poor</td></tr>
<tr><td><2019-12-18 Wed></td><td>Empire - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / pretty good</td><td>Conquest</td><td>N</td><td>OK</td></tr>
<tr><td><2019-12-18 Wed></td><td>Empire - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / pretty good challenge</td><td>Conquest</td><td>N</td><td>Good</td></tr>
<tr><td><2019-09-22 Sun></td><td>Extinct Volcano</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>N / stupid, floods eventually</td><td>Survival, just build a boat</td><td>N</td><td>Poor</td></tr>
<tr><td><2019-09-22 Sun></td><td>Fields of Meroe</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>M</td><td></td><td>N / very hard</td><td>Wonder, barely</td><td>N</td><td>Poor</td></tr>
<tr><td><2019-12-19 Thu></td><td>Fields of Meroe - Dry</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>H</td><td>M</td><td></td><td>Y / pretty fun</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2019-12-19 Thu></td><td>Fields of Meroe - Rainy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>M</td><td></td><td>N / sucked, too many elephants</td><td>Wonder via Orange</td><td>Y</td><td>Good, but only defensive</td></tr>
<tr><td><2019-09-23 Mon></td><td>Flood</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / too much lag</td><td>QUIT too much lag, unplayable</td><td>N</td><td>N/A</td></tr>
<tr><td><2019-09-23 Mon></td><td>Fortress</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>L</td><td>L</td><td></td><td>Y / hard, heavy wood, central metal</td><td>LOST</td><td>Y</td><td>SUCKED</td></tr>
<tr><td><2019-09-23 Mon></td><td>Frontier - sand</td><td>2</td><td>1</td><td>3</td><td>-</td><td>-</td><td>-</td><td>-</td><td>-</td><td>N / disconnect immediately</td><td>QUIT disconnect first time. wouldn’t load second time</td><td>N</td><td>N/A</td></tr>
<tr><td><2019-09-23 Mon></td><td>Frontier - winter</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>H</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Strong</td></tr>
<tr><td><2019-12-20 Fri></td><td>Frontier - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>M</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Poor</td></tr>
<tr><td><2019-12-20 Fri></td><td>Frontier - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Poor</td></tr>
<tr><td><2019-12-20 Fri></td><td>Frontier - Desert</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>N / sucked. was squished for starting civ</td><td>LOST</td><td>N</td><td>DIED</td></tr>
<tr><td><2019-12-20 Fri></td><td>Frontier - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>N / sucked. got destroyed</td><td>QUIT</td><td>N</td><td>Useless</td></tr>
<tr><td><2019-12-31 Tue></td><td>Frontier - Savanna</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>N / mediocre</td><td>Conquest</td><td>N</td><td>Useless</td></tr>
<tr><td><2019-12-31 Tue></td><td>Frontier - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>N / okay, destroyed them</td><td>Conquest</td><td>Y</td><td>Useless</td></tr>
<tr><td><2020-01-01 Wed></td><td>Frontier - Temperate</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>N / sucked, ambushed by 11 elephants because AI antagonized them</td><td>QUIT</td><td>N</td><td>JERKS</td></tr>
<tr><td><2020-01-01 Wed></td><td>Frontier - Tropic</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / was actually fun because we could block a canyon</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2019-09-23 Mon></td><td>Gear</td><td>2</td><td>1</td><td>3</td><td>-</td><td>-</td><td>-</td><td>-</td><td>-</td><td>N / disconnect immediately for Player 2</td><td>QUIT</td><td>N</td><td>N/A</td></tr>
<tr><td><2019-09-23 Mon></td><td>Gear</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>H</td><td>L</td><td>Y / fun, worked the second time with halt freeze every 10 s</td><td>Conquest</td><td>N</td><td>OK</td></tr>
<tr><td><2020-01-03 Fri></td><td>Gear - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>L</td><td>Y / fun</td><td>Conquest</td><td>N</td><td>Sucked, lost civ center and died in town phase</td></tr>
<tr><td><2020-01-04 Sat></td><td>Gear - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td>L</td><td>Y / fun</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-04 Sat></td><td>Gear - Desert</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td>L</td><td>N / died, overpowered by 8 (!) elephants</td><td>LOST</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-04 Sat></td><td>Gear - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td>L</td><td>N / died, overpowered by more elephants</td><td>LOST</td><td>N</td><td>Weak, useless</td></tr>
<tr><td><2020-01-04 Sat></td><td>Gear - Savanna</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td>L</td><td>N / won, but trees kinda sucked. early attacking elephant people helped</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-04 Sat></td><td>Gear - Snowy</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y / won, no real elephants</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-05 Sun></td><td>Gear - Temperate</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y / won, attacked them early and no real elephants</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-05 Sun></td><td>Gear - Tropic</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y / won, same, basically single player</td><td>Conquest</td><td>N</td><td>Weak, almost lost civ center</td></tr>
<tr><td><2019-09-26 Thu></td><td>Guadalquivir River</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun, kind of hard</td><td>Wonder, needed 2 more min to conquer</td><td>N</td><td>Strong at end</td></tr>
<tr><td><2019-09-29 Sun></td><td>Gulf of Bothnia - winter</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>L</td><td>L</td><td>M</td><td>Y / fun</td><td>Wonder, needed 2 more min to conquer</td><td>Y</td><td>Strong</td></tr>
<tr><td><2020-01-05 Sun></td><td>Gulf of Bothnia - frozen</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-05 Sun></td><td>Gulf of Bothnia - spring</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>H</td><td>L</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-09-30 Mon></td><td>Harbor</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>M</td><td>M</td><td>Y / fun, basically same as last but with natural wall borders</td><td>Wonder, needed 2 more min to conquer</td><td>Y</td><td>Strong</td></tr>
<tr><td><2020-01-07 Tue></td><td>Harbor - alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Strong</td></tr>
<tr><td><2020-01-09 Thu></td><td>Harbor - autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Strong</td></tr>
<tr><td><2020-01-10 Fri></td><td>Harbor - desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-10 Fri></td><td>Harbor - mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-13 Mon></td><td>Harbor - savanna</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2020-01-13 Mon></td><td>Harbor - snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>M</td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Strong</td></tr>
<tr><td><2020-01-18 Sat></td><td>Harbor - temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td>M</td><td>Y / easy, fun</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2020-01-18 Sat></td><td>Harbor - tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td>M</td><td>Y / wasn’t as easy due to early attacks</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-10-02 Wed></td><td>Hell’s Pass - green</td><td>3</td><td>0</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / disconnect immediately before host even loads</td><td>QUIT</td><td>N</td><td>N/A</td></tr>
<tr><td><2019-10-02 Wed></td><td>Hell’s Pass - desert</td><td>3</td><td>0</td><td>3</td><td>H</td><td>L</td><td>M</td><td>L</td><td>L</td><td>Y / hard, close allies, no metal outside first pile</td><td>Wonder, needed 3 hours to conquer</td><td>N</td><td>N/A</td></tr>
<tr><td><2020-01-19 Sun></td><td>Hell’s Pass - alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>H</td><td>L</td><td>L</td><td>Y / hard, limited metal</td><td>Wonder, needed 10 more min to conquer</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-19 Sun></td><td>Hell’s Pass - autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>H</td><td>L</td><td>L</td><td>Y / okay</td><td>Conquest</td><td>N</td><td>OK</td></tr>
<tr><td><2020-01-19 Sun></td><td>Hell’s Pass - desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>M</td><td>L</td><td>L</td><td>N / annoying bottlenecks, scarce resources, generally not fun</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-19 Sun></td><td>Hell’s Pass - mediterranean</td><td>2</td><td>1</td><td>3</td><td>L</td><td>L</td><td>L</td><td>M</td><td>L</td><td>N / resource starved for everything</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-19 Sun></td><td>Hell’s Pass - savanna</td><td>2</td><td>1</td><td>3</td><td>L</td><td>L</td><td>L</td><td>L</td><td>L</td><td>N / resource starved, just got slammed. not very fun</td><td>LOST</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-19 Sun></td><td>Hell’s Pass - snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>H</td><td>L</td><td>L</td><td>N / ally died, so wonder cond went to enemy. overpowered</td><td>LOST</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-21 Tue></td><td>Hell’s Pass - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>H</td><td>L</td><td>L</td><td>Y / kind of sucked being in front of everyone and squished = no chance</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-01-21 Tue></td><td>Hell’s Pass - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>H</td><td>L</td><td>L</td><td>N / pretty annoying. overall, hell’s pass is a terrible map - no rest, all conflict</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2019-10-02 Wed></td><td>Hellas</td><td>3</td><td>0</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td>M</td><td>N / pretty hard, unusable terrain, naval wasn’t as big as map promised</td><td>LOST</td><td>N</td><td></td></tr>
<tr><td><2019-10-02 Wed></td><td>Hyrcanian Shores</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / disconnect immediately</td><td>QUIT</td><td>N</td><td></td></tr>
<tr><td><2019-10-02 Wed></td><td>India</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / disconnect</td><td>QUIT</td><td>N</td><td></td></tr>
<tr><td><2019-10-02 Wed></td><td>Jebel Barkal - very hard</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>M</td><td>M</td><td>N / STUPID hard</td><td>Conquest with cheating</td><td>N</td><td>Weak</td></tr>
<tr><td><2019-10-02 Wed></td><td>Kerala</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td>M</td><td>Y / pretty easy once you kill an enemy center</td><td>Conquest</td><td>N/A</td><td>Meh</td></tr>
<tr><td><2019-10-03 Thu></td><td>Lake - Snowy</td><td>3</td><td>0</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / lagged badly</td><td>QUIT</td><td></td><td></td></tr>
<tr><td><2019-10-03 Thu></td><td>Lake - Desert</td><td>3</td><td>0</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td>H</td><td>Y / fun</td><td>Wonder, needed 4 min to conquer</td><td>Y</td><td>N/A</td></tr>
<tr><td><2020-01-23 Thu></td><td>Lake - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y / fun but laggy</td><td>Conquest</td><td>Y</td><td>Meh</td></tr>
<tr><td><2020-01-24 Fri></td><td>Lake - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-24 Fri></td><td>Lake - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>L</td><td>L</td><td>L</td><td>Y / fun</td><td>Wonder, needed 30 sec to finish</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-25 Sat></td><td>Lake - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>L</td><td>L</td><td>L</td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Good</td></tr>
<tr><td><2020-01-25 Sat></td><td>Lake - Savanna</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>H</td><td>L</td><td>L</td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-27 Mon></td><td>Lake - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>H</td><td>L</td><td>L</td><td>Y / fun, more metal in enemy civs</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-29 Wed></td><td>Lake - Temperate</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / quit because too much lag</td><td>QUIT</td><td></td><td></td></tr>
<tr><td><2020-01-29 Wed></td><td>Lake - Temperate</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / quit because too much lag</td><td>QUIT</td><td></td><td></td></tr>
<tr><td><2020-01-29 Wed></td><td>Lake - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>L</td><td>N / was okay, kind of boring</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-10-03 Thu></td><td>Latium</td><td>3</td><td>0</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / disconnect and out of sync immediately. stupid square map.</td><td>QUIT</td><td></td><td></td></tr>
<tr><td><2019-10-03 Thu></td><td>Lion’s Den</td><td>3</td><td>0</td><td>3</td><td>H</td><td>L</td><td>M</td><td>L</td><td></td><td>Y / hard to control map</td><td>Wonder, needed a lot of time to conquer</td><td>Y</td><td>N/A</td></tr>
<tr><td><2020-01-30 Thu></td><td>Lion’s Den - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Strong</td></tr>
<tr><td><2020-01-30 Thu></td><td>Lion’s Den - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / had fun blocking map and forcing enemy routes</td><td>Conquest (JM Wonder)</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-31 Fri></td><td>Lion’s Den - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>N / fun but not as good as the other biomes</td><td>Conquest (JM Wonder)</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-01-31 Fri></td><td>Lion’s Den - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>N / quit because got overpowered by elephants and rams</td><td>QUIT</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-01 Sat></td><td>Lion’s Den - Savanna</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td></td><td>Y / good despite tree scarcity</td><td>Conquest</td><td>Y</td><td>Strong</td></tr>
<tr><td><2020-02-02 Sun></td><td>Lion’s Den - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>Y / fun, resource rich</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2020-02-02 Sun></td><td>Lion’s Den - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td></td><td>Y / fun, killed them all quickly</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-02 Sun></td><td>Lion’s Den - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>M</td><td>L</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-10-10 Thu></td><td>Lorraine Plain</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun</td><td>Wonder, needed 5 min to conquer</td><td></td><td></td></tr>
<tr><td><2019-10-10 Thu></td><td>Lower Nubia</td><td>2</td><td>1</td><td>3</td><td>M</td><td>H</td><td>H</td><td>L</td><td></td><td>N / too much collision, trader and unit pileups</td><td>Wonder, would have needed awhile to conquer</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-10-11 Fri></td><td>Mainland</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun, easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-02 Sun></td><td>Mainland - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-02 Sun></td><td>Mainland - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / hard, too many elephants and rams</td><td>Wonder</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-03 Mon></td><td>Mainland - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>Y / easy, no elephants</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-12 Wed></td><td>Mainland - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-12 Wed></td><td>Mainland - Savanna</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-13 Thu></td><td>Mainland - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-13 Thu></td><td>Mainland - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>Y / easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-16 Sun></td><td>Mainland - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>N / hate the biome for the lions</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-10-13 Sun></td><td>Marmara</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>M</td><td>M</td><td>L</td><td>Y / hard</td><td>LOST</td><td>Y</td><td>SUCKED</td></tr>
<tr><td><2019-10-23 Wed></td><td>Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>L</td><td>M</td><td>L</td><td>N / hard, kind of annoying pathfinding</td><td>Wonder</td><td></td><td></td></tr>
<tr><td><2019-10-24 Thu></td><td>Neareastern Badlands</td><td>3</td><td>0</td><td>3</td><td>H</td><td>H</td><td>M</td><td>H</td><td></td><td>Y / hard</td><td>Wonder</td><td>Y</td><td></td></tr>
<tr><td><2019-10-24 Thu></td><td>Ngorongoro</td><td>3</td><td>0</td><td>3</td><td>M</td><td>H</td><td>M</td><td>H</td><td></td><td>N / lost</td><td>LOST</td><td>Y</td><td></td></tr>
<tr><td><2019-10-25 Fri></td><td>Northern Lights</td><td>3</td><td>0</td><td>3</td><td>L</td><td>H</td><td>H</td><td>L</td><td>L</td><td>Y / very hard</td><td>Wonder</td><td>Y</td><td></td></tr>
<tr><td><2019-10-25 Fri></td><td>Oasis</td><td>3</td><td>0</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun, hard at first but easy once you start crushing</td><td>Conquest</td><td>Y</td><td></td></tr>
<tr><td><2019-10-28 Mon></td><td>Persian Highlands</td><td>2</td><td>1</td><td>3</td><td>L</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun, ditto</td><td>Wonder, needed 10 min to conquer</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-18 Tue></td><td>Persian Highlands - Spring</td><td>2</td><td>1</td><td>3</td><td>L</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun, easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-18 Tue></td><td>Persian Highlands - Summer</td><td>2</td><td>1</td><td>3</td><td>L</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun, easy</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-10-28 Mon></td><td>Phonecian Levant</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / square map, doesn’t work</td><td>QUIT</td><td></td><td></td></tr>
<tr><td><2019-10-28 Mon></td><td>Polar Sea</td><td>2</td><td>1</td><td>3</td><td>L</td><td>L</td><td>L</td><td>L</td><td>M</td><td>Y / naval trade</td><td>Wonder</td><td>N</td><td>SUCKED, 0 K/D ratio</td></tr>
<tr><td><2019-10-30 Wed></td><td>Pompeii</td><td>2</td><td>1</td><td>3</td><td>M</td><td>L</td><td>M</td><td>L</td><td></td><td>Y / hard to build anywhere which can give some players an advantage</td><td>Wonder, was just getting enough $ to start conquest</td><td>N</td><td>SUCKED, lost civ center</td></tr>
<tr><td><2019-10-30 Wed></td><td>Pyrenean Sierra</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y</td><td>LOST</td><td>Y</td><td>SUCKED</td></tr>
<tr><td><2019-10-30 Wed></td><td>Pyrenean Sierra</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>M</td><td>Y / hard depending on whether you can build bottlenecks or not</td><td>Wonder</td><td>Y</td><td>SUCKED</td></tr>
<tr><td><2019-10-31 Thu></td><td>Ratumacos</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / very hard</td><td>LOST</td><td>N</td><td>SUCKED, lost civ center twice</td></tr>
<tr><td><2019-11-02 Sat></td><td>Red Sea</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td>M</td><td>Y / very hard if placed in the middle</td><td>Wonder, needed time for conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-11-02 Sat></td><td>Rhine Marshlands</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>N / too much lag</td><td>QUIT</td><td>Y</td><td></td></tr>
<tr><td><2019-11-02 Sat></td><td>Rivers</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y / fun controlling half a map</td><td>Conquest</td><td>Y</td><td>SUCKED, died</td></tr>
<tr><td><2020-02-18 Tue></td><td>Rivers - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-18 Tue></td><td>Rivers - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-18 Tue></td><td>Rivers - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-19 Wed></td><td>Rivers - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>L</td><td>N / swarms of elephants</td><td>Wonder</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-20 Thu></td><td>Rivers - Savanna</td><td>2</td><td>1</td><td>3</td><td>M</td><td>H</td><td>H</td><td>H</td><td>L</td><td>N / tree disparity is annoying</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-22 Sat></td><td>Rivers - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>L</td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-02-23 Sun></td><td>Rivers - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>L</td><td>Y / fun</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
<tr><td><2020-02-23 Sun></td><td>Rivers - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td>L</td><td>Y / fun</td><td>Conquest</td><td>Wonder</td><td>Weak</td></tr>
<tr><td><2019-11-03 Sun></td><td>Saharan Oases</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td><2019-11-04 Mon></td><td>Sahel</td><td>2</td><td>1</td><td>3</td><td>L</td><td>M</td><td>M</td><td>M</td><td></td><td>Y / disconnected P2 immediately first try, but easy conquest second try</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2019-11-04 Mon></td><td>Sahel Watering Holes</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>M</td><td></td><td>Y / fun little pizza slices to own/defend</td><td>Conquest</td><td>Y</td><td>Mediocre</td></tr>
<tr><td><2019-11-06 Wed></td><td>Schwarzwald</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td>L</td><td>Y / fun for conquest, easy ram travel</td><td>Conquest</td><td>N</td><td>SUCKED, died</td></tr>
<tr><td><2019-11-06 Wed></td><td>Scythian Rivulet</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun, pretty easy for conquest if you attack early</td><td>Conquest</td><td>Y</td><td>Strong</td></tr>
<tr><td><2019-11-12 Tue></td><td>Snowflake Searocks</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / fun, easy to play turtle/defensive</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-02-23 Sun></td><td>Snowflake Searocks - Alpine</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun, hard if you block yourself off to the world early – can’t expand</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-02-23 Sun></td><td>Snowflake Searocks - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun, needed 5 more min to conquer (blew our wonder up)</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-02-23 Sun></td><td>Snowflake Searocks - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / fun, needed 2 min to conquer (blew our wonder up)</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-02-24 Mon></td><td>Snowflake Searocks - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / wood was sparse</td><td>Conquest</td><td>N</td><td>Strong</td></tr>
<tr><td><2020-02-24 Mon></td><td>Snowflake Searocks - Savanna</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / wood was sparse</td><td>Conquest</td><td>N</td><td>OK</td></tr>
<tr><td><2020-02-24 Mon></td><td>Snowflake Searocks - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y</td><td>Conquest</td><td>N</td><td>Strong</td></tr>
<tr><td><2020-03-01 Sun></td><td>Snowflake Searocks - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>Y</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-03-01 Sun></td><td>Snowflake Searocks - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>L</td><td></td><td>N / hard to move siege in</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2019-11-17 Sun></td><td>Stronghold</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>M</td><td></td><td>Maybe / difficult</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-03-04 Wed></td><td>Stronghold - Alpine</td><td>2</td><td>1</td><td>3</td><td>L</td><td>H</td><td>M</td><td>L</td><td></td><td>N / difficult, pretty annoying being frontline</td><td>Wonder</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-03-14 Sat></td><td>Stronghold - Alpine</td><td>2</td><td>1</td><td>3</td><td>L</td><td>M</td><td>M</td><td>L</td><td></td><td>N / quit because this sucks</td><td>QUIT</td><td>N</td><td>Weak, died</td></tr>
<tr><td><2020-03-14 Sat></td><td>Stronghold - Autumn</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>M</td><td></td><td>Y / was pretty easy being on the back civ and attacking early</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-03-14 Sat></td><td>Stronghold - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>M</td><td></td><td>Y / metal and wood rich, good battling</td><td>Conquest</td><td>N</td><td>Weak, died</td></tr>
<tr><td><2020-03-15 Sun></td><td>Stronghold - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>N / not as resource rich</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-03-15 Sun></td><td>Stronghold - Savanna</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>N / not as resource rich</td><td>Conquest</td><td>N</td><td>Weak</td></tr>
<tr><td><2020-03-15 Sun></td><td>Stronghold - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / resource rich</td><td>Conquest</td><td>N</td><td>Weak, died</td></tr>
<tr><td><2020-03-15 Sun></td><td>Stronghold - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / resource rich</td><td>Conquest</td><td>N</td><td>Strong</td></tr>
<tr><td><2020-03-15 Sun></td><td>Stronghold - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>L</td><td>L</td><td></td><td>N / sucked</td><td>QUIT</td><td>N</td><td>Weak, died</td></tr>
<tr><td><2019-11-17 Sun></td><td>Survival of the Fittest</td><td>2</td><td>1</td><td>3</td><td></td><td></td><td></td><td></td><td></td><td>Skipped, no point</td><td></td><td></td><td></td></tr>
<tr><td><2019-11-17 Sun></td><td>Syria</td><td>2</td><td>1</td><td>3</td><td>M</td><td>M</td><td>M</td><td>L</td><td></td><td>Y / very difficult</td><td>Wonder, needed a few min more for conquest</td><td>Y</td><td>Strong towards the end</td></tr>
<tr><td><2019-11-17 Sun></td><td>Volcanic Lands</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>L</td><td></td><td>Y / easy conquest</td><td>Conquest</td><td>Y</td><td>Meh</td></tr>
<tr><td><2019-11-17 Sun></td><td>Wild Lake</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>H</td><td>H</td><td>N / hard travel</td><td>Conquest</td><td>Y</td><td>Meh</td></tr>
<tr><td><2020-03-15 Sun></td><td>Wild Lake - Alpine</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>M</td><td>H</td><td>H</td><td>N / hard to move siege weapons</td><td>Conquest</td><td>Y</td><td>Meh</td></tr>
<tr><td><2020-03-23 Mon></td><td>Wild Lake - Autumn</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>H</td><td>H</td><td>H</td><td>N / map is annoying to build and move on</td><td>Conquest</td><td>Y</td><td>Meh</td></tr>
<tr><td><2020-03-28 Sat></td><td>Wild Lake - Desert</td><td>2</td><td>1</td><td>3</td><td>H</td><td>L</td><td>H</td><td>H</td><td>H</td><td>N / worst map. units get stuck, units take wrong paths, can’t rebuild walls</td><td>QUIT</td><td>Y</td><td>Weak, useless</td></tr>
<tr><td><2020-03-28 Sat></td><td>Wild Lake - Mediterranean</td><td>2</td><td>1</td><td>3</td><td>H</td><td>M</td><td>H</td><td>H</td><td>H</td><td>Y / better placement, could build inside iberian walls</td><td>Conquest</td><td>Y</td><td>Weak, died</td></tr>
<tr><td><2020-03-29 Sun></td><td>Wild Lake - Savanna</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>H</td><td>H</td><td>N / couldn’t find space for a wonder for most of game</td><td>Wonder</td><td>Y</td><td>Weak, useless</td></tr>
<tr><td><2020-03-29 Sun></td><td>Wild Lake - Snowy</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>H</td><td>H</td><td>Y / was much more fun and could actually build in more places</td><td>Conquest</td><td>Y</td><td>Weak</td></tr>
<tr><td><2020-03-29 Sun></td><td>Wild Lake - Temperate</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>H</td><td>H</td><td>N / sucked, hard to build and move units</td><td>Wonder</td><td>Y</td><td>OK</td></tr>
<tr><td><2020-03-29 Sun></td><td>Wild Lake - Tropic</td><td>2</td><td>1</td><td>3</td><td>H</td><td>H</td><td>H</td><td>H</td><td>H</td><td>N / metal piles were often sideways and un-mineable</td><td>Conquest</td><td>Y</td><td>OK</td></tr>
</table>
Returning Early from Map in Ruby2019-12-13T00:00:00-08:00http://www.jmdeldin.com/posts/2019/early-return-from-map-in-ruby<p>Here’s a quick tip: Use <code>next</code> with an argument to return the value
early from an iterator.</p>
<p>(For the following examples, imagine much more complicated API logic
than checking whether numbers are odd or even.)</p>
<p>We’re all used to <code>next</code> to skip to the next item in the list:</p>
<pre class="src" lang="ruby">
[1, 2, 3, 4, 5, 6].map { |x|
next if x.even?
x**2
}
#=> [1, nil, 9, nil, 25, nil]
</pre>
<p>but what if you want to return the value? Typically, you would wrap your
block in a conditional or use ternary:</p>
<pre class="src" lang="ruby">
[1, 2, 3, 4, 5, 6].map { |x|
if x.even?
x
else
x**2
end
}
#=> [1, 2, 9, 4, 25, 6]
</pre>
<p>Gross! Early returns (guard clauses) are all the rage, but how do you do
it in something like <code>map</code>?</p>
<pre class="src" lang="ruby">
[1, 2, 3, 4, 5, 6].map { |x|
next(x) if x.even?
x**2
}
#=> [1, 2, 9, 4, 25, 6]
</pre>
<p><code>:boom:</code></p>
Ruby URI.join Gotcha2019-06-04T00:00:00-07:00http://www.jmdeldin.com/posts/2019/ruby-uri-join-gotcha<p>Quick tip: Don’t be dumb and assume Ruby’s <code>URI.join</code> is like
<code>Array.join</code>. I made a seemingly innocent change to add some new
functionality to an old API:</p>
<pre class="src" lang="ruby">
URI.join("http://example.com", "/admin/important_base", "/some_endpoint_argument")
</pre>
<p>I expected this:</p>
<pre class="src" lang="ruby">
http://example.com/admin/important_base/some_endpoint_argument
</pre>
<p>but I got this instead:</p>
<pre class="src">
http://example.com/admin/some_endpoint_argument
</pre>
<h3>Options</h3>
<p><code>File.join</code> gives the closest functionality, as far as handling as
slashes intelligently:</p>
<pre class="src" lang="ruby">
File.join("http://example.com", "/admin/important_base/", "/some_endpoint_argument")
#=> "http://example.com/admin/important_base/some_endpoint_argument"
URI(_)
#=> #<URI::HTTP http://example.com/admin/important_base/some_endpoint_argument>
</pre>
<p>The other obvious candidates – <code>Array.join</code> or string concatenation –
require managing forward-slashes, which is what I was hoping to avoid
in the first place.</p>
Managing OpenSSL and Curl with Older Rubies2019-05-09T00:00:00-07:00http://www.jmdeldin.com/posts/2019/managing-older-openssl-and-curl-for-ruby<p>One of the projects I run for work uses Ruby 1.9 and will probably not
be upgraded to 2.x anytime soon. I’ve been running it inside a Vagrant
box with an older version of Ubuntu, but I finally upgraded the machine
only to die by a thousand tiny cuts. Here are a couple of tips if you’re
working with older Ruby software and sick of finding other people’s
stacktraces on the internet:</p>
<h3>OpenSSL</h3>
<p>Ruby < 2.3 is incompatible with OpenSSL 1.1+ and will not build. It’s an
easy fix:</p>
<pre class="src" lang="sh">
sudo apt install libssl1.0-dev
</pre>
<h3><code>libcurl4</code> / <code>libcurl4-openssl-dev</code> are incompatible with <code>libssl1.0-dev</code></h3>
<pre class="src" lang="sh">
sudo apt install libssl1.0-dev libcurl3 libcurl-openssl1.0-dev
</pre>
<p>Then <code>rbenv</code> or compile Ruby and you should be able to install Typhoeus
or other <code>libcurl</code> gems.</p>
<h3>Important</h3>
<p>The above commands work on Ubuntu <= 18.04 (Bionic Beaver). I have not
found a fix for 19.04 Disco Dingo yet.</p>
Freewheel Burning2019-04-22T00:00:00-07:00http://www.jmdeldin.com/posts/2019/freewheel-burning<p>At the end of February, I converted my commuter bike to a fixed-gear via
a flip-flop hub as an experiment, but I just reverted back to a
freewheel after almost 90 miles of riding. Here’s what I learned:</p>
<h3>The <b>best</b> parts about riding a fixie</h3>
<ol>
<li><b>You just keep pedaling.</b> It makes riding a lot more engaging and you
can’t zone out (safely). <i>It’s the purest form of riding, man.</i></li>
<li><b>Pedaling backwards</b> and actually going backwards was kind of fun, but
I didn’t achieve bike-polo competency nor did I do any sweet
<a href="https://www.youtube.com/watch?v=85ccyUWnUXo">fixed-gear freestyle</a>.
</li>
<li><b>It’s like learning to bike again.</b> It really is fun and made my
short commute a lot more exciting.</li>
</ol>
<h3>The <b>worst</b> parts about riding a fixie</h3>
<ol>
<li><b>Dealing with sudden change.</b> My city is not bike-friendly, so I
am often forced onto the sidewalk in busy parts. It is very natural
to coast and/or to stand when rolling down and up a sidewalk ramp.
This is a mistake on a fixie, as your pedals will keep going and you
will emit some kind of embarrassing <i>Wuh-woh-wuhh</i> noise and flail
as you try to stay on the bike. The same goes for bunny-hopping steel
plates or buckets of KFC chicken that are thrown at you.</li>
<li><b>Leaning into curves.</b> My commute has a short section of high speed
curves. Leaning into them is a guaranteed death.</li>
<li><b>Weaving between obstacles</b> (e.g., planters or bike lane hazards)
requires you to be mindful of your pedals. It is very easy to forget
that you can’t stop pedaling and <i>Oh, crap!</i> as you almost clip a
curb.</li>
<li><b>Trackstanding sucks</b>. I have been trackstanding (balancing in place)
a long time on trials bikes, commuters, BMX, etc. so I am used to
being able to rock back-and-forth and ratchet freely. It’s not fun at
all on a fixie. Furthermore, you have to plan where you’re going to
stop in order to have your good foot forward. More often than not, I
ended up in the pedestrian crosswalk at intersections.</li>
<li><b>Braking downhill and STILL pedaling.</b> Similarly, riding downhill
with your feet off the pedals because you’re going too fast and
cannot coast. Both scenarios are dumb.</li>
<li><b>Coasting on long rides.</b> It’s nice to get out of the saddle, but you
have to wait until you’re going slow enough that it’s safe to do so
and then <b>keep pedaling</b>.</li>
</ol>
<h3>Conclusion</h3>
<figure>
<img src="/images/bike/everett_marina_at_sunset.jpg" alt="Photo of the Puget Sound and Everett marina at sunset">
<figcaption>Puget Sound and Everett Marina at Sunset, taken on my final fixie ride.</figcaption>
</figure>
<p>The first time I tried a fixie was my neighbor’s bike in Portland; I
couldn’t make it out of the parking lot. When I was looking for a cheap
commuter bike a few years ago, I wanted a flip-flop hub so I could
entertain myself in the rainy winters since we lost our indoor bike park
(RIP Burlington Bike Park). The last few months have made plain old
commuting a lot more exciting, but my last longer ride convinced me to
revert back to a freewheel for the final reason above: coasting. Whether
it’s resting, stretching, or managing human parts that don’t like to be
squished in a seat for long, coasting is great!</p>
<p>Would I ride a fixie again? Definitely! I will probably convert back to
a fixed gear next winter, after I get my longer destination rides out of
the way this summer and fall. Maybe I’ll even learn how to play bike
polo.</p>
<h3>Appendix: Ride Data</h3>
<p>Most of my rides are pretty short trips to the gym and mostly downhill
(boring uphill home). My fiancée is just starting to ride road bikes, so
in the following table, there is some variation on the days she joined
me, although she has gotten much faster recently.</p>
<ul>
<li>23 rides, 88.28 mi, 7 h 41 min in the saddle</li>
<li>0 crashes</li>
<li>3 near death experiences to be chronicled in an <a href="https://en.wikipedia.org/wiki/The_OA">upcoming Netflix
season</a></li>
</ul>
<h4>Strava</h4>
<table>
<tr><th>Ride</th><th>Distance (mi)</th><th>Time (mm:ss)</th></tr>
<tr><td>2/27</td><td>3.03</td><td>11:38</td></tr>
<tr><td>2/27</td><td>3.24</td><td>17:34</td></tr>
<tr><td>2/27</td><td>1.86</td><td>08:47</td></tr>
<tr><td>2/28</td><td>3.19</td><td>16:25</td></tr>
<tr><td>2/28</td><td>3.10</td><td>23:28</td></tr>
<tr><td>3/13</td><td>4.48</td><td>20:35</td></tr>
<tr><td>3/13</td><td>5.23</td><td>43:50</td></tr>
<tr><td>3/15</td><td>6.24</td><td>36:27</td></tr>
<tr><td>3/18</td><td>3.10</td><td>14:07</td></tr>
<tr><td>3/18</td><td>3.05</td><td>20:23</td></tr>
<tr><td>3/20</td><td>3.13</td><td>13:21</td></tr>
<tr><td>3/20</td><td>3.50</td><td>23:40</td></tr>
<tr><td>3/22</td><td>3.12</td><td>12:57</td></tr>
<tr><td>3/22</td><td>3.08</td><td>22:47</td></tr>
<tr><td>4/12</td><td>3.25</td><td>11:51</td></tr>
<tr><td>4/12</td><td>3.19</td><td>16:53</td></tr>
<tr><td>4/15</td><td>3.18</td><td>11:36</td></tr>
<tr><td>4/15</td><td>3.18</td><td>21:00</td></tr>
<tr><td>4/17</td><td>3.14</td><td>10:36</td></tr>
<tr><td>4/17</td><td>3.14</td><td>16:07</td></tr>
<tr><td>4/19</td><td>3.12</td><td>11:32</td></tr>
<tr><td>4/19</td><td>3.07</td><td>18:05</td></tr>
<tr><td>4/19</td><td>13.66</td><td>57:22</td></tr>
</table>
Hyperspecific Solution to a Vagrant Authentication Failure2019-03-18T00:00:00-07:00http://www.jmdeldin.com/posts/2019/fixing-vagrant-authentication-failure<p>Like a fool, I upgraded my Ubuntu 18.04 machine to 18.10 over the
weekend because I needed a new LaTeX package and was too lazy to use
<code>tlmgr</code>. On Monday morning, I did my usual <code>make launch</code> and found eight
<code>tmux</code> windows reporting a similar message:</p>
<pre class="src" lang="sh">
==> core: Waiting for machine to boot. This may take a few minutes...
core: SSH address: 127.0.0.1:2222
core: SSH username: vagrant
core: SSH auth method: private key
core: Warning: Connection reset. Retrying...
core: Warning: Authentication failure. Retrying...
core: Warning: Authentication failure. Retrying...
:
: ...
core: Warning: Authentication failure. Retrying...
</pre>
<p>I don’t know if it’s because I haven’t restarted my computer in a month
or two and I’d been hiding the problem, or if it was an unrelated
update, but oh well.</p>
<p>After much grumbling, I figured out the problem and its trivial
solution. Notice how it says <code>SSH username: vagrant</code> above? It turns out
that the Ubuntu-packaged box I’m using configured its username to
<code>ubuntu</code>. Set <code>config.ssh.username</code> in your Vagrantfile and be done!
Better yet, provision a new box that doesn’t have this same issue.</p>
<h3>How do you find out the default credentials?</h3>
<ol>
<li>Note which box your <code>Vagrantfile</code> uses. Mine is <code>ubuntu/xenial64</code>.</li>
<li>Figure out which version of that box your machine is running with
some sloppy shell programming. This is really only needed if you have
multiple versions like me. The VM’s name in question is <code>core</code>, so
substitute whatever yours is below:
<pre class="src" lang="sh">
python -mjson.tool < ~/.vagrant.d/data/machine-index/index | grep core -A15 | grep version
"version": "20171208.0.0"
</pre>
</li>
<li>Armed with the version, figure out the username and password for the box:
<pre class="src" lang="sh">
grep ssh ~/.vagrant.d/boxes/ubuntu-VAGRANTSLASH-xenial64/20171208.0.0/virtualbox/Vagrantfile
config.ssh.username = "ubuntu"
config.ssh.password = "some_password"
</pre>
</li>
</ol>
<h3>How do you set the credentials?</h3>
<ol>
<li>Update your <code>Vagrantfile</code>:
<pre class="src" lang="ruby">
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
# ...
config.ssh.username = "ubuntu"
# optional, if you want to bypass logging in with a private key
# config.ssh.password = "some_password"
# ...
end
</pre>
</li>
<li>Restart your Vagrant box:
<pre class="src" lang="sh">
vagrant reload core && vagrant ssh core
</pre>
</li>
<li>Rejoice in your time lost to stupid computers. Get back to work.</li>
</ol>
Bluetooth Disappears on Wake2019-02-21T00:00:00-08:00http://www.jmdeldin.com/posts/2019/bluetooth-disappears-on-wake<p>Another day, another mysterious Linux issue in the middle of the
workday. I woke my laptop up from sleep to find I had no Bluetooth.
After restarting the service “successfully”, I still had no controllers
(i.e., my speakers) in <code>bluetoothctl</code>. After a lot of digging, I found
this <a href="https://bbs.archlinux.org/viewtopic.php?pid%3D1719775#p1719775">ArchLinux post</a> that blocked and unblocked bluetooth, and sure
enough, it worked! Turning it on and off again is still a valid
solution.</p>
<p>Here is the shell script with the last line modified for Ubuntu 18.04:</p>
<pre class="src" lang="sh">
rfkill block bluetooh
rfkill unblock bluetooth
sudo service bluetooth restart
</pre>
<p>The next problem with sleep/wake that I haven’t figured out is how to
get my virtual boxes to stop eating all my CPU on wake. Some day, I will
have a sane, “normal” laptop.</p>
Simple Electrolysis Tank Setup for Tool & Cast Iron Pan Restoration2018-05-22T00:00:00-07:00http://www.jmdeldin.com/posts/2018/simple-electrolysis-tank-for-tool-restoration<p>I was talking to one of my friends about how I’ve been restoring tools
and cast iron pans lately, so I made a short video of what my current
electrolysis tank looks like. Afterwards, I realized I should write up
my current setup for other woodworkers, tool collectors, and pan nerds.</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/DienxNuu_vc" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<h3>What is Electrolysis?</h3>
<p>From <a href="https://en.wikipedia.org/wiki/Electrolysis#Overview">Wikipedia</a>:</p>
<blockquote>
<p>Electrolysis is the passing of a direct electric current through an
ionic substance that is either molten or dissolved in a suitable
solvent, producing chemical reactions at the electrodes and a separation
of the materials.</p>
</blockquote>
<p>In practical terms: a simple, easy, and affordable way to remove rust
from garage sale finds.</p>
<h3>Materials</h3>
<ol>
<li>Manual car/boat/motorcycle battery charger. I picked an old NAPA one
from OfferUp for $15, but you can <a href="https://amzn.to/2L7R1ZJ">spend a little more</a> for a new one
and not deal with people on the internet. What you need is a charger
that does not have “automatic” or “smart” in the description. When
you plug it in, you should get a charge immediately.
<p>Note: If you see an old one with rusty positive/negative clamps, you
can replace them easily with a pair of wire strippers and a $5 set of
alligator clips from O’Reilly, NAPA, AutoZone, etc.</p>
</li>
<li>Anodes: Rebar or steel of some kind. I use a few 12-18” precut rebar
depending on the size of your tank (~$0.60/piece). These get
destroyed in the process, so it is a good idea to have extras on
hand. <b>DO NOT</b> use stainless steel for it can produce small amounts
of hexavalent chromium, which is toxic and illegal.</li>
<li>A bucket/tank of some kind. You can use an aquarium tank, a 2- or
5-gallon bucket, or a horse trough. Do not expect to use this for
anything else again though, as it will be quite stained with rust. I
started with a 2 gallon bucket, but the saw blades I wanted to
de-rust were too large, so I switched to an 18” paint roller bucket I
had in the basement. Not long after making the switch, I needed to
restore a huge cast iron wok, so I needed a larger tank. Fortunately,
I found a guy selling horse feeders for $1 at a garage sale.</li>
<li>Steel fencing wire to link the anodes together. You’ll also use this
to suspend your tool in the tank too. Buy this in the fencing
department of your home center for <$10 for a long spool.
<p>Note: Some people use insulated electrical wire, copper, and wire
nuts to link rebar together, but it’s a pain to change out in my
experience.</p>
</li>
<li>Electrolyte: Washing soda, AKA dishwasher detergent. Only use soaps
with sodium carbonate (not bicarbonate – baking soda) in them. I pay
~$2 at my grocery store.</li>
<li>Water. Just fill your tank with your garden hose.</li>
<li>Cutting pliers for cutting the fence wire</li>
<li>Slip-joint or needle nose pliers for twisting the fence wire (fencing
pliers would also work, but I don’t have any).</li>
<li>A multimeter is useful if you have to verify the setup, but it is not
required.</li>
</ol>
<h3>Setup</h3>
<ol>
<li>Find a location with good ventilation, preferably outside and near a
power outlet. Ensure it is safe from children, pets, and wildlife.
Electrolysis releases hydrogen into the air, which is flammable, so
do not do this indoors.</li>
<li>Install the rebar. You want the rebar to have “line of sight” with
the object you’re de-rusting. For example, if you have a rectangular
tank, put one piece of rebar in each corner of the tank. You will
then suspend your tool in the middle of the tank. If you have a round
tank, put all the rebar on one half (as close to the sidewalls as
possible) to make your life easier.
<p>Because I de-rust objects of variable sizes, I attach my rebar to a
set of broken BMX handlebars that I can shift in the tank as needed.</p>
</li>
<li>Fill the tank with enough water to cover your rusty object.</li>
<li>Add washing soda. A rule of thumb is 1 Tbsp per gallon, but more
won’t hurt (or help). Just pour some in.</li>
<li>Suspend your tool in the tank with wire. If you cannot cover the
entire tool with water, you can always flip it around and de-rust in
a second pass. <b>DO NOT</b> let the tool touch the rebar.
<p>If you have a scrap piece of wood, you can make a hook with wire and
hang your tool that way.</p>
</li>
<li>Connect the positive clamp to one of your rebar pieces.</li>
<li>Connect the negative clamp to the wire on your tool.</li>
<li>Turn on your battery charger.</li>
<li>You should see bubbles forming around your tool. If you do not, check
the gauge on the battery charger. I normally run my charger at 12V
and hit around 6 Amps. The amperage decreases as your piece becomes
less rusty.
<p>If you have a multimeter, check each piece of rebar. If your charge
is good, you may need to add some more sodium carbonate before you
start seeing bubbles.</p>
</li>
<li>Check back in awhile. I’ve found it takes 12 h for light rust, but
on heavily rusted hand planes, it is often 48 h. The great thing
about electrolysis is it’s self-regulating, so if you leave a tool
in the tank for a few extra days, it won’t be harmed, unlike with
vinegar.</li>
<li>Remove the tool and scrub the rust away with an abrasive sponge or
Scotch Brite pad.</li>
<li>If it’s a tool, polish, dry, and apply some sort of protectant like
<a href="https://amzn.to/2L85vJ5">3-in-1 Oil</a> or <a href="https://amzn.to/2JfqlIX">Autosol</a>. If it’s a cast iron pan, <a href="/cast/">wash and season</a>. I
never did anything with my chemistry degree, so I’m not sure why
some tools and pans seem to be prone to “flash” rusting, but I’ve
learned to be fast with the scrubbing to protecting phases.</li>
</ol>
<h3>Disposal</h3>
<p>If you’re restoring tools and pans, let’s face it: you’re going to keep
acquiring more projects. I recommend covering your tank with a tarp to
keep your wire and rebar from rusting when they’re not in use. That way
all you have to do is wire up your latest acquisition and connect the
battery charger.</p>
<p>You don’t need to dump the water out of your tank every time, or ever,
really. However, if you need to impress someone and don’t want a bucket
of sludge on your porch, you should carefully dump your tank out on a
patch of dirt/sand/gravel and not your lawn. Don’t dump it into the
storm runoff drains either.</p>
<h3>Examples</h3>
<p>Here’s a Stanley #4 I recently cleaned up:</p>
<figure>
<img src="/images/restoration/stanley-4/stanley-4-before.front.jpg" alt="Photo of the Stanley #4 front before restoration">
<figcaption>A bit rough</figcaption>
</figure>
<figure>
<img src="/images/restoration/stanley-4/stanley-4-before.side.jpg" alt="Photo of the Stanley #4 side before restoration">
<figcaption>Ugly cheeks.</figcaption>
</figure>
<figure>
<img src="/images/restoration/stanley-4/stanley-4-after.front.jpg" alt="Photo of the Stanley #4 front after restoration">
<figcaption>I tried keeping the yellow behind “Stanley”, but I accidentally nicked an edge with the wire wheel, so I had to finish it off.</figcaption>
</figure>
<figure>
<img src="/images/restoration/stanley-4/stanley-4-after.side.jpg" alt="Photo of the Stanley #4 side after restoration">
<figcaption>Cleaned up sides.</figcaption>
</figure>
<dl>
<dt>Body</dt><dd>Electrolysis tank for a few days, lots of scrubbing, sanding
and flattening of side and sole on sandpaper and diamond
stones. I used a coat of Autosol on the finish to prevent rust
(hopefully). I tried a clear coat Rustoleum, but I am not good
at spray painting, so I stripped it and started over.</dd>
<dt>Little parts</dt><dd>Vinegar bath and wire wheel polishing</dd>
<dt>Blade</dt><dd>Ground a new primary bevel, sharpened to 1200 grit on diamond
stone + leather strop</dd>
<dt>Brass parts</dt><dd>Barkeeper’s Friend, scrubbing, wire wheel</dd>
<dt>Wood parts</dt><dd>Sanding from 60 grit to 220 grit. Could have done more,
but I don’t care enough too, since this is just a plane
for me to use. I did a couple coats of boiled linseed
oil for finish too.</dd>
</dl>
View Display/Monitor Resolution in Linux2017-12-08T00:00:00-08:00http://www.jmdeldin.com/posts/2017/view-display-resolution<p>Feeling too lazy to look up your computer’s display specs? Type in the
following to get your resolution:</p>
<pre class="src" lang="sh">
xrandr --current | head -2
</pre>
<p>You’ll get something like this, but be mindful that the output can be
ludicrous sometimes:</p>
<pre class="src" lang="sh">
Screen 0: minimum 320 x 200, current 2560 x 1440, maximum 8192 x 8192
eDP-1 connected primary 2560x1440+0+0 (normal left inverted right x axis y axis) 310mm x 170mm
</pre>
Removing Chimney and Wallpaper2017-07-23T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-removing-chimney-and-wallpaper<p>We managed to remove three stories of chimney, a facade chimney, and way
too much wallpaper and wallboard. In photos:</p>
<h3>Chimney Removal</h3>
<p>Armed with a small sledgehammer, we started at the top. The roofers
removed the chimney to the roof line, so it was a bit easier. After
removing the wood paneling, we had easy access to the fire hazard of a
former chimney. I removed bricks while Nathan shuttled them to the
window and tossed them down, where Ron and Ethan loaded them into our
rented trailer. Repeat.</p>
<figure>
<img src="/images/remodel/2017-07-23/upstairs_chimney.jpg" alt="Upstairs chimney">
<figcaption>Removing the upstairs chimney.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/brick_toss.jpg" alt="Bricks tossed onto a tarp">
<figcaption>Tossing bricks out the window.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_abyss.jpg" alt="Inside of chimney">
<figcaption>Hoping we wouldn’t find Santa or a cat down here.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_to_kitchen.jpg" alt="Upstairs chimney mostly removed">
<figcaption>The bricks popped off so easily, often without whacking them.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_seat.jpg" alt="Looking down into the kitchen">
<figcaption>Made my way down into the kitchen.</figcaption>
</figure>
<p>It turned out the dining room chimney was a big fat phony, so we had two
chimneys to remove. Given the linoleum and wall paneling was attached to
this chimney, it <i>almost</i> makes sense now.</p>
<figure>
<img src="/images/remodel/2017-07-23/chimney_kitchen_foam.jpg" alt="Foam in the fireplace">
<figcaption>Seems legit.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_portal.jpg" alt="Portal to the dining room">
<figcaption>We can see into the dining room now.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_kitchen_progress.jpg" alt="Kitchen chimney progress">
<figcaption>So much creosote.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_rat.jpg" alt="Charbroiled rat">
<figcaption>Thankfully, I did not find a large dead mammal, but I did find a charbroiled rat.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_to_kitchen_gone.jpg" alt="No more kitchen chimney">
<figcaption>Made a giant mess, but the chimney is gone in the kitchen. </figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_to_basement.jpg" alt="Chimney stud">
<figcaption>Deleted the chimney down to the concrete pillar it was atop of.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_basement_shooting_up.jpg" alt="No more chimney">
<figcaption>No more chimney! (Shot from basement to the upstairs.)</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/moscow.jpg" alt="Moscow brick">
<figcaption>Probably Moscow, ID, brick.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/chimney_selfie.jpg" alt="Chimney selfie">
<figcaption>Since Cat was at work, I sent her a picture of my ash.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/winston_curl.jpg" alt="Winston's lip curl">
<figcaption>Winston and Shep spent most of today in jail.</figcaption>
</figure>
<h3>Facade Chimney</h3>
<p>With the real chimney out of the way, we tore apart the considerably
more difficult facade chimney. I don’t know why you would build a
useless chimney, but they built it with much better mortar and brick
than the real one. I posted an ad on Craigslist and had some strange man
pick up some of our red brick (picky bastard), so at least we didn’t
have to trash it all.</p>
<figure>
<img src="/images/remodel/2017-07-23/facade_chimney.jpg" alt="Facade chimney before destroying it">
<figcaption>Here is the facade chimney before we tore it down.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/facade_no_more.jpg" alt="Facade chimney after destroying it">
<figcaption>And after.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/new_hallway.jpg" alt="New hallway into kitchen">
<figcaption>Our new entry/gaping hole into the kitchen and basement.</figcaption>
</figure>
<h3>Paneling and Boards</h3>
<p>We also removed a bunch of wallpaper and paneling:</p>
<figure>
<img src="/images/remodel/2017-07-23/no_wallboard.jpg" alt="No wallboard in office">
<figcaption>No more paneling in the office.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-23/run.jpg" alt="RUN, inscribed in the wallpaper">
<figcaption>RUN. Way to bury the lede. We found this under a few layers of wallpaper.</figcaption>
</figure>
<h2>Conclusion</h2>
<figure>
<img src="/images/remodel/2017-07-23/wallpaper_free.jpg" alt="Photo of dining room sans wallpaper">
<figcaption>Our very open dining room.</figcaption>
</figure>
Removing Wallboard and Linoleum2017-07-22T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-destruction<p>Cat’s brother, Ethan, came up from Oregon with a big truck, so under his
and Ron’s guidance, we destroyed the house further by ripping off a
bunch of wallboard and linoleum.</p>
<figure>
<img src="/images/remodel/2017-07-22/ripping_walls.jpg" alt="Ripping wallboard off">
<figcaption>Ethan, Ron, and Nathan ripping wallboard off </figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-22/layers_of_wallboard.jpg" alt="Layers of wallboard">
<figcaption>Layers of wallboard. The paneling on the left was underneath the style on the right. Underneath all that is layers of wallpaper.</figcaption>
</figure>
<p>The dining room is/was carpet on top of linoleum. We used a spade
(“spud” tool) to remove all the linoleum and the subfloor that was
constructed atop the tile floor.</p>
<figure>
<img src="/images/remodel/2017-07-22/partial_destruction.jpg" alt="Dining room destruction">
<figcaption>Dining room destruction. We used the spud tool (pictured) to remove the linoleum and subfloor, only to find tile underneath.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-22/removing_linoleum.jpg" alt="Removing linoleum with a spud tool">
<figcaption>Nathan removing lineoleum with the spud tool. The key is to catch an edge and drive the spud tool all the way forward like a football player. If done correctly, you will end up with a neat spiral of linoleum.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-22/no_more_linoleum-1.jpg" alt="No more linoleum">
<img src="/images/remodel/2017-07-22/no_more_linoleum-2.jpg" alt="No more linoleum">
<img src="/images/remodel/2017-07-22/no_more_linoleum-3.jpg" alt="No more linoleum">
<figcaption>No more linoleum</figcaption>
</figure>
<p>Unfortunately, the next layer of flooring is tile set in tar.</p>
Re-Roofing Begins2017-07-21T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-roofing-begins<p>The roofers were unable to schedule us earlier, so they removed our
unsafe chimney off at the roof line for free. Ron arrived tonight too!</p>
Incensed by Incense2017-07-20T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-walls<p>Ron is coming out from Montana to save our bacon! Without having clear
direction, we tried to remove the sickly sweet incense odor in the
master bedroom wood paneling to no avail (soapy water and then vinegar
water). No dice.</p>
Idling2017-07-19T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-idling<p>We didn’t do much work today, as we’re somewhat stalled. Some
highlights:</p>
<ol>
<li>After consulting Ron and my mom over the phone, our walls may not be
as dire it seemed last night. We can install drywall and texture over
the wood boards. (We briefly thought there was some plaster [the
colored wall parts], but it is just wallpaper.)</li>
<li>We need to hire an electrician to modernize some of our now exposed
outlets. There are a number of ungrounded outlets in the main floor,
so hopefully it won’t be a ton of money to deal with, even though the
wiring was done by Edison.</li>
<li>“Installed” a hygrometer in the basement (i.e., put a battery in a
cheap device) to monitor the humidity. I should’ve done this before I
removed all the dirt, but this hasn’t been a very regimented project.</li>
<li>We hypothesize the dining room is raised due to underlayment or
something under the linoleum. Based on the living room and main floor
bedrooms having original wood flooring, it seems like the dining room
would as well. We’re going to leave it alone in case it’s asbestos
flooring for now, but it would be great if we didn’t need to deal
with leveling the rooms after all.</li>
<li>Further, the suspected asbestos ceiling tiles may be newer, as it
seems like a continuous sheet. Perhaps the original plaster is
underneath, and this was just a poor design decision somewhere
between 1925 and now.</li>
<li>A floor install is coming out next Tuesday to measure for carpet and
laminate flooring.</li>
</ol>
<p>Thankfully, we were able to extend our apartment lease, which transfers
the burden of remodeling while living in the house and puts it on our
budget instead.</p>
<ol>
<li>Drywall, texture, and paint walls. If we can redo the crummy tile
ceiling too, that would be swell.</li>
<li>If there is wood floor in the dining room, then perhaps we will patch
and refinish it all to save some money and have a better product,
since Winston slides so much on laminate.</li>
<li>Replace carpet upstairs and in bedrooms (lower bedrooms may stay as
wood floor – depends on dining room).</li>
<li>Modernize electrical as much as we can (afford).</li>
<li>Replace stupid, ugly, disgusting, bulky baseboard heaters with wall
heaters.</li>
</ol>
<figure>
<img src="/images/remodel/day5/new_blinds.jpg" alt="Photo of our new blinds">
<figcaption>Our new curtains.</figcaption>
</figure>
<figure>
<img src="/images/remodel/day5/newspaper.jpg" alt="Photo of newspaper shoved inside window trim">
<figcaption>Here’s a closeup of the newspaper clippings packed under the windows. We are curious if we can find a date, but we do not want to bring the whole house down by pulling this sheet out.</figcaption>
</figure>
<figure>
<img src="/images/remodel/day5/pit.jpg" alt="Photo of our pit to the crawl space">
<figcaption>Since we took the walls off yesterday, we figured we’d take the flimsy panel hiding the hole to the crawl space for a better look.</figcaption>
</figure>
<figure>
<img src="/images/remodel/day5/dining_room_width.jpg" alt="Photo of our living room wall panel width">
<img src="/images/remodel/day5/living_room_width.jpg" alt="Photo of our living room wall panel width">
<figcaption>The plank widths for the underlying walls are different in the dining room (above) and living room.</figcaption>
</figure>
Wall Hell2017-07-18T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-walls-of-garbage<p>In short:</p>
<blockquote class="imgur-embed-pub" lang="en" data-id="fSYHh0T"><a href="//imgur.com/fSYHh0T">I've made a huge mistake</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
<p>We made an appointment to get our house measured by a Lowe’s floor
installer today, picked out a laminate floor and carpet, and chose some
paint colors for the living and dining rooms. We felt like we were
making progress and that <i>maybe</i> we could make our deadline of the end
of the month for remodeling and moving in.</p>
<figure>
<img src="/images/remodel/2017-07-18/flooring_samples.jpg" alt="Photo of laminate floor and carpet samples">
<figcaption>We think this laminate floor and carpet will work.</figcaption>
</figure>
<p>Then we started painting, and things started bending, and things started
falling off.</p>
<figure>
<img src="/images/remodel/2017-07-18/garbage_floor.jpg" alt="Photo of our terrible floor">
<figcaption>Nice floor patch job. Notice the huge gaps by the former baseboards too. Why are they concave?</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-18/no_90s.jpg" alt="Photo of a 90 degree stopper">
<figcaption>Originally, I thought this crown moulding was decorative, albeit sloppy. It is actually hiding the fact that the paneling does not touch the other wall.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-18/fireplace_hole.jpg" alt="Photo of a hole in our chimney">
<figcaption>This hole into the chimney (?) was literally stuffed with toilet paper. Also, somehow the paneling is squeezed behind the chimney.</figcaption>
</figure>
<p>Finally, I suggested we just rip the crappy fake paneling off because it
felt like we were – pardon the Palin – putting lipstick on a pig if we
were to paint over some shoddy work.</p>
<figure>
<img src="/images/remodel/2017-07-18/family_pre.jpg" alt="Photo of our room with the paneling">
<figcaption>Before we made a regrettable decision</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-18/family_post.jpg" alt="Photo of our room with a torn up wall">
<figcaption>After our regrettable decision. There is a mix of creepy wallpaper, actual wood, and plaster.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-18/ancient.jpg" alt="Photo of terribly old wiring">
<figcaption>I don’t think I want to power any devices with this outlet.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-18/wtf_outlet.jpg" alt="Photo of an unknown ancient outlet">
<figcaption>What is this ancient outlet for? The switchplate was painted over, but we have no idea what this is.</figcaption>
</figure>
<p>Having made a giant mess of the living room, we went ahead and tried to
shoot moon:</p>
<figure>
<img src="/images/remodel/2017-07-18/before_chaos.jpg" alt="Before chaos">
<figcaption>Dining room before destruction. (We had started painting the paneling.)</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-18/after_chaos.jpg" alt="After chaos">
<figcaption>Dining room after destruction</figcaption>
</figure>
<p>We have now made a giant mess.</p>
<figure>
<img src="/images/remodel/2017-07-18/dining_to_family.jpg" alt="Photo from the dining room to family room">
<figcaption>Dining room to family room: Pure Mess</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-18/family_to_dining.jpg" alt="Photo from the family room to the dining room">
<figcaption>Family room to dining room: More Mess</figcaption>
</figure>
<p>I feel like we’ve ripped a cuticle in trying to trim our nails, and now
we’ve lost the entire fingernail.</p>
Overzealous Carpet Pulling2017-07-17T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-overzealous-carpet-pulling<p>Today was relatively light. Cat and Nathan returned from vacation, so we
went over to the house, and one thing led to another, and we pulled up
most of the carpet in the main area. We found some “interesting”
woodwork, like a gaping hole to the basement instead of subfloor that
was obscured by the carpet before.</p>
<figure>
<img src="/images/remodel/2017-07-17/subfloor_abyss1.jpg" alt="Photo of our subfloor hole">
<figcaption>We are hesitant to peek behind this flimsy piece of board.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-17/subfloor_abyss2.jpg" alt="Photo of our subfloor hole">
<figcaption>Subfloor? Never knew ya.</figcaption>
</figure>
<p>We measured every room, so our plan – funds permitting – is to replace
the living room and dining room with laminate floor and re-carpet the
bedrooms and upstairs with a pet-friendly, stain-resistant carpet. Tile
would be ideal since we have a puppy and a senior dog, but it’s $5.50/sq
ft to install according to Home Depot. Hopefully, we can find a laminate
that will be textured enough for Winston. Bamboo is also an option, but
it sounds somewhat finicky with expansion, so I am hesitant to add weird
stuff to a weird house.</p>
<figure>
<img src="/images/remodel/2017-07-17/carpet.jpg" alt="Photo of torn up carpet">
<figcaption>We have hardwood floor in the living room, master bedroom, and office. Linoleum under carpet in the dining room.</figcaption>
</figure>
Dungeon Extraction2017-07-16T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-dungeon-extraction<p>More basement work, more hardware store purchases. I ran by the house to
begin airing it out after yesterday’s bug bombs, which meant I had time
to kill. I returned my super-wimpy-not-sure-why-they-bother-selling-it
air compressor (0.6 CFM, 1/3 HP, 100 PSI) to Harbor Freight and upgraded
to a larger one. Perhaps they make all their money in the restocking
fees. The new one is much nicer and can actually blow dust away, so it
could be handy in the basement, but mainly, it can actually do its job
of blowing up tires and of blowing grips on and off.</p>
<figure>
<img src="/images/remodel/2017-07-16/backyard.jpg" alt="Photo of Shep and Winston relaxing">
<figcaption>Shep and Winston relaxing in the yard</figcaption>
</figure>
<p>The dirt mound was too large for a broom, so I invested in some shovels
and dust masks. Since I don’t have a wheelbarrow and since the basement
is down a steep set of stairs, I used recycling bins to transfer dirt to
the yard. After filling 10 of them, I finally have a relatively level,
75 sq ft area of dirt in my basement. (I am glad I’ve been doing
deadlifts at the gym lately.) It’d be nice to concrete this in, but that
will have to wait until we have more time/funds.</p>
<figure>
<img src="/images/remodel/2017-07-16/dirt_moving.jpg" alt="Photo of a pile of dirt">
<figcaption>Moving dirt and finding brick floor.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-16/helpers.jpg" alt="Photo of Shep and Winston aiding in dirt removal">
<figcaption>My helpers for the day.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-16/complete.jpg" alt="Photo of basement completed">
<figcaption>Winston, enjoying the now-level 75 sq ft of dirt and brick.</figcaption>
</figure>
Keys!2017-07-15T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-keys<p>I met our real estate agent at the house at 08:00 and picked up our
multiple unlabeled keys. I’m a homeowner now and a bit overwhelmed, but
at least the previous owner left behind some treasure:</p>
<ul>
<li>cones</li>
<li>circular saw (unsure if it works)</li>
<li>trash cans and recycling bins (yay!)</li>
<li>pallets (maybe good for DIY wall rides)</li>
<li>blankets in the basement (for culturing mold)</li>
<li>surround sound system minus power and receiver (not really sure what
is needed to connect everything)</li>
<li>second fridge in basement with a sausage in it</li>
<li>washer and dryer</li>
<li>free-standing storage cabinets</li>
<li>table and chairs with extension leaves (future game table)</li>
</ul>
<p>Cat was out of town, so I worked on the basement to remove the heaps of
dirt in it and to remove the general serial killer feeling.</p>
<figure>
<img src="/images/remodel/2017-07-15/basement_pano.jpg" alt="Photo of our scary basement">
<figcaption>This is our scary basement.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-15/dejunk.jpg" alt="Photo of back of house with junk out">
<figcaption>All the junk from the basement</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-15/jail.jpg" alt="Photo of Shep and Winston in jail">
<figcaption>Jail time. Our tiny decrepit patio is good for something.</figcaption>
</figure>
<p>There is so much dirt in this one corner, and under a bit of it, some
brick and mortar. I don’t know why there is no cement here. Did the
original owners just run out and call it a day? Were they growing
potatoes? Is grandma buried here?</p>
<figure>
<img src="/images/remodel/2017-07-15/progress.jpg" alt="Photo of basement pit progress">
<figcaption>I’ve made some progress on the hell corner, but I need to procure a shovel.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-15/stuck.jpg" alt="Photo of Shep stuck behind the washer">
<figcaption>Shep managed to get stuck behind the washer within a few minutes of entering his new house.</figcaption>
</figure>
<figure>
<img src="/images/remodel/2017-07-15/winston.jpg" alt="Photo of Winston smiling in the Durango">
<figcaption>Winston enjoying shotgun privileges (revoked after this ride).</figcaption>
</figure>
Closing2017-07-14T00:00:00-07:00http://www.jmdeldin.com/posts/2017/house-closing<p>Our lender moved closing up a week, which was great! I rushed to
Kirkland to sign my name a hundred times for various liabilities I’d
already e-signed a month prior, and then I received a giant paper copy
of all those things that I already had digital copies of. Once we get
the recording numbers (title things?), we will get keys.</p>
<p>It was quite anticlimactic, but I got to visit Kirkland for the first
time, and after driving 405 S at lunchtime, hopefully the last time.</p>
Taking a Screenshot with Just X2017-01-09T00:00:00-08:00http://www.jmdeldin.com/posts/2017/taking-a-screenshot-with-just-X<p>Working on making an ultra lean Linux machine and can’t bear the idea of
installing <code>scrot</code> or another program for taking screenshots? Fear not!
You probably already have <code>x11-utils</code> installed, so you can do this:</p>
<ol>
<li><code>xwininfo</code> and click the window you want to take a screenshot of.
This will give you the window ID. Commit this hex value to memory.</li>
<li><code>import -window that_last_hex_value /tmp/screenshot.png</code></li>
</ol>
<p>Or more simply, as a function:</p>
<pre class="src" lang="sh">
function screenshot {
id=$(xwininfo | fgrep 'Window id' | awk '{print $4}')
import -window "$id" "$1"
}
screenshot /tmp/screenshot.png
</pre>
Showing sunrise and sunset information in Emacs2016-11-21T00:00:00-08:00http://www.jmdeldin.com/posts/2016/sunrise-and-sunsets-in-emacs<p>As days get shorter and shorter, I find myself wondering when the sun
will set at whichever skatepark I plan on visiting. In the past,
Googling “sunrise|sunset <location>” sufficed, but I wanted something
that ran locally and automatically on my Linux machine, and like any
Emacs user, I wanted it to run inside Emacs. As it turns out, this
functionality is already built into Emacs’ diary feature.</p>
<h3>The finished product</h3>
<figure>
<img src="/images/emacs_sunrise.png" alt="Screenshot of Emacs showing sunrise and sunset times in an agenda buffer.">
<figcaption>The Pacific Northwest certainly has its perks, but short, gray days are not one of them.
</figcaption>
</figure>
<h3>Steps</h3>
<ol>
<li>If you haven’t set Org-mode up already, you should edit your
<code>~/.emacs.d/init.el</code> and add the following lines:
<pre class="src" lang="emacs-lisp">
(setq org-directory "/tmp/org")
(setq org-agenda-files (file-expand-wildcards org-directory))
</pre>
</li>
<li>Specify your latitude and longitude in the next chunk. You can use
<a href="http://maps.google.com">Google Maps</a> or <a href="http://www.latlong.net/">LatLong</a> to find out:
<pre class="src" lang="emacs-lisp">
(setq calendar-latitude 47.9790)
(setq calendar-longitude -122.2021)
(setq calendar-location-name "Everett, WA")
</pre>
</li>
<li>Modify one of your Org agenda files specified in #1, e.g.,
<code>/tmp/test.org</code>:
<pre class="src" lang="org">
* Calendar
%%(diary-sunrise-sunset)
</pre>
</li>
<li>Save/reload your init file, then execute <code>M-x org-agenda</code>, press <code>a</code>.
<i>Tip</i>: To see the sunrise/sunset times for the entire year (and to
get depressed about winter): <code>M-x org-agenda RET a v y</code></li>
</ol>
Calculating business days in Emacs2016-11-13T00:00:00-08:00http://www.jmdeldin.com/posts/2016/emacs-business-days<p>I do all of my client invoicing inside Emacs, and one thing I keep track
of is an expected payment date, which is the invoice date plus
NET15/NET30/etc. terms (i.e., 15 business days after the invoice date).
Until now, it’s been a rough guess, but thanks to Emacs <code>calc</code>, it is
now more precise.</p>
<p>For calculating the current date + some number of business days:</p>
<ol>
<li><code>M-x calc</code></li>
<li>Type <code>'</code> to start an algebraic entry</li>
<li>Enter your starting date with angle brackets, e.g., <code><2016-11-01></code>.
Hit return.</li>
<li>Enter the number of business days, e.g., <code>15</code>. Hit return.
<img src="/images/emacs_calc_pre.png" alt="Screenshot of Emacs calc buffer with only data entered.">
</li>
<li>Type <code>t +</code> (or use <code>M-x calc-business-days-plus</code>)
<img src="/images/emacs_calc_post.png" alt="Screenshot of Emacs calc buffer after computing the business day offset.">
</li>
</ol>
<p>For more info, see the <a href="https://www.gnu.org/software/emacs/manual/html_node/calc/Business-Days.html">manual</a> and <a href="http://nullprogram.com/blog/2009/06/23/">Chris Wellons’ post about calc</a>.</p>
Counting the number of XML elements with REXML and XPATH2016-09-22T00:00:00-07:00http://www.jmdeldin.com/posts/2016/counting-xml-elements-with-ruby-stdlib<p>Sometimes you need a quick-and-dirty way of counting some elements, but
not as dirty as calling out to shell and using <code>grep</code> and <code>wc</code> on it
(e.g., <code>grep '<resident>' my.xml | wc -l</code>). Imagine you have the
only have the Ruby standard library available and wish to count the
number of <code><resident></code> elements:</p>
<pre class="src" lang="ruby">
require "rexml/document"
xml = <<EOF
<?xml version="1.0" encoding="utf-8"?>
<residents>
<resident name="Foo"/>
<resident name="Bar"/>
<resident name="Baz"/>
</residents>
EOF
doc = REXML::Document.new(xml)
REXML::XPath.first(doc, "count(//residents/resident)")
#=> 3
</pre>
Show all Chromebook WiFi passwords2016-06-12T00:00:00-07:00http://www.jmdeldin.com/posts/2016/show-chromebook-wifi-passwords<p>Note: This cannot recover the WiFi password used in setup. Additionally,
you must have Crouton installed.</p>
<ol>
<li><code>Ctrl-Alt-T</code></li>
<li><code>shell</code></li>
<li>Run the following:</li>
</ol>
<pre class="src" lang="sh">
egrep '(Name|Passphrase)=' $(sudo find /home/root -name shill.profile) |
while read l; do
[[ $l =~ Passphrase=* ]] &&
echo $(echo $l | awk -F rot47: '{print $2}' | tr '!-~' 'P-~!-O') || echo $l;
done
</pre>
Mounting an encrypted drive in Ubuntu2016-06-11T00:00:00-07:00http://www.jmdeldin.com/posts/2016/mounting-an-encrypted-drive-in-ubuntu<p>My laptop recently died (System76 Galago Ultra), but thankfully, it
wasn’t a drive failure. However, recovering the data proved harder than
I thought due to the full-disk encryption. What follows is annotated
output from my <code>script</code> session.</p>
<h3>Requirements</h3>
<dl>
<dt>Original drive</dt><dd>I had an encrypted disk for my main hard drive -
when I set up Ubuntu 15.10, I checked “full-disk
encryption” and didn’t customize the partitions,
i.e., my <code>/boot</code>, <code>/home</code>, etc., were all on the
same partition. As I found out later, I had
apparently made an LVM-encrypted drive too.</dd>
<dt>Recovery laptop</dt><dd>I used a Chromebook with an Ubuntu 16.04 chroot via
Crouton.</dd>
<dt>Drive enclosure</dt><dd>I picked up two cheap USB 3.0 enclosures - <a href="http://amzn.to/2e52VUU">one
for my primary (SATA) drive</a> and <a href="http://amzn.to/2e1Q3O5">another for my small mSATA
drive</a>).</dd>
</dl>
<h3>Recovery</h3>
<p>After many failed attempts, the basic process is:</p>
<ol>
<li>Find the drive identifier</li>
<li>Decrypt the drive</li>
<li>Deal with LVM</li>
<li>Mount the drive</li>
</ol>
<p>On your recovery system, open a terminal, switch to root (<code>sudo su</code>),
and begin. I recommend using <code>script</code> to record your commands so
you’ll have a record of your steps for the future.</p>
<h4>Find the encrypted drive</h4>
<pre class="src" lang="sh">
# lsblk -f /dev/sda
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
|-sda1 ext2 a1e8f1af-1849-49f4-8b6b-3c157e4f1f72 /var/host/media/removable/USB Drive 1
|-sda2
`-sda5 crypto_LUKS a16056e1-631e-47d1-8eaf-da8e8d72df94
# lsblk -f /dev/sda5
NAME FSTYPE LABEL UUID MOUNTPOINT
sda5 crypto_LUKS a16056e1-631e-47d1-8eaf-da8e8d72df94
</pre>
<p>(As an aside, I had a swap partition that was encrypted, but it was
cluttering the results, so I deleted it with LVM in one of my earlier
attempts.)</p>
<h4>Decrypt the drive</h4>
<pre class="src" lang="sh">
# cryptsetup luksOpen /dev/sdb5 garbage
Enter passphrase for /dev/sda5:
</pre>
<p>Double-check that it succeeded:</p>
<pre class="src" lang="sh">
(xenial)root@localhost: /home/jmdeldin # echo $?
0
</pre>
<h4>LVM</h4>
<p>Unfortunately, now we need to deal with LVM.</p>
<p>Find out our volume group name with <code>vgdisplay</code>:</p>
<pre class="src" lang="sh">
# vgdisplay
/run/lvm/lvmetad.socket: connect failed: No such file or directory
WARNING: Failed to connect to lvmetad. Falling back to internal scanning.
--- Volume group ---
VG Name ubuntu-vg
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 238.23 GiB
PE Size 4.00 MiB
Total PE 60987
Alloc PE / Size 56910 / 222.30 GiB
Free PE / Size 4077 / 15.93 GiB
VG UUID lIcU2S-NJ3d-gAPj-wIwP-3pJ9-F9LC-2X4akS
</pre>
<p><code>lvmetad</code> wasn’t running, and the internal scanning process had
failed every other time. After a quick <code>man lvmetad</code>, fire it up:</p>
<pre class="src" lang="sh">
# lvmetad
</pre>
<p>Check <code>vgdisplay</code> again:</p>
<pre class="src" lang="sh">
# vgdisplay
--- Volume group ---
VG Name ubuntu-vg
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 4
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 238.23 GiB
PE Size 4.00 MiB
Total PE 60987
Alloc PE / Size 56910 / 222.30 GiB
Free PE / Size 4077 / 15.93 GiB
VG UUID lIcU2S-NJ3d-gAPj-wIwP-3pJ9-F9LC-2X4akS
</pre>
<p>Success! Let’s get information about the volume:</p>
<pre class="src" lang="sh">
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root ubuntu-vg -wi------- 222.30g
</pre>
<p>Activate the volume:</p>
<pre class="src" lang="sh">
# lvchange -ay ubuntu-vg/root
# echo $?
0
</pre>
<p>Use <code>vgscan</code> to create the necessary <code>/dev/</code> links:</p>
<pre class="src" lang="sh">
# vgscan --mknodes
Reading all physical volumes. This may take a while...
Found volume group "ubuntu-vg" using metadata type lvm2
The link /dev/ubuntu-vg/root should have been created by udev but it was not
found. Falling back to direct link creation.
</pre>
<p>Confirm the volume is now active:</p>
<pre class="src" lang="sh">
# lvscan
ACTIVE '/dev/ubuntu-vg/root' [222.30 GiB] inherit
</pre>
<h4>Mount the drive</h4>
<p>Finally!</p>
<pre class="src" lang="sh">
# mkdir /media/old
# mount /dev/ubuntu-vg/root /media/old
# ls /media/old/home
jmdeldin
</pre>
Just Enough Air Pressure2015-09-09T00:00:00-07:00http://www.jmdeldin.com/posts/2015/just-enough-air-pressure<p><figure>
<img width="100%"
src="/images/just_enough_air.jpg"
alt="Photo showing low tire pressure compression in bike trials"/>
<figcaption>
30 PSI, 24" Kenda Kiniptions, and a generic tube leave just enough
room for a flat-free pedal kick. This strikes a decent balance between
pop and responsiveness while minimizing pinch flats when riding
street. (20 PSI is fine for my backyard
“<a href="https://instagram.com/p/1uOdF-OaLu/?taken-by=jmdeldin">course</a>”.)
</figcaption>
</figure></p>
<p>The source of the still:</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/7W0GtYOaGD/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">A scrappy, headless clip of one of my favorite features in Portland. It's always fun to return to this after riding brakeless #bmx for awhile. #portland #downtown #pdx #biketrials</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-09-08T04:37:52+00:00">Sep 7, 2015 at 9:37pm PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
Assorted Tiny BMX Clips2015-09-09T00:00:00-07:00http://www.jmdeldin.com/posts/2015/assorted-tiny-clips<p>Just another vacuous roundup of Instagram clips.</p>
<p>One of the best views:</p>
<blockquote class="instagram-media" data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://instagram.com/p/6CYG14OaCH/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_top">A photo posted by Jon-Michael Deldin (@jmdeldin)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-08-06T09:37:01+00:00">Aug 6, 2015 at 2:37am PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
<p>A silly way to damage a phone:</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/668JAkOaEk/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">Relaxing way to finish a Thursday @lumberyardmtb. (See also: making disaster stalls into disasters for my phone. #shouldvehadatripod) #portland #bmx #lumberyardmtb</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-08-28T08:49:21+00:00">Aug 28, 2015 at 1:49am PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
<p>Bunnyhops never get old:</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/7GoqS5uaMj/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">One of my favorite stupid bunnyhop transfers @lumberyardmtb. Thanks to @posumstix for shooting and @shaunmmartin for showing me this line almost two years ago. Can't believe it's been this long! So happy to have been adopted by a bike hooligan family since moving here. #bmx #lumberyardmtb #portland</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-09-01T21:50:01+00:00">Sep 1, 2015 at 2:50pm PDT</time></p></div></blockquote>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/7PlEr_uaAq/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">Moving/rolling bench to handicap ramp hop. Just a BMX nightcap to finish off a great day and night! #bmx #portland #stupidgap</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-09-05T09:11:50+00:00">Sep 5, 2015 at 2:11am PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
<p>A few attempts at pedal stalls. I’ll be back with a vengeance (and shin
pads):</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/7Ne6NVyPnT/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">JMD sessioning pedal stalls last night at the Lumberyard. The prize was an elusive one, but that's why it's called sessioning, right? To be continued... #bmx #ridebmx #ridemore #ridelikeagirl #session #makeawesomehappen @lumberyardmtb @jmdeldin</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by @theumabomber on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-09-04T13:39:30+00:00">Sep 4, 2015 at 6:39am PDT</time></p></div></blockquote>
Deep Fetching Keys in Ruby Hashes2015-08-21T00:00:00-07:00http://www.jmdeldin.com/posts/2015/deep-fetching-hashes-in-ruby<p>Have you ever wished Ruby had a simple way to “deep
<a href="http://ruby-doc.org/core-2.2.0/Hash.html#method-i-fetch">fetch</a>” a key
from a hash table? I’ve re-implemented <code>Hash#deep_fetch</code> numerous times
now for dealing with hierarchical hashes (e.g.,
<a href="http://jsonapi.org/">JSON API</a> responses), so I’m finally posting the
following snippet:</p>
<pre><code class="ruby">## Fetch nested keys in a more convenient way.
#
# Author :: Jon-Michael Deldin (@jmdeldin)
# License :: WTFPL
#
module DeepFetch
def deep_fetch(*args)
args.reduce(self) { |hsh, k| hsh.fetch(k) { |x| yield(x) } }
end
end
if $0 == __FILE__
require 'minitest/autorun'
describe DeepFetch do
it 'works for flat hashes' do
h = {foo: :bar}.extend(DeepFetch)
h.deep_fetch(:foo).must_equal :bar
end
it 'returns the value' do
h = {foo: {bar: {baz: :spam}}}.extend(DeepFetch)
h.deep_fetch(:foo, :bar).must_equal({baz: :spam})
h.deep_fetch(:foo, :bar, :baz).must_equal :spam
end
it 'supports a not-found block' do
h = {foo: {bar: :baz}}.extend(DeepFetch)
h.deep_fetch(:foo, :spam) { |k| "no #{k}!" }.must_equal "no spam!"
end
end
end
</code></pre>
<p>It’s way too small for a Ruby Gem, but it fits quite nicely in a <code>lib</code>
directory.</p>
How to Make Emacs Miserable with One Weird Trick2015-08-18T00:00:00-07:00http://www.jmdeldin.com/posts/2015/emacs-cron<p>Have you ever wanted to be periodically reminded of something in Emacs
in an intrusive way? Perhaps, something like <code>cron</code> + <code>alert("HI MOM")</code>
for Emacs? Maybe you want to print a (de)motivational message every few
hours, or run some 1337-elisp to update your iWatch’s NTP server.</p>
<p>Enter <code>run-with-idle-timer</code>. Here’s an example that displays a message
every four hours:</p>
<pre><code class="lisp">;; paste this into your *scratch* buffer
;; execute with M-x eval-buffer RET
(defun debugging-advice ()
"Sage wisdom, from a computer."
(interactive)
(message "Have you tried turning it off and then on?"))
;; assign your timer to a variable. this is important -- without this,
;; you will be unable to easily cancel your timer
(setq my-timer (run-with-idle-timer 14400 t 'debugging-advice))
;; 4 hours (14,400 seconds) too soon? cancel it:
;; (cancel-timer my-timer)
</code></pre>
<p>You can view active timers with <code>C-h v timer-idle-list RET</code>.</p>
Southwest Portland Skatepark Expedition2015-07-30T00:00:00-07:00http://www.jmdeldin.com/posts/2015/southwest-portland-skatepark-expedition<p>Jim & I went to Gabriel and Tigard skateparks for the first time
yesterday and had a blast! Gabriel is surprisingly fun – you can pump
it and rip around easily, and the walls outside the bowl are quite fun
to jib on too.</p>
<p>We arrived at Tigard past dusk, so we were limited in our exploration,
but we still had a good time pumping bowls and fumbling fastplants.
Definitely going to head back when we can actually see what we’re
riding.</p>
<p>I painstakingly edited a few clips together and produced the following
video. Video editing on Linux: even less fun than photo editing. I’m on
my green/yellow Norco (brakeless) and Jim is on his lavender Deity:</p>
<iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/qayDvxV0JnM" frameborder="0" allowfullscreen></iframe>
Spine Line2015-07-12T00:00:00-07:00http://www.jmdeldin.com/posts/2015/spine-line<p>First real ride on my 20" post-shoulder injury! No suspension is a
little rough, but the spine-to-vert wall is so much fun that a little
soreness is worth it.</p>
<blockquote class="instagram-media" data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://instagram.com/p/5Cr2EaOaCv/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_top">A video posted by Jon-Michael Deldin (@jmdeldin)</a> on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-07-12T15:58:05+00:00">Jul 12, 2015 at 8:58am PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
Night DJ Rides2015-07-07T00:00:00-07:00http://www.jmdeldin.com/posts/2015/night-dj-rides<p>Here are a few clips from riding my Norco around downtown Portland
(primarily the Waterfront and Esplanade):</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/408pwaOaAg/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">Cut my teeth (well, shins) on this wall a few years ago, and it's still one of my favorite bunnyhop/j-hop spots. Filmed and narrated by @ckuttruff. #portland #bmx #psbmx #bunnyhop #hop #urban</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-07-07T07:55:35+00:00">Jul 7, 2015 at 12:55am PDT</time></p></div></blockquote>
<p><br> This is the most fun long-and-low <del>jump</del> <ins>driveway</ins> I’ve
found in Portland so far. <br></p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/4073NvOaPg/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">Doing hoodrat stuff with @ckuttruff. Found this very low tabletop on the Esplanade, but it's a blast to launch. Just watch out for the curb right after the landing. #bmx #psbmx #portland #street #gap #potatocamera</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-07-07T07:48:41+00:00">Jul 7, 2015 at 12:48am PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
Video: Mini Pumptrack Session2015-07-05T00:00:00-07:00http://www.jmdeldin.com/posts/2015/mini-pumptrack-clip<p><a href="http://umabomber.com/">Uma</a> made a sweet Instagram video of one of my
favorite things: the pumptrack at the Lumberyard.</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/4ueTQ9yPtj/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">JMD showing the kids how it's done on the pump track @lumberyardmtb—the best air conditioned activity in Portland! The 'yard is closed July 4th because 'Murika, Eff Yeah! But they'll be open to fuel—and cool—your pump track riding tomorrow. ;-) @jmdeldin #pumped #pumptrack #jumpline #jumpjam #ride #ridemore #mtb #bmx #happyplace #shredfilter #makeawesomehappen</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Uma Kleppinger (@theumabomber) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-07-04T19:34:56+00:00">Jul 4, 2015 at 12:34pm PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
Failing at doubles2015-07-02T00:00:00-07:00http://www.jmdeldin.com/posts/2015/double-with-shaun<p>Shaun and I were riding doubles through the blue line, and I took the
high corner, but my wheel slid out, nearly crashing into him and
destroying myself. Thankfully, the automatic camera caught this photo of
both of us casing post-disaster-avoidance:</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/4p_ozklUj7/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">This picture describes @jmdeldin and @shawnmartin all too well. Way too much fun! @lumberyardmtb #bmx #mtb #lumberyardrules #portland #oregon #indoorbikepark @sniperactionphoto</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A photo posted by Levi Weert (@leviweert) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-07-03T01:50:02+00:00">Jul 2, 2015 at 6:50pm PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
Video: 180 up the step up @ The Lumberyard2015-07-01T00:00:00-07:00http://www.jmdeldin.com/posts/2015/step-up-180<p>Levi harangued me into a 20-second Tuesday at the Lumberyard (video
forthcoming) and convinced me this was a good idea. It’s pretty weird,
as you’re spinning <em>before</em> you clear the lip. Thanks to Levi, Henry,
and Silas' encouragement, I landed it after a few tries.</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/4njHZcFUne/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">@jmdeldin @lumberyardmtb @henrypolvorosa #180 #bmx #mtb #lumberyardrules</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Levi Weert (@leviweert) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-07-02T03:02:19+00:00">Jul 1, 2015 at 8:02pm PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
Pumping Pier Park2015-06-08T00:00:00-07:00http://www.jmdeldin.com/posts/2015/pumping-pier-park<p>Recovering from a sprained AC-joint means no hopping and jumping, but
pumping seems to work pretty well:</p>
<iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/QhryDlQSuFE" frameborder="0" allowfullscreen></iframe>
Sunday Night at the 'Yard2015-05-27T00:00:00-07:00http://www.jmdeldin.com/posts/2015/sunday-night-at-the-yard<p><a href="http://ckuttruff.com">Chris</a> and I went to the Lumberyard for a little
session. Unfortunately, it ended with me clipping my right shoulder on
the lip of a ramp, so I am in a sling for a few weeks due to an AC-joint
sprain.</p>
<p>Pumping:</p>
<iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/g6Y1QnsCoIQ" frameborder="0" allowfullscreen></iframe>
<p>Black-to-Blue:</p>
<iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/h-o9XlkkTL4" frameborder="0" allowfullscreen></iframe>
A brief tour of Montana's Skateparks2015-05-03T00:00:00-07:00http://www.jmdeldin.com/posts/2015/montana-skatepark-tour<p><a href="http://ckuttruff.com">Chris</a> and I accidentally ended up touring a few
Montana skateparks on a recent trip back home. We started in central
Montana (Cascade) and eventually made our way West. Here are a few tiny
clips!</p>
<h2>Cascade</h2>
<p>This is sadly not much of a park, but it provides enough entertainment
between watching the high speed winds destroy your house and eating a
corn dog.</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/2EyYJVuaCY/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">Slightly longer "run" from the tiny park. Thanks to @ckuttruff for filming. #clymblife #bmx #montanabmx #montana</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-04-29T21:59:28+00:00">Apr 29, 2015 at 2:59pm PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/2J7j6COaHb/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">A very silly 270 on a windy, bleak day. #bmx #montanabmx #clymblife</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-05-01T21:55:55+00:00">May 1, 2015 at 2:55pm PDT</time></p></div></blockquote>
<h2>Great Falls</h2>
<p>While Cascade was entertaining on lunch breaks, Great Falls has a
phenomenal park. Unfortunately, we only managed to film late at night on
a crummy phone:</p>
<iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/1GWEsPcR-ho" frameborder="0" allowfullscreen></iframe>
<h2>Helena</h2>
<p>I didn’t get a chance to film the park, but I am excited about the jumps
and pump tracks Helena is building next to it!</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/2OfkAkOaDq/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">Ran into a former Oregonian at the Helena skatepark who showed me this funny set of new dirt jumps near #carrollcollege. They're a little too small for the speed you gain, but it was a fun way to break up the drive nonetheless. It'll be great to hit them in a few months after they've been built out a little more. #helena #montana #roadtrip #montanabmx #bmx #dirtjumps</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-05-03T16:27:28+00:00">May 3, 2015 at 9:27am PDT</time></p></div></blockquote>
<h2>Missoula</h2>
<p>This is still my favorite park, probably because I spent so many late,
icy nights in it, got my first concussion here, and learned how to air
out here.</p>
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="4" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf//42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB/lQPb79drWOyJVa/DAvg9B/rLB4cC+Nqgdz/TvBbBnr6GBReqn/nRmDgaQEej7WhonozjF+Y2I/fZou/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://instagram.com/p/2OgVVguaF0/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_top">I love this bowl and cradle/cereal bowl! Charging on concrete has never felt so good. I used to spend nights here just racing around and listening to the sweet sound of high pressure tires on pavement. Happy to do that again! #zootown #missoula #montana #mobash #skatepark #bowl #montanabmx #bmx #clymblife #roadtrip</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A video posted by Jon-Michael Deldin (@jmdeldin) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2015-05-03T16:34:12+00:00">May 3, 2015 at 9:34am PDT</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>
Sunday Spines at the Lumberyard2015-01-26T00:00:00-08:00http://www.jmdeldin.com/posts/2015/sunday-spines-at-the-lumberyard<p>Stoked I learned the spine, box-footplant, and transfer to blue this month!</p>
<iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/x7cTnoAxMm0" frameborder="0" allowfullscreen></iframe>
Windy Bike Trials in Portland2014-09-27T00:00:00-07:00http://www.jmdeldin.com/posts/2014/windy-bike-trials-in-portland<p>Went for a short bike trials ride today at PSU, and this is the result.</p>
<iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/1BShbrIwkI0" frameborder="0" allowfullscreen></iframe>
Sunday Street Trials in Portland2013-11-03T00:00:00-07:00http://www.jmdeldin.com/posts/2013/sunday-street-trials-in-portland<p>Some short street bike trials clips taken during this morning’s brief
drizzle-free spell.</p>
<p>9 months of riding trials, ~5 months of riding my Inspired Fourplay.</p>
<iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/AVq4hEmMeNU" frameborder="0" allowfullscreen></iframe>
Hello, World2013-07-06T00:00:00-07:00http://www.jmdeldin.com/posts/2013/hello-world<p>Ah, the inaugural “Hello, World” post. It’s a holiday weekend, and I have
finally run out of excuses for not maintaining a blog. So, here we are.</p>
<p>Since this site’s been dead since 2006 or so, allow me to catch you up
to speed.</p>
<ul>
<li>2005–2009: Completing my undergrad in biology and chemistry in Great
Falls, MT. Lots of freelance work.</li>
<li>2009–2013: Starting and finishing a master’s in computer science in
Missoula, MT. First office programming jobs, teaching, and an
unhealthy number of side projects.</li>
</ul>
<h3>Now</h3>
<p>The last few months have been pretty crazy for me, but the dust is
finally settling.</p>
<ul>
<li>May 13: Defending my <a href="http://cs.jmdeldin.com">master’s portfolio</a>
surrounded by a close group of friends.</li>
<li>May 17: Leaving my friends and coworkers at
<a href="http://www.biomimicry.net">Biomimicry 3.8</a>.</li>
<li>May 18: Graduation! Left for Portland that night.
<figure>
<img src="/images/moving.jpg" alt="Photo of a white 2012 Subaru Impreza">
<figcaption>Slammed. Am I doing it right?</figcaption>
</figure></li>
<li>May 20: Started my new job at
<a href="https://www.theclymb.com/invite-from/jonmichael">The Clymb</a>!</li>
<li>May 20-26: Apartment hunting. Painfully assembling IKEA furniture.
Getting lost repeatedly (I later broke down and bought an Android for
navigation).
<figure>
<img src="/images/ikea.jpg" alt="Photo of IKEA instruction hell">
<figcaption>Friends don’t let friends assemble IKEA furniture alone.</figcaption>
</figure></li>
<li>June: Pushing out a new version of The Clymb, coping with free time
(i.e., riding trials daily), picking up skimboarding again, and slowly
exploring Portland.</li>
</ul>
<h3>Outlook</h3>
<p>I am interested in blogging again because I have a few interesting
projects rotting in <a href="https://github.com/jmdeldin">GitHub</a>, so I’d like
to write about them and future recreational programming projects.
Additionally, I want to document my trials riding progress. In the words
of Tobias Fünke, let the great experiment begin!</p>
Node2012-10-18T00:00:00-07:00http://www.jmdeldin.com/posts/2012/node<hr/>
<p><b>Note (2019-04-23):</b> The following was written at 4 AM after a long
night of debugging Node and npm for a <a href="https://github.com/jmdeldin/content-usability">research project in grad school</a>.
While I’ve warmed up towards Node in the years since, dependency hell
has only worsened. I’ve preserved this short rant for my own digital
time capsule of a 20-something, stressed out me.</p>
<hr/><br/>
<p>Node is garbage. Seriously. 99% of the doc modules don’t work.
<code>dox-basic</code> – carriage return in the shebang? Really?</p>
<p>Installing a nodejs module: It’s like Christmas day, and your parents
have wrapped 32 boxes, but only one of them actually contains a present.
The others are either empty or contain live badgers.</p>
Scheme Sandbox2012-07-25T00:00:00-07:00http://www.jmdeldin.com/posts/2012/scheme-sandbox<p>Because the world needed <a href="https://github.com/jmdeldin/scheme-sandbox">another unfinished Scheme library</a>. I’ve been
working through <a href="https://amzn.to/2DwI6iZ">the Little Schemer</a> this summer and thought I’d record my
progress in a Github project. Here’s a quick sample:</p>
<pre class="src" lang="scheme">
;; (jm/select (lambda (x) (eq? x 2)) '(2 3 4 2)) => '(2 2)
(define (jm/select f l)
(define (aux matches remaining)
(if (null? remaining)
matches
(aux (if ((eval f) (car remaining))
(cons (car remaining) matches)
matches) (cdr remaining))))
(aux '() l))
</pre>
<p>Send me an email for enterprise pricing.</p>