<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Desert Moon (Posts about Software Development)</title><link>http://www.dmoonc.com/</link><description></description><atom:link href="http://www.dmoonc.com/categories/software-development.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Fri, 03 Jul 2026 16:06:42 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Custom validation messages w. Svelte</title><link>http://www.dmoonc.com/posts/2023/02/svelte-and-custom-input-validation-messages/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;h3&gt;Example.svelte&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ts"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;HTMLInputElement&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueMissing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setCustomValidity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Please provide a date of birth.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"date"&lt;/span&gt;
  &lt;span class="na"&gt;bind:this&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{control}"&lt;/span&gt;
  &lt;span class="na"&gt;required&lt;/span&gt;
  &lt;span class="na"&gt;on:invalid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{validate}"&lt;/span&gt;
  &lt;span class="na"&gt;on:change&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{validate}"&lt;/span&gt;
  &lt;span class="na"&gt;on:input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{validate}"&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"A required input"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;required&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;125&lt;/span&gt;&lt;span class="kt"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;vertical-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;top&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Result&lt;/h3&gt;
&lt;div style="margin: 2rem"&gt;
&lt;img srcset="/images/2023/02/sv_custom_input_val/custom_validation_msg.png 2x" style="border: 1px solid #ccc; border-radius: 0.25rem;"&gt;
&lt;/div&gt;</description><category>Software Development</category><category>Svelte</category><category>Web Development</category><guid>http://www.dmoonc.com/posts/2023/02/svelte-and-custom-input-validation-messages/</guid><pubDate>Mon, 13 Feb 2023 18:16:21 GMT</pubDate></item><item><title>SvelteKit Session Management</title><link>http://www.dmoonc.com/posts/2023/02/sveltekit-session-management/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;div&gt;&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt; Manage session cookies using &lt;code&gt;hooks.server.ts&lt;/code&gt;, the &lt;code&gt;handle&lt;/code&gt; function, &lt;code&gt;event.locals&lt;/code&gt; and &lt;code&gt;app.d.ts&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dmoonc.com/posts/2023/02/sveltekit-session-management/"&gt;Read more…&lt;/a&gt; (2 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>Software Development</category><category>SvelteKit</category><category>Typescript</category><category>Web Development</category><guid>http://www.dmoonc.com/posts/2023/02/sveltekit-session-management/</guid><pubDate>Sat, 11 Feb 2023 16:04:38 GMT</pubDate></item><item><title>Testing SwiftUI Tables</title><link>http://www.dmoonc.com/posts/2023/01/testing-swiftui-tables/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;p&gt;I maintain a macOS SwiftUI app whose user interface contains a Table, one with a bound sortOrder.&lt;/p&gt;
&lt;p&gt;The app's Xcode project contains UI tests that exercise the sorting logic, by clicking on the column headers. These tests are really fragile. Odds are good that any new release of macOS, or Xcode, or SwiftUI, will break them.&lt;/p&gt;
&lt;p&gt;I'm not sure why they're so fragile. I suspect the way SwiftUI generates the underlying view hierarchy for a Table may still be in flux.&lt;/p&gt;
&lt;p&gt;In any case, here is what I'm currently using to click on the column headers of a SwiftUI Table. This is for macOS 13.1, Xcode 14.2, Swift 5.7, SwiftUI 4.2.11.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;clickTableColumnHeaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tableEl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;XCUIElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tableEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tableColumns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allElementsBoundByIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;// Assume the column header lies above the column.&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CGFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;offset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;CGVector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;coords&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coordinate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;withNormalizedOffset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;// Click twice to exercise both sort orders.&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>macOS</category><category>Software Development</category><category>Swift</category><category>SwiftUI</category><category>Xcode</category><guid>http://www.dmoonc.com/posts/2023/01/testing-swiftui-tables/</guid><pubDate>Mon, 09 Jan 2023 14:09:00 GMT</pubDate></item><item><title>Svelte's Take on ObservableObject</title><link>http://www.dmoonc.com/posts/2022/12/sveltes-take-on-swiftuis-observableobject/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;div&gt;&lt;p&gt;SwiftUI's &lt;a href="https://developer.apple.com/documentation/combine/observableobject"&gt;ObservableObject and @Published&lt;/a&gt; make it easy to group related properties into a single class, and to react to changes of individual properties.&lt;/p&gt;
&lt;p&gt;I recently complained to my friend, Bobi, that &lt;a href="https://svelte.dev/"&gt;Svelte&lt;/a&gt; seemed lacking in this regard.  &lt;a href="https://svelte.dev/tutorial/reactive-assignments"&gt;Its tutorials&lt;/a&gt; always show components whose exportable state is defined by separate, top-level variable declarations.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'count is dangerously high!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;She set me straight: if you want to group related, observable properties, just use a writable store whose value is an Object (or if you prefer, a class instance).  Whenever any property is changed, interested parties react automatically.  &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dmoonc.com/posts/2022/12/sveltes-take-on-swiftuis-observableobject/"&gt;Read more…&lt;/a&gt; (1 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>Reactive</category><category>Software Development</category><category>Svelte</category><category>Swift</category><category>SwiftUI</category><guid>http://www.dmoonc.com/posts/2022/12/sveltes-take-on-swiftuis-observableobject/</guid><pubDate>Mon, 05 Dec 2022 13:33:06 GMT</pubDate></item><item><title>macOS, Xcode, Ventura: When CloudKit Stops Syncing</title><link>http://www.dmoonc.com/posts/2022/11/macos-ventura-when-cloudkit-stops-syncing/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;div&gt;&lt;p&gt;(This is for future reference, when this sort of problem arises again.)&lt;/p&gt;
&lt;p&gt;Last spring I started working on a pair (macOS, iOS) of personal utility applications.  They relied on CloudKit storage.  For months they worked well together.  Then, as soon as I updated to macOS 13 Ventura, they stopped syncing.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dmoonc.com/posts/2022/11/macos-ventura-when-cloudkit-stops-syncing/"&gt;Read more…&lt;/a&gt; (1 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>CloudKit</category><category>Core Data</category><category>Mac</category><category>macOS</category><category>Software Development</category><category>Xcode</category><guid>http://www.dmoonc.com/posts/2022/11/macos-ventura-when-cloudkit-stops-syncing/</guid><pubDate>Tue, 08 Nov 2022 19:43:01 GMT</pubDate></item><item><title>Git Default Branches: from master to main</title><link>http://www.dmoonc.com/posts/2022/10/git-default-branches-from-master-to-main/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;div&gt;&lt;h3&gt;Short Form&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;old_repository
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;branch&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;master&lt;span class="w"&gt; &lt;/span&gt;main
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;push&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;main

$&lt;span class="w"&gt; &lt;/span&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;my_hosting_provider
my_hosting_provider$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;code_repos/my_bare_repo.git
my_hosting_provider$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;symbolic-ref&lt;span class="w"&gt; &lt;/span&gt;HEAD&lt;span class="w"&gt; &lt;/span&gt;refs/heads/main

my_hosting_provider$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;push&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;--delete&lt;span class="w"&gt; &lt;/span&gt;master
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.dmoonc.com/posts/2022/10/git-default-branches-from-master-to-main/"&gt;Read more…&lt;/a&gt; (1 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>Software Development</category><guid>http://www.dmoonc.com/posts/2022/10/git-default-branches-from-master-to-main/</guid><pubDate>Sun, 09 Oct 2022 14:28:47 GMT</pubDate></item><item><title>Detecting Polygon Collisions Using SAT</title><link>http://www.dmoonc.com/posts/2021/12/detecting-polygon-collisions-using-sat/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;div&gt;&lt;p&gt;Detecting and resolving collisions between point-mass particles is pretty straightforward.  See the previous post on "&lt;a href="http://www.dmoonc.com/posts/2021/12/simulating-lift-particle-particle-collisions/"&gt;Simulating Lift: Particle-Particle Collisions&lt;/a&gt;".  But how does one detect collisions between particles and a 2D polygon, e.g., an airfoil shape?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dmoonc.com/posts/2021/12/detecting-polygon-collisions-using-sat/"&gt;Read more…&lt;/a&gt; (2 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>Algorithms</category><category>Simulation</category><category>Software Development</category><guid>http://www.dmoonc.com/posts/2021/12/detecting-polygon-collisions-using-sat/</guid><pubDate>Tue, 21 Dec 2021 17:45:49 GMT</pubDate></item><item><title>Simulating Lift: Particle-Particle Collisions</title><link>http://www.dmoonc.com/posts/2021/12/simulating-lift-particle-particle-collisions/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;div&gt;&lt;p&gt;In 2020 &lt;a href="http://www.dmoonc.com/posts/how-a-wing-works"&gt;I complained about superficial explanations of how wings work&lt;/a&gt;.  That post left me wondering whether a particle-based fluid simulation could manifest lift.&lt;/p&gt;
&lt;p&gt;The short answer: yes.&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/qUdsK5staI0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;a href="http://www.dmoonc.com/posts/2021/12/simulating-lift-particle-particle-collisions/"&gt;Read more…&lt;/a&gt; (2 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>Algorithms</category><category>macOS</category><category>Simulation</category><category>Software Development</category><category>Swift</category><category>SwiftUI</category><guid>http://www.dmoonc.com/posts/2021/12/simulating-lift-particle-particle-collisions/</guid><pubDate>Sat, 18 Dec 2021 23:04:03 GMT</pubDate></item><item><title>If not GPG, then what?</title><link>http://www.dmoonc.com/posts/if-not-gpg-then-what/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;p&gt;Sometimes you need to keep secrets.  Maybe you are involved in organized crime or a revolutionary organization.  Maybe you need safe-keeping for your build system credentials.&lt;/p&gt;
&lt;p&gt;In my very limited experience, gpg is painful to use.&lt;/p&gt;
&lt;p&gt;I've tried to use Hashicorp Vault, but I'm not sure I've understood its documentation.  I think it recommends storing secrets in a vault on a dedicated secret server, and connecting to that server via a well-known URL when you need authentication tokens.  And if/when that server needs to restart?  Require three separate humans to manually, interactively, apply their keys to unlock the vault and get things running again.&lt;/p&gt;
&lt;p&gt;Yikes.&lt;/p&gt;
&lt;p&gt;What are the alternatives?&lt;/p&gt;
&lt;p&gt;Darned if I know.  But I just tripped across &lt;a href="https://latacora.micro.blog/2019/07/16/the-pgp-problem.html"&gt;this post&lt;/a&gt; by &lt;a href="https://latacora.com"&gt;Latacora&lt;/a&gt; and am grateful to its author(s).  The recommendations seem to be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For secure chat, use &lt;a href="https://www.signal.org/"&gt;Signal&lt;/a&gt;.  (Or WhatsApp?  Really?)&lt;/li&gt;
&lt;li&gt;Don't encrypt email.  [Insert long list of failure modes.]&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://github.com/warner/magic-wormhole"&gt;Magic Wormhole&lt;/a&gt; or &lt;a href="https://www.signal.org/"&gt;Signal&lt;/a&gt; to send files securely.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://www.tarsnap.com/design.html"&gt;tarsnap&lt;/a&gt; to encrypt backups.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://man.openbsd.org/signify.1"&gt;signify&lt;/a&gt; or &lt;a href="https://jedisct1.github.io/minisign/"&gt;Minisign&lt;/a&gt; to sign packages.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://download.libsodium.org/doc/"&gt;libsodium&lt;/a&gt; to encrypt application data.&lt;/li&gt;
&lt;/ul&gt;</description><category>Software Development</category><guid>http://www.dmoonc.com/posts/if-not-gpg-then-what/</guid><pubDate>Sat, 15 Feb 2020 14:05:24 GMT</pubDate></item><item><title>Fundamental Interconnectedness</title><link>http://www.dmoonc.com/posts/fundamental-interconnectedness/</link><dc:creator>Mitch Chapman</dc:creator><description>&lt;p&gt;&lt;a href="https://twitter.com/McFaul/status/1064777881522302977"&gt;From twitter:&lt;/a&gt;&lt;/p&gt;
&lt;div style="border:1px solid black;margin:1em;padding:0.5em;background:#eeeeee;font-family:helvetica,arial,sans"&gt;
&lt;a href="https://twitter.com/McFaul/status/1064777881522302977"&gt;@McFaul&lt;/a&gt;: Hey &lt;a href="https://twitter.com/McFaul/status/1064777881522302977"&gt;@Grady_Booch&lt;/a&gt;, I want to learn Python. Whats your recommendation for how at my stage in life?
    &lt;div style="border:1px solid black;margin:1em;padding: 0.5em;background:#f7f7f7"&gt;
    &lt;a href="https://twitter.com/McFaul/status/1064777881522302977"&gt;@Grady_Booch&lt;/a&gt;: Hey &lt;a href="https://twitter.com/McFaul/status/1064777881522302977"&gt;@gvanrossum&lt;/a&gt; you have another fan.
    &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Professor Michael McFaul is a former U.S. Ambassador to Russia.&lt;/p&gt;
&lt;p&gt;Grady Booch is perhaps best known for developing UML.&lt;/p&gt;
&lt;p&gt;Guido van Rossum is the creator of Python, the programming language (and community) that has made my professional life so interesting.&lt;/p&gt;
&lt;p&gt;Suddenly I wonder: is my twitter feed the product of a travesty generator?&lt;/p&gt;</description><category>Civics</category><category>Python</category><category>Russia</category><category>Software Development</category><guid>http://www.dmoonc.com/posts/fundamental-interconnectedness/</guid><pubDate>Tue, 20 Nov 2018 13:10:26 GMT</pubDate></item></channel></rss>