<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Huey's Posts]]></title><description><![CDATA[Huey's Posts]]></description><link>https://huey.xyz/posts</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 12 Apr 2026 15:00:30 GMT</lastBuildDate><ttl>1440</ttl><item><title><![CDATA[Securing Linkding with OIDC]]></title><description><![CDATA[Using PocketID for passwordless authentication for my Linkding instance

I have self-hosted various services for years. The primary reason for this is so that I have control over these and they do not change under…]]></description><link>https://huey.xyz/posts/2026-04-11-securing-linkding-with-oidc</link><guid isPermaLink="false">f890bd0e2cb055645e7c6d5061ad346ad3d3faf68470b011cee6d46a20d88835</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 11 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Using PocketID for passwordless authentication for my Linkding instance&lt;/h2&gt;&lt;p&gt;I have self-hosted various services for years. The primary reason for this is so that I have control over these and they do not change under my feet (whether in terms of feature set, pricing, hardware requirements, etc).&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This has generally included a &apos;read-it-later&apos; service. I find such a service quite useful when going through my RSS feeds — my usual workflow is to scan through the headlines and abstracts quickly, and mark interesting articles to be read later via a &apos;read-it-later&apos; service.&lt;/p&gt;
&lt;p&gt;I&apos;ve used many &apos;read-it-later&apos; services over the years, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instapaper (&lt;a href=&quot;https://www.theverge.com/2023/12/5/23989725/read-it-later-service-instapaper-is-doubling-the-price-of-premium&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;stopped allowing access to archived articles and doubled its subscription price&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Pocket (&lt;a href=&quot;https://techcrunch.com/2025/05/22/mozilla-is-shutting-down-read-it-later-app-pocket/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;acquired by Mozilla and subsequently shut down&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Omnivore (&lt;a href=&quot;https://web.archive.org/web/20241231090553/https://blog.omnivore.app/p/omnivore-is-joining-elevenlabs&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;acquired by ElevenLabs and subsequently shut down&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Wallabag (worked well but I found it a bit slow and I didn&apos;t quite like the user interface)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;ve now settled on &lt;a href=&quot;https://linkding.link/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Linkding&lt;/a&gt;, which I have been happily using for over a year. It&apos;s fast, light, easy to self-host (single docker container + sqlite database) and does everything I need. &lt;a href=&quot;https://addons.mozilla.org/en-GB/firefox/addon/linkding-extension/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;There is a Firefox extension&lt;/a&gt; allowing you to quickly add articles when browsing the web (and a keyboard shortcut: &lt;kbd&gt;Alt&lt;/kbd&gt; &lt;kbd&gt;Shift&lt;/kbd&gt;&lt;kbd&gt;L&lt;/kbd&gt;).&lt;/p&gt;
&lt;p&gt;The one thing it is doesn&apos;t have built-in is a mobile app. However, it has a simple API&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; and &lt;a href=&quot;https://linkding.link/how-to/#using-http-shortcuts-app-on-android&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the Linkding documentation includes instructions to add a custom share intent&lt;/a&gt; using &lt;a href=&quot;https://http-shortcuts.rmy.ch/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;HTTP Shortcuts&lt;/a&gt; on Android to share articles to your Linkding instance. &lt;a href=&quot;https://linkding.link/how-to/#create-a-share-action-on-ios-for-adding-bookmarks-to-linkding&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;There are similar instructions using iOS Shortcuts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If I want to view the URLs I&apos;ve saved on Linkding on mobile, I just visit my Linkding instance in Firefox (you can add the site to your home screen if you like).&lt;/p&gt;
&lt;h1 id=&quot;the-broader-picture&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-broader-picture&quot; aria-label=&quot;the broader picture permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The broader picture&lt;/h1&gt;
&lt;p&gt;My Linkding instance does not contain any particularly sensitive data, hence I have been happy to expose it to the public internet (behind a reverse proxy), with the built-in username and password authentication.&lt;/p&gt;
&lt;p&gt;Lately however, as part of a general review and refresh of my self-hosted systems, I have been looking at harmonising authentication across all my self-hosted systems and implementing single-sign on (SSO), so I don&apos;t need separate usernames and passwords for every service. The built-in authentication methods for some of my self-hosted services are quite basic (e.g. just username and password for Linkding, no MFA/2FA), so the hope is that implementing SSO would also raise the security posture of my services (or at least the authentication aspects) of my services to a certain floor.&lt;/p&gt;
&lt;p&gt;Rather than a single username and password to rule them all, my plan is to advance directly to passwordless authentication, using passkeys. I have a few physical FIDO tokens and I use software passkeys as well, so this should work well. The other users of my self-hosted services should also have access to software passkeys (e.g. via Google or Apple), or if need be I can hand them a physical security key. This would also conveniently avoid the security issues arising when users set weak and easily-guessable passwords, or are too lazy to set up and use MFA/2FA.&lt;/p&gt;
&lt;h1 id=&quot;pocketid&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#pocketid&quot; aria-label=&quot;pocketid permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;PocketID&lt;/h1&gt;
&lt;p&gt;This is all at a fairly preliminary stage. As a low-risk trial before a broader rollout, I have decided to try implementing OpenID Connect (OIDC) authentication with passkeys for Linkding.&lt;/p&gt;
&lt;p&gt;There are many self-hostable OIDC services available, including &lt;a href=&quot;https://www.authelia.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Authelia&lt;/a&gt; and &lt;a href=&quot;https://www.keycloak.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Keycloak&lt;/a&gt;. I selected &lt;a href=&quot;https://pocket-id.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;PocketID&lt;/a&gt; because I didn&apos;t need all the bells and whistles of the more fully-featured solutions and I wanted something that would be lightweight and simple to self-host and maintain.&lt;/p&gt;
&lt;p&gt;I set up PocketID as a docker container in my usual way with a reverse proxy and followed &lt;a href=&quot;https://pocket-id.org/docs/client-examples/linkding&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the helpful PocketID documentation&lt;/a&gt; to configure OIDC with Linkding via environment variables. It worked very well!&lt;/p&gt;
&lt;h1 id=&quot;migration&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#migration&quot; aria-label=&quot;migration permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Migration&lt;/h1&gt;
&lt;p&gt;Ideally OIDC should be set up right at at start, i.e. when you first initialise your Linkding instance and create your user. Unfortunately, I did not have such foresight.&lt;/p&gt;
&lt;p&gt;The difficulty I had was essentially this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I set up my PocketID user and my Linkding user with different email addresses&lt;/li&gt;
&lt;li&gt;Upon OIDC authentication, Linkding creates a new user with the authenticating email address. You can force a certain username using the &lt;code class=&quot;language-text&quot;&gt;OIDC_USERNAME_CLAIM&lt;/code&gt; environment variable and setting up a custom claim on the PocketID side, but this still creates a new user. If you have an existing user with that username, the new user creation process will fail and therefore this does not fully solve the problem I had.&lt;/li&gt;
&lt;li&gt;Even if I changed my Linkding user to use the same email address as my PocketID email address, the core issue was that Linkding would always attempt to create a new user rather than allow me to log in as an existing user.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;ve been using my Linkding instance for awhile and my user has quite a lot of bookmarks and other user data that I would like to retain. Whilst I believe I could export my bookmmarks and import them into my new PocketID user, there didn&apos;t seem to be a built-in way to transfer over my API keys, which would mean I would need to reconfigure my various Linkding integrations (e.g. mobile and eilmeldung integrations). As far as possible, I wanted to login via PocketID to my existing Linkding user. Fortunately, I managed to achieve this.&lt;/p&gt;
&lt;p&gt;My hackish solution was to login with PocketID, which created a new user, then shutdown the Linkding instance, muck around with the &lt;code class=&quot;language-text&quot;&gt;sqlite&lt;/code&gt; database (I used the very useful &lt;a href=&quot;https://github.com/Maxteabag/sqlit&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sqlit&lt;/code&gt;&lt;/a&gt; for this)&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; by swapping the row IDs of my two users, then stand the instance back up. This worked because the foreign keys in the bookmarks and other tables are the user row IDs.&lt;/p&gt;
&lt;p&gt;I was quite satisfied with this, so I went ahead and disabled login via username and password by setting &lt;code class=&quot;language-text&quot;&gt;LD_DISABLE_LOGIN_FORM = True&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;See in particular: &lt;a href=&quot;https://en.wikipedia.org/wiki/Enshittification&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://en.wikipedia.org/wiki/Enshittification&lt;/a&gt;&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;I have also configured Linkding support for my favourite RSS reader, &lt;a href=&quot;https://github.com/christo-auer/eilmeldung&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;eilmeldung&lt;/a&gt; — this will likely be the subject of a subsequent article.&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;Linkding does expose a Django admin dashboard to admin users, but I couldn&apos;t swap the user IDs via the dashboard because it didn&apos;t actually expose the user IDs in the GUI (only the usernames).&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Processing podcast MP3s with sox and ffmpeg]]></title><description><![CDATA[Adjusting playback speed and removing silence

I recently acquired a MP3 player-like device. I wanted to try using it to listen to podcasts. The problem I faced was that I usually listen…]]></description><link>https://huey.xyz/posts/2026-01-24-podcast-ffmpeg</link><guid isPermaLink="false">36c121f57cc1dcd097d3628ff929bc33903660b315d39e5a0c389b92a9a734e0</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 24 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Adjusting playback speed and removing silence&lt;/h2&gt;&lt;p&gt;I recently acquired a MP3 player-like device. I wanted to try using it to listen to podcasts. The problem I faced was that I usually listen to podcasts at about 1.25 speed, with silent parts of the audio automatically removed (for example, using &lt;a href=&quot;https://antennapod.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;AntennaPod&lt;/a&gt;). The player itself has pretty limited playback controls, and certainly does not have any functionality to change the playback speed to cut out silence.&lt;/p&gt;
&lt;p&gt;It therefore seemed clear that I would have to pre-process the MP3s to change the playback speed and remove silence before loading the MP3s onto the device.&lt;/p&gt;
&lt;p&gt;I fiddled around with &lt;code class=&quot;language-text&quot;&gt;sox&lt;/code&gt; a bit and put together a suitable command for my use case:&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;sox --show-progress &lt;span class=&quot;token variable&quot;&gt;$input_file&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$temp_file&lt;/span&gt; silence &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;% &lt;span class=&quot;token parameter variable&quot;&gt;-1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.4&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;% tempo &lt;span class=&quot;token number&quot;&gt;1.25&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;sox&lt;/code&gt; command above essentially applies 2 filters on the input MP3: (1) removes periods of silence in the audio; and (2) use &lt;code class=&quot;language-text&quot;&gt;atempo&lt;/code&gt; to adjust the playback speed to 25% (this does not change the pitch of the audio). For (1), more specifically, it considers any audio less than 1% in volume to be silence, and will cut all periods of silence &gt; 1s in length to 0.4s max.&lt;/p&gt;
&lt;p&gt;I turned this into a simple bash script with the assistance of DeepSeek-V3.2 for the scaffolding:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;#!/bin/sh

if [ -z &quot;$1&quot; ]; then
  echo &quot;Usage: $0 &amp;lt;input.mp3&gt;&quot;
  exit 1
fi

input_file=&quot;$1&quot;

# Extract directory and filename
dir=$(dirname &quot;$input_file&quot;)
filename=$(basename &quot;$input_file&quot; .mp3)

temp_file=&quot;${dir}/${filename}.processed.wav&quot;

# Output file path
output_file=&quot;${dir}/${filename}.processed.mp3&quot;

sox --show-progress $input_file $temp_file silence -l 1 0.1 1% -1 0.4 1% tempo 1.25

ffmpeg -i $temp_file -q:a 0 -vn &quot;$output_file&quot;

# Check if succeeded
if [ $? -eq 0 ]; then
  echo &quot;Processing complete. Output saved to: $output_file&quot;
else
  echo &quot;Processing failed. Check for errors.&quot;
fi&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This does require you to have &lt;code class=&quot;language-text&quot;&gt;sox&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;ffmpeg&lt;/code&gt; installed. On NixOS, this is as simple as:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;nix-shell -p sox ffmpeg&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;sox&lt;/code&gt; does not have MP3 output support built in (or at least the version packaged in NixOS does not), hence &lt;code class=&quot;language-text&quot;&gt;.wav&lt;/code&gt; output and subsequent conversion to &lt;code class=&quot;language-text&quot;&gt;.mp3&lt;/code&gt; via &lt;code class=&quot;language-text&quot;&gt;ffmpeg&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The script works well:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[nix-shell:~/Desktop]$ sh script.sh ~/Downloads/GlobalNewsPodcast-20251205-FourCountriesBoycottEurovisionOverIsraelsInclusion.mp3

Input File     : &apos;/home/huey/Downloads/GlobalNewsPodcast-20251205-FourCountriesBoycottEurovisionOverIsraelsInclusion.mp3&apos;
Channels       : 1
Sample Rate    : 44100
Precision      : 16-bit
Duration       : 00:36:49.80 = 97452288 samples = 165735 CDDA sectors
File Size      : 17.8M
Bit Rate       : 64.3k
Sample Encoding: MPEG audio (layer I, II or III)

In:100%  00:36:49.59 [00:00:00.21] Out:73.0M [======|======] Hd:2.3 Clip:454  
sox WARN dither: dither clipped 454 samples; decrease volume?
Done.
ffmpeg version 8.0 Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 14.3.0 (GCC)
  configuration: --disable-static --prefix=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-full-8.0 --target_os=linux --arch=x86_64 --pkg-config=pkg-config --enable-gpl --enable-version3 --disable-nonfree --disable-static --enable-shared --enable-pic --disable-thumb --disable-small --enable-runtime-cpudetect --enable-gray --enable-swscale-alpha --enable-hardcoded-tables --enable-safe-bitstream-reader --enable-pthreads --disable-w32threads --disable-os2threads --enable-network --enable-pixelutils --datadir=/nix/store/rvx1lss70sfq3qpx0v2crlfqls6mj3kh-ffmpeg-full-8.0-data/share/ffmpeg --enable-ffmpeg --enable-ffplay --enable-ffprobe --bindir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-full-8.0-bin/bin --enable-avcodec --enable-avdevice --enable-avfilter --enable-avformat --enable-avutil --enable-swresample --enable-swscale --libdir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-full-8.0-lib/lib --incdir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-full-8.0-dev/include --enable-doc --enable-htmlpages --enable-manpages --mandir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-full-8.0-man/share/man --enable-podpages --enable-txtpages --docdir=/nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-ffmpeg-full-8.0-doc/share/doc/ffmpeg --enable-alsa --enable-amf --enable-libaom --enable-libaribb24 --enable-libaribcaption --enable-libass --enable-avisynth --enable-libbluray --enable-libbs2b --enable-bzlib --enable-libcaca --enable-libcdio --enable-libcelt --enable-chromaprint --enable-libcodec2 --enable-cuda --enable-cuda-llvm --disable-cuda-nvcc --enable-cuvid --enable-libdav1d --enable-libdavs2 --enable-libdc1394 --enable-libdrm --enable-libdvdnav --enable-libdvdread --disable-libfdk-aac --enable-ffnvcodec --enable-libflite --enable-fontconfig --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libfribidi --enable-libgme --enable-gmp --enable-gnutls --enable-libgsm --enable-libharfbuzz --enable-iconv --enable-libilbc --enable-libjack --enable-libjxl --enable-libkvazaar --enable-ladspa --enable-liblc3 --enable-liblcevc-dec --enable-lcms2 --enable-lzma --disable-metal --disable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libmysofa --disable-libnpp --enable-nvdec --enable-nvenc --enable-openal --enable-liboapv --enable-opencl --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-opengl --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libplacebo --enable-libpulse --enable-libqrencode --enable-libquirc --enable-librav1e --enable-librist --disable-librtmp --enable-librubberband --enable-libsmbclient --enable-sdl2 --enable-libshaderc --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-librsvg --enable-libsvtav1 --disable-libtensorflow --enable-libtheora --enable-libtwolame --enable-libuavs3d --enable-libv4l2 --enable-v4l2-m2m --enable-vaapi --enable-vdpau --enable-libvpl --enable-libvidstab --enable-libvmaf --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-vulkan --enable-libvvenc --enable-libwebp --enable-whisper --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxavs2 --enable-libxcb --enable-libxcb-shape --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxevd --enable-libxeve --enable-xlib --enable-libxml2 --enable-libxvid --enable-libzimg --enable-zlib --enable-libzmq --enable-libzvbi --disable-debug --enable-optimizations --disable-extra-warnings --disable-stripping
  libavutil      60.  8.100 / 60.  8.100
  libavcodec     62. 11.100 / 62. 11.100
  libavformat    62.  3.100 / 62.  3.100
  libavdevice    62.  1.100 / 62.  1.100
  libavfilter    11.  4.100 / 11.  4.100
  libswscale      9.  1.100 /  9.  1.100
  libswresample   6.  1.100 /  6.  1.100
[aist#0:0/pcm_s16le @ 0x55f5052989c0] Guessed Channel Layout: mono
Input #0, wav, from &apos;/home/huey/Downloads/GlobalNewsPodcast-20251205-FourCountriesBoycottEurovisionOverIsraelsInclusion.processed.wav&apos;:
  Duration: 00:27:36.46, bitrate: 705 kb/s
  Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, mono, s16, 705 kb/s
Stream mapping:
  Stream #0:0 -&gt; #0:0 (pcm_s16le (native) -&gt; mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to &apos;/home/huey/Downloads/GlobalNewsPodcast-20251205-FourCountriesBoycottEurovisionOverIsraelsInclusion.processed.mp3&apos;:
  Metadata:
    TSSE            : Lavf62.3.100
  Stream #0:0: Audio: mp3, 44100 Hz, mono, s16p
    Metadata:
      encoder         : Lavc62.11.100 libmp3lame
[out#0/mp3 @ 0x55f5052851c0] video:0KiB audio:24931KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.000885%
size=   24931KiB time=00:27:36.45 bitrate= 123.3kbits/s speed= 174x elapsed=0:00:09.54    
Processing complete. Output saved to: /home/huey/Downloads/GlobalNewsPodcast-20251205-FourCountriesBoycottEurovisionOverIsraelsInclusion.processed.mp3&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At the moment, I do have to manually download and process the relevant MP3. One way I do this with AntennaPod is to browse to the relevant podcast episode in AntennaPod and share this to my computer via &lt;a href=&quot;https://kdeconnect.kde.org/download.html&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;KDE Connect&lt;/a&gt;, then run the script on the downloaded file.&lt;/p&gt;
&lt;p&gt;If I find myself using this workflow enough I may look into augmenting the script to further automate this process.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;This was a useful reference: &lt;a href=&quot;https://digitalcardboard.com/blog/2009/08/25/the-sox-of-silence/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://digitalcardboard.com/blog/2009/08/25/the-sox-of-silence/&lt;/a&gt;&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Fake micro SD cards]]></title><description><![CDATA[Identifying and 'fixing' a fraudulent micro SD card

I have been on a bit of a year-end tidying and cleanup spree. In the course of this, I came across the following micro SD card: Photograph…]]></description><link>https://huey.xyz/posts/2025-12-14-fraudulent-flash</link><guid isPermaLink="false">c0a7f8ce5966aacb1a39afd95f233c18cefe9dd4166c2181b9ce57f276c41e35</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sun, 14 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Identifying and &apos;fixing&apos; a fraudulent micro SD card&lt;/h2&gt;&lt;p&gt;I have been on a bit of a year-end tidying and cleanup spree. In the course of this, I came across the following micro SD card:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971096.189229674549/micro_sd_card.avif&quot; alt=&quot;Photograph of micro SD card&quot;&gt;&lt;/p&gt;
&lt;p&gt;There weren&apos;t any obvious red flags in the design or construction of the micro SD card (putting aside the claimed capacity). I don&apos;t recall how I obtained this micro SD card — it had been lying in a drawer for some time.&lt;/p&gt;
&lt;p&gt;The capacity appeared to be quite impressive: 512 GB(?). It looked too new to be a 512 MB card, and indeed when I plugged it in, it claimed to have about about a 500 GB capacity. That is a suspiciously large capacity, which whilst technically possible, would probably be beyond my usual price range for SD cards (I think the next largest SD card I have is 128GB?).&lt;/p&gt;
&lt;h1 id=&quot;a-brief-rant-about-fake-flash-storage-listings&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#a-brief-rant-about-fake-flash-storage-listings&quot; aria-label=&quot;a brief rant about fake flash storage listings permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;A brief rant about fake flash storage listings&lt;/h1&gt;
&lt;p&gt;I am all too aware that fake SD cards (and fake flash drives and SSDs) are pretty common. Matt Cole conducted a self-funded survey of about 476 SD cards purchased from Amazon and AliExpress and found that about 12% were completely fraudulent.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; I suspect the number would be much higher if he tested higher capacity SD cards or if his sample included dodgier cards such as Xiaomi SD cards (Xiaomi doesn&apos;t make SD cards) and generic SD cards.&lt;/p&gt;
&lt;p&gt;The number of fraudulent flash storage listings on online e-commerce platforms such as Shopee is quite astounding and the platforms&apos; anti-fraud measures (if any) are clearly inadequate. A simple search will quickly reveal many &apos;Xiaomi&apos; SD cards (again, Xiaomi doesn&apos;t make SD cards) and 2TB SD cards for incredible prices:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971096.189229674551/shopee_1.avif&quot; alt=&quot;Screenshot of Xiaomi SD card on Shopee&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971096.189229674554/shopee_2.avif&quot; alt=&quot;Screenshot of cheap SSD on Shopee&quot;&gt;&lt;/p&gt;
&lt;p&gt;I previously reported one particular Shopee seller who attempted to sell me a fraudulent SSD, and pointed out in my report that his other listings were very likely to be fraudulent as well. 3 months later, the seller is still happily selling on the platform with new listings (but with the same photos), at similarly incredible prices, and with a 4.6 / 5 rating. Looking at the reviews, I suspect most are not authentic and a minority are from buyers who have fallen victim to the scam and who have yet to realise the claimed capacity does not match the actual capacity.&lt;/p&gt;
&lt;p&gt;I had a strong suspicion I had one of those fraudulent SD cards on my hands and I set out to confirm this.&lt;/p&gt;
&lt;h1 id=&quot;investigation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#investigation&quot; aria-label=&quot;investigation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Investigation&lt;/h1&gt;
&lt;p&gt;Flash fraud is a well known problem and various people much more experienced and talented than I have created useful tools to combat this. One of these tools is &lt;a href=&quot;https://fight-flash-fraud.readthedocs.io/en/latest/introduction.html&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;f3&lt;/code&gt;&lt;/a&gt;, which stands for Fight Flash Fraud. It&apos;s a simple command line tool for testing flash storage devices.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://search.nixos.org/packages?channel=25.11&amp;#x26;show=f3&amp;#x26;query=f3&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;f3&lt;/code&gt; is in &lt;code class=&quot;language-text&quot;&gt;nixpkgs&lt;/code&gt;&lt;/a&gt; so it&apos;s simple to install in NixOS, I just added it to &lt;code class=&quot;language-text&quot;&gt;environment.systemPackages&lt;/code&gt; in my &lt;code class=&quot;language-text&quot;&gt;configuration.nix&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;f3&lt;/code&gt; tests the device by continuously writing data to the device until the device is filled, and in this way determines whether the claimed capacity matches the actual capacity.&lt;/p&gt;
&lt;p&gt;As expected, my &apos;512GB&apos; micro SD card was fraudulent and had a usable capacity of only 29.44 GB.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971096.189229674556/terminal.avif&quot; alt=&quot;Screenshot of f3 tool in action&quot;&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://man7.org/linux/man-pages/man1/dmesg.1.html&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dmesg&lt;/code&gt;&lt;/a&gt; output similarly indicated that the manufacturer was &apos;Generic&apos; and not Samsung as the exterior of the micro SD card claimed.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;f3&lt;/code&gt; helpfully provides a useful function to &apos;fix&apos; the fake card essentially by repartitioning the card to fit its actual capacity. I went ahead and did this, and now I have a generic 29.44GB micro SD card instead (which I still don&apos;t entirely trust and wouldn&apos;t use for any data I actually wanted to keep).&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;&lt;a href=&quot;https://www.bahjeez.com/the-great-microsd-card-survey/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.bahjeez.com/the-great-microsd-card-survey/&lt;/a&gt;&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Adding a USD 4.5 Xiaomi temperature sensor to Home Assistant via ZigBee]]></title><description><![CDATA[Flashing custom firmware that adds ZigBee support to this BLE device

Xiaomi sells what they describe as a "Smart Temperature and Humidity Monitor". Essentially it is a tiny plastic box, about 4x4cm, that…]]></description><link>https://huey.xyz/posts/2025-09-21-xiaomi-temperature-sensor</link><guid isPermaLink="false">c7d2aabd121110833593e1d4af48a21d3a4a58543c32ebd1d7789c7c43b1af86</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sun, 21 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Flashing custom firmware that adds ZigBee support to this BLE device&lt;/h2&gt;&lt;p&gt;Xiaomi sells what they describe as a &quot;Smart Temperature and Humidity Monitor&quot;. Essentially it is a tiny plastic box, about 4x4cm, that measures the temperature and displays it on its tiny LCD display.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.mi.com/global/product/xiaomi-smart-temperature-and-humidity-monitor-3/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;This is the latest version at the time of writing&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971095.189229674540/xiaomi.avif&quot; alt=&quot;Screenshot of Xiaomi marketing page&quot;&gt;&lt;/p&gt;
&lt;p&gt;I have not tested the accuracy of the temperature or humidity readings, but my experience so far has been that the readings are broadly in line with my expectations. &lt;a href=&quot;https://www.mi.com/global/support/faq/details/KA-06622/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Xiaomi claims&lt;/a&gt; the margin of error is ±0.3℃ for the temperature reading and ±3% for humidity.&lt;/p&gt;
&lt;p&gt;Anyway, the devices are pretty cheap. You can get an older version (with essentially the same functionality) &lt;a href=&quot;https://www.aliexpress.com/item/1005006133725144.html&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;off AliExpress for SGD 5.70 (about USD 4.5)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A simple display with the temperature and humidity, whilst nice, isn&apos;t terribly exciting though.&lt;/p&gt;
&lt;p&gt;Xiaomi says that these devices are &apos;smart&apos;. What they mean is that the device integrates with Xiaomi&apos;s Mi Home ecosystem, and you can pair the device with your phone (or a Mi Home gateway), and read the temperature and humidity data off the Mi Home app.&lt;/p&gt;
&lt;p&gt;I am not particularly inclined to get into the closed Mi Home ecosystem or install the Mi Home app. What I wanted to do was to integrate this device with the &lt;a href=&quot;https://www.home-assistant.io/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;open source Home Assistant automation system&lt;/a&gt; which I already have setup.&lt;/p&gt;
&lt;p&gt;Fortunately, this is very much possible.&lt;/p&gt;
&lt;h1 id=&quot;ble&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#ble&quot; aria-label=&quot;ble permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;BLE&lt;/h1&gt;
&lt;p&gt;Out of the box, the device advertises itself and transmits data via Bluetooth Low Energy (BLE). I was able to add the device via the &lt;a href=&quot;https://gadgetbridge.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Gadgetbridge&lt;/a&gt; Android app, but could not read the temperature or humidity data. It looks like support for retrieving temperature and humidity data &lt;a href=&quot;https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/3803&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;is coming to Gadgetbridge soon, but is not there as yet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There is a fairly well trodden path for adding the device to Home Assistant via BLE by flashing open source custom firmware to the device that has BTHome support. The latest version at the moment is at &lt;a href=&quot;https://github.com/pvvx/ATC_MiThermometer&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;github.com/pvvx/ATC_MiThermometer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Adding the device via BLE to Home Assistant, whilst possible, was not my preferred route because that would mean I would need to set up a &lt;a href=&quot;https://esphome.io/components/bluetooth_proxy/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Bluetooth Proxy&lt;/a&gt; to talk to the device. I already have a decent ZigBee network over ZigBee2MQTT and would prefer to stick to that.&lt;/p&gt;
&lt;h1 id=&quot;zigbee&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#zigbee&quot; aria-label=&quot;zigbee permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;ZigBee&lt;/h1&gt;
&lt;p&gt;Fortunately, there is open source custom firmware that allows the device to transmit via ZigBee instead of BLE: &lt;a href=&quot;https://github.com/devbis/z03mmc&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;github.com/devbis/z03mmc&lt;/a&gt;. The device is inherently a BLE device, but how the magic happens is by taking advantage of the built-in but unused capabilities of the microcontroller unit (MCU). The MCU is a Telink MCU which supports both BLE and ZigBee. The ZigBee capability seems to be unused by the stock firmware.&lt;/p&gt;
&lt;p&gt;Flashing the custom ZigBee firmware is simple and can even be done over-the-air (OTA) from a web browser:&lt;/p&gt;
&lt;p&gt;First, visit &lt;a href=&quot;https://devbis.github.io/telink-zigbee/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;devbis.github.io/telink-zigbee/&lt;/a&gt;, which is an OTA flashing web app developed by the developer of the custom firmware&lt;/p&gt;
&lt;p&gt;You&apos;ll have to visit in a Chromium browser, as the Web Bluetooth browser APIs used in the web app are currently only available on Chromium browsers&lt;/p&gt;
&lt;p&gt;If on Linux, you may need to &lt;a href=&quot;https://askubuntu.com/questions/133235/how-do-i-allow-non-root-access-to-ttyusb0&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;add yourself to the &lt;code class=&quot;language-text&quot;&gt;dialout&lt;/code&gt;&lt;/a&gt; or &lt;code class=&quot;language-text&quot;&gt;tty&lt;/code&gt; groups, log out, and log back in, if your browser complains about not being able to access the tty port.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Next, via the web app, connect to your device by clicking the &quot;Connect button&quot;.&lt;/p&gt;
&lt;p&gt;If your device is not appearing in the list, you may need to put it into pairing mode. Remove the back cover of the device and connect the Ground and Reset pins via a wire.&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; The screen of the device should turn off and back on. I took the following photo when replacing the CR2032 battery:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971095.189229674536/back-of-device.avif&quot; alt=&quot;Photograph of back of the device&quot;&gt;&lt;/p&gt;
&lt;p&gt;The model number of the device should appear in the list. Mine was &quot;LYWSD03MMC&quot;. Proceed to pair.&lt;/p&gt;
&lt;p&gt;If you wanted to go down the BLE route mentioned above, you would select &quot;Custom Firmware&quot;. For ZigBee support, you should select &quot;Zigbee Firmware&quot;, and click &quot;Start Flashing&quot;. This will flash the custom ZigBee firmware I linked to earlier.&lt;/p&gt;
&lt;p&gt;Once flashing is complete, you can proceed to pair the device with your ZigBee network. In my case, I toggled &quot;enable join&quot; to allow devices to join my ZigBee network then reset the device by connecting the Ground and Reset pins, as before, to put the device in pairing mode.&lt;/p&gt;
&lt;p&gt;ZigBee2MQTT quickly paired and interviewed the device. &lt;a href=&quot;https://www.zigbee2mqtt.io/devices/LYWSD03MMC-z.html&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;It has native support in ZigBee2MQTT&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971095.189229674542/zigbee2mqtt_1.avif&quot; alt=&quot;Screenshot of device page on ZigBee2MQTT&quot;&gt;&lt;/p&gt;
&lt;p&gt;It exposes the temperature and humidity sensors and a whole bunch of options:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971096.189229674544/zigbee2mqtt_2.avif&quot; alt=&quot;Screenshot of entities and options exposed by device on ZigBee2MQTT&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;There seems to be an issue with &lt;a href=&quot;https://search.nixos.org/packages?channel=25.05&amp;#x26;show=google-chrome&amp;#x26;query=google-chrome&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;google-chrome&lt;/code&gt; on nixpkgs&lt;/a&gt; that prevents the Web Bluetooth APIs from working properly, which is probably to be expected since Web Bluetooth support is experimental on Linux anyway. I was not in the mood to debug this so as a quick fix I just used Google Chrome on Android phone, which worked perfectly well.&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;A male-to-male breadboard jumper wire should work well. I didn&apos;t have one handy though, so I improved with 2 screws I had lying around. It worked.&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Migrating from Omnivore to Wallabag]]></title><description><![CDATA[Self-hosted setup using docker-compose and importing of articles from Omnivore

UPDATE (2025): I have since moved to Linkding, which I prefer to Wallabag, mostly because it is much snappier. The read-it-later app which I…]]></description><link>https://huey.xyz/posts/2024-11-23-wallabag-omnivore-import</link><guid isPermaLink="false">b699caae4d9a33d372d1506b06d4b8f80f294bb18c1e976ceb08ba178aafff76</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 23 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Self-hosted setup using docker-compose and importing of articles from Omnivore&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;UPDATE (2025)&lt;/strong&gt;: I have since moved to &lt;a href=&quot;https://github.com/sissbruecker/linkding&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Linkding&lt;/a&gt;, which I prefer to Wallabag, mostly because it is much snappier.&lt;/p&gt;
&lt;p&gt;The read-it-later app which I had been using, &lt;a href=&quot;https://omnivore.app/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Omnivore&lt;/a&gt;, recently announced that it was being acquired by EvenLabs and would shut down on 30 November 2024.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Although Omnivore is technically open source (which was one of the reasons I selected it), the project is not mature. &lt;a href=&quot;https://github.com/omnivore-app/omnivore/pull/4465&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;It does not actually support self-hosted installations at the moment&lt;/a&gt; and the mobile apps will in any case need to be republished with a developer account.&lt;/p&gt;
&lt;p&gt;I figured that this was a good lesson and an opportune time to migrate to &lt;a href=&quot;https://wallabag.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;a well-established, open source, self-hostable read-it-later service, Wallabag&lt;/a&gt;. This was in fact one of the options recommended by the Omnivore team and appears to be a fairly common choice amongst many former Omnivore users.&lt;/p&gt;
&lt;p&gt;Wallabag very helpfully includes support for importing articles from Omnivore.&lt;/p&gt;
&lt;h1 id=&quot;export-from-omnivore&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#export-from-omnivore&quot; aria-label=&quot;export from omnivore permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Export from Omnivore&lt;/h1&gt;
&lt;p&gt;First, you have to export your data from Omnivore, which you can do by navigating to &lt;a href=&quot;https://omnivore.app/settings/account&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://omnivore.app/settings/account&lt;/a&gt; and clicking the &quot;Export Data&quot; button:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971094.189229674529/omnivore.avif&quot; alt=&quot;Screenshot of Omnivore export screen&quot;&gt;&lt;/p&gt;
&lt;p&gt;You should do this before 30 November 2024 because Omnivore may not be accessible after that date.&lt;/p&gt;
&lt;h1 id=&quot;wallabag-setup&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#wallabag-setup&quot; aria-label=&quot;wallabag setup permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Wallabag setup&lt;/h1&gt;
&lt;p&gt;Next, if you have not already done so, you should &lt;a href=&quot;https://doc.wallabag.org/en/admin/installation/readme&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;set up your Wallabag installation&lt;/a&gt; (or using the hosted Wallabag server).&lt;/p&gt;
&lt;p&gt;The process is quite similar to other self-hosted apps. I used &lt;a href=&quot;https://docs.docker.com/compose/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;docker-compose&lt;/code&gt;&lt;/a&gt; and my &lt;code class=&quot;language-text&quot;&gt;docker-compose&lt;/code&gt; file looks something like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;docker&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-docker line-numbers&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;services:
  app:
    image: wallabag/wallabag
    env_file: .env
    ports:
      - 80:80
    volumes:
      - ./data:/var/www/wallabag/data
      - ./config:/var/www/wallabag/config
      - ./images:/var/www/wallabag/web/assets/images
    depends_on:
      - wallabag-db
      - wallabag-redis
    
  db:
    image: postgres:17-alpine
    env_file: .env
    volumes:
      - ./postgresql_data:/var/lib/postgresql/data
    
  redis:
    image: redis:alpine&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;.env&lt;/code&gt; file looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;SYMFONY__ENV__DOMAIN_NAME=https://your-url.com
SYMFONY__ENV__SECRET=supersecure
SYMFONY__ENV__SERVER_NAME=&quot;Your Wallabag Server&quot;  
TZ=Asia/Singapore  
PUID=[INSERT]  
PGID=[INSERT]   
SYMFONY__ENV__DATABASE_DRIVER=pdo_pgsql  
SYMFONY__ENV__DATABASE_HOST=db  
SYMFONY__ENV__DATABASE_PORT=5432  
SYMFONY__ENV__DATABASE_NAME=wallabag  
SYMFONY__ENV__DATABASE_USER=wallabag  
SYMFONY__ENV__DATABASE_PASSWORD=wallabager  
POSTGRES_USER=wallabag  
POSTGRES_PASSWORD=wallabager  
POPULATE_DATABASE=true  
SYMFONY__ENV__FOSUSER_REGISTRATION=false  
SYMFONY__ENV__REDIS_HOST=redis&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You will obviously need to fill in the placeholders and replace the dummy values as appropriate.&lt;/p&gt;
&lt;p&gt;One issue I ran into was that the initial database migrations do not appear to run automatically when the docker containers are created, resulting in errors to the effect that database tables are not found or do not exist:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;no such table: wallabag_internal_setting&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Table &apos;wallabag_db.wallabag_craue_config_setting&apos; doesn&apos;t exist&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1 no such table: wallabag_internal_setting&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This &lt;a href=&quot;https://github.com/wallabag/docker/issues/377&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;seems to be a known issue&lt;/a&gt;. A &lt;a href=&quot;&quot;&gt;pull request which should fix this is pending&lt;/a&gt;, but in the meantime this can easily be resolved by running the migrations manually. &lt;code class=&quot;language-text&quot;&gt;docker exec&lt;/code&gt; into the app container and run the following:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bin/console doctrine:migrations:migrate &lt;span class=&quot;token parameter variable&quot;&gt;--env&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;prod --no-interaction&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Separately, the default credentials for the initial user created by the setup process don&apos;t appear to be documented in &lt;a href=&quot;https://doc.wallabag.org/en/admin/installation/readme&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the Wallabag documentation site&lt;/a&gt;. The default credentials are set out in &lt;a href=&quot;https://github.com/wallabag/docker#how-to-use-this-image&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the README for the docker image&lt;/a&gt; but just to save you the trouble of looking it up:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Username: wallabag&lt;/p&gt;
&lt;p&gt;Password: wallabag&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;importing-omnivore-articles-into-wallabag&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#importing-omnivore-articles-into-wallabag&quot; aria-label=&quot;importing omnivore articles into wallabag permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Importing Omnivore articles into Wallabag&lt;/h1&gt;
&lt;p&gt;After you have successfully logged into Wallabag, you will find that on the import page, there is an option to upload and import your Omnivore JSON export files:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971095.189229674532/wallabag.avif&quot; alt=&quot;Screenshot of Wallabag import screen&quot;&gt;&lt;/p&gt;
&lt;p&gt;Keen-eyed readers will however, have noticed, that the importer purports to require the JSON export files to be uploaded &quot;one by one&quot;. For me, this was a highly unsatisfactory state of affairs because I had more than 1,000 articles to import, and each JSON file contained about 20 articles.&lt;/p&gt;
&lt;p&gt;Fortunately, it seems that the constraint is with the number of files that can be uploaded at once and not the number of items imported.&lt;/p&gt;
&lt;p&gt;I aggregated all my JSON exports into a single file with the handy &lt;a href=&quot;https://jqlang.github.io/jq/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;jq&lt;/code&gt; CLI utility&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ~/omnivore_export_directory
jq &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[.[][]]&apos;&lt;/span&gt; *.json &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; omnivore.json&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After uploading this to Wallabag, Wallabag appeared to freeze for several minutes whilst processing the files, but the import ultimately succeeded and I am now a satisfied Wallabag user.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;&lt;a href=&quot;https://techcrunch.com/2024/10/29/elevenlabs-has-hired-the-team-behind-omnivore-a-reader-app/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The intention seems to be to use some of Omnivore&apos;s capabilities in ElevenLabs&apos; own AI-powered reader app.&lt;/a&gt;&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Resetting your password on NixOS]]></title><description><![CDATA[What to do after if you accidentally lock yourself out

When messing around with my NixOS config during an install, I managed to accidentally log myself out of my system by setting my…]]></description><link>https://huey.xyz/posts/2024-10-07-nixos-password-reset</link><guid isPermaLink="false">dd9275cb38e1ff740232cb510ca41a13d283ba5667e44af4dbf4186c6f3b9b82</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Mon, 07 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;What to do after if you accidentally lock yourself out&lt;/h2&gt;&lt;p&gt;When messing around with my &lt;a href=&quot;https://nixos.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NixOS&lt;/a&gt; config during an install, I managed to accidentally log myself out of my system by setting my hashedPassword to a string that was not a hash.&lt;/p&gt;
&lt;p&gt;Much of the time, the easiest way to fix this will be to revert to an earlier configuration in the bootloader (this being NixOS and all), but my situation was a bit special because this was the first configuration following a fresh install.&lt;/p&gt;
&lt;p&gt;I was not inclined to go through the reinstall process, so fortunately, after a bit of searching and experimentation, I was able to reset my password by rebooting into single user mode. I set out the steps below for the benefit of my future self (lest this happen again) and any other foolhardy NixOS tinkerers.&lt;/p&gt;
&lt;p&gt;You can enter single user mode by amending the kernel parameters at the GRUB boot menu:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select the desired NixOS boot entry&lt;/li&gt;
&lt;li&gt;Press &lt;kbd&gt;e&lt;/kbd&gt; to edit the boot entry&lt;/li&gt;
&lt;li&gt;Append the following: &lt;code class=&quot;language-text&quot;&gt;single systemd.setenv=SYSTEMD_SULOGIN_FORCE=1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Continue to boot&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You should get a root prompt and can then reset your user&apos;s password using &lt;code class=&quot;language-text&quot;&gt;passwd&lt;/code&gt;, e.g. &lt;code class=&quot;language-text&quot;&gt;passwd huey&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Kubuntu 24.04 LTS display bug]]></title><description><![CDATA[Blank screen on boot and external monitors not detected

I recently installed Kubuntu 24.04 LTS (Noble Numbat) on a laptop and all was well. I had been using flavours of Ubuntu 20.04 LTS, but when…]]></description><link>https://huey.xyz/posts/2024-06-01-kubuntu-24-display-bug</link><guid isPermaLink="false">d26cac97bc986de3166b15c994ea2f0b5c959efcfba7cd433791ddba4f336a4d</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 01 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Blank screen on boot and external monitors not detected&lt;/h2&gt;&lt;p&gt;I recently installed Kubuntu 24.04 LTS (Noble Numbat) on a laptop and all was well. I had been using flavours of Ubuntu 20.04 LTS, but when I was creating a new boot media this time round, the default Ubuntu download was 24.04 so I went with that. Maybe it would have been wiser to wait for 24.04.4.&lt;/p&gt;
&lt;p&gt;The first and second boots were fine. However, on one of the subsequent boots, after the GRUB menu, the Kubuntu splash logo never showed up, and there was just a black screen. Trying to get to an alternative TTY via &lt;code class=&quot;language-text&quot;&gt;Ctrl-Alt-F2&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;F3&lt;/code&gt;, etc. didn&apos;t work either. The only way out was to do a hard shutdown by holding the power button.&lt;/p&gt;
&lt;p&gt;Interestingly, booting into recovery mode, and then resuming normal boot allowed me to boot to desktop, although then I had a second issue — external monitors were not detected in the KDE settings app and also not via &lt;code class=&quot;language-text&quot;&gt;xrandr -q&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It turns out that many other people have encountered this rather serious bug:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://old.reddit.com/r/Kubuntu/comments/1cdko49/beware_kubuntu_2404_is_presenting_displaygraphics/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;/r/Kubuntu — Beware: Kubuntu 24.04 Is Presenting Display/Graphics Driver Issues For Some Users&lt;/a&gt; (26 April 2024)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://old.reddit.com/r/Kubuntu/comments/1c915x0/heads_up_i_hit_a_serious_bug_while_testing/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;/r/Kubuntu — Heads up: I hit a serious bug while testing Kubuntu 24.04!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It also looks like the bug has already been reported on Launchpad and GitHub as a bug in &lt;code class=&quot;language-text&quot;&gt;ssdm&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/sddm/+bug/2063143&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;sddm/simpledrm race conditions leads to frequent black display on bootup &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/sddm/+bug/2065321&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Kubuntu 24.04 Second boot always black screen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sddm/sddm/issues/1917&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;ssdm/ssdm — SDDM races with DRM GPU drivers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the meantime, there is a fairly simple workaround — simply skip the splash screen by editing the kernel options to remove &apos;splash&apos;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt; /etc/default/grub

&lt;span class=&quot;token comment&quot;&gt;# Remove &apos;splash&apos; from the `GRUB_CMDLINE_LINUX_DEFAULT`&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# so that the line looks like this:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# GRUB_CMDLINE_LINUX_DEFAULT=&apos;quiet&apos;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;update-grub&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reboot, and all should be well again.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Using a custom domain with Fly.io]]></title><description><![CDATA[How to set up a custom domain with a shared IPv4 address on Fly.io

From 1 February 2024, Fly.io stopped providing  dedicated IPv4 addresses for free and started charging for these. If you don't need a…]]></description><link>https://huey.xyz/posts/2024-03-02-custom-domain-with-flyio</link><guid isPermaLink="false">5c4aac1b89eb9d92065c72d5ef00b9543a7a1adda312b31579a8cb3d80bf6e7b</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 02 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;How to set up a custom domain with a shared IPv4 address on Fly.io&lt;/h2&gt;&lt;p&gt;From 1 February 2024, Fly.io &lt;a href=&quot;https://community.fly.io/t/new-date-we-are-going-to-start-charging-for-dedicated-ipv4-in-january-1st-starting-february-1st/15970&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;stopped providing  dedicated IPv4 addresses for free&lt;/a&gt; and started charging for these. If you don&apos;t need a dedicated IPv4 address, it is still possible to have your app publicly-accessible on the web via a shared IPv4 address instead (see instructions in the foregoing hyperlink).&lt;/p&gt;
&lt;p&gt;What is less clear from Fly.io&apos;s documentation is how this gels with custom domains. I recently received rather high traffic on a Fly.io app and racked up some bandwidth costs so I decided to put Cloudflare in front of my Fly.io app. The process was not as straightforward as I hoped so I thought I&apos;d just document it here for my future self as well as anyone else trying to do the same.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://fly.io/docs/networking/custom-domain/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Fly.io &quot;Use a custom domain&quot; page&lt;/a&gt; makes this out to be easier than it actually is: it just states that you have to set a CNAME to your &lt;code class=&quot;language-text&quot;&gt;*.fly.dev&lt;/code&gt; hostname or A record to your IPv4 address. But as you may have realised since you are on this page, that alone doesn&apos;t work and will net you a Cloudflare error code 520 (&quot;Web server is returning an unknown error&quot;).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971090.189229674510/cloudflare_520.avif&quot; alt=&quot;Cloudflare Error 520&quot;&gt;&lt;/p&gt;
&lt;p&gt;There are two missing steps:&lt;/p&gt;
&lt;h1 id=&quot;registering-your-custom-domain&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#registering-your-custom-domain&quot; aria-label=&quot;registering your custom domain permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Registering your custom domain&lt;/h1&gt;
&lt;p&gt;The first missing step is to set up a SSL cert with Fly.io for your custom domain. You need to do this &lt;em&gt;even if you are only accessing your app via HTTP&lt;/em&gt; because this is how Fly.io proxies requests to shared IPv4 addresses. Using &lt;a href=&quot;https://fly.io/docs/hands-on/install-flyctl/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;flyctl&lt;/code&gt;&lt;/a&gt;, i.e. the Fly.io CLI tool:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;flyctl certs add your.custom.domain.com&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is briefly mentioned on the &lt;a href=&quot;https://fly.io/docs/networking/custom-domain/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&quot;Use a custom domain&quot; page&lt;/a&gt; under the header &quot;Get certified&quot;, but it is not made clear that you need to set up a SSL cert even if you are not relying on Fly.io for a SSL certificate.&lt;/p&gt;
&lt;h1 id=&quot;cloudflare-ssltls-encryption&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#cloudflare-ssltls-encryption&quot; aria-label=&quot;cloudflare ssltls encryption permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Cloudflare SSL/TLS encryption&lt;/h1&gt;
&lt;p&gt;Next, you should turn your SSL/TLS encryption mode on the Cloudflare dashboard to &apos;Full&apos;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971094.189229674519/cloudflare_ssl_settings.avif&quot; alt=&quot;Cloudflare SSL settings&quot;&gt;&lt;/p&gt;
&lt;p&gt;If you have other subdomains on Cloudflare that require less strict encryption, it may be more convenient and less hassle to do this via a Cloudflare configuration rule:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971090.189229674513/cloudflare_rule1.avif&quot; alt=&quot;Cloudflare configuration rules - top section&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971094.189229674516/cloudflare_rule2.avif&quot; alt=&quot;Cloudflare configuration rules - bottom section&quot;&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Useful RSS feeds for legal practice in Singapore]]></title><description><![CDATA[So you don't miss anything and don't have to rely on LinkedIn

Over time I have put together a number of RSS feeds to stay up to date on developments relevant to legal practice in Singapore. Some of…]]></description><link>https://huey.xyz/posts/2024-01-17-useful-rss-feeds-for-legal-practice-in-singapore</link><guid isPermaLink="false">a822668121570de46d48b4998cc237c9e085530d08757aa41ddd456d8ea686a0</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Wed, 17 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;So you don&apos;t miss anything and don&apos;t have to rely on LinkedIn&lt;/h2&gt;&lt;p&gt;Over time I have put together a number of RSS feeds to stay up to date on developments relevant to legal practice in Singapore. Some of these may be useful for other legal practitioners in Singapore so I thought to publish a list. Some of these are provided by the source websites directly and others are feeds automatically generated via my &lt;a href=&quot;https://github.com/hueyy/HungryHippo&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;HungryHippo project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you are not sure how to use an RSS feed, it&apos;s simple, &lt;a href=&quot;/posts/2022-01-06-practical-rss/#pick-a-rss-reader&quot;&gt;you need a RSS reader&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;news&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#news&quot; aria-label=&quot;news permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;News&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://lawgazette.com.sg/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Law Society of Singapore: The Singapore Law Gazette&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.singaporelawwatch.sg/Portals/0/RSS/Headlines.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Law Watch: Headlines&lt;/a&gt; — this includes advertisements&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cookies.your-amicus.app/index.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SG Law Cookies by Your Amicus&lt;/a&gt; — an algorithmically-produced daily digest of legal news in Singapore, accompanied by an even shorter summary in the form of a short poem, courtesy of &lt;a href=&quot;https://www.lovelawrobots.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Hou Fu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mlaw.gov.sg/feed.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Ministry of Law: Press Releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;primary-sources-and-related-developments&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#primary-sources-and-related-developments&quot; aria-label=&quot;primary sources and related developments permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Primary sources and related developments&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.singaporelawwatch.sg/Results/rss/category/426/judgments-1&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Law Watch: Judgments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.singaporelawwatch.sg/Results/rss/category/426/notices-and-directions&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Law Watch: Notices and Directions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sso.agc.gov.sg/What&amp;#x27;s-New/New-Legislation/RSS&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Statutes Online: New Legislation&lt;/a&gt; — this includes &lt;em&gt;all&lt;/em&gt; new legislation so the volume is very high&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lawgazette.com.sg/category/notices/disciplinary-tribunal-reports/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Disciplinary Tribunal Reports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/sal.org.sg/lawreform&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SAL: Law Reform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;commentary&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#commentary&quot; aria-label=&quot;commentary permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Commentary&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.singaporelawwatch.sg/Results/rss/category/426/commentaries&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Law Watch: Commentaries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SAL Practitioner Journal
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Advocacy-and-Procedure&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Advocacy and Procedure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Arbitration-and-Mediation&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Arbitration and Mediation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Construction-and-Infrastructure&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Construction and Infrastructure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Corporate&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Corporate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Crime&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Crime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Employment-Law&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Employment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Family-and-Personal-Law&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Family and Personal Law&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Fintech&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;FinTech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Insolvency-and-Restructuring&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Insolvency and Restructuring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-practitioner/?area=Transportation&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Transportation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/sal-journal&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SAL Journal (SAcLJ)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/academypublishing.org.sg/annual-review-of-cases&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SAL Annual Review of Singapore Cases&lt;/a&gt; — will be empty when there is nothing in e-First&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/law1.nus.edu.sg/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Journal of Legal Studies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.asialawnetwork.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Asia Law Network Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lexology.com/email/rss.aspx?tagType=5&amp;#x26;tagRef=155&amp;#x26;tagTitle=%20Singapore&amp;#x26;extrajr=&amp;#x26;extrawr=&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Lexology: Singapore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nus.edu.sg/lawresearch/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NUS Law Research Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/law.nus.edu.sg/trail&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NUS TRAIL: Bits &amp;#x26; Bytes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://singaporeinternationalarbitration.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore International Arbitration Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;continuing-legal-education&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#continuing-legal-education&quot; aria-label=&quot;continuing legal education permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Continuing legal education&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/silecpdcentre.sg/CALAS&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SILE CPD Events: Calendar of Accredited Learning Activities (CALAS)&lt;/a&gt; — this covers all SILE-accredited CPD events&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.singaporelawwatch.sg/Results/rss/category/426/continuing-legal-education&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Law Watch — Continuing Legal Education&lt;/a&gt; — this includes events that are not accredited by SILE&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hungryhippo.huey.xyz/individual-site/law.nus.edu.sg/events&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NUS Law Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.trumba.com/calendars/SMU_SchoolLaw.rss?filterview=Publish+to+NextWeb&amp;#x26;filter4=_798882_&amp;#x26;filterfield4=37908&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SMU School of Law Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.trumba.com/calendars/SMU_CLE.xml?filterview=Publish+to+NextWeb&amp;#x26;filter4=_798882_&amp;#x26;filterfield4=37908&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SMU Law Academy Events&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Daisy-chaining GitHub actions]]></title><description><![CDATA[Triggering a GitHub action from a git push from another GitHub action

This site is a static site with a deployment pipeline that comprises various daisy-chained GitHub actions. For example, there is a GitHub…]]></description><link>https://huey.xyz/posts/2024-01-13-daisy-chaining-github-actions</link><guid isPermaLink="false">5bd968bd612c4235f6e79318fd801562ab5fc600390299d8aa1f41098430a601</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 13 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Triggering a GitHub action from a git push from another GitHub action&lt;/h2&gt;&lt;p&gt;This site is a static site with a deployment pipeline that comprises various daisy-chained &lt;a href=&quot;https://github.com/features/actions&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;GitHub actions&lt;/a&gt;. For example, there is a GitHub action that checks &lt;a href=&quot;https://orreadi.com/user/huey&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;my BookWyrm orreadi.com profile&lt;/a&gt; periodically, and updates a JSON file in the GitHub repository for this site if there are changes to the books that I am currently reading. The push to the GitHub repository in turn triggers the deployment GitHub action that rebuilds and redeploys this site.&lt;/p&gt;
&lt;p&gt;Initially, this process inexplicably failed to work — the git push from the first action somehow did not trigger the second action, even though the git push was successful and the second action had the &lt;code class=&quot;language-text&quot;&gt;push&lt;/code&gt; event as a triggering event.&lt;/p&gt;
&lt;p&gt;The relevant extract from the first action:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yml line-numbers&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Checkout repo
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v2
      &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Commit and push if it changed
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;
          git config user.name &quot;Automated update&quot;
          git config user.email &quot;actions@users.noreply.github.com&quot;
          git add &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;A
          timestamp=$(TZ=&apos;Asia/Singapore&apos; date)
          &lt;span class=&quot;token key atrule&quot;&gt;git commit -m &quot;Update content/data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;timestamp&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&quot; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; exit 0
          git pull &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;rebase
          git push&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the second action:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yml line-numbers&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; deploy
        &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After some digging, I came to learn that the problem was a restriction imposed by GitHub: when an action pushes using the repository&apos;s &lt;code class=&quot;language-text&quot;&gt;GITHUB_TOKEN&lt;/code&gt;,&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; the resulting push will &lt;strong&gt;not&lt;/strong&gt; trigger any other actions configured to run when push events occur.&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; It&apos;s not clear why this restriction is imposed. Perhaps it is intended as a safety precaution to prevent users from accidentally creating runaway self-triggering chains of actions.&lt;/p&gt;
&lt;p&gt;In any case, it is fairly straightforward to work around this restriction by simply providing your own GitHub personal access token:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Generate a new personal access token (PAT) at &lt;a href=&quot;https://github.com/settings/tokens&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;github.com/settings/tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Add the PAT as a secret to your repository via Settings &gt; Secrets and variables &gt; Actions &gt; New repository secret&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Amend the &lt;code class=&quot;language-text&quot;&gt;actions/checkout&lt;/code&gt; step in your action that pushes to the repository to include your PAT.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Extract of my amended first action:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-yml line-numbers&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ubuntu&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;latest
    &lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Checkout repo
        &lt;span class=&quot;token key atrule&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; actions/checkout@v2
        &lt;span class=&quot;token key atrule&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; secrets.PAT &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Commit and push if it changed
        &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;
          git config user.name &quot;Automated update&quot;
          git config user.email &quot;actions@users.noreply.github.com&quot;
          git add &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;A
          timestamp=$(TZ=&apos;Asia/Singapore&apos; date)
          &lt;span class=&quot;token key atrule&quot;&gt;git commit -m &quot;Update content/data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;timestamp&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&quot; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; exit 0
          git pull &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;rebase
          git push&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;A GitHub access token automatically injected into the action for convenience.&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;See &lt;a href=&quot;https://github.com/orgs/community/discussions/25702#discussioncomment-3248819&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;this discussion&lt;/a&gt; on GitHub.&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;Take note of what you name the secret, I named mine &lt;code class=&quot;language-text&quot;&gt;PAT&lt;/code&gt;. If you name yours something different, you will have to use that name when amending your action.&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Automated requests and Cloudflare's TLS fingerprinting]]></title><description><![CDATA[My (initially unsuccessful) attempts to fetch a RSS feed via curl

When making automated requests to a RSS feed, I recently came across very peculiar behaviour. The RSS feed (lawgazette.com.sg/feed/) would…]]></description><link>https://huey.xyz/posts/2023-11-19-automated-requests-and-cloudflare-tls-fingerprinting</link><guid isPermaLink="false">93879804af7209b3d9f96270fcae63f7807a51576044f48912c26f78ef9717da</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sun, 19 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;My (initially unsuccessful) attempts to fetch a RSS feed via curl&lt;/h2&gt;&lt;p&gt;When making automated requests to a &lt;a href=&quot;/posts/2021-07-18-rss/&quot;&gt;RSS feed&lt;/a&gt;, I recently came across very peculiar behaviour. The RSS feed (&lt;a href=&quot;https://lawgazette.com.sg/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;lawgazette.com.sg/feed/&lt;/a&gt;) would load just fine in my browser (Firefox) but not when I used &lt;a href=&quot;https://curl.se/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt;&lt;/a&gt;, e.g.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; https://lawgazette.com.sg/feed/

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;DOCTYPE html&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;html &lt;span class=&quot;token assign-left variable&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;en-US&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Just a moment&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/title&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;meta http-equiv&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;text/html; charset=UTF-8&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;meta http-equiv&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IE=Edge&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;meta &lt;span class=&quot;token assign-left variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;robots&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;noindex,nofollow&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;meta &lt;span class=&quot;token assign-left variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;viewport&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;width=device-width,initial-scale=1&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;link &lt;span class=&quot;token assign-left variable&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/cdn-cgi/styles/challenges.css&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/head&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;body &lt;span class=&quot;token assign-left variable&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;no-js&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token assign-left variable&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;main-wrapper&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token assign-left variable&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;main-content&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;noscript&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token assign-left variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;challenge-error-title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token assign-left variable&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;h2&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span &lt;span class=&quot;token assign-left variable&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;icon-wrapper&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div &lt;span class=&quot;token assign-left variable&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;heading-icon warning-icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span &lt;span class=&quot;token assign-left variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;challenge-error-text&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Enable JavaScript and cookies to continue&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/noscript&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
// blah blah blah, you get the idea
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;script defer &lt;span class=&quot;token assign-left variable&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://static.cloudflareinsights.com/beacon.min.js/v8b253dfea2ab4077af8c6f58422dfbfd1689876627854&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;integrity&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sha512-bjgnUKX4azu3dLTVtie9u6TKqgx29RBwfj3QXYt5EKfWM/9hPSAI/4qcV5NACjwAo8UtTeWefx6Zq5PHcMm7Tg==&quot;&lt;/span&gt; data-cf-beacon&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;{&quot;rayId&quot;:&quot;812eb66bb8535c33&quot;,&quot;version&quot;:&quot;2023.8.0&quot;,&quot;b&quot;:1,&quot;token&quot;:&quot;ede0727b61e541778f23feef22f36592&quot;,&quot;si&quot;:100}&apos;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;crossorigin&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;anonymous&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/script&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/body&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/html&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;%&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The unminified HTML returned above is Cloudflare&apos;s challenge page.&lt;/p&gt;
&lt;h1 id=&quot;investigation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#investigation&quot; aria-label=&quot;investigation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Investigation&lt;/h1&gt;
&lt;p&gt;Pretty simple, I thought, Cloudflare is probably running all sorts of &apos;real browser&apos; checks, e.g. calling HTML canvas APIs, checking what fonts are installed, looking at the user agent, etc. But then I noticed that I had the &lt;a href=&quot;https://jshelter.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;JShelter&lt;/a&gt; browser extension enabled, which thwarts most fingerprinting attempts. Odd.&lt;/p&gt;
&lt;p&gt;If I had been ssh&apos;ed into a VPS, I would have chalked it up to IP address blacklisting or greylisting, but I was calling &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt; from my own residential IP address.&lt;/p&gt;
&lt;p&gt;Since the page I was loading was a RSS feed, I popped it into a desktop RSS reader, &lt;a href=&quot;https://hyliu.me/fluent-reader/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Fluent Reader&lt;/a&gt;, just to check, fully expecting that the HTTP request sent by the RSS reader would trigger the Cloudflare challenge. But the feed loaded just fine. Very odd.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971090.189229674501/fluent.avif&quot; alt=&quot;Screenshot of Fluent Reader&quot;&gt;&lt;/p&gt;
&lt;p&gt;At this point, I recalled that Fluent Reader was an &lt;a href=&quot;https://hyliu.me/fluent-reader/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Fluent Reader&lt;/a&gt; so it was possible that the request was being sent via headless Chrome, which might pass the &apos;real browser&apos; checks. It seemed unlikely the RSS feed was being fetched in the frontend headless Chrome layer rather than the Node.JS backend, not least because the former would give rise to &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;CORS issues&lt;/a&gt;, but I decided to try fetching the RSS feed in a non-Electron app, &lt;a href=&quot;https://github.com/QuiteRSS/quiterss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;QuiteRSS&lt;/a&gt;, just to be sure.&lt;/p&gt;
&lt;p&gt;It worked again. Very odd. Perhaps there was some kind of secret HTTP header sent by RSS clients? I ran &lt;a href=&quot;https://mitmproxy.org/index.html&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;mitmproxy&lt;/a&gt; to intercept the HTTP requests sent by &lt;a href=&quot;https://quiterss.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;QuiteRSS&lt;/a&gt; and began to investigate.&lt;/p&gt;
&lt;p&gt;As far as I could tell, the HTTP requests being sent by QuiteRSS and my own HTTP requests via &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt; were identical. Save for minor differences in the TLS version. Surely not? I added the &lt;code class=&quot;language-text&quot;&gt;--tlsv1.3&lt;/code&gt; flag to force &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt; to use TLS 1.3. Nope, still didn&apos;t work.&lt;/p&gt;
&lt;h1 id=&quot;resolution&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#resolution&quot; aria-label=&quot;resolution permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Resolution&lt;/h1&gt;
&lt;p&gt;But that got me thinking. Maybe there were minute differences in the way TLS was implemented in &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt; and in web browsers like Chrome and Firefox that Cloudflare was taking advantage of to identify &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt; requests and show challenge pages in response.&lt;/p&gt;
&lt;p&gt;Fortunately for me, I am far from the first person to be plagued by this issue, and others far more talented than I had already implemented a solution: &lt;a href=&quot;https://github.com/lwthiker/curl-impersonate&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;lwthiker/curl-impersonate&lt;/code&gt;&lt;/a&gt;, which is a derivative of &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt; that performs HTTP and TLS handshakes identical to that of Chrome and Firefox. I installed the dependencies, downloaded the binary, and made my HTTP request:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt; libnss3 nss-plugin-pem ca-certificates

curl-impersonate-ff &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Accept: application/atom+xml,application/rss+xml;q=0.9,application/xml;q=0.8,text/xml;q=0.7,*/*;q=0.6&apos;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0&apos;&lt;/span&gt; https://lawgazette.com.sg/category/notices/disciplinary-tribunal-reports/feed/&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It worked beautifully.&lt;/p&gt;
&lt;h1 id=&quot;whitelisting&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#whitelisting&quot; aria-label=&quot;whitelisting permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Whitelisting&lt;/h1&gt;
&lt;p&gt;It looks like most major RSS readers (and other &apos;bots&apos;) don&apos;t have to use this workaround &lt;a href=&quot;https://radar.cloudflare.com/traffic/verified-bots&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;because they are whitelisted by Cloudflare&lt;/a&gt;.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Aside from the usual suspects (Googlebot, Bingbot, etc.) there are also entries from other tech solution providers such as OpenAI, Better Uptime, Slack, and Telegram, as well as RSS readers such as Feedly, Feeder, and Feedbin. Under this system, &apos;friendly bots&apos; to be submitted to Cloudflare to be whitelisted after verification.&lt;/p&gt;
&lt;p&gt;This is fine, but should there be a need to get Cloudflare&apos;s permission before fetching a RSS feed? Since &lt;a href=&quot;https://docs.google.com/forms/d/e/1FAIpQLSdqYNuULEypMnp4i5pROSc-uP6x65Xub9svD27mb8JChA_-XA/viewform&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the verification methods that Cloudflare supports&lt;/a&gt; for validating traffic are reverse DNS and IP range whitelisting &lt;em&gt;only&lt;/em&gt;, the system doesn&apos;t seem to allow for whitelisting of client-side solutions that run on the user&apos;s machine such that the IP address cannot be pre-determined.&lt;/p&gt;
&lt;h1 id=&quot;looking-beyond&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#looking-beyond&quot; aria-label=&quot;looking beyond permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Looking beyond&lt;/h1&gt;
&lt;p&gt;Separately, what remains unclear to me is why a challenge page was shown for &lt;em&gt;this particular&lt;/em&gt; RSS feed. Many sites are behind Cloudflare these days (including this one), and Cloudflare doesn&apos;t show a challenge page for vanilla &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt; requests to &lt;a href=&quot;/rss.xml&quot;&gt;my feed&lt;/a&gt;, so why that one? My suspicion is that it has something to do with the Cloudflare security configuration for that site:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971090.189229674498/cloudflare_bots.avif&quot; alt=&quot;Cloudflare Bot Fight Mode screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;Maybe it has &apos;&lt;a href=&quot;https://developers.cloudflare.com/bots/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Bot Fight Mode&lt;/a&gt;&apos; or &lt;a href=&quot;https://developers.cloudflare.com/fundamentals/reference/under-attack-mode/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Cloudflare&apos;s general &apos;Under Attack&apos; mode&lt;/a&gt; turned on? The showing of the challenge page is clearly not intentional — it&apos;s a RSS feed; &lt;em&gt;it&apos;s meant to be fetched in an automated fashion&lt;/em&gt;, not read in a browser directly. It&apos;s not difficult to get around this at the moment, but there shouldn&apos;t be a need for developers to play this sort of cat-and-mouse game for non-malicious applications.&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Considering how widespread usage of Cloudflare (and other similar solutions such as Akamai) is, there does appear to be a risk to RSS as a technology as well as to the open web more broadly if this sort of blocking, solely based on the nature of the request, becomes the default option or the recommended option on the basis of &apos;security&apos;.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;This list is not exhaustive.&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;This unintended blocking of RSS feeds as a result of heavy-handed anti-DDoS and anti-bot measures has also been highlighted by others. See e.g. &lt;a href=&quot;https://kevincox.ca/2021/12/07/cloudflare-bot-block-failures/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Kevin Cox, &quot;Problems with Cloudflare Bot Blocking&quot; (2021)&lt;/a&gt;, &lt;a href=&quot;https://flak.tedunangst.com/post/cloudflare-and-rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;this&lt;/a&gt;, etc.&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Applying for admission to the Singapore Bar: Overview]]></title><description><![CDATA[An overview of the application process for admission as an advocate and solicitor in Singapore

After fulfilling all the requirements to be admitted as an advocate and solicitor in Singapore (mainly, being a 'qualified person' and…]]></description><link>https://huey.xyz/posts/2023-09-10-applying-for-admission-to-the-singapore-bar</link><guid isPermaLink="false">c7c96068d3d3e117ca400dcd03862cf014c822fd9efd8db8bb3084ac5782c194</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sun, 10 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;An overview of the application process for admission as an advocate and solicitor in Singapore&lt;/h2&gt;&lt;p&gt;After fulfilling all the requirements to be admitted as an advocate and solicitor in Singapore (mainly, being a &apos;qualified person&apos; and completing the mandatory training period), the next step to actually qualify in Singapore is to apply for admission. This post seeks to provide some guidance on the actual application procedure.&lt;/p&gt;
&lt;p&gt;Much of the information is available online &lt;em&gt;somewhere&lt;/em&gt;, but requires some looking and may be outdated.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; For instance, much of SILE&apos;s guidance on its website predates the new &lt;a href=&quot;https://sso.agc.gov.sg//SL/SCJA1969-S914-2021&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Rules of Court 2021&lt;/a&gt; and/or new procedures put in place since then and &lt;a href=&quot;https://law-society-singapore-prod.s3.ap-southeast-1.amazonaws.com/2019/12/Checklist_Filing-Affidavits_V1110831.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the Law Society&apos;s checklist has not been updated since 2011&lt;/a&gt;. This is an attempt to consolidate and streamline the information, as well as augment it based on anecdotes and my own experiences, for the benefit of future applicants.&lt;/p&gt;
&lt;p&gt;The procedure is somewhat involved and it is advisable to have a general idea of the steps in broad strokes and cast an eye over all the requirements at an early stage so that you can ensure you fulfil them early on and avoid having to rush and risk missing the mass call date. In particular, you will probably want to look through the requirements in the &lt;a href=&quot;https://www.sile.edu.sg/pdf/SILE_PTCC_Form-for_print%26sign.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;practice training contract checklist (PTC checklist)&lt;/a&gt; and make sure that you complete the necessary &lt;a href=&quot;https://www.lawsociety.org.sg/cpd/ethics-in-practice-legal-profession-rules/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;e-Learning courses&lt;/a&gt; conducted by the Law Society in good time.&lt;/p&gt;
&lt;p&gt;There may have been changes to the application and admission procedure since this post was drafted — do check the relevant legislation and agencies&apos; websites before relying on the information here.&lt;/p&gt;
&lt;h1 id=&quot;overview&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#overview&quot; aria-label=&quot;overview permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Overview&lt;/h1&gt;
&lt;p&gt;The process from application to mass call is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/posts/2023-09-02-applying-to-the-singapore-bar-the-originating-application/&quot;&gt;Originating application&lt;/a&gt;: File an originating application (an OA, previously known as an originating summons) to be admitted as an advocate and solicitor&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/2023-08-09-applying-for-admission-to-the-singapore-bar-sile-certificate/&quot;&gt;Request for SILE certificate&lt;/a&gt;: After completing your training contract and before filing your supporting affidavit, you need to request for SILE to issue you a certificate confirming that you have met the substantive requirements for admission.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/2023-09-03-applying-to-the-singapore-bar-supporting-affidavit/&quot;&gt;Supporting affidavit&lt;/a&gt;: After the SILE certificate has been issued, you can proceed to file your supporting affidavit and request for a hearing date.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/2023-09-09-admission-mass-call/&quot;&gt;Mass call&lt;/a&gt;: Attend the mass call briefing and mass call, then collect your practising certificate.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Click the links above for more details about each respective stage.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prerequisites&quot; aria-label=&quot;prerequisites permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Prior to or in parallel to this process, you will have to fulfil the substantive requirements to be admitted, mainly:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;QP&lt;/strong&gt;: Be a &apos;qualified person&apos; (QP) under the &lt;a href=&quot;https://sso.agc.gov.sg/SL/161-R15&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Legal Profession (Qualified Person) Rules&lt;/a&gt; (QPR). To obtain proof of your status as a QP, you should register with SILE. In practice, this is done as part of the registration for the Part B course with SILE (for both local and overseas graduates).&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; SILE will then furnish you with a letter confirming that they have entered your name into the register of QPs (&lt;a href=&quot;/1776002971090.189229674494/qp-sample.pdf&quot;&gt;sample here&lt;/a&gt;); and&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TC&lt;/strong&gt;: Complete the mandatory training period (i.e. your training contract) as required under the &lt;a href=&quot;https://sso.agc.gov.sg//SL/LPA1966-S244-2011&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Legal Profession (Admission) Rules 2011&lt;/a&gt; (LPAR). Do remember to &lt;a href=&quot;https://www.sile.edu.sg/registration-and-approval&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;get SILE&apos;s approval&lt;/a&gt; before commencing your training contract.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Whilst you have to be a QP before applying to be admitted (i.e. before filing your OA), you can (and should) file your OA &lt;em&gt;during&lt;/em&gt; your TC, although you can only proceed with the subsequent steps after completing your TC. This is because you can only file your supporting affidavit 30 days after your OA has been filed.&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; Filing the OA at least 30 days before the end of your TC allows you to file your supporting affidavit as soon as possible once your TC ends, giving yourself some time to address any irregularities.&lt;/p&gt;
&lt;h1 id=&quot;other-guidance&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#other-guidance&quot; aria-label=&quot;other guidance permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Other guidance&lt;/h1&gt;
&lt;p&gt;I hope this helps you on your journey to be admitted to the Singapore bar.&lt;/p&gt;
&lt;p&gt;Here&apos;s some other useful guidance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SILE&apos;s
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sile.edu.sg/pdf/1_ADMISSION_TO_THE_SINGAPORE_BAR_-_Admission_Procedure.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Guide to the Admission Procedure in General&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sile.edu.sg/pdf/3_Main_Steps_in_Admission_Process.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Summary of the Admission Procedure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Guide on Mass Call: &lt;a href=&quot;https://www.sile.edu.sg/pdf/SILE_Guide_on_Mass_Call_2022.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;2022&lt;/a&gt;, &lt;a href=&quot;https://www.sile.edu.sg/pdf/SILE_Guide_on_Mass_Call_2023.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;2023&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AGC&apos;s page titled &lt;a href=&quot;https://www.agc.gov.sg/legal-processes/admission-of-advocates-and-solicitors&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Admission of Advocates and Solicitors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Law Society&apos;s
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://law-society-singapore-prod.s3.ap-southeast-1.amazonaws.com/2020/01/FAQs_for_Admission.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;FAQs on Admission&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://law-society-singapore-prod.s3.ap-southeast-1.amazonaws.com/2019/12/Checklist_Filing-Affidavits_V1110831.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Checklist for Applicants Filing Affidavits&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=643423&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Jack Tsen-Ta Lee, &quot;Getting Called: A Practical Guide&quot; (1997) 18 &lt;em&gt;Singapore Law Review&lt;/em&gt; 455&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;I found &lt;a href=&quot;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=643423&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Jack Tsen-Ta Lee, &quot;Getting Called: A Practical Guide&quot; (1997) 18 &lt;em&gt;Singapore Law Review&lt;/em&gt; 455&lt;/a&gt; to be a useful reference, although it is very much out of date.&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;Broadly speaking, local graduates will be QPs upon passing their final exams and attaining the requisite grades whereas overseas graduates will additionally need to complete their RLT and pass Part A. For more information about the QP requirements for overseas graduates, see this &lt;a href=&quot;http://sile.edu.sg/pdf/QP_Infographic.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SILE infographic&lt;/a&gt;.&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;I have assumed here (as is the case for most people) that you will be doing Part B before your TC. It does seem to be possible to file your OA even before commencing your TC, although in practice this may be tricky since without eLitigation you would need to go down to the CrimsonLogic Service Bureau? Anyway there does not seem to be much benefit to filing so far in advance. See r 25(4) LPAR. Also, note that the OA &lt;a href=&quot;/posts/2023-09-02-applying-to-the-singapore-bar-the-originating-application/#timing&quot;&gt;may expire after a year&lt;/a&gt;.&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Geotagging photographs on cameras without GPS functionality]]></title><description><![CDATA[How to embed GPS data from your smartphone as EXIF data

Many smartphones automatically add GPS EXIF data to photographs (i.e. geotag photos), such that the GPS coordinates where the photograph…]]></description><link>https://huey.xyz/posts/2023-09-09-adding-gps-exif-data-to-photographs</link><guid isPermaLink="false">f44b0ea89ef25f404c72ec97d3e8a251fde24bb559907b9fce0fa40c61136aab</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 09 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;How to embed GPS data from your smartphone as EXIF data&lt;/h2&gt;&lt;p&gt;Many smartphones &lt;a href=&quot;https://en.wikipedia.org/wiki/Geotagged_photograph&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;automatically add GPS EXIF data to photographs (i.e. geotag photos)&lt;/a&gt;, such that the GPS coordinates where the photograph where the photograph was taken are embedded as part of the metadata accompanying the photograph.&lt;/p&gt;
&lt;p&gt;This can be quite useful when reviewing old photographs — you can easily identify where a photograph was taken. It also facilitates features such as searching for all photographs taken at a particular location and generating a &apos;map view&apos; of your photographs.&lt;/p&gt;
&lt;p&gt;However, older &apos;point-and-shoot&apos; cameras and DSLRs may not embed GPS EXIF data, often because they don&apos;t actually have a GPS module — such modules are expensive and energy-hungry.&lt;/p&gt;
&lt;p&gt;To address this and &apos;retrofit&apos; my older cameras with GPS tracking functionality, I have settled on the following 2-step setup:&lt;/p&gt;
&lt;p&gt;First, I track my GPS location using &lt;a href=&quot;https://osmand.net/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;OsmAnd&lt;/a&gt;&apos;s recording feature, which allows me to export my location data as a GPX file. OsmAnd is open source and &lt;a href=&quot;https://osmand.net/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;available for both iOS and Android devices&lt;/a&gt;. It is also a decent maps app, quite apart from the GPS tracking functionality.&lt;/p&gt;
&lt;p&gt;This means I have to ensure that location recording is enabled whenever I take photographs, but it&apos;s not too much bother. I can just enable it when I set off and leave it on till I return, the battery drain is quite acceptable.&lt;/p&gt;
&lt;p&gt;Second, after I get back, I export the location data as a GPX file, and use the open source &lt;a href=&quot;https://github.com/jmlich/geotagging&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Geotagging&lt;/a&gt; app to read the GPX file and insert appropriate GPS EXIF data into my photographs. Geotagging runs on Windows and Linux right now (it&apos;s available as a Flatpak). For macOS, there appears to be a similar app called &lt;a href=&quot;https://apps.apple.com/us/app/geotag/id1465180184?mt=12&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;GeoTag&lt;/a&gt; but I haven&apos;t used it personally.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971089.189229674484/geotagging.avif&quot; alt=&quot;Screenshot of GeoTagging app running on Lubuntu&quot;&gt;&lt;/p&gt;
&lt;p&gt;Some of the many useful features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It allows me to adjust the timestamps on my photographs too. If my camera clock and smartphone clock are out of sync, I can simply add an appropriate offset. I like how it allows me to just key in the current time on my camera and it automatically calculates the correct offset so I don&apos;t need to do any mental arithmetic.&lt;/li&gt;
&lt;li&gt;It supports importing of multiple GPX files (in case I accidentally create several GPX files)&lt;/li&gt;
&lt;li&gt;It can assign coordinates approximated/extrapolated between two points (useful where GPS signal is lost or where I use a longer tracking interval for energy efficiency).&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Applying for admission to the Singapore Bar: the Mass Call]]></title><description><![CDATA[The mass call briefing and the actual mass call hearing

After you have filed your supporting affidavit (and requested for a hearing), you should be assigned a hearing date. There is generally one…]]></description><link>https://huey.xyz/posts/2023-09-09-admission-mass-call</link><guid isPermaLink="false">47a9fa9fa270f04188b6636852860b1d36eba7c397526ebcd0408cf58b23c554</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 09 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;The mass call briefing and the actual mass call hearing&lt;/h2&gt;&lt;p&gt;After you have &lt;a href=&quot;/posts/2023-09-03-applying-to-the-singapore-bar-supporting-affidavit/&quot;&gt;filed your supporting affidavit (and requested for a hearing)&lt;/a&gt;, you should be assigned a hearing date. There is generally one admissions hearing a month, except for court vacation periods, and the dates are published on &lt;a href=&quot;https://www.judiciary.gov.sg/legal-professionals/admission-advocate-solicitor&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the Judiciary&apos;s website&lt;/a&gt;. That said, the mass call dates are generally only published about 2 months before the mass call (e.g. late May if the mass call is in the 3rd or 4th week of August).&lt;/p&gt;
&lt;p&gt;Attending your call is very much compulsory, i.e. you must attend in order to get called. If you miss the mass call, it is possible to get called at one of the ad-hoc admission hearings (see above) — however this will mean you will be called later and will need to arrange for your own mover.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h1 id=&quot;mass-call-briefing&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#mass-call-briefing&quot; aria-label=&quot;mass call briefing permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Mass call briefing&lt;/h1&gt;
&lt;p&gt;About a week before the actual mass call, there will be a mass call briefing. This is an administrative briefing covering the procedure to be followed during the mass call itself. In &lt;a href=&quot;https://web.archive.org/web/20220824104608/https://www.judiciary.gov.sg/legal-professionals/admission-advocate-solicitor&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;2022&lt;/a&gt; and &lt;a href=&quot;https://web.archive.org/web/20230910072020/https://www.judiciary.gov.sg/legal-professionals/admission-advocate-solicitor&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;2023&lt;/a&gt;, the mass call briefing was held in-person, at the Supreme Court Auditorium.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971089.189229674490/mass_call_screenshot_2023.avif&quot; alt=&quot;Screenshot from the Judiciary&amp;#x27;s website&quot;&gt;&lt;/p&gt;
&lt;p&gt;The mass call briefing is compulsory and the Courts are strict about this. &lt;strong&gt;There is no alternative briefing session&lt;/strong&gt; and anyone who does not attend the briefing will be rescheduled for the next hearing.&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; Accordingly, the likely date of the mass call briefing is something you will probably want to consider when planning your call break.&lt;/p&gt;
&lt;p&gt;Although the briefing is scheduled to last an hour, it may not necessarily start on time, so it may be best to assume it may take up to 2 hours (e.g. 10am – 12pm).&lt;/p&gt;
&lt;p&gt;Since there will likely be a large number of attendees (about 400 in 2023), you may also want to factor in some time to clear security and register prior to the briefing. For this reason, registration will probably commence more than an hour before the actual start time (e.g. 8.30am if the briefing is scheduled to begin at 10am), although there is no need to arrive that early — about 30 – 40 mins before the briefing begins will probably be quite comfortable.&lt;/p&gt;
&lt;p&gt;Although the Courts do not appear to prescribe any particular attire for the briefing, the appropriate attire will probably be &lt;a href=&quot;https://www.judiciary.gov.sg/attending-court/guide-to-attending-court#dress-code&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;courtroom attire&lt;/a&gt; (i.e. the attire required for members of the public attending public hearings). White shirt and black jacket not required.&lt;/p&gt;
&lt;h1 id=&quot;the-mass-call-itself&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-mass-call-itself&quot; aria-label=&quot;the mass call itself permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The mass call itself&lt;/h1&gt;
&lt;p&gt;On the day of mass call, you will probably also want to arrive comfortably early and give yourself at least 45 minutes to clear security and register prior to the hearing — there will likely be other hearings that day and you may not be allowed to attend the hearing if you are late or fail to register before registration closes.&lt;/p&gt;
&lt;p&gt;Conventionally, each applicant is allowed to invite two guests to the hearing. Although the hearing is notionally a public hearing (and not &lt;em&gt;in camera&lt;/em&gt;), only guests with invites will be allowed in.&lt;/p&gt;
&lt;p&gt;Do remember to bring:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a blue pen&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.judiciary.gov.sg/legal-professionals/wearing-of-robes&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;court robes&lt;/a&gt;&lt;sup id=&quot;fnref-4&quot;&gt;&lt;a href=&quot;#fn-4&quot; class=&quot;footnote-ref&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;suitable identification (e.g. NRIC or passport)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;&lt;a href=&quot;https://www.lawsociety.org.sg/our-community/aas-hearings/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;This should generally be your supervising solicitor&lt;/a&gt;. If they are not available, your mover can be another lawyer with at least 5 years PQE and a valid practising certificate. There may also be financial consequences that result from a later call date that you should consider — for example, some organisations may pay you a higher salary only after your call date.&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;See the &lt;a href=&quot;https://web.archive.org/web/20230910072020/https://www.judiciary.gov.sg/docs/default-source/legal-professionals-docs/mass-call-2023---faqs.pdf?sfvrsn=b4fe4d65_2&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;FAQs&lt;/a&gt;&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;To sign the declaration you are required to make under &lt;a href=&quot;https://sso.agc.gov.sg/SL/LPA1966-S244-2011?DocDate=20230111&amp;#x26;ProvIds=P1VI-#pr30-&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;r 30&lt;/a&gt; and the &lt;a href=&quot;https://sso.agc.gov.sg/SL/LPA1966-S244-2011?DocDate=20230111&amp;#x26;ProvIds=Sc1-#Sc1-&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;First Schedule&lt;/a&gt; of the Legal Profession (Admission) Rules 2011. Making this declaration is not technically a requirement for you to be admitted: &lt;a href=&quot;https://www.elitigation.sg/gd/s/2021_SGHC_216&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;em&gt;Re Vikram Kumar Tiwary&lt;/em&gt; [2021] SGHC 216&lt;/a&gt;.&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;If you intend to do court work, you will probably want to purchase a set of robes, but otherwise you can probably borrow a set from your organisation, a friend, a colleague, etc.&lt;a href=&quot;#fnref-4&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Applying for admission to the Singapore Bar: the Supporting Affidavit]]></title><description><![CDATA[Filing your supporting affidavit and the various exhibits

After receiving the SILE certificate, you can proceed to file your supporting affidavit. You should also file your request for hearing at…]]></description><link>https://huey.xyz/posts/2023-09-03-applying-to-the-singapore-bar-supporting-affidavit</link><guid isPermaLink="false">07641bcf734cb2660921b0a326df225418e5eba9a5254211d4e95aefc4908791</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sun, 03 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Filing your supporting affidavit and the various exhibits&lt;/h2&gt;&lt;p&gt;After receiving the SILE certificate, you can proceed to file your supporting affidavit. You should also file your request for hearing at the same time.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The form of the supporting affidavit is prescribed in the Second Schedule of the Legal Profession (Admission) Rules. You can also refer to the following template.&lt;/p&gt;
&lt;p&gt;The following exhibits should be annexed to the affidavit:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;SILE letter certifying that you are a QP (Exhibit A)&lt;/li&gt;
&lt;li&gt;COD (Exhibit B)&lt;/li&gt;
&lt;li&gt;2 recent certificates of good character (Exhibit C)&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;requesting-for-a-hearing-date&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#requesting-for-a-hearing-date&quot; aria-label=&quot;requesting for a hearing date permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Requesting for a hearing date&lt;/h1&gt;
&lt;p&gt;It is very important that you request for a hearing date at the same time that you file your supporting affidavit. This can be done by checking a box and composing the request for hearing via eLitigation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971088.189229674461/elitigation1.avif&quot; alt=&quot;screenshot of checkbox in eLitigation&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971088.189229674464/elitigation2.avif&quot; alt=&quot;screenshot of document view in eLitigation&quot;&gt;&lt;/p&gt;
&lt;p&gt;If you do not request for a hearing date, your application will not be scheduled to be heard at the next available call date — you may miss &apos;mass call&apos; if applicable.&lt;/p&gt;
&lt;h1 id=&quot;guidelines-for-supporting-affidavit&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#guidelines-for-supporting-affidavit&quot; aria-label=&quot;guidelines for supporting affidavit permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Guidelines for supporting affidavit&lt;/h1&gt;
&lt;p&gt;To avoid issues with your application, you should take note of the following — some of these are put together from the guidance published by the various organisations and some are from my personal experience. You may want to use this as a checklist of sorts to be checked against when drafting and just before you file your affidavit.&lt;/p&gt;
&lt;h2 id=&quot;formatting-requirements&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#formatting-requirements&quot; aria-label=&quot;formatting requirements permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Formatting requirements&lt;/h2&gt;
&lt;p&gt;Certain requirements pertaining to affidavits are prescribed under &lt;a href=&quot;https://epd2021-supremecourt.judiciary.gov.sg/part-10-evidence-witnesses-affidavits-and-exhibits#78-form-of-affidavits&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;para 78 of the Supreme Court PD 2021&lt;/a&gt;. In particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Formatting&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;There should be a blank margin of ≥ 35mm on all 4 sides of the page&lt;/li&gt;
&lt;li&gt;The text of the affidavits must be double-spaced on white paper&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top right hand corner&lt;/strong&gt;: The following information must be printed in a single line at the top right hand corner of the first page of every affidavit:
&lt;ul&gt;
&lt;li&gt;The party on whose behalf the affidavit is filed&lt;/li&gt;
&lt;li&gt;The name of the maker of the affidavit&lt;/li&gt;
&lt;li&gt;The ordinal number of the affidavit in relation to the previous affidavits filed in the matter by the maker of the affidavit&lt;/li&gt;
&lt;li&gt;The date on which the affidavit is to be filed&lt;/li&gt;
&lt;li&gt;For example, &quot;Applicant; Alfred Denning; 1st; 05.06.2023&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pagination&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Every page of the affdavit must be paginated consecutively and the page number must be inserted at the centre top of each page of the affidavit other than the exhibits and separators.&lt;/li&gt;
&lt;li&gt;Every page of the exhibits, including cover pages, dividing sheets or separators between exhibits, must be consecutively numbered at the top right hand corner of each page, following from the page numbers of the text of the affidavit (i.e., the first page of the exhibits must take the page number following the last sheet of the text of the affidavit). The page number of the affidavit must correspond to the page number in the PDF version.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bookmarks&lt;/strong&gt;: Each exhibit in the affidavit must be separately bookmarked in the PDF that is filed. The names of the bookmarks should follow the initials of the maker of the affidavit, e.g., &quot;AD-1&quot;, &quot;AD-2&quot;, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;content-of-affidavit&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#content-of-affidavit&quot; aria-label=&quot;content of affidavit permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Content of affidavit&lt;/h2&gt;
&lt;p&gt;Be sure to carefully scrutinise the contents of your affidavit and ensure the language is up to date, especially if you referred to an old template. &lt;a href=&quot;/1776002971089.189229674481/supporting-affidavit-template-2023.odt&quot;&gt;Here&apos;s a template from 2023&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In particular, you should check the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The affidavit should be filed in the &lt;em&gt;General Division&lt;/em&gt; of the High Court&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Legislation&lt;/strong&gt;: The references to legislation should be to the &lt;a href=&quot;https://www.agc.gov.sg/our-roles/drafter-of-laws/legislation-and-revisions&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;2020 Revised Editions of Legislation&lt;/a&gt;, e.g. you should refer to the &quot;Legal Profession Act 1966&quot; instead of to the &quot;Legal Profession Act (Cap. 161)&quot;, &quot;Mental Capacity Act 2008&quot; rather than &quot;Mental Capacity Act (Cap. 177A)&quot;, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name and NRIC&lt;/strong&gt;: Your name and NRIC (including in the affidavit title) should exactly match that specified in your NRIC. Any punctuation and spacing should be the same.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Citizenship&lt;/strong&gt;: Ensure you correctly state your citizenship status.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Degree&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Ensure that the type of degree you have (LLB/JD), the name of your university, and the date on which the degree was conferred is as per the graduation certificate you previously provided to SILE (as part of the QP registration process) and also matches the details in your eLitigation profile.&lt;/li&gt;
&lt;li&gt;There is no need to specify the class of your degree (e.g. Second Upper, etc).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Practice training period&lt;/strong&gt;: Ensure the details here match the COD.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Suitability to practice&lt;/strong&gt;: Anything affecting your suitability to practice (including, criminal convictions, stern warnings,&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; as well as plagiarism,&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; cheating during assessments,&lt;sup id=&quot;fnref-4&quot;&gt;&lt;a href=&quot;#fn-4&quot; class=&quot;footnote-ref&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; and other academic/assessment misconduct) should be declared and sufficient particulars given.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pronouns&lt;/strong&gt;: Ensure the pronouns you use throughout the affidavit are correct. To reduce the risk of errors, you may want to avoid using pronouns as far as possible.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Swearing/affirming&lt;/strong&gt;: Ensure you are consistent in swearing/affirming, in the main content of the affidavit and in the exhibit cover pages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exhibits&lt;/strong&gt;: Ensure that all exhibits have the requisite cover page and are issued and dated on or before the date of affirming/swearing of the affidavit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Do also carefully review your affidavit &lt;em&gt;after&lt;/em&gt; it has been scanned, before you file it. I have heard of affidavits being returned because the scanner or the PDF software used to view and edit the affidavit (e.g. to add page numbers) altered some text slightly (e.g. turning the &apos;S&apos; in a NRIC number into a &apos;5&apos;). This can happen with certain scanners, PDF software, OCR features, etc.&lt;sup id=&quot;fnref-5&quot;&gt;&lt;a href=&quot;#fn-5&quot; class=&quot;footnote-ref&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;certificate-of-diligence&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#certificate-of-diligence&quot; aria-label=&quot;certificate of diligence permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Certificate of diligence&lt;/h2&gt;
&lt;p&gt;Check to ensure that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The COD is in &lt;a href=&quot;https://www.sile.edu.sg/relevant-forms&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the form prescribed by SILE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The COD clearly states the designation of the persons signing the certificate. Such persons must be either a partner or director of the law practice and their designation should be stated as such, rather than e.g. Chairman or CEO.&lt;/li&gt;
&lt;li&gt;The start and end dates of your practice training period match that specified in your eLitigation profile.&lt;/li&gt;
&lt;li&gt;The date on your COD should be earlier than that on the SILE Certificate.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;certificates-of-good-character&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#certificates-of-good-character&quot; aria-label=&quot;certificates of good character permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Certificates of Good Character&lt;/h2&gt;
&lt;p&gt;Check to ensure that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You have at least 2 certificates of good character annexed&lt;sup id=&quot;fnref-6&quot;&gt;&lt;a href=&quot;#fn-6&quot; class=&quot;footnote-ref&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Each certificate must be signed by the certifier (and dated)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Applicant&apos;s details&lt;/strong&gt;: Each certificate states the applicant&apos;s full name exactly as per their NRIC (including any punctuation and spacing).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Certifier&apos;s details&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Each certifier&apos;s full name and residential address (not office or c/o address) should be stated. The address should include the postal code and unit number, where applicable.&lt;/li&gt;
&lt;li&gt;Although the &lt;a href=&quot;https://law-society-singapore-prod.s3.ap-southeast-1.amazonaws.com/2019/12/Checklist_Filing-Affidavits_V1110831.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Law Society&apos;s guidance&lt;/a&gt; continues to state that the &quot;NRIC numbers (Passport numbers for non-Singapore citizens)&quot; of each certifier must be stated, this does not appear to be necessary. The template in the LP(A)R 2011 does not require this and I know of applicants who did not specify the NRIC numbers of their certifiers yet did not have their applications objected to.&lt;/li&gt;
&lt;li&gt;At least one of the certifiers must be a Singapore resident.&lt;sup id=&quot;fnref-7&quot;&gt;&lt;a href=&quot;#fn-7&quot; class=&quot;footnote-ref&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Relationship with applicant&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The certifiers must not be immediately related to the applicant.&lt;sup id=&quot;fnref-8&quot;&gt;&lt;a href=&quot;#fn-8&quot; class=&quot;footnote-ref&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; The &lt;a href=&quot;https://law-society-singapore-prod.s3.ap-southeast-1.amazonaws.com/2019/12/Checklist_Filing-Affidavits_V1110831.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Law Society&apos;s guidance&lt;/a&gt; says that, for example, this means your fiancé or family relative should not be your certifier.&lt;/li&gt;
&lt;li&gt;Each certifier must have known the applicant for at least 2 years.&lt;sup id=&quot;fnref-9&quot;&gt;&lt;a href=&quot;#fn-9&quot; class=&quot;footnote-ref&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;You should state the relationship between the certifier and the applicant clearly (usually this will be &quot;friend&quot;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Occupation&lt;/strong&gt;: The occupation of each certifier must be clearly stated.
&lt;ul&gt;
&lt;li&gt;According to SILE&apos;s guidance, stating the occupation as &quot;law graduate&quot; or &quot;in between jobs&quot; is unacceptable as that is not an occupation. In such situations, the certifier should be expressly stated to be &quot;unemployed&quot;.&lt;/li&gt;
&lt;li&gt;The certifier does not need to be working full time. According to &lt;a href=&quot;https://www.sile.edu.sg/pdf/SILE_Guide_on_Mass_Call_2023.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SILE&apos;s guidance&lt;/a&gt;, a &quot;trainee&quot;, &quot;intern&quot;, &quot;student&quot;, &quot;homemaker&quot;, etc. can be a certifier.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Importantly, each certifier must have had &quot;opportunities to judge the applicant&apos;s character&quot;. There should be some elaboration showing this (1-2 sentences or so ought to be sufficient).&lt;/p&gt;
&lt;p&gt;The Law Society&apos;s guidance states that the following examples are insufficient:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;The applicant and I met in secondary school&quot;&lt;/li&gt;
&lt;li&gt;&quot;I find that the applicant is of good character&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some examples I am aware of that were not objected to include:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I am a friend of the applicant and was his senior at [university]. I was his facilitator in the freshmen orientation camp and we also attended several events and elective classes together.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I am a friend of the applicant and was her schoolmate at [university] where we attended several classes together. We have had many opportunities to interact together and build our friendship inside and outside of school. When we were schoolmates, we studied, shared notes and discussed difficult questions together leading up to our final examinations. Thereafter, we kept in contact and would regularly meet up over food and activities such as attending mini golf sessions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Over the course of our training stint in the [department of law firm], we worked closely together on multiple matters. Some examples of instances where we collaborated together include [redacted example]. Outside of work, I have also had numerous opportunities to judge the applicant&apos;s character. We regularly meet up over the weekends and frequently attend various art exhibitions, talks, and fairs in Singapore together…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I am a friend of the applicant and was his classmate at [secondary school]. We collaborated on several projects together in secondary school and have travelled overseas together on several occasions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I am a friend of the applicant and we have collaborated on several community service projects together in Singapore, for the benefit of the elderly and underprivileged children.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I was his flatmate when we were both studying in [university] and continue to be a friend of his. We have also travelled together on a number of occasions, including to [names of countries].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I am a friend of the applicant and have previously travelled overseas with him. We have also collaborated on various projects. My experiences as a friend, travel companion, and collaborator have provided me with numerous occasions to assess his character.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;commissioning-of-supporting-affidavit&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#commissioning-of-supporting-affidavit&quot; aria-label=&quot;commissioning of supporting affidavit permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Commissioning of supporting affidavit&lt;/h1&gt;
&lt;p&gt;Since this is an affidavit, it will have to be sworn/affirmed&lt;sup id=&quot;fnref-10&quot;&gt;&lt;a href=&quot;#fn-10&quot; class=&quot;footnote-ref&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; before a Commissioner for Oaths.&lt;sup id=&quot;fnref-11&quot;&gt;&lt;a href=&quot;#fn-11&quot; class=&quot;footnote-ref&quot;&gt;11&lt;/a&gt;&lt;/sup&gt; This may be arranged by the organisation with which you are doing your training contract, or you may have to arrange it yourself. You can probably get some recommendations by asking around the office or from friends.&lt;/p&gt;
&lt;p&gt;Generally, Commissioners for Oaths in Singapore do not charge for commissioning services in relation to supporting affidavits for applications for admission.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://legalisation.sal.sg/Directory&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SAL Commissioners for Oaths Directory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lawsociety.org.sg/our-community/advertisements-for-notary-public-commissioner-for-oaths/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Law Society Advertisements for Commissioner for Oaths&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The commissioning process is short and straightforward. After booking an appointment or walking in (possible in some cases), the Commissioner for Oaths will verify your identity (e.g. by checking your NRIC, driving licence, passport, etc. against your affidavit) and witness your signing of the affidavit, before signing and placing their stamp at the relevant locations.&lt;/p&gt;
&lt;p&gt;If necessary, you can amend your affidavit before it is filed by re-affirming it before a Commissioner for Oaths.&lt;sup id=&quot;fnref-12&quot;&gt;&lt;a href=&quot;#fn-12&quot; class=&quot;footnote-ref&quot;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;affirming-your-affidavit-overseas&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#affirming-your-affidavit-overseas&quot; aria-label=&quot;affirming your affidavit overseas permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Affirming your affidavit overseas&lt;/h2&gt;
&lt;p&gt;A supporting affidavit (or a supplemental affidavit) is an affidavit like any other affidavit filed in court, hence it can be sworn/affirmed overseas.&lt;sup id=&quot;fnref-13&quot;&gt;&lt;a href=&quot;#fn-13&quot; class=&quot;footnote-ref&quot;&gt;13&lt;/a&gt;&lt;/sup&gt; However, it must be sworn/affirmed before a &quot;person authorised to administer oaths and affirmations&quot; in the relevant jurisdiction — this will generally be a Notary, Notary Public, or equivalent.&lt;sup id=&quot;fnref-14&quot;&gt;&lt;a href=&quot;#fn-14&quot; class=&quot;footnote-ref&quot;&gt;14&lt;/a&gt;&lt;/sup&gt; You may have to pay for the relevant notarisation services.&lt;/p&gt;
&lt;p&gt;If you are fortunate enough to be in a city where there is a Singapore embassy or consulate, you can also seek consulate assistance to administer your oath/affirmation (e.g. in &lt;a href=&quot;https://www.mfa.gov.sg/Overseas-Mission/Hong-Kong/Consular-Services/Notarial-Services&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Hong Kong&lt;/a&gt;, &lt;a href=&quot;https://www.mfa.gov.sg/Overseas-Mission/Washington/Consular-Services/Notarial-Services/Witnessing-of-Signature-on-Affidavit-for-use-in-Singapore&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;San Francisco, Washington, New York&lt;/a&gt;, etc). It may also be possible to request for notary services from a Commonwealth embassy/consulate, but my understanding is that generally embassies/consulates only provide such services for documents to be used in legal proceedings in their home country and I don&apos;t personally know anyone who has managed to do this.&lt;/p&gt;
&lt;p&gt;It is unlikely that you will need to prove that the person who administered your oath/affirmation overseas is authorised to do so.&lt;sup id=&quot;fnref-15&quot;&gt;&lt;a href=&quot;#fn-15&quot; class=&quot;footnote-ref&quot;&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Whilst I don&apos;t think it&apos;s common for applicants to affirm their supporting/supplemental affidavits overseas, and it&apos;s probably best to avoid the trouble if possible, I know of a few people who were required by circumstances to do so (e.g. in the USA, in Taiwan, in Japan, etc), successfully did so, and were admitted.&lt;/p&gt;
&lt;h1 id=&quot;timing-for-filing-of-supporting-affidavit&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#timing-for-filing-of-supporting-affidavit&quot; aria-label=&quot;timing for filing of supporting affidavit permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Timing for filing of supporting affidavit&lt;/h1&gt;
&lt;p&gt;It is customary for practice trainees to take a call break after completing their training contract. This is in essence a period of no-pay leave in between their completion of the training contract and the date on which they are called to the bar. The specifics (e.g. duration, when exactly you can take it, etc) vary from organisation to organisation — some organisation will allow you to take the full period off (which may about 2 months or so), others will give you 2-4 weeks, whereas others may not allow you to take a call break at all (on account of &apos;work exigencies&apos;, &apos;manpower requirements&apos;, etc).&lt;/p&gt;
&lt;p&gt;Since you can only file your supporting affidavit after you have fulfilled all the substantive requirements (in particular, after you have completed your training contract), it is common for there to be some time pressure vis-a-vis filing &lt;em&gt;before&lt;/em&gt; you take the customary call break. It may therefore be prudent for you to draft your affidavit &lt;em&gt;in advance&lt;/em&gt; and have it ready to be signed and commissioned as soon as you receive the SILE certificate.&lt;/p&gt;
&lt;p&gt;In the event that you are unable to affirm and file your supporting affidavit before your call break, and you are travelling overseas during your call break, you may have to affirm and file it overseas (see &lt;a href=&quot;#affirming-your-affidavit-overseas&quot;&gt;Affirming your affidavit overseas&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;On a separate note, when planning your call break, you will also want to consider the likely dates of the &lt;a href=&quot;/posts/2023-09-09-admission-mass-call/#the-mass-call-itself&quot;&gt;mass call&lt;/a&gt; and &lt;a href=&quot;/posts/2023-09-09-admission-mass-call/#mass-call-briefing&quot;&gt;mass call hearing&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;letter-of-no-objection&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#letter-of-no-objection&quot; aria-label=&quot;letter of no objection permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Letter of no objection&lt;/h1&gt;
&lt;p&gt;After you file your supporting affidavit, just sit back and wait for SILE, AGC, and the Law Society to send you a letter confirming that they have no objections to your application for admission. Generally, the organisations will review your application in that order (i.e. SILE, AGC, then the Law Society), and you should receive the letters of no objection in that order. Here are some sample letters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/1776002971089.189229674469/sile-letter-no-objection-sample.pdf&quot;&gt;from SILE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/1776002971088.189229674458/agc-letter-no-objection-sample.pdf&quot;&gt;from AGC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/1776002971088.189229674467/lss-letter-no-objection-sample.pdf&quot;&gt;from the Law Society&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The letters should all be sent via email (as attached PDFs), though AGC may additionally send an original of their letter via snail mail.&lt;/p&gt;
&lt;p&gt;The SILE, AGC, and Law Society must provide their letters of no objection (or file their objections) no later than 5 days before the hearing date.&lt;sup id=&quot;fnref-16&quot;&gt;&lt;a href=&quot;#fn-16&quot; class=&quot;footnote-ref&quot;&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;As SILE takes the first cut, most if not all issues with your application should be caught by SILE, so once you receive SILE&apos;s letter of no objection, it is quite likely the others will follow shortly. That said, I have heard of cases where AGC returns the affidavit even after SILE has issued their letter of no objection (because AGC caught some irregularity that SILE missed), or where SILE returns the affidavit despite already having issued their letter of no objection (because they identified some irregularity upon further review).&lt;/p&gt;
&lt;h1 id=&quot;supplemental-affidavit&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#supplemental-affidavit&quot; aria-label=&quot;supplemental affidavit permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Supplemental affidavit&lt;/h1&gt;
&lt;p&gt;It is not uncommon for affidavits to be returned by SILE or AGC. In many cases, applicants will be figuring out the admission process and drafting their affidavit whilst working full time and dealing with a full workload. The organisations reviewing the affidavits seem to be very particular and may return your affidavit for very minor (e.g. a statute reference not using the 2020 Revised Edition title). Having your affidavit returned is not the end of the world — most issues can be quickly remedied by filing a supplemental affidavit.&lt;/p&gt;
&lt;h2 id=&quot;timing-for-filing-of-supplemental-affidavit&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#timing-for-filing-of-supplemental-affidavit&quot; aria-label=&quot;timing for filing of supplemental affidavit permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Timing for filing of supplemental affidavit&lt;/h2&gt;
&lt;p&gt;When returning your supporting affidavit, SILE will generally specify a deadline by which they expect you to file your supplemental affidavit. If the return occurs fairly early (e.g. in mid-June when the mass call is in August), you may be able to get an extension of time if necessary.&lt;sup id=&quot;fnref-17&quot;&gt;&lt;a href=&quot;#fn-17&quot; class=&quot;footnote-ref&quot;&gt;17&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The AGC and the Law Society may not specify a deadline and may also not respond to queries or requests for extension of time. This may be because they generally review applications &lt;em&gt;after&lt;/em&gt; SILE and are under greater time pressure to complete their review before the mass call date.&lt;/p&gt;
&lt;h2 id=&quot;format&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#format&quot; aria-label=&quot;format permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Format&lt;/h2&gt;
&lt;p&gt;The LP(A)R 2011 does not prescribe the format a supplemental affidavit should take, but you can refer to these templates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/1776002971089.189229674478/supplemental-template-irregularity-title-2023.odt&quot;&gt;Supplemental affidavit addressing irregularity in title&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/1776002971089.189229674472/supplemental-template-irregularity-content-2023.odt&quot;&gt;Supplemental affidavit addressing irregularity in content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/1776002971089.189229674475/supplemental-template-irregularity-exhibit-2023.odt&quot;&gt;Supplemental affidavit addressing irregularity in exhibit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some other pointers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do double check the title and content of your supplemental affidavit to ensure all is in order — it would be best to avoid having to file an additional supplemental affidavit&lt;/li&gt;
&lt;li&gt;Also check the exhibit references, dates, and the header&lt;/li&gt;
&lt;li&gt;An affidavit cannot technically be altered (so you should avoid using language suggesting you are amending your previous affidavit). Instead, mistakes in an earlier affidavit can be &lt;em&gt;corrected&lt;/em&gt; via a later affidavit&lt;sup id=&quot;fnref-18&quot;&gt;&lt;a href=&quot;#fn-18&quot; class=&quot;footnote-ref&quot;&gt;18&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;&lt;a href=&quot;https://epd2021-supremecourt.judiciary.gov.sg/part-18-matters-under-the-legal-profession-act-1966#156-applications-for-admission-as-an-advocate-and-solicitor-of-the-supreme-court&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Para 156(4) Supreme Court Practice Directions 2021&lt;/a&gt;&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;E.g. &lt;a href=&quot;https://www.elitigation.sg/gd/s/2023_SGHC_59&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;em&gt;Re Tay Jie Qi&lt;/em&gt; [2023] SGHC 59&lt;/a&gt;&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;E.g. &lt;a href=&quot;https://www.elitigation.sg/gd/s/2023_SGHC_129&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;em&gt;Re Suria Shaik Aziz&lt;/em&gt; [2023] SGHC 129&lt;/a&gt;&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;E.g. &lt;a href=&quot;https://www.elitigation.sg/gdviewer/s/2022_SGHC_133&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;em&gt;Re Tay Quan Li Leon&lt;/em&gt; [2022] SGHC 133&lt;/a&gt; and &lt;a href=&quot;https://www.elitigation.sg/gd/s/2022_SGHC_237&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;em&gt;Re Wong Wai Loong Sean&lt;/em&gt; [2022] SGHC 237&lt;/a&gt;&lt;a href=&quot;#fnref-4&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-5&quot;&gt;See e.g. &lt;a href=&quot;https://www.dkriesel.com/en/blog/2013/0802_xerox-workcentres_are_switching_written_numbers_when_scanning&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Xerox scanners/photocopiers randomly alter numbers in scanned documents&lt;/a&gt;; also see &lt;a href=&quot;https://www.theverge.com/2013/8/6/4594482/xerox-copiers-randomly-replacing-numbers-in-documents&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Verge article&lt;/a&gt;&lt;a href=&quot;#fnref-5&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-6&quot;&gt;It seems possible to annex more than 2, just in case, and I might have done so if it had occurred to me at the time. But you will incur the per-page filing fees. Perhaps worth it &apos;just to be safe&apos;?&lt;a href=&quot;#fnref-6&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-7&quot;&gt;r 25(5)(b), LP(A)R 2011&lt;a href=&quot;#fnref-7&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-8&quot;&gt;r 25(5)(a)(i), LP(A)R 2011&lt;a href=&quot;#fnref-8&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-9&quot;&gt;r 25(5)(a)(ii), LP(A)R 2011&lt;a href=&quot;#fnref-9&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-10&quot;&gt;Sworn if you are a Christian or Catholic, affirmed otherwise.&lt;a href=&quot;#fnref-10&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-11&quot;&gt;O 15 r 18, ROC 2021.&lt;a href=&quot;#fnref-11&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-12&quot;&gt;O 15 r 26(1) ROC 2021.&lt;a href=&quot;#fnref-12&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-13&quot;&gt;O 15, r 17, ROC 2021.&lt;a href=&quot;#fnref-13&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-14&quot;&gt;O 15 r 23, ROC 2021.&lt;a href=&quot;#fnref-14&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-15&quot;&gt;The seal or signature of a commissioner for oaths in an affidavit affirmed in or outside Singapore must be accepted as valid unless the contrary is shown (O 15 r 28, ROC 2021).&lt;a href=&quot;#fnref-15&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-16&quot;&gt;r 29, LP(A)R 2011.&lt;a href=&quot;#fnref-16&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-17&quot;&gt;I know of one person who successfully got an extension of time of a week or so, allowing them to file their supplemental affidavit after they returned to Singapore.&lt;a href=&quot;#fnref-17&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-18&quot;&gt;O 15 r 26(2), ROC 2021.&lt;a href=&quot;#fnref-18&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Applying for admission to the Singapore Bar: the Originating Application]]></title><description><![CDATA[Filing your OA and commencing your application

After you become a QP, and ideally at least 30 days before you complete your TC, you should file your Originating Application (OA). SILE…]]></description><link>https://huey.xyz/posts/2023-09-02-applying-to-the-singapore-bar-the-originating-application</link><guid isPermaLink="false">22592b14bcb29fc1338622bce06714da57188dd6c0cd549ac41258019244ae8a</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sat, 02 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Filing your OA and commencing your application&lt;/h2&gt;&lt;p&gt;After you become a QP, and ideally at least 30 days before you complete your TC, you should file your Originating Application (OA).&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; SILE additionally suggests that the OA be filed:&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After receipt of SILE’s Letter of Registration as Qualified Person and at least 60 days before the date fixed for hearing application of admission. It is not necessary to wait for release of Part B Exam results before filing [OA]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;content&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#content&quot; aria-label=&quot;content permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Content&lt;/h1&gt;
&lt;p&gt;You can refer to &lt;a href=&quot;/1776002971088.189229674454/originating-application-template.odt&quot;&gt;this template OA&lt;/a&gt; to see the general form that the OA should take. You can also refer to this &lt;a href=&quot;https://www.elitigation.sg/_layouts/IELS/ELITWebHelp/Other_Types_of_Filing/Other_Case_Types/Admission_of_Advocates_and_Solicitors/AAS.htm&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;eLitigation guide&lt;/a&gt; when actually filing the OA via eLitigation, although it seems it may be a little out of date. If you file via eLitigation, there is no need to upload your OA as a document — you can compose your OA via eLitigation which ensures that it is already in the right format.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971088.189229674447/elitigation2.avif&quot; alt=&quot;Screenshot of documents page on eLitigation&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971088.189229674450/elitigation3.avif&quot; alt=&quot;Screenshot of OA compose view on eLitigation&quot;&gt;&lt;/p&gt;
&lt;p&gt;You can&apos;t amend the default prayer so don&apos;t worry if it hasn&apos;t been updated and still refers to the &quot;Legal Profession Act (Cap.161)&quot; instead of the Legal Profession Act 1966.&lt;/p&gt;
&lt;p&gt;You will need to fill in the following information into eLitigation when filing your OA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Party details (i.e. your details)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;NRIC / Passport Number&lt;/li&gt;
&lt;li&gt;Gender&lt;/li&gt;
&lt;li&gt;Place of Birth&lt;/li&gt;
&lt;li&gt;Date of Birth&lt;/li&gt;
&lt;li&gt;Citizenship&lt;/li&gt;
&lt;li&gt;Religion and whether Affirming or Swearing&lt;/li&gt;
&lt;li&gt;Marital Status&lt;/li&gt;
&lt;li&gt;Residential Address&lt;/li&gt;
&lt;li&gt;Mobile Number&lt;/li&gt;
&lt;li&gt;Email Address&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Details about your degree&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Country of University&lt;/li&gt;
&lt;li&gt;Name of University&lt;/li&gt;
&lt;li&gt;Type of Qualification (Bachelor of Laws, Doctor of Jurisprudence, etc)&lt;/li&gt;
&lt;li&gt;Class of Degree&lt;/li&gt;
&lt;li&gt;Length of Degree Course&lt;/li&gt;
&lt;li&gt;Degree Course Admission Date.&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Date of Conferment of Degree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Details about your TC&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Name of Supervising Solicitor&lt;/li&gt;
&lt;li&gt;Law Practice Name&lt;/li&gt;
&lt;li&gt;Date of Commencement of Training Contract&lt;/li&gt;
&lt;li&gt;Estimated date of completion of Training Contract&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Rule under the LPAR pursuant to which you are filing for admission (Rule 25 or Rule 27) — this should be Rule 25 unless you are already a Malaysian practitioner&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.189229674444/elitigation1.avif&quot; alt=&quot;eLitigation screenshot showing details that need to be filled in&quot;&gt;&lt;/p&gt;
&lt;p&gt;At the same time that you file your OA, you will also have to file SILE&apos;s letter of registration confirming that you are a QP.&lt;/p&gt;
&lt;h1 id=&quot;timing&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#timing&quot; aria-label=&quot;timing permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Timing&lt;/h1&gt;
&lt;p&gt;The OA will expire a year after it is filed if no party to the matter takes any step that is recorded in the court&apos;s records.&lt;sup id=&quot;fnref-4&quot;&gt;&lt;a href=&quot;#fn-4&quot; class=&quot;footnote-ref&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; This occurred, for instance, in &lt;em&gt;Re Rajagopal Muralitharan&lt;/em&gt;&lt;sup id=&quot;fnref-5&quot;&gt;&lt;a href=&quot;#fn-5&quot; class=&quot;footnote-ref&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; where the applicant&apos;s Originating Summons (as it then was) expired because the applicant had to resit the Part B examinations and it was not possible for him to take any further steps to pursue the matter. Under such circumstances, the applicant should have applied for an extension of time.&lt;sup id=&quot;fnref-6&quot;&gt;&lt;a href=&quot;#fn-6&quot; class=&quot;footnote-ref&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;r 25(2) LPAR states that the application should be made via an OA (formerly known as an originating summons) as opposed to an originating claim.&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;See &lt;a href=&quot;https://www.sile.edu.sg/pdf/1_ADMISSION_TO_THE_SINGAPORE_BAR_-_Admission_Procedure.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SILE&apos;s Guide to the Admission Procedure in General&lt;/a&gt;&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;This should technically be the date on which you &quot;&lt;em&gt;secure a place as a candidate for the course of study&lt;/em&gt;&quot;, i.e. the date you were informed you were admitted to the university, rather than the date of your matriculation or the first day of the term, etc (per r 3 LPQR). See Jack Tsen-Ta Lee (1997), p 462 - 463. However, I know of many people who were not aware of r 3 and who put down the date that they matriculated or registered with the university instead and this was not raised as an issue and did not in any way impede their call.&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;O 16 r 7(2), ROC 2021.&lt;a href=&quot;#fnref-4&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-5&quot;&gt;&lt;a href=&quot;https://www.elitigation.sg/gd/s/2023_SGHC_133&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;[2023] SGHC 133&lt;/a&gt;&lt;a href=&quot;#fnref-5&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-6&quot;&gt;Under what is now O 16 r 7(9), ROC 2021.&lt;a href=&quot;#fnref-6&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Applying for admission to the Singapore Bar: the eLearning courses]]></title><description><![CDATA[On the e-Learning: Ethics in Practice and the e-Learning: Legal Profession (Solicitors' Account) Rules courses

One of the requirements prescribed by the Singapore Institute of Legal Education (SILE) that must be fulfilled before SILE will issue a…]]></description><link>https://huey.xyz/posts/2023-08-09-applying-for-admission-to-the-singapore-bar-elearning-courses</link><guid isPermaLink="false">332cf240d137afa3e774a1d1184092907974ee76e83e17e56f7ff3dabbd8347c</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Wed, 09 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;On the e-Learning: Ethics in Practice and the e-Learning: Legal Profession (Solicitors&apos; Account) Rules courses&lt;/h2&gt;&lt;p&gt;One of the requirements prescribed by the &lt;a href=&quot;https://www.sile.edu.sg/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Institute of Legal Education (SILE)&lt;/a&gt; that must be fulfilled before SILE will issue a certificate confirming that an applicant has met the substantive requirements to be admitted as an advocate and solicitor in Singapore is that the applicant complete the &lt;a href=&quot;https://www.lawsociety.org.sg/cpd/ethics-in-practice-legal-profession-rules/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;em&gt;e-Learning: Ethics in Practice&lt;/em&gt; and the &lt;em&gt;e-Learning: Legal Profession (Solicitors&apos; Account) Rules&lt;/em&gt; courses conducted by the Law Society&lt;/a&gt;. This is a requirement under the &lt;a href=&quot;https://www.sile.edu.sg/pdf/SILE%20Practice%20Training%20Contract%20Guidelines.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SILE Practice Training Contract Guidelines&lt;/a&gt;,&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; which states:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For the purposes of rule 19(1)(c) of the Legal Profession (Admission) Rules 2011, a supervising solicitor shall ensure that each practice trainee under his supervision attends the following courses conducted by the Law Society of Singapore:&lt;/p&gt;
&lt;p&gt;(a) a course on the Legal Profession (Solicitors’ Accounts) Rules (Cap. 161, R 8); and&lt;/p&gt;
&lt;p&gt;(b) a course on professional ethics.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;overview&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#overview&quot; aria-label=&quot;overview permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Overview&lt;/h1&gt;
&lt;p&gt;The course is an e-learning course consisting of animated videos.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.189229674425/case-study-7.avif&quot; alt=&quot;Screenshot depicting case study 7&quot;&gt;&lt;/p&gt;
&lt;p&gt;The videos were bite-sized, usually just a few minutes in length, which weas probably intended to make the course manageable and make it easy to drop off and resume at any point.&lt;/p&gt;
&lt;h1 id=&quot;cost&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#cost&quot; aria-label=&quot;cost permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Cost&lt;/h1&gt;
&lt;p&gt;The fee for each course is SGD 108, adding up to a total of SGD 216 for both. After making payment, you will receive a receipt via email.&lt;/p&gt;
&lt;h1 id=&quot;difficulty&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#difficulty&quot; aria-label=&quot;difficulty permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Difficulty&lt;/h1&gt;
&lt;p&gt;The passing mark is 80% and you only get 2 attempts, but the course is fairly straightforward, especially so if you attempt it soon after taking Part B because it almost entirely overlaps with the Ethics and Professional Responsibility module in Part B.&lt;sup id=&quot;fnref-4&quot;&gt;&lt;a href=&quot;#fn-4&quot; class=&quot;footnote-ref&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.189229674423/assessment-results.avif&quot; alt=&quot;Assessment results&quot;&gt;&lt;/p&gt;
&lt;p&gt;I completed each module within 2 hours. You can adjust the playback speed by right clicking on the video if you&apos;re using Firefox. I think this can also be accomplished using a browser extension on Chrome. Right clicking seems to be impeded on some of the &apos;interactive&apos; videos because the interactive layer is overlaid on top of the video — this can be overcome with some fiddling with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/z-index&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;z-index&lt;/code&gt;&lt;/a&gt; using the browser developer tools, or you can just sit through those videos, they are not unbearably long.&lt;/p&gt;
&lt;p&gt;The assessment questions appear to be randomly chosen from a question bank so I did not see all of them, but I noticed that one of questions displayed to me had an incorrect answer:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.189229674429/question-10.avif&quot; alt=&quot;Question 10&quot;&gt;&lt;/p&gt;
&lt;p&gt;Under &lt;a href=&quot;https://sso.agc.gov.sg/Act/LPA1966?ProvIds=P15A-#pr70F-&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Section 70F of the Legal Profession Act 1966&lt;/a&gt;, the Council has the power to inspect any law practice &lt;strong&gt;both&lt;/strong&gt; on its own motion &lt;strong&gt;and&lt;/strong&gt; upon a written complaint by a client. Anyway, I brought this to the Law Society&apos;s attention and this error should be corrected going forward.&lt;/p&gt;
&lt;h1 id=&quot;timing&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#timing&quot; aria-label=&quot;timing permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Timing&lt;/h1&gt;
&lt;p&gt;You can register for and complete these courses at your convenience. However, it&apos;s probably best to register only when you are confident you have some time to sit through the videos and complete the assessment because your access will expire 3 days after registration.&lt;/p&gt;
&lt;p&gt;At the time I took it, the WizLearn system that the Law Society used to conduct the course appeared to be configured such that no matter what time of day you registered, your registration would only take effect and you would only receive the login details at 1am.&lt;sup id=&quot;fnref-5&quot;&gt;&lt;a href=&quot;#fn-5&quot; class=&quot;footnote-ref&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; You will then have exactly 72 hours from that 1am to complete that course.&lt;/p&gt;
&lt;p&gt;If you choose to register for both courses at the same time, you will get 6 days (i.e. 144 hours) to complete them both.&lt;/p&gt;
&lt;p&gt;For reference, the registration confirmation email broadly takes the following form:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;FROM: noreply@wizlearn.com

Dear [your name]

Thank you for Registering &quot;e-Learning Programmes: Ethics in Practice &amp;amp; Solicitors&apos; Accounts&apos; Rules&quot;.

Do find the following details for your information:

Programme
- e-Learning: Ethics in Practice
- e-Learning: Legal Profession (Solicitors&apos; Account) Rules&apos;

Expiry Date
21 January 2023, Saturday 01.00 AM
*Strictly NO extension of the viewing period is allowed.*

Log In Details
Website 	https://lms.wizlearn.com/lawsocelearning/Login.aspx
UserID 	  [email address]
Password 	Please use [URL] to reset your password

**Please note that the access will automatically be disabled after the expiry date.**

For course related matters, please contact cpd@lawsoc.org.sg

For technical matters, please contact lmssupport@wizlearn.com

Thank you.

The Law Society of Singapore
cpd@lawsoc.org.sg
+65 6530-2500

Please note that the Learning Management System (LMS) will be under scheduled maintenance on the last Sunday of every month (from 00:00 to 07:00am, Singapore time). During this period, the LMS is not accessible. Kindly write in to us at cpd@lawsoc.org.sg should extension of access is required due to the maintenance and we will grant the extension accordingly. Please note that request of extension of access for reasons beyond the maintenance and any other technical glitches will not be acceded.

[This is a computer generated email. Please do not reply back to this email.]&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;completion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#completion&quot; aria-label=&quot;completion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Completion&lt;/h1&gt;
&lt;p&gt;After you pass the assessment for each module, you will receive the certificate of completion for that module via email, which you will later have to provide to SILE when requesting for &lt;a href=&quot;/posts/2023-08-09-applying-for-admission-to-the-singapore-bar-sile-certificate/&quot;&gt;the SILE certificate&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;Issued under r 23, Legal Profession (Admission) Rules 2011&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;It seems to be possible to register for and complete both courses &lt;em&gt;during Part B&lt;/em&gt; which might be useful revision for the Ethics and Professional Responsibility Module and reduce your workload during your practice training period. However, I did not think of doing this at the time and I don&apos;t know anyone who had the foresight to do this so I cannot confirm that this is possible.&lt;a href=&quot;#fnref-4&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-5&quot;&gt;For instance, I registered at about 12.30pm on a Saturday and only received the registration confirmation at 1am on Sunday.&lt;a href=&quot;#fnref-5&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Applying for admission to the Singapore Bar: the SILE certificate]]></title><description><![CDATA[Requesting for the SILE certificate prior to filing your supplementary affidavit

The SILE certificate (sample here) must be attached as an exhibit to your supporting affidavit. Obtaining this certificate is a 2-step…]]></description><link>https://huey.xyz/posts/2023-08-09-applying-for-admission-to-the-singapore-bar-sile-certificate</link><guid isPermaLink="false">e8c4261a74bc5e719946d2099b4fdeb4c97e038ad5f5bf6235e2ad40def91fcb</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Wed, 09 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Requesting for the SILE certificate prior to filing your supplementary affidavit&lt;/h2&gt;&lt;p&gt;The SILE certificate (&lt;a href=&quot;/1776002971087.189229674440/sile-cert-sample-2023.pdf&quot;&gt;sample here&lt;/a&gt;) must be attached as an exhibit to your supporting affidavit.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Obtaining this certificate is a 2-step process involving: (a) a request via email; and (b) a request via eLitigation.&lt;/p&gt;
&lt;h1 id=&quot;email-request&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#email-request&quot; aria-label=&quot;email request permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Email request&lt;/h1&gt;
&lt;p&gt;First, you must send a request for the certificate via email to &lt;a href=&quot;mailto:admissions@sile.edu.sg&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;admissions@sile.edu.sg&lt;/a&gt;, with the subject as &quot;&lt;em&gt;Certificate of Diligence for AAS of (your name and Part B student number)&lt;/em&gt;&quot;, and the following documents attached:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Signed certificate of diligence (COD)&lt;/strong&gt;: This should be in the form prescribed in the Second Schedule of the LPAR.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; SILE also provides Microsoft Word copies of the form &lt;a href=&quot;https://www.sile.edu.sg/relevant-forms&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;here&lt;/a&gt;. You should pick the form applicable to the organisation with which you have done your TC with. A template form for a LLP with ≥ 2 partners can be found &lt;a href=&quot;/1776002971087.189229674433/COD-template-2023.odt&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Signed PTC checklist&lt;/strong&gt;: SILE requires &lt;a href=&quot;https://www.sile.edu.sg/pdf/SILE_PTCC_Form-for_print%26sign.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;this checklist&lt;/a&gt; to be filled out. Inconveniently, they only provide a PDF version, but you can find an editable copy &lt;a href=&quot;/1776002971087.189229674436/PTC-checklist-2023.odt&quot;&gt;here&lt;/a&gt;, which will allow you to easily check the boxes and add the necessary remarks.&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Certificates of completion&lt;/strong&gt;: SILE requires you to submit certificates of completion for the &lt;a href=&quot;https://www.lawsociety.org.sg/cpd/ethics-in-practice-legal-profession-rules/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;em&gt;e-Learning: Ethics in Practice&lt;/em&gt; and the &lt;em&gt;e-Learning: Legal Profession (Solicitors&apos; Account) Rules&lt;/em&gt; courses conducted by the Law Society&lt;/a&gt;. More details about the e-Learning courses are available &lt;a href=&quot;/posts/2023-08-09-applying-for-admission-to-the-singapore-bar-elearning-courses/&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SILE states &lt;a href=&quot;https://www.sile.edu.sg/relevant-forms&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;on its website&lt;/a&gt; that the COD and PTC checklist can be signed electronically or via wet ink.&lt;/p&gt;
&lt;h1 id=&quot;elitigation-request&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#elitigation-request&quot; aria-label=&quot;elitigation request permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;eLitigation request&lt;/h1&gt;
&lt;p&gt;After SILE has reviewed your request and notified you via email that you may proceed to file your request via eLitigation, you can do so.&lt;/p&gt;
&lt;p&gt;r 31 LPAR prescribes Form B(3), but in any case you can compose the request via eLitigation so there is no need to upload any document.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;See &lt;a href=&quot;https://sso.agc.gov.sg/SL/LPA1966-S244-2011?DocDate=20230111&amp;#x26;ProvIds=P1VI-#pr25-&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;r 25(4), Legal Profession (Admission) Rules 2011 (LPAR)&lt;/a&gt;&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;Regarding the requirement that you attend a Court of Appeal hearing, considering this requirement was put in place prior to the introduction of the Appellate Division and Court of Appeal hearings are accordingly much rarer than before, I wrote to SILE asking if attending an Appellate Division hearing would suffice. SILE confirmed that it would not object to this.&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Untruncated file names on SSO]]></title><description><![CDATA[how to ensure that the PDFs you download from Singapore Statutes Online are appropriately named

If you have had the (mis)fortune of having to regularly download legislation from Singapore Statutes Online (sso.agc.gov.sg), you may have…]]></description><link>https://huey.xyz/posts/2022-11-21-untruncated-file-names-on-sso</link><guid isPermaLink="false">a3fb319441600343a5555a9ac0c93e37db89e6c94d948a2abb149a3f5c714530</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Mon, 21 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;how to ensure that the PDFs you download from Singapore Statutes Online are appropriately named&lt;/h2&gt;&lt;p&gt;If you have had the (mis)fortune of having to regularly download legislation from &lt;a href=&quot;https://sso.agc.gov.sg/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Statutes Online&lt;/a&gt; (&lt;a href=&quot;https://sso.agc.gov.sg/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;sso.agc.gov.sg&lt;/a&gt;), you may have noticed that SSO appears to have a maximum length of 50 characters for downloaded PDF files. This can cause file names for legislation with long titles to be truncated. For instance the &lt;a href=&quot;https://sso.agc.gov.sg//SL/IRDA2018-S619-2020&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Insolvency, Restructuring and Dissolution (Prescribed Companies and Entities) Order 2020&lt;/a&gt; becomes &lt;code class=&quot;language-text&quot;&gt;Insolvency, Restructuring and Dissolution (Prescri.pdf&lt;/code&gt;, which is coincidentally the same truncated file name that is assigned to the &lt;a href=&quot;https://sso.agc.gov.sg//SL/IRDA2018-S616-2020?DocDate=20200728&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Insolvency, Restructuring and Dissolution (Prescribed Contracts under Section 440) Regulations 2020&lt;/a&gt;, &lt;a href=&quot;https://sso.agc.gov.sg//SL/IRDA2018-S53-2021?DocDate=20210128&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Insolvency, Restructuring and Dissolution (Prescribed Periods for Parts 5A and 10A) Order 2021&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;There are plenty of other examples.&lt;/p&gt;
&lt;p&gt;SSO is managed by the Legislation Division of the AGC, and I understand from them that they do not believe it is technically feasible to modify the SSO system to allow for downloaded PDFs to be named according to the full title of the relevant legislation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The length of file names of downloaded PDFs from SSO relate to current system requirements, and it is not feasible to make your proposed change. Users who download a PDF copy of legislation from SSO can manually edit the title of the PDF document on their devices according to their preferences.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unfortunate, but not very difficult to work around. For my own convenience (and hopefully many other users&apos; convenience as well), I&apos;ve added this functionality to Clerkent.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.189229674419/sso_screenshot.avif&quot; alt=&quot;Screenshot of renamed file in save dialog&quot;&gt;&lt;/p&gt;
&lt;p&gt;As of &lt;a href=&quot;https://github.com/lacuna-technologies/clerkent/releases/tag/v3.4.4&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;v3.4.4&lt;/a&gt;, &lt;a href=&quot;https://clerkent.huey.xyz/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Clerkent&lt;/a&gt;, a browser extension for Chrome and Firefox, will rename PDFs downloaded from SSO with the full title of the relevant legislation.&lt;/p&gt;
&lt;p&gt;Try it out!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Transferring files to and from a Fly.io volume]]></title><description><![CDATA[how to manage data on a persistent volume

Fly.io provides a generous free tier, including up to 3 VMs with shared CPUs and up to 256MB of RAM. That's more than enough to run 3 simple…]]></description><link>https://huey.xyz/posts/2022-09-28-flyio-file-transfer</link><guid isPermaLink="false">b7d7525f85ece96da36fec509d93f80f1acc6e46c991164ea770cb28b8324001</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Wed, 28 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;how to manage data on a persistent volume&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://fly.io/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Fly.io&lt;/a&gt; provides a &lt;a href=&quot;https://fly.io/docs/about/pricing/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;generous free tier&lt;/a&gt;, including up to 3 VMs with shared CPUs and up to 256MB of RAM. That&apos;s more than enough to run 3 simple web apps.&lt;/p&gt;
&lt;p&gt;I&apos;ve run many things on Fly.io, including the Ghost blogging platform, Telegram bots, and miscellaneous backend services.&lt;/p&gt;
&lt;p&gt;One thing to note when before migrating to Fly.io is that since it&apos;s marketed towards developers, most of the functionality is primarily available via the &lt;code class=&quot;language-text&quot;&gt;flyctl&lt;/code&gt; CLI tool. But the tool is fairly simple to use, so this shouldn&apos;t be much of a problem.&lt;/p&gt;
&lt;p&gt;A more significant annoyance for me was that Fly.io doesn&apos;t provide a straightforward way to access and modify the persistent volumes that are attached to VMs. For instance, I might want to copy the contents of a volume to my local environment to test on &apos;production&apos; data, or I might want to import data when migrating an app to Fly.io. I did not see any simple and fuss-free way to accomplish this.&lt;/p&gt;
&lt;p&gt;My solution is to SSH into the VM and then transfer the data using &lt;code class=&quot;language-text&quot;&gt;rsync&lt;/code&gt; or similar.&lt;/p&gt;
&lt;h1 id=&quot;getting-ssh-access&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#getting-ssh-access&quot; aria-label=&quot;getting ssh access permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Getting SSH access&lt;/h1&gt;
&lt;p&gt;It is not possible to SSH into a VM from an external IP address by default, so you should first &lt;a href=&quot;https://fly.io/docs/flyctl/proxy/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;proxy&lt;/a&gt; your connection:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl proxy &lt;span class=&quot;token number&quot;&gt;10022&lt;/span&gt;:22&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This proxies port 22 on the VM to port 10022 locally. I&apos;ve used 10022 as an arbitrary port. You can proxy to any unused port (just remember to specify that port when you SSH in later).&lt;/p&gt;
&lt;p&gt;Next, &lt;a href=&quot;https://fly.io/docs/flyctl/ssh-issue/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;get a SSH private key&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flyctl &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; issue&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I stored mine in &lt;code class=&quot;language-text&quot;&gt;~/.ssh/fly_temp&lt;/code&gt;. It will be valid for 24 hours only, but you can repeat the process if you need it again.&lt;/p&gt;
&lt;p&gt;If you just want to SSH in, you can run &lt;code class=&quot;language-text&quot;&gt;flyctl ssh console&lt;/code&gt; instead.&lt;/p&gt;
&lt;h1 id=&quot;ssh-in&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#ssh-in&quot; aria-label=&quot;ssh in permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;SSH in&lt;/h1&gt;
&lt;p&gt;At this point, you can already SSH in:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10022&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; ~/.ssh/fly_temp root@localhost&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The username you should use will vary depending on what Docker image you have deployed. I&apos;m using an Alpine image, hence it&apos;s &lt;code class=&quot;language-text&quot;&gt;root&lt;/code&gt;. It might be &lt;code class=&quot;language-text&quot;&gt;ubuntu&lt;/code&gt; for Ubuntu images, etc.&lt;/p&gt;
&lt;p&gt;However, rather than run ad-hoc SSH commands with a bunch of flags and arguments, I found it more convenient to edit my SSH config at &lt;code class=&quot;language-text&quot;&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Host fly
  HostName localhost
  Username root
  IdentityFile ~/.ssh/fly_temp
  Port &lt;span class=&quot;token number&quot;&gt;10022&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This also allows you to &lt;code class=&quot;language-text&quot;&gt;rsync&lt;/code&gt; your files easily:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;rsync&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-aP&lt;/span&gt; ~/files/ fly:/app/files/&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Recommending books to NLB]]></title><description><![CDATA[a brief overview and details about recommendation statuses

I'm not sure many people realise that the National Library Board (NLB) of Singapore welcomes book recommendations. I'm an avid book…]]></description><link>https://huey.xyz/posts/2022-09-27-nlb-recommendations</link><guid isPermaLink="false">2330b44a56be1249f7c1f4106cde89253e423e1c3f912af36f90a80495027f1b</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Tue, 27 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;a brief overview and details about recommendation statuses&lt;/h2&gt;&lt;p&gt;I&apos;m not sure many people realise that the &lt;a href=&quot;https://www.nlb.gov.sg/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;National Library Board (NLB) of Singapore&lt;/a&gt; welcomes book recommendations. I&apos;m an avid book recommender and have recommended many books over the years, and am glad to say that quite a number of my recommendations have been accepted.&lt;/p&gt;
&lt;p&gt;I&apos;m not sure what approach NLB takes towards determining whether or not to accept a recommendation, but in the off chance that they do take into account the quality of my previous recommendations, such as by measuring how often the recommended book was subsequently borrowed, I always try to borrow any books I recommend once they become available.&lt;/p&gt;
&lt;p&gt;You can recommend books via NLB&apos;s website by visiting the &lt;a href=&quot;https://www.nlb.gov.sg/recommend/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Recommend A Title&lt;/a&gt;. You do have to log in with your NLB account (and you therefore have to be a NLB member to recommend a title). The interface is pretty self-explanatory:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.169429674409/web1.avif&quot; alt=&quot;Screenshot of web interface&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.169429674412/web2.avif&quot; alt=&quot;Screenshot of recommendation modal&quot;&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m not quite sure what should go in the &quot;Other Information&quot; field, but I usually put in the ISBN (if it&apos;s not already automatically retrieved) and a link to the product listing for the book on Book Depository, Amazon.sg, or some other retailer.&lt;/p&gt;
&lt;p&gt;You can also recommend titles using the new and improved NLB app:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.169429674406/mobile1.avif&quot; alt=&quot;Screenshot of mobile app&quot;&gt;&lt;/p&gt;
&lt;p&gt;As you will have noticed, NLB assigns each recommendation a status of sorts. So far, I&apos;ve seen the following statuses, and NLB has helpfully clarified that they have the following meanings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Recommended&lt;/strong&gt;: this is the initial status set once you submit your recommendation. NLB says that this means that its vendors are checking the stock availability of the title recommended.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accepted&lt;/strong&gt;: your recommendation has been accepted 🎉&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unable to Purchase&lt;/strong&gt;: according to NLB, this means that their vendor is unable to supply the title or they are unable to process the recommendation (e.g. ISBN of the title has not been provided).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On Order&lt;/strong&gt;: this status is assigned after the &quot;Accepted&quot; status and indicates that the recommended title is currently on order through NLB&apos;s vendors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There therefore does not appear to be a &quot;Rejected&quot; status &lt;em&gt;per se&lt;/em&gt; (or perhaps my recommendations are of such quality that they are never rejected 🤔), but from experience it appears that the &quot;Unable to Purchase&quot; may also be used as a &quot;Rejection&quot; status.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Debugging a Crestar fan]]></title><description><![CDATA[how to save $50 when your remote control stops working

I have a Crestar ValueAir 48/55WD + LED fan. It is controlled by a PP-KG-23 remote control that looks like this: KG23 remote control The…]]></description><link>https://huey.xyz/posts/2022-09-18-crestar-fan</link><guid isPermaLink="false">51fc956936d3672180e96daf900c25d7c499a6a8e01b3b96a48eecdd781c4b14</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sun, 18 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;how to save $50 when your remote control stops working&lt;/h2&gt;&lt;p&gt;I have a &lt;a href=&quot;https://crestarfan.com.sg/products/valueair-5blades-48-55inch&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Crestar ValueAir 48/55WD + LED fan&lt;/a&gt;. It is controlled by a PP-KG-23 remote control that looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.169429674401/kg23.avif&quot; alt=&quot;KG23 remote control&quot;&gt;&lt;/p&gt;
&lt;p&gt;The remote control never worked all that well, but recently it finally gave up and stopped working completely. Considering that it continued to remain non-functional after I changed the batteries, my first thought was that the remote control was not working and I needed a new remote.&lt;/p&gt;
&lt;p&gt;I contacted Crestar who informed me I could purchase a new one for SGD 45 from their Tampines outlet. Unfortunately, I have spent too much time debugging software and I overthought the matter. I mentioned a possibility that the customer support person on the line did not appear to have considered — what if it was the fan&apos;s receiver and not the remote that was defective?&lt;/p&gt;
&lt;p&gt;After pausing for a moment to consider this, Crestar customer support informed me that it would be necessary for a technician to conduct an on-site examination to determine if this was the case. Having dug myself into this hole, I had little choice but to agree.&lt;/p&gt;
&lt;p&gt;Naturally, after inspecting the remote, the technician informed me that the receiver was perfectly functional and my first instinct was right — it was the remote control that had given way. And so I needlessly paid an extra SGD 50 service fee on top of the SGD 45 for the actual remote control.&lt;/p&gt;
&lt;p&gt;At least now I know how to determine if the remote or the receiver is defective and can record it here for posterity: if no sound is emitted when pressing buttons on the remote, the remote is defective. If there is sound, but no movement on the part of the fan, that&apos;s when the receiver is defective. I hope someone is able to use this knowledge to save themselves $50.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Generating legal diagrams from text]]></title><description><![CDATA[more efficient diagram-making with Mermaid

The law is very text-heavy. It is common for legislation and case law to set out complex concepts and complicated procedures in prose, which…]]></description><link>https://huey.xyz/posts/2022-08-25-legal-diagrams-and-mermaid</link><guid isPermaLink="false">a78a54083c64195f75ebe22f45ecd9251915623a5d95b41952937da976a4551d</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Thu, 25 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;more efficient diagram-making with Mermaid&lt;/h2&gt;&lt;p&gt;The law is very text-heavy. It is common for legislation and case law to set out complex concepts and complicated procedures in prose, which can be tedious to read and difficult to understand.&lt;/p&gt;
&lt;p&gt;Quite a bit of the value-add of a lawyer is reading all that prose for you, and distilling it down into a quick summary that is relevant to your situation. Sometimes this summary is in prose (but shorter and more punchy prose), and sometimes the summary includes diagrams. Such diagrams can be incredibly helpful in conveying the relationship between concepts and processes.&lt;/p&gt;
&lt;h1 id=&quot;the-state-of-the-art&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-state-of-the-art&quot; aria-label=&quot;the state of the art permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The state of the art&lt;/h1&gt;
&lt;p&gt;These diagrams are generally created via PowerPoint or Word.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Lawyers use PowerPoint and Word for diagram-making for good reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;they use these programs every day and are innately familiar with how to use them&lt;/li&gt;
&lt;li&gt;the learning curve for these programs is gentle. The drag-and-drop, WYSIWYG interface makes it easy for anyone to quickly start designing diagrams one text box or callout at a time. SmartArt makes it easy to make the diagrams look decent (albeit somewhat &lt;em&gt;cliché&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;modification-is-difficult&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#modification-is-difficult&quot; aria-label=&quot;modification is difficult permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Modification is difficult&lt;/h2&gt;
&lt;p&gt;Diagram-making via these programs works pretty well, but there are in my view, one key disadvantage: creating is easy, but modification is difficult.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971085.189229674380/diagram1.avif&quot; alt=&quot;Diagram 1&quot;&gt;&lt;/p&gt;
&lt;p&gt;As anyone who has had to modify a diagram on PowerPoint or Word will know, after changing the size of one shape, you then have to manually resize all the surrounding shapes accordingly. If you re-arrange a shape or add a new one, you have to shift all your related shapes accordingly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971085.189229674383/diagram2.avif&quot; alt=&quot;Diagram 2&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;If you want to increase the size of one shape and insert a new shape in between, you have plenty of re-arranging to do.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;And if you have your perfect diagram, but for some reason need it to be narrower or shorter (e.g. so you can squeeze some explanatory text by the side), all hell breaks loose and you will need to both resize and re-arrange everything.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971085.189229674386/diagram3.avif&quot; alt=&quot;Diagram 3&quot;&gt;&lt;/p&gt;
&lt;p&gt;SmartArt ameliorates this problem by allowing you to simply edit text versions of the diagram, whereupon it takes care of all the resizing and re-organisation for you.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971085.189229674389/diagram4.avif&quot; alt=&quot;Diagram 4&quot;&gt;&lt;/p&gt;
&lt;p&gt;But it doesn&apos;t go far enough. To preserve the gentle learning curve associated with PowerPoint and Word, the standard editing method is preserved and it&apos;s very easy to unknowingly break out of text-based generation and enter a hybrid world where the diagram is partly the product of text-based generation and partly the product of your manual edits. If you shift the position of one of the shapes or change its size, SmartArt will try to adjust the others accordingly, but subsequent diagram-editing will not be as straightforward because the formatting will be inconsistent and there is no easy way to return to pure text-based generation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971086.189229674392/diagram5.avif&quot; alt=&quot;Diagram 5&quot;&gt;&lt;/p&gt;
&lt;p&gt;SmartArt is also limited — it only allows generation of diagrams that conform to its rigid templates. For instance, it is not possible to label the arrows above without doing it manually, or to add a new arrow going upwards such as in the following diagram:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971087.169429674395/diagram6.avif&quot; alt=&quot;Diagram 6&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;generating-diagrams-from-text&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#generating-diagrams-from-text&quot; aria-label=&quot;generating diagrams from text permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Generating diagrams from text&lt;/h1&gt;
&lt;p&gt;Generating diagrams from text overcomes the difficulties in modifying diagrams and also makes creating diagrams quicker and more efficient. Some front-loaded investment in learning is needed considering the steeper learning, but this is more than repaid in terms of time saved for anyone who expects to be creating diagrams for years to come.&lt;/p&gt;
&lt;p&gt;One popular markup language that allows text-based generation is &lt;a href=&quot;https://mermaid-js.github.io/mermaid/#/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Mermaid&lt;/a&gt;. It has a fairly straightforward syntax that supports creation of complex diagrams and is far more flexible than SmartArt.&lt;/p&gt;
&lt;p&gt;For example, the following text:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-mermaid line-numbers&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;flowchart&lt;/span&gt; TD
  T&lt;span class=&quot;token text string&quot;&gt;[Trademark application]&lt;/span&gt;&lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;F&lt;span class=&quot;token text string&quot;&gt;[Formalities examination]&lt;/span&gt;
  F&lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;S&lt;span class=&quot;token text string&quot;&gt;[Substantive examination]&lt;/span&gt;
  S&lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;O&lt;span class=&quot;token text string&quot;&gt;[Office action]&lt;/span&gt;
&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;will generate the following diagram:&lt;/p&gt;
&lt;div class=&quot;mermaid&quot;&gt;
flowchart TD
  T[Trademark application]--&gt;F[Formalities examination]
  F--&gt;S[Substantive examination]
  S--&gt;O[Office action]
&lt;/div&gt;
&lt;p&gt;The syntax is simple: just draw arrows between text using dashes and angular brackets. It is readable on its own without the generated diagram.&lt;/p&gt;
&lt;p&gt;With text-based generation, it is trivial to add new shapes and text. Mermaid will automatically re-arrange the shapes in a sane manner. For example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;mermaid&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-mermaid line-numbers&quot;&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;flowchart&lt;/span&gt; TD
  Application&lt;span class=&quot;token text string&quot;&gt;[Trademark application]&lt;/span&gt;
  Application&lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;Formalities
  Formalities&lt;span class=&quot;token text string&quot;&gt;[Formalities examination]&lt;/span&gt;
  Formalities&lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;Substantive
  Substantive&lt;span class=&quot;token text string&quot;&gt;[Substantive examination]&lt;/span&gt;
  Substantive&lt;span class=&quot;token inter-arrow-label&quot;&gt;&lt;span class=&quot;token arrow-head arrow operator&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;token label property&quot;&gt;objection&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;/span&gt;OA&lt;span class=&quot;token text string&quot;&gt;[Office action]&lt;/span&gt;
  OA&lt;span class=&quot;token inter-arrow-label&quot;&gt;&lt;span class=&quot;token arrow-head arrow operator&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;token label property&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;/span&gt;Substantive
  OA&lt;span class=&quot;token inter-arrow-label&quot;&gt;&lt;span class=&quot;token arrow-head arrow operator&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;token label property&quot;&gt;objections overcome&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;/span&gt;TMJ&lt;span class=&quot;token text string&quot;&gt;[Published in Trade Marks Journal]&lt;/span&gt;
  Substantive&lt;span class=&quot;token inter-arrow-label&quot;&gt;&lt;span class=&quot;token arrow-head arrow operator&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;token label property&quot;&gt;no objections&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;/span&gt;TMJ
  TMJ&lt;span class=&quot;token inter-arrow-label&quot;&gt;&lt;span class=&quot;token arrow-head arrow operator&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;token label property&quot;&gt;no opposition&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;/span&gt;Registration&lt;span class=&quot;token text string&quot;&gt;[Mark is registered]&lt;/span&gt;
  TMJ&lt;span class=&quot;token arrow operator&quot;&gt;---&gt;&lt;/span&gt;Opposition&lt;span class=&quot;token text string&quot;&gt;[Opposition proceedings]&lt;/span&gt;
  Opposition&lt;span class=&quot;token inter-arrow-label&quot;&gt;&lt;span class=&quot;token arrow-head arrow operator&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;token label property&quot;&gt;opposition unsuccessful&lt;/span&gt; &lt;span class=&quot;token arrow operator&quot;&gt;--&gt;&lt;/span&gt;&lt;/span&gt;Registration&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;mermaid&quot;&gt;
flowchart TD
  Application[Trademark application]
  Application--&gt;Formalities
  Formalities[Formalities examination]
  Formalities--&gt;Substantive
  Substantive[Substantive examination]
  Substantive-- objection --&gt;OA[Office action]
  OA-- response --&gt;Substantive
  OA-- objections overcome --&gt;TMJ[Published in Trade Marks Journal]
  Substantive-- no objections --&gt;TMJ
  TMJ-- no opposition --&gt;Registration[Mark is registered]
  TMJ---&gt;Opposition[Opposition proceedings]
  Opposition-- opposition unsuccessful --&gt;Registration
&lt;/div&gt;
&lt;p&gt;There is much to be said for using Mermaid to create diagrams in legal work. No need to bother with sizing or placing each node — Mermaid does it automatically for you. All you need to do is specify the content and relationship between each node. And Mermiad is highly customisable. You can have sections with different orientations, adjust the length of the connecting lines, use different shapes besides squares, and even include &lt;a href=&quot;https://fontawesome.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Font Awesome icons&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That said, I realise any transition will be tricky because PowerPoint and Word will continue to remain industry standards for the foreseeable future. Even the new &lt;a href=&quot;https://epd-supcourt-2021.opendoc.gov.sg/PART-07-Case%20Conferences.html#56-documents-to-be-filed-for-case-conferences&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Supreme Court Practice Directions 2021&lt;/a&gt; refer to &quot;Microsoft Word format&quot;.&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; As an interim solution, one way to use Mermaid whilst continuing to work primarily in PowerPoint and Word is to use the &lt;a href=&quot;https://mermaid.live/edit#pako:eNptkk1v4jAQhv-K5TOgfEEgh5Wo2j0gVVRbTpv0MNgTcDexI3_0YxH_fe3Qhqhd5eDxvK-fmbFzokxxpAWtG_XKjqAt2d1UkpB11zWCgRVKljsNHFvQfwhcs09fXNPpj59Kt9AIK9AEcbQtRzHBN2iFvEJGmoc8ur2xIK14wSCOtuUo_gYZadMpUftnZEEjnrhdl9u6FgwJsMG_XXubRtMpaZB8r9vrA8YQ9YKaqba37u435YPbN8IckRMhSX9B5N7fkCEb5bSE5j9NSTUGXjjB5ZcPteuUEZ9t_8KDMFZfniCwiTC-45BEjfxpOOonHA6W15B0WjFELuTBXEYepDDa1eekcYyhMbVrvhau_EcntEX_RIL7_-QUSBW1R2yxooUPOdbgGlvRSp691XUcLN5xYZWmRQ2NwQkFZ9Xju2S0sNrhp-lWwEFDO7g6kLQ40TdaZIt0lkSrLEvidLnI49WEvvtsPEviLI7yeZxmSZ6n2XlC_yrlCdFsFc2j1FuX-SJJF8ue9rvXQsnzP3yHAcw&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Mermaid Live Editor web app&lt;/a&gt; that generates diagrams from mermaid text in your browser. The diagrams can then be exported as PNGs or SVGs and included in the relevant PowerPoint and Word documents.&lt;/p&gt;
&lt;p&gt;One major flaw with the interim solution above is that there will likely be doc-rot. Diagrams will become more difficult to maintain if they are generated via Mermaid text that is not contained in the same file. The Mermaid text is likely to be lost or misplaced, and the diagram will have to be generated from scratch.&lt;/p&gt;
&lt;p&gt;One solution to this I have in mind is to embed the Mermaid text (perhaps compressed) into the diagram file directly (i.e. the SVG or PNG), in an area that will be ignored by most PNG and SVG viewers, but which can then be read by a modified version of the Mermaid Live Editor web app.&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; Essentially, you would then be able to drag a PNG image of a Mermaid file onto the editor, edit the Mermaid text, and re-export it.&lt;/p&gt;
&lt;p&gt;In the longer term, however, I think there should be a Mermaid PowerPoint and Word add-on that allows you to edit Mermaid diagrams within the relevant programs, in-place. Perhaps I&apos;ll build this at some point.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Aside: I refer to the legal industry above because that is an area I am familiar with, but I believe much of the above applies equally to other professions that involve office work. Consultants, accountants, and other office-workers will likely also reap similar benefit from learning to generate diagrams from text instead of using PowerPoint and Word.&lt;/small&gt;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;Or more rarely, Google Docs or the macOS equivalents, Keynote and Pages&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;para 56(12)&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;It may be possible to store the text in the file metadata, which would simplify the implementation, but this would come at the cost of file size and some risk that the metadata will be stripped when embedding or sending the file (e.g. WhatsApp strips metadata of images).&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Manually generating a Zoom link]]></title><description><![CDATA[from the meeting ID and meeting password

The organiser of a recent Zoom meeting I attended provided me with only the meeting ID and meeting password, instead of simply giving me the…]]></description><link>https://huey.xyz/posts/2022-07-27-zoom-link</link><guid isPermaLink="false">02572e21e4cc7754d293daf3e8addfdba5e770c761f47d19d4fee2966db5944b</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Wed, 27 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;from the meeting ID and meeting password&lt;/h2&gt;&lt;p&gt;The organiser of a recent Zoom meeting I attended provided me with only the meeting ID and meeting password, instead of simply giving me the meeting link, as people normally do.&lt;/p&gt;
&lt;p&gt;This being a recurring meeting, it was a bit inconvenient to regularly have to copy and paste the meeting ID and meeting password into the Zoom client. I decided to try to generate a meeting link and bookmark it or something.&lt;/p&gt;
&lt;h1 id=&quot;my-attempts&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#my-attempts&quot; aria-label=&quot;my attempts permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;My attempts&lt;/h1&gt;
&lt;p&gt;My first naïve attempt was to host a meeting of my own, get a meeting link, and substitute the meeting ID and password:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;https://zoom.us/j/012345678?pwd=0123456&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Surprisingly, this sorta worked. Navigating to this link will launch the Zoom client and prompt you for the meeting password, which suggests that the meeting ID but not the meeting password is being passed.&lt;/p&gt;
&lt;p&gt;Since the host is a member of an organisation, I thought perhaps I needed to use the organisation-specific link, e.g.:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;https://lacuna-technologies.zoom.us/j/012345678?pwd=0123456&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, this worked no better.&lt;/p&gt;
&lt;p&gt;It was then I realised that the Zoom client is hashing or encoding the password URL parameter in some way. Instead of simply passing &lt;code class=&quot;language-text&quot;&gt;pwd=0123456&lt;/code&gt;, Zoom would pass &lt;code class=&quot;language-text&quot;&gt;pwd=ZGx3cTVHU1FHU0Q3LzhRK2lOV0RLdz09&lt;/code&gt; for instance. Initially, since the length of the string was 32 characters, I thought it might be a simple MD5 hash. However, I quickly realised the length of the string wasn&apos;t fixed and might be 31 characters, or some other length. The last 3 characters appeared to be fixed though.&lt;/p&gt;
&lt;p&gt;I also tried to &lt;code class=&quot;language-text&quot;&gt;base64&lt;/code&gt; decode it. Sometimes, &lt;code class=&quot;language-text&quot;&gt;base64&lt;/code&gt; decoding it twice would produce a string of alphanumeric characters, which suggested that a double &lt;code class=&quot;language-text&quot;&gt;base64&lt;/code&gt; encode formed some part of the encoding algorithm (as also observed by participants of this thread). But clearly there were some other steps I was missing.&lt;/p&gt;
&lt;h1 id=&quot;sidestepping-the-problem&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#sidestepping-the-problem&quot; aria-label=&quot;sidestepping the problem permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Sidestepping the problem&lt;/h1&gt;
&lt;p&gt;At this point I was getting a bit restless and attempting to reverse-engineer Zoom&apos;s encoding algorithm by trial and error seemed a bit too tedious an endeavour. I therefore settled for a simpler solution: simply use a deep link URL instead. Deep links generated by Zoom still appear to use a plain text password URL parameter instead an encoded one, so this allowed me to sidestep the encoding algorithm issue.&lt;/p&gt;
&lt;p&gt;I&apos;m not entirely sure why Zoom began encoding its meeting passwords. On the one hand, this does prevent passwords from being saved in plaintext in the browser history, or being displayed in plaintext in the address bar (which may have led to Zoombombing when people share a screenshot of their in-browser Zoom meeting). But on the other hand the password is still there — it&apos;s just encoded. If you have the meeting link that includes the encoded password you join the meeting just as easily as before. Maybe the length of an encoded password ensures that it is never fully visible in the browser address bar? But this could just as easily be addressed by generating longer passwords by default.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Anyway, a deep link like the following worked almost-perfectly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;zoommtg://zoom.us/join?confno=012345678&amp;#x26;pwd=0123456&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My sole nit-pick was that deep links aren&apos;t hyperlinked by default in some applications, like WhatsApp, Telegram, Microsoft Word, etc. Or worse, the bit beginning from &lt;code class=&quot;language-text&quot;&gt;zoom.us&lt;/code&gt; is hyperlinked only, so the link appears to be broken to less tech-savvy users.&lt;/p&gt;
&lt;p&gt;My solution to this was to make a simple site that redirects you to the deep link and host it at a pretty URL, e.g. &lt;code class=&quot;language-text&quot;&gt;https://zoom-link.example.org&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Convenient Zoom Link&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;noscript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Javascript must be enabled&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;noscript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; userAgent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; navigator
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;userAgent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;(Android|iPhone|iPad|iPod|Opera Mini|phone|mobile|tablet)&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;i&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;zoomus://zoom.us/join?confno=012345678&amp;amp;pwd=0123456&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;zoommtg://zoom.us/join?confno=012345678&amp;amp;pwd=0123456&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This has the added benefit of opening the appropriate deep link on mobile.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;I guess this would make it more inconvenient to type, but I&apos;m not sure how many people manually type in their passwords rather than just copy and paste them or click the meeting link&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[HSBC transfer limits]]></title><description><![CDATA[counterintuitive design and error -10004

I'm documenting this for the benefit of future me, and for anyone else who facing an  whilst trying to change their transfer limit in their…]]></description><link>https://huey.xyz/posts/2022-07-22-hsbc</link><guid isPermaLink="false">3d77692f5c70af822cab83045673cf672a2a371b70725292168a56f08184754f</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Fri, 22 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;counterintuitive design and error -10004&lt;/h2&gt;&lt;p&gt;I&apos;m documenting this for the benefit of future me, and for anyone else who facing an &lt;code class=&quot;language-text&quot;&gt;error -10004&lt;/code&gt; whilst trying to change their transfer limit in their HSBC Singapore account.&lt;/p&gt;
&lt;p&gt;The design of HSBC Singapore&apos;s transfer limit changing system is not very intuitive. The steps are similar to the systems used by the other banks in Singapore: you visit the bank&apos;s website, visit the transfer limit page, key in a new transfer limit, then key your new transfer limit into an app or physical token to get a 2FA PIN, and then key in said 2FA PIN.&lt;/p&gt;
&lt;p&gt;I did all that, but received an &lt;code class=&quot;language-text&quot;&gt;error -10004&lt;/code&gt;. This error indicates that the wrong transaction code was input or generated.&lt;/p&gt;
&lt;p&gt;I checked and re-checked the limit total I keyed in when generating a security code on the HSBC Singapore app, and also verified that I had copied the transaction code correctly. At first, I thought it might be a fluke, or that the code had somehow expired before I keyed it in, but I retried 3 times without success.&lt;/p&gt;
&lt;p&gt;After much head-scratching, I finally realised that HSBC&apos;s 2FA PIN generation system is different from the other banks&apos;. Instead of generating your 2FA PIN from the new transfer limit you have just keyed in ($10,000 in my case), the PIN should be generated from your new aggregate transfer limit that is labelled &quot;Limit total&quot; ($9,000,061,000.00 in my case).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971084.189229674374/hsbc_screenshot.avif&quot; alt=&quot;screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;Rather counterintuitive design.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A Practical Guide to RSS]]></title><description><![CDATA[how to get started in 2 minutes and what feeds to follow

So, you want to do one or more of the above: 'get off social media', avoid spending so much time doomscrolling and chasing dopamine, get a…]]></description><link>https://huey.xyz/posts/2022-01-06-practical-rss</link><guid isPermaLink="false">1f2364d35ef262c7efad2e52037358d25b35674e7a21ec9e1cc35d61ad01927d</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Thu, 06 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;how to get started in 2 minutes and what feeds to follow&lt;/h2&gt;&lt;p&gt;So, you want to do one or more of the above: &apos;get off social media&apos;, avoid spending so much time doomscrolling and chasing dopamine, get a broader media diet, read more widely, etc. And you want to do this now before you lose motivation? This is the post for you.&lt;/p&gt;
&lt;p&gt;This post is for people who&apos;ve already decided to use RSS. If you haven&apos;t decided yet, read &lt;a href=&quot;/posts/2021-07-18-rss&quot;&gt;my other RSS post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are only 2 steps in your RSS journey:&lt;/p&gt;
&lt;h1 id=&quot;pick-a-rss-reader&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#pick-a-rss-reader&quot; aria-label=&quot;pick a rss reader permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Pick a RSS reader&lt;/h1&gt;
&lt;p&gt;There are many. You want one that is easy-to-use, and cross-platform (so you can use the same one on your phone and computer).&lt;/p&gt;
&lt;p&gt;You probably want to use &lt;a href=&quot;https://feedly.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Feedly&lt;/a&gt;. It&apos;s easy to use, looks decent, and can be used on every major platform. Here are the links for &lt;a href=&quot;https://apps.apple.com/us/app/feedly-smart-news-reader/id396069556&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;iOS&lt;/a&gt; and &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.devhd.feedly&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Android&lt;/a&gt; so you can get it now.&lt;/p&gt;
&lt;p&gt;If you don&apos;t want to use Feedly for some reason, also consider: &lt;a href=&quot;https://apps.apple.com/us/app/flipboard-latest-stories/id358801284&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Flipboard&lt;/a&gt;, or &lt;a href=&quot;https://apps.apple.com/us/app/newsify-rss-reader/id510153374&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Newsify (iOS)&lt;/a&gt;, &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.levelup.palabre&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Palabre (Android)&lt;/a&gt;, or &lt;a href=&quot;https://play.google.com/store/apps/details?id=net.frju.flym&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Flynn (Android)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&quot;https://bazqux.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;BazQux&lt;/a&gt; myself, which you can try out for free, but it&apos;s not for everybody.&lt;/p&gt;
&lt;p&gt;Update (17 Jan 2024): If you want to get started very very quickly, you can also use a RSS to Telegram bot such as &lt;a href=&quot;https://t.me/RSStT_Bot&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;@RSStT_Bot&lt;/a&gt;, but this will probably get unwieldy if you subscribe to multiple feeds or have a substantial volume of items in your feeds.&lt;/p&gt;
&lt;h1 id=&quot;find-some-feeds&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#find-some-feeds&quot; aria-label=&quot;find some feeds permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Find some feeds&lt;/h1&gt;
&lt;p&gt;If you&apos;re using Feedly, as you probably should be, finding some feeds to add is as simple as typing some search terms into the search bar. You can search by topic: &apos;technology&apos;, &apos;Australia news&apos;, &apos;sourdough&apos;, &apos;pokemon&apos;, etc and Feedly will suggest some relevant feeds. You can also try adding feeds from sources you already know, such as your local newspaper, or some other website or blog you know.&lt;/p&gt;
&lt;p&gt;So you can get started quickly, I&apos;ve included some of my recommendations categorised by topic below.&lt;/p&gt;
&lt;p&gt;RSS feeds are URLs to a chunk of text in a special format that RSS readers parse. Depending on your browser and the feed in question, they might display in a human-readable way, but in others they might just display as some unreadable XML text, never finish loading (because they try and fail to load as webpages), or your browser might try to download them as a file.&lt;/p&gt;
&lt;p&gt;What you want to do is just copy the URLs below and paste each one into your RSS feeder. In Feedly, you paste it into the add new feed / search box. Feedly should detect the feed, and you can then add it.&lt;/p&gt;
&lt;p&gt;Consider adding some less well-known sources above. One of the benefits of RSS is it lets you keep up with many feeds no matter how niche they are or unfrequently they update, whereas these may be lost or deprioritised in your standard social media newsfeed.&lt;/p&gt;
&lt;p&gt;It&apos;s possible to share all your RSS subscriptions at one go (including categorisations) via an OPML file, and &lt;a href=&quot;https://www.gwern.net/docs/personal/rss-subscriptions.opml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;some people do make theirs public&lt;/a&gt;, but I have a lot and some are private and specific to me so I&apos;ve extracted the ones that will probably be most useful to you below.&lt;/p&gt;
&lt;p&gt;I&apos;ll add more feed categories soon.&lt;/p&gt;
&lt;p&gt;Update (16 August 2022): I learnt that &lt;a href=&quot;https://www.youneedfeeds.com/starter-packs&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;You Need Feeds&lt;/a&gt; also provides starter packs of feeds on a wide range of topics and interests. Do check them out.&lt;/p&gt;
&lt;h2 id=&quot;world-news&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#world-news&quot; aria-label=&quot;world news permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;World News&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Portal:Current_events&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Wikipedia: Current Events&lt;/a&gt;: &lt;a href=&quot;https://www.to-rss.xyz/wikipedia/current_events/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.to-rss.xyz/wikipedia/current_events/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.project-syndicate.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Project Syndicate&lt;/a&gt;: &lt;a href=&quot;https://www.project-syndicate.org/rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.project-syndicate.org/rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://restofworld.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Rest of World&lt;/a&gt;: &lt;a href=&quot;https://restofworld.org/feed/latest&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://restofworld.org/feed/latest&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don&apos;t follow these myself because they pump out too much content and I usually learn about events from other sources anyway, but you might want to consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bbc.com/news/world&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;BBC (World)&lt;/a&gt;: &lt;a href=&quot;https://feeds.bbci.co.uk/news/world/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://feeds.bbci.co.uk/news/world/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nytimes.com/section/world&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NYT (World)&lt;/a&gt;: &lt;a href=&quot;https://www.nytimes.com/svc/collections/v1/publish/https://www.nytimes.com/section/world/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.nytimes.com/svc/collections/v1/publish/https://www.nytimes.com/section/world/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.washingtonpost.com/world/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;WaPo (World)&lt;/a&gt;: &lt;a href=&quot;https://feeds.washingtonpost.com/rss/world&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://feeds.washingtonpost.com/rss/world&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.aljazeera.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Al Jazeera (World)&lt;/a&gt;: &lt;a href=&quot;https://www.aljazeera.com/xml/rss/all.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.aljazeera.com/xml/rss/all.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;asia-news&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#asia-news&quot; aria-label=&quot;asia news permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Asia News&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.scmp.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SCMP&lt;/a&gt;: &lt;a href=&quot;https://www.scmp.com/rss/3/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.scmp.com/rss/3/feed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://supchina.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SupChina&lt;/a&gt;: &lt;a href=&quot;https://supchina.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://supchina.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kyotoreview.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Kyoto Review&lt;/a&gt;: &lt;a href=&quot;https://kyotoreview.org/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://kyotoreview.org/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://interconnected.blog/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Interconnected&lt;/a&gt;: &lt;a href=&quot;https://interconnected.blog/rss/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://interconnected.blog/rss/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lillianli.substack.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Chinese Characteristics&lt;/a&gt;: &lt;a href=&quot;https://lillianli.substack.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://lillianli.substack.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://asiaundercovered.substack.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Asia Uncovered&lt;/a&gt;: &lt;a href=&quot;https://asiaundercovered.substack.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://asiaundercovered.substack.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chinatalk.substack.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;China Talk&lt;/a&gt;: &lt;a href=&quot;https://chinatalk.substack.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://chinatalk.substack.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bridgetwelsh.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Bridget Welsh&lt;/a&gt;: &lt;a href=&quot;https://bridgetwelsh.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://bridgetwelsh.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sinocism.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Sinocism&lt;/a&gt;: &lt;a href=&quot;https://sinocism.com/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://sinocism.com/feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;singapore-news&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#singapore-news&quot; aria-label=&quot;singapore news permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Singapore News&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mothership.sg&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Mothership&lt;/a&gt;: local tabloid
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mothership.sg/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://mothership.sg/feed/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.straitstimes.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Straits Times&lt;/a&gt;: most widely-read newspaper
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.straitstimes.com/singapore&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Home&lt;/a&gt;: &lt;a href=&quot;https://www.straitstimes.com/singapore/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.straitstimes.com/singapore/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.straitstimes.com/opinion&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Opinion&lt;/a&gt;: &lt;a href=&quot;https://www.straitstimes.com/news/opinion/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.straitstimes.com/news/opinion/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.straitstimes.com/tech&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Tech&lt;/a&gt;: &lt;a href=&quot;https://www.straitstimes.com/news/tech/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.straitstimes.com/news/tech/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.channelnewsasia.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;CNA&lt;/a&gt;: &lt;a href=&quot;https://www.channelnewsasia.com/rssfeeds/8396082&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.channelnewsasia.com/rssfeeds/8396082&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ricemedia.co/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Rice Media&lt;/a&gt;: &lt;a href=&quot;https://www.ricemedia.co/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.ricemedia.co/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://s-pores.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;s/pors journal&lt;/a&gt;: &lt;a href=&quot;https://s-pores.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://s-pores.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://spj.hkspublications.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Policy Journal&lt;/a&gt;: &lt;a href=&quot;https://spj.hkspublications.org/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://spj.hkspublications.org/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theparrotreview.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Parrot Review&lt;/a&gt;: &lt;a href=&quot;https://www.theparrotreview.com/op-ed?format=rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theparrotreview.com/op-ed?format=rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ipscommons.sg/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;IPS Commons&lt;/a&gt;: &lt;a href=&quot;https://ipscommons.sg/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://ipscommons.sg/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.academia.sg/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;AcademiaSG&lt;/a&gt;: &lt;a href=&quot;https://www.academia.sg/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.academia.sg/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://coconuts.co/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Coconuts&lt;/a&gt;: &lt;a href=&quot;https://coconuts.co/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://coconuts.co/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.singaporeinternet.watch/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Singapore Internet Watch&lt;/a&gt;: &lt;a href=&quot;https://newsletter.singaporeinternet.watch/?format=rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://newsletter.singaporeinternet.watch/?format=rss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;uk-news&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#uk-news&quot; aria-label=&quot;uk news permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;UK News&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://news.camden.gov.uk/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Camden Newsroom&lt;/a&gt;: &lt;a href=&quot;https://news.camden.gov.uk/tagfeed/en/tags/headlines,pr&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://news.camden.gov.uk/tagfeed/en/tags/headlines,pr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.private-eye.co.uk/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Private Eye&lt;/a&gt;: &lt;a href=&quot;https://www.private-eye.co.uk/rss/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.private-eye.co.uk/rss/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.politeia.co.uk/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Politeia&lt;/a&gt;: &lt;a href=&quot;https://www.politeia.co.uk/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.politeia.co.uk/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theguardian.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Guardian&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theguardian.com/politics/series/politicsweekly&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Politics&lt;/a&gt;: &lt;a href=&quot;https://www.theguardian.com/politics/series/politicsweekly/rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theguardian.com/politics/series/politicsweekly/rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theguardian.com/uk-news&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;UK News&lt;/a&gt;: &lt;a href=&quot;https://www.theguardian.com/uk-news/rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theguardian.com/uk-news/rss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.independent.co.uk/news/uk&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Independent (UK News)&lt;/a&gt;: &lt;a href=&quot;https://www.independent.co.uk/news/uk/rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.independent.co.uk/news/uk/rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.telegraph.co.uk/news/uk/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Telegraph (UK News)&lt;/a&gt;: &lt;a href=&quot;https://www.telegraph.co.uk/news/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.telegraph.co.uk/news/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thecritic.co.uk/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Critic&lt;/a&gt;: &lt;a href=&quot;https://thecritic.co.uk/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://thecritic.co.uk/feed/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;technology&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#technology&quot; aria-label=&quot;technology permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Technology&lt;/h2&gt;
&lt;p&gt;For general technology news, I like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Verge&lt;/strong&gt;: while you can subscribe to &lt;a href=&quot;https://www.theverge.com/rss/index.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;all posts&lt;/a&gt;, the Verge does post a lot, and I cannot read 150+ articles from a single source a day, so I just subscribe to a few specific sections and topics
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theverge.com/features&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Features&lt;/a&gt;: &lt;a href=&quot;https://www.theverge.com/rss/features/index.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theverge.com/rss/features/index.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theverge.com/editorial&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Editorial&lt;/a&gt;: &lt;a href=&quot;https://www.theverge.com/rss/editorial/index.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theverge.com/rss/editorial/index.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theverge.com/privacy&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Privacy&lt;/a&gt;: &lt;a href=&quot;https://www.theverge.com/rss/privacy/index.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theverge.com/rss/privacy/index.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ars Technica&lt;/strong&gt;: generally more technical, but still pretty accessible
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://arstechnica.com/features/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Features&lt;/a&gt;: &lt;a href=&quot;https://feeds.arstechnica.com/arstechnica/features&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://feeds.arstechnica.com/arstechnica/features&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nytimes.com/section/technology&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NYT (Tech)&lt;/a&gt;:  &lt;a href=&quot;https://www.nytimes.com/svc/collections/v1/publish/https://www.nytimes.com/section/technology/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.nytimes.com/svc/collections/v1/publish/https://www.nytimes.com/section/technology/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theregister.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Register&lt;/a&gt;: UK outlet, focuses on enterprise tech news, but with an light-hearted writing style; may not be accessible if you don&apos;t have a tech background though
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theregister.com/headlines.atom&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theregister.com/headlines.atom&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.technologyreview.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;MIT Technology Review&lt;/a&gt;: &lt;a href=&quot;https://www.technologyreview.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.technologyreview.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.wired.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;WIRED&lt;/a&gt;: &lt;a href=&quot;https://www.wired.com/feed/rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.wired.com/feed/rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://onezero.medium.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;OneZero&lt;/a&gt;: &lt;a href=&quot;https://onezero.medium.com/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://onezero.medium.com/feed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://debugger.medium.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Debugger&lt;/a&gt;: &lt;a href=&quot;https://debugger.medium.com/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://debugger.medium.com/feed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.axios.com/technology/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Axios (Tech)&lt;/a&gt;: &lt;a href=&quot;https://api.axios.com/feed/technology&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://api.axios.com/feed/technology&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Products (things you can use and buy):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://9to5mac.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;9to5Mac&lt;/a&gt;: &lt;a href=&quot;https://9to5mac.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://9to5mac.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.androidpolice.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Android Police&lt;/a&gt;: &lt;a href=&quot;https://www.androidpolice.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.androidpolice.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.hardwarezone.com.sg/tech-news/list&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;HardwareZone Singapore&lt;/a&gt;: &lt;a href=&quot;https://feeds.feedburner.com/hardwarezone/news&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://feeds.feedburner.com/hardwarezone/news&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://liliputing.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Liliputing&lt;/a&gt;: mobile technology, small portable computers
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://liliputing.com/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://liliputing.com/feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://twentyfirsttech.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Twenty First Tech&lt;/a&gt;: &lt;a href=&quot;https://twentyfirsttech.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://twentyfirsttech.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Verge
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theverge.com/kickstarter&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Kickstarters&lt;/a&gt;: &lt;a href=&quot;https://www.theverge.com/rss/kickstarter/index.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theverge.com/rss/kickstarter/index.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theverge.com/reviews&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Reviews&lt;/a&gt;: &lt;a href=&quot;https://www.theverge.com/rss/index.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theverge.com/rss/index.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bloomberg.com/authors/AS7Hj1mBMGM/mark-gurman&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Bloomberg (Mark Gurman)&lt;/a&gt;: &lt;a href=&quot;https://www.bloomberg.com/authors/AS7Hj1mBMGM/mark-gurman.rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.bloomberg.com/authors/AS7Hj1mBMGM/mark-gurman.rss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tech policy, trajectory, broader trends, etc (some of the above may also cover this):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://thehill.com/policy/technology&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Hill (Tech Policy)&lt;/a&gt;: &lt;a href=&quot;https://thehill.com/taxonomy/term/27/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://thehill.com/taxonomy/term/27/feed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.protocol.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Protocol&lt;/a&gt;: &lt;a href=&quot;https://www.protocol.com/feeds/newsletters/sourcecode.rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.protocol.com/feeds/newsletters/sourcecode.rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stratechery.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Stratechery by Ben Thompson&lt;/a&gt;: &lt;a href=&quot;https://stratechery.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://stratechery.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://themarkup.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Markup&lt;/a&gt;: &lt;a href=&quot;https://themarkup.org/feeds/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://themarkup.org/feeds/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Asian tech news:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kr-asia.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;KrASIA&lt;/a&gt;: &lt;a href=&quot;https://console.kr-asia.com/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://console.kr-asia.com/feed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ft.com/tech-asia&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Financial Times (#techAsia)&lt;/a&gt;: &lt;a href=&quot;https://www.ft.com/tech-asia?format=rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.ft.com/tech-asia?format=rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://e27.co/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;e27&lt;/a&gt; : &lt;a href=&quot;https://e27.co/index_wp.php/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://e27.co/index_wp.php/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vulcanpost.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Vulcan Post&lt;/a&gt;: &lt;a href=&quot;https://vulcanpost.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://vulcanpost.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.techinasia.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Tech in Asia&lt;/a&gt;: feeds.feedburner.com/techinasia&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;European tech news:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sifted.eu&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Sifted&lt;/a&gt;: &lt;a href=&quot;https://sifted.eu/feed/?post_type=article&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://sifted.eu/feed/?post_type=article&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://siliconcanals.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Silicon Canals&lt;/a&gt;: &lt;a href=&quot;https://siliconcanals.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://siliconcanals.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cool hardware projects, weird electronic hacks, etc:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.core77.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Core77&lt;/a&gt;: &lt;a href=&quot;https://www.core77.com/home/rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.core77.com/home/rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hackaday.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Hackaday&lt;/a&gt;: &lt;a href=&quot;https://hackaday.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://hackaday.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://1technophile.blogspot.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Technophile&lt;/a&gt;: &lt;a href=&quot;https://1technophile.blogspot.com/feeds/posts/default?alt=rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://1technophile.blogspot.com/feeds/posts/default?alt=rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bunniestudios.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;bunnie:studios&lt;/a&gt;: &lt;a href=&quot;https://www.bunniestudios.com/blog/?feed=rss2&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.bunniestudios.com/blog/?feed=rss2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weeklyrobotics.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Weekly Robotics&lt;/a&gt;: &lt;a href=&quot;https://weeklyrobotics.com/atom.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://weeklyrobotics.com/atom.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://buttondown.email/hardwarethings&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Hardware Things&lt;/a&gt;: covers hardware on the African continent
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://buttondown.email/hardwarethings/rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://buttondown.email/hardwarethings/rss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.benjamin-cabe.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Benjamin Cabé&lt;/a&gt;: &lt;a href=&quot;https://blog.benjamin-cabe.com/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://blog.benjamin-cabe.com/feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of my more niche feeds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.aboutchromebooks.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;About Chromebooks&lt;/a&gt;: yes, I like Chromebooks
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.aboutchromebooks.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.aboutchromebooks.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Emojis
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jenniferdaniel.substack.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Did Someone Say Emoji?&lt;/a&gt;: &lt;a href=&quot;https://jenniferdaniel.substack.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://jenniferdaniel.substack.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.emojipedia.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Emojipedia&lt;/a&gt;: &lt;a href=&quot;https://blog.emojipedia.org/rss/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://blog.emojipedia.org/rss/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://usesthis.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;uses this&lt;/a&gt;: things people use
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://usesthis.com/feed.atom&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://usesthis.com/feed.atom&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.northkoreatech.org&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;North Korean Tech&lt;/a&gt;: &lt;a href=&quot;https://www.northkoreatech.org/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.northkoreatech.org/feed/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;finance&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#finance&quot; aria-label=&quot;finance permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Finance&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.asiancenturystocks.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Asian Century Stocks&lt;/a&gt;: &lt;a href=&quot;https://www.asiancenturystocks.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.asiancenturystocks.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bam.kalzumeus.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Bits about Money by Patrick McKenzie&lt;/a&gt;: &lt;a href=&quot;https://bam.kalzumeus.com/archive/rss/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://bam.kalzumeus.com/archive/rss/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.collaborativefund.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Collaborative Fund&lt;/a&gt;: &lt;a href=&quot;https://feeds.feedburner.com/collabfund&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://feeds.feedburner.com/collabfund&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketsentiment.substack.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Market Sentiment&lt;/a&gt;: &lt;a href=&quot;https://marketsentiment.substack.com/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://marketsentiment.substack.com/feed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ft.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;FT&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ft.com/markets&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Markets&lt;/a&gt;: &lt;a href=&quot;https://www.ft.com/markets?format=rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.ft.com/markets?format=rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ft.com/trade-secrets&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Trade Secrets&lt;/a&gt;: &lt;a href=&quot;https://www.ft.com/trade-secrets?format=rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.ft.com/trade-secrets?format=rss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://monevator.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Monevator&lt;/a&gt;: &lt;a href=&quot;https://feeds2.feedburner.com/Monevatorcom&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://feeds2.feedburner.com/Monevatorcom&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.thegoodinvestors.sg/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Good Investors&lt;/a&gt;: &lt;a href=&quot;https://www.thegoodinvestors.sg/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.thegoodinvestors.sg/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://softwarestackinvesting.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Software Stack Investing&lt;/a&gt;: &lt;a href=&quot;https://softwarestackinvesting.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://softwarestackinvesting.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;people-i-follow&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#people-i-follow&quot; aria-label=&quot;people i follow permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;People I follow&lt;/h2&gt;
&lt;p&gt;A non-exhaustive selection:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nytimes.com/column/zeynep-tufekci&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NYT (Zeynep Tufekci)&lt;/a&gt;: &lt;a href=&quot;https://www.nytimes.com/svc/collections/v1/publish/https://www.nytimes.com/column/zeynep-tufekci/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.nytimes.com/svc/collections/v1/publish/https://www.nytimes.com/column/zeynep-tufekci/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://doctorow.medium.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Cory Doctorow&lt;/a&gt;: &lt;a href=&quot;https://medium.com/feed/@doctorow&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://medium.com/feed/@doctorow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yourlocalepidemiologist.substack.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Your Local Epidemiologist&lt;/a&gt;: &lt;a href=&quot;https://yourlocalepidemiologist.substack.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://yourlocalepidemiologist.substack.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ez.substack.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Ed Zitron&lt;/a&gt;: &lt;a href=&quot;https://ez.substack.com/feed&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://ez.substack.com/feed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.schneier.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Schneier on Security&lt;/a&gt;: &lt;a href=&quot;https://www.schneier.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.schneier.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;humour&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#humour&quot; aria-label=&quot;humour permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Humour&lt;/h2&gt;
&lt;p&gt;Jokes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bloomberg.com/opinion/authors/ARbTQlRLRjE/matthew-s-levine&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Bloomberg (Matt Levine)&lt;/a&gt;: &lt;a href=&quot;https://www.bloomberg.com/opinion/authors/ARbTQlRLRjE/matthew-s-levine.rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.bloomberg.com/opinion/authors/ARbTQlRLRjE/matthew-s-levine.rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mcsweeneys.net/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;McSweeney&apos;s&lt;/a&gt;: &lt;a href=&quot;https://feeds.feedburner.com/mcsweeneys&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://feeds.feedburner.com/mcsweeneys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theolognion.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The O(logn)ion&lt;/a&gt;: &lt;a href=&quot;https://www.theolognion.com/rss/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.theolognion.com/rss/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://olifro.st/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Oli Frost&lt;/a&gt;: &lt;a href=&quot;https://olifro.st/feed.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://olifro.st/feed.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Drawings and comics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://abstrusegoose.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Abstruse Goose&lt;/a&gt;: &lt;a href=&quot;https://abstrusegoose.com/feed.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://abstrusegoose.com/feed.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arcaderage.co/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Arcade Rage&lt;/a&gt;: &lt;a href=&quot;https://arcaderage.co/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://arcaderage.co/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;www.ucomics.com/calvinandhobbes/&quot;&gt;Calvin &amp;#x26; Hobbes&lt;/a&gt;: &lt;a href=&quot;https://wdr1.com/blog/calvin_and_hobbes.rdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://wdr1.com/blog/calvin_and_hobbes.rdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.commitstrip.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;CommitStrip&lt;/a&gt;: &lt;a href=&quot;https://www.commitstrip.com/en/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.commitstrip.com/en/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.monkeyuser.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Monkey User&lt;/a&gt;: &lt;a href=&quot;https://www.monkeyuser.com/feed.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.monkeyuser.com/feed.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.smbc-comics.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;SMBC&lt;/a&gt;: &lt;a href=&quot;https://smbc-rss-plus.mindflakes.com/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://smbc-rss-plus.mindflakes.com/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://workchronicles.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Work Chronicles&lt;/a&gt;: &lt;a href=&quot;https://workchronicles.com/feed/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://workchronicles.com/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xkcd.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;XKCD&lt;/a&gt;: &lt;a href=&quot;https://xkcd.com/rss.xml&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://xkcd.com/rss.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Videos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UC9v7v79mAlvKCrjrJvj-Fww&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;BAHFest&lt;/a&gt;: &lt;a href=&quot;https://www.youtube.com/feeds/videos.xml?channel_id=UC9v7v79mAlvKCrjrJvj-Fww&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.youtube.com/feeds/videos.xml?channel_id=UC9v7v79mAlvKCrjrJvj-Fww&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/user/LastWeekTonight&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Last Week Tonight&lt;/a&gt;: &lt;a href=&quot;https://www.youtube.com/feeds/videos.xml?channel_id=UC3XTzVzaHQEd30rQbuvCtTQ&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.youtube.com/feeds/videos.xml?channel_id=UC3XTzVzaHQEd30rQbuvCtTQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/StevieMartin&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Stevie Martin&lt;/a&gt;: &lt;a href=&quot;https://www.youtube.com/feeds/videos.xml?channel_id=UC3ssq0RVd3Vrmy0-WiOHq4g&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.youtube.com/feeds/videos.xml?channel_id=UC3ssq0RVd3Vrmy0-WiOHq4g&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/TheMockingbirdNewsChannelSG&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Mockingbird&lt;/a&gt;: &lt;a href=&quot;https://www.youtube.com/feeds/videos.xml?channel_id=UCQ-riBpJvn8ZA-UEtVm9mrQ&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.youtube.com/feeds/videos.xml?channel_id=UCQ-riBpJvn8ZA-UEtVm9mrQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;social-media&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#social-media&quot; aria-label=&quot;social media permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Social Media&lt;/h2&gt;
&lt;p&gt;Yes, part of the reason you use RSS might be to get off social media. But you might want or need to subscribe to certain content that can only be found on social media. Here&apos;s how to do it via RSS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;YouTube: you can subscribe to a channel using Feedly (and many other RSS readers) by simply pasting in the URL of the channel into the add feed box, e.g.  &lt;a href=&quot;https://www.youtube.com/snl&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.youtube.com/snl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Facebook/Twitter/Instagram: there are services that create RSS feeds out of public Facebook pages. There&apos;s &lt;a href=&quot;https://github.com/RSS-Bridge/rss-bridge&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;rss-bridge&lt;/a&gt;, &lt;a href=&quot;https://github.com/DIYgod/RSSHub&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;RSSHub&lt;/a&gt;, &lt;a href=&quot;https://github.com/hueyy/hungryhippo&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;HungryHippo&lt;/a&gt;, etc. These services don&apos;t not always work, in part because the social media sites usually impose restrictions on access to their content by external services, but they&apos;re a decent alternative.&lt;/li&gt;
&lt;li&gt;Reddit: just plonk a &lt;code class=&quot;language-text&quot;&gt;.rss&lt;/code&gt; behind your reddit url, e.g. for &lt;a href=&quot;https://reddit.com/r/DaystromInstitute/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;reddit.com/r/DaystromInstitute/&lt;/a&gt;, it&apos;s &lt;a href=&quot;https://reddit.com/r/DaystromInstitute/.rss&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;reddit.com/r/DaystromInstitute/.rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Goodreads: for a given user such as &lt;a href=&quot;https://goodreads.com/user/show/11004626-gwern&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;goodreads.com/user/show/11004626-gwern&lt;/a&gt;, the RSS feed is &lt;a href=&quot;https://goodreads.com/user/updates_rss/11004626?v=as&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;goodreads.com/user/updates_rss/11004626?v=as&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If getting certain content that&apos;s only available on social media is important to you, consider using a premium RSS service with social media feed extraction capabilities. &lt;a href=&quot;https://feedly.com/i/pro/welcome&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Feedly Pro+&lt;/a&gt; handles Twitter feeds well, and has an experimental RSS Builder that can be used to create RSS feeds from any social media site. &lt;a href=&quot;https://bazqux.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;BazQux&lt;/a&gt; handles Facebook, Twitter, and Instragram feeds well too (and comments on many sites, including Reddit).&lt;/p&gt;
&lt;h2 id=&quot;discovering-rss-feeds&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#discovering-rss-feeds&quot; aria-label=&quot;discovering rss feeds permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Discovering RSS feeds&lt;/h2&gt;
&lt;p&gt;A lot of standard-issue software has RSS built in. Here are some tips for unearthing RSS feeds which are not clearly publicised:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WordPress: (almost?) all WordPress installations have RSS enabled and a feed for the entire website located at &lt;code class=&quot;language-text&quot;&gt;/feed&lt;/code&gt;. There may be sub-feeds for authors and/or tags as well.&lt;/li&gt;
&lt;li&gt;Browser Extensions: the following browser extensions can show you when a RSS feed is available on a website you are visiting
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://addons.mozilla.org/en-GB/firefox/addon/feed-preview/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Feed Preview (Firefox)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/awesome-rss/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Awesome RSS (Firefox)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/rss-subscription-extensio/nlbjncdgjeocebhnmkbbbdekmmmcbfjd?hl=en&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;RSS Subscription Extension (by Google) (Chrome)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/get-rss-feed-url/kfghpdldaipanmkhfpdcjglncmilendn/related?hl=en&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Get RSS Feed URL (Chrome)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kill-the-newsletter.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Kill The Newsletter&lt;/a&gt;: very useful for converting email newsletters (or other regular email updates) into a RSS feed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, Feedly and BazQux are smart. Often, simply pasting the website&apos;s URL into Feedly/BazQux will do the job.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Using utteranc.es with a private repository]]></title><description><![CDATA[add comments on a static site powered by GitHub issues in a private repository

utteranc.es is a set of scripts that adds comment functionality to static site. It makes use of GitHub to handle authentication, editing…]]></description><link>https://huey.xyz/posts/2021-11-07-utterances</link><guid isPermaLink="false">069f6cc8ece9cff233f51a978647469ccb7d357ef50848f69cefdc3a63d55ccf</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sun, 07 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;add comments on a static site powered by GitHub issues in a private repository&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://utteranc.es/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;utteranc.es&lt;/a&gt; is a set of scripts that adds comment functionality to static site. It makes use of &lt;a href=&quot;https://github.com/utterance&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;GitHub&lt;/a&gt; to handle authentication, editing, storage, etc. A GitHub issue is created for each post, and each comment on a post is stored as a comment on the corresponding issue. It even has support for reactions.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971084.189229674368/utterances-screenshot.avif&quot; alt=&quot;utterances-screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;For many sites, setting up utterances will be a straightforward matter of adding an appropriate &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script&gt;&lt;/code&gt; tag to embed the comments widget and installing the utterances GitHub app on the relevant repository. This does mean your readers will need a GitHub account to post comments, but technical readers will probably already have one and it&apos;s pretty straightforward to create one anyway.&lt;/p&gt;
&lt;p&gt;But what if you want to use utterances with a private repository? For example, the site might be an internal documentation site or an internal blog. utterances sadly &lt;a href=&quot;https://github.com/utterance/utterances/issues/203&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;does not support private repositories&lt;/a&gt; at the moment. There two main changes that need to be made:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The widget needs to be modified to require sign-in before displaying comments. At the moment, it will attempt to fetch comments from the repository&apos;s issues list and promptly fail if the repository is private and the user isn&apos;t signed in.&lt;/li&gt;
&lt;li&gt;In &lt;code class=&quot;language-text&quot;&gt;src/utterances.ts&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;loadUser&lt;/code&gt; should be called before &lt;code class=&quot;language-text&quot;&gt;loadIssue&lt;/code&gt; so the user is logged in before the search request is sent.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A little bit of work also needs to be done to support posting comments to a private repo. Currently, comments are posted via the utterances GitHub bot, so you will need to add the bot as a collaborator to the repository, and someone on the utterances team will need to accept that invitation. This does mean that the utterances-bot will have full access to your private repository, which may less than ideal.&lt;/p&gt;
&lt;h2 id=&quot;self-hosting&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#self-hosting&quot; aria-label=&quot;self hosting permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Self Hosting&lt;/h2&gt;
&lt;p&gt;My solution to the above was to self-host utterances. There are two key components of utterances:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the widget, i.e. the main utterances repository that contains the &lt;code class=&quot;language-text&quot;&gt;client.js&lt;/code&gt; script to be embedded on your site&lt;/li&gt;
&lt;li&gt;the oauth handler, which handles the oauth callback from GitHub and passes the token to the widget&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Anyone interested in self-hosting utterances can find my forked repositories here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hueyy/utterances&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;hueyy/utterances&lt;/a&gt; - I&apos;ve hosted this on GitHub pages&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hueyy/utterances-oauth&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;hueyy/utterances-oauth&lt;/a&gt; - I&apos;m running this as a Cloudflare Workers on Cloudflare&apos;s generous free tier&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There were some gaps in the existing documentation which I have yet to properly fill in but have briefly outlined in the relevant READMEs, for my future self and anyone else who might embark on this.&lt;/p&gt;
&lt;p&gt;You can find the final result below.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why you should consider using RSS]]></title><description><![CDATA[See only the content you want on your feed; avoid being locked in by closed platforms

Update (16 August 2022): Some time after writing this post, I discovered other great explanations of how RSS works and why you should use it…]]></description><link>https://huey.xyz/posts/2021-07-18-rss</link><guid isPermaLink="false">88f947288d87086dd5ee1836c447f20693615bbee34dd3fd1614edbfaced843b</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Sun, 18 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;See only the content you want on your feed; avoid being locked in by closed platforms&lt;/h2&gt;&lt;p&gt;Update (16 August 2022): Some time after writing this post, I discovered other great explanations of how RSS works and why you should use it that are probably better than mine. Do check them out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://aboutfeeds.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;About Feeds&lt;/a&gt; by &lt;a href=&quot;https://interconnected.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Matt Webb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youneedfeeds.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;You Need Feeds&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-is-rss&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#what-is-rss&quot; aria-label=&quot;what is rss permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;What is RSS?&lt;/h2&gt;
&lt;p&gt;Really Simple Syndication (RSS)&lt;sup id=&quot;fnref-6&quot;&gt;&lt;a href=&quot;#fn-6&quot; class=&quot;footnote-ref&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; is a very well-established protocol&lt;sup id=&quot;fnref-2&quot;&gt;&lt;a href=&quot;#fn-2&quot; class=&quot;footnote-ref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; that allows you to keep track of content from many different sources in a single news aggregator. You&apos;ve probably seen the &lt;img src=&quot;https://upload.wikimedia.org/wikipedia/en/thumb/4/43/Feed-icon.svg/16px-Feed-icon.svg.png&quot; style=&quot;display: inline-block; margin-bottom: 5px;&quot; /&gt; icon before even though you might only be vaguely aware of RSS itself or perhaps have never heard of it at all. Nonetheless, it is surprisingly prevalent across the web. Many apps and services that serve up news rely on RSS, including Google News, Apple News, Siri, and Google Assistant. Most news sites and blogs support RSS,&lt;sup id=&quot;fnref-3&quot;&gt;&lt;a href=&quot;#fn-3&quot; class=&quot;footnote-ref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; although they rarely advertise this prominently. It&apos;s not just for news but for any constantly-updating content you might want to subscribe to.&lt;/p&gt;
&lt;p&gt;It&apos;s an open standard, like WiFi (which Apple/Samsung/Sony/Nintendo/HP devices can all use), JPEG (which you can open with Adobe Photoshop, iPhoto, IrfanView, etc.), and HTTP (which allows you to browse the web using any web browser). Here&apos;s an excerpt from the BBC Top News RSS Feed (it&apos;s just a text file generated in the XML markup language) that includes some details about the feed itself (in &lt;code class=&quot;language-text&quot;&gt;&amp;lt;channel&gt;&lt;/code&gt;) and 2 news items (in &lt;code class=&quot;language-text&quot;&gt;&amp;lt;item&gt;&lt;/code&gt;):&lt;sup id=&quot;fnref-7&quot;&gt;&lt;a href=&quot;#fn-7&quot; class=&quot;footnote-ref&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-xml line-numbers&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml-stylesheet title=&quot;XSL_formatting&quot; type=&quot;text/xsl&quot; href=&quot;/shared/bsp/xsl/rss/nolsol.xsl&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;rss&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;dc&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://purl.org/dc/elements/1.1/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://purl.org/rss/1.0/modules/content/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;atom&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2005/Atom&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;2.0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;media&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://search.yahoo.com/mrss/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[BBC News - Home]]&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[BBC News - Home]]&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;https://www.bbc.co.uk/news/&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;https://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;BBC News - Home&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;https://www.bbc.co.uk/news/&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;generator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;RSS for Node&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;generator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;lastBuildDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Mon, 02 Aug 2021 01:48:18 GMT&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;lastBuildDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;copyright&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[Copyright: (C) British Broadcasting Corporation, see http://news.bbc.co.uk/2/hi/help/rss/4498287.stm for terms and conditions of reuse.]]&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;copyright&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;language&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[en-gb]]&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;language&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;15&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ttl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[Coronavirus: New rules for fully jabbed US and EU arrivals begin]]&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[People vaccinated in the EU or US will not need to isolate when coming to the UK from an amber country.]]&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;https://www.bbc.co.uk/news/uk-58050538&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;guid&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;isPermaLink&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;https://www.bbc.co.uk/news/uk-58050538&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;guid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pubDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Sun, 01 Aug 2021 23:48:56 GMT&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pubDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[Tanker attack: UK and US blame Iran for deadly ship attack]]&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[The UK accuses Tehran of violating international law, while Iran calls the accusations &quot;baseless&quot;.]]&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;https://www.bbc.co.uk/news/world-middle-east-58048007&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;guid&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;isPermaLink&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;https://www.bbc.co.uk/news/world-middle-east-58048007&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;guid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pubDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Sun, 01 Aug 2021 21:28:11 GMT&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pubDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;rss&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here&apos;s a screenshot from Google News, one of the many apps that draw upon that RSS feed and reorganises and repackages it:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971083.189229674353/google-news.avif&quot; alt=&quot;google-news&quot;&gt;&lt;/p&gt;
&lt;p&gt;It was probably most popular in the early 2000s, and gradually waned in popularity as more people began consuming content on proprietary platforms like Tumblr, Facebook, and Twitter. These platforms often initially offered RSS support to make switching over easier, and later disabled it to lock users in. The &lt;a href=&quot;https://en.wikipedia.org/wiki/Google_Reader#Discontinuation&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;discontinuation of Google Reader&lt;/a&gt;, a very popular and easy-to-use RSS reader, in 2013 also made it more difficult for new users to get started with RSS.  More recently, however, there has been a bit of a RSS renaissance. Podcasts, which are generally published over RSS feeds that podcast players then consume, have grown in popularity. People have also become more concerned about filter bubbles produced by heavy use of recommender systems on social media newsfeeds and censorship of certain content on those same platforms. &lt;a href=&quot;https://techcrunch.com/2021/05/19/undead-again-google-brings-back-rss/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Google Chrome is also experimenting with a &quot;Follow&quot; button&lt;/a&gt; that would allow users to subscribe directly to news sites via RSS.&lt;/p&gt;
&lt;p&gt;If you&apos;re already convinced, you can &lt;a href=&quot;#getting-started&quot;&gt;skip to the Getting Started section&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;why-you-should-use-rss&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#why-you-should-use-rss&quot; aria-label=&quot;why you should use rss permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Why you should use RSS&lt;/h2&gt;
&lt;p&gt;It&apos;s difficult to keep up with all the content you enjoy today. To deal with the sheer abundance of content, many people have opted to let their social media platform or default news app (Google News, Apple News, etc.) do the filtering for them. While these apps and platforms may derive their content from the same RSS source, using these apps and platforms leaves you beholden to their curation process and allows them to collect information about what you follow, click, and read. The goals of the companies that offer these services will generally be to sell information about your interests and preferences to advertisers, which may not align with your own goals.&lt;/p&gt;
&lt;p&gt;RSS provides you with control over the content you consume. It aggregates the content you&apos;re interested in in a single place. It&apos;s a simple way to get a streamlined feed of content that caters to your interests only.&lt;/p&gt;
&lt;h3 id=&quot;you-decide-what-you-see&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#you-decide-what-you-see&quot; aria-label=&quot;you decide what you see permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;You decide what you see&lt;/h3&gt;
&lt;p&gt;Recommender systems purport to curate and sort content for you and try to consistently show you only the interesting stuff. The problem is that existing curation and sorting mechanisms (&apos;algorithms&apos;) aren&apos;t necessarily very good, and even the good ones may not be working in your best interests.&lt;/p&gt;
&lt;p&gt;The curation process tends to take into account the following factors (amongst others):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Have your friends/followers/similar people on the platform also engaged with this content?&lt;/li&gt;
&lt;li&gt;Have you engaged with similar content or content from the same creator?&lt;/li&gt;
&lt;li&gt;Will this content likely make you spend more time on the platform (e.g. is it addictive)?&lt;/li&gt;
&lt;li&gt;Has anyone paid to have this content shown to you?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These factors may not accurately indicate whether you&apos;ll like certain content.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You may be friends with people who do not share your tastes in content.&lt;/li&gt;
&lt;li&gt;You may have accidentally liked a post or a page you&apos;re not actually fond of, and now have to resign yourself with constantly being recommended uninteresting related content.&lt;/li&gt;
&lt;li&gt;A key metric for recommender systems, especially on social media platforms, tends to be engagement -- in short, how many things you do and how long you spend on the platform. This may not align with what &lt;strong&gt;you&lt;/strong&gt; want to get out of the platform -- you might want to quickly read the latest news and get on with your day, but instead end up watching a series of amusing but ultimately distracting videos.&lt;/li&gt;
&lt;li&gt;Social media platforms are advertising platforms, so promoted and sponsored content will show up on your newsfeed. Less obviously paid-for content can also make its way into your feed because the metrics recommender systems use can, and often are, gamed via paid-for likes, followers, and comments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sean Parker, founding president of Facebook &lt;a href=&quot;https://www.theguardian.com/technology/2017/dec/11/facebook-former-executive-ripping-society-apart&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;put it this way&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The thought process that went into building these applications, Facebook being the first of them, ... was all about: &apos;How do we consume as much of your time and conscious attention as possible?&apos;&lt;/p&gt;
&lt;p&gt;And that means that we need to sort of give you a little dopamine hit every once in awhile, because someone liked or commented on a photo or a post or whatever. And that&apos;s going to get you to contribute more content, and that&apos;s going to get you ... more likes and comments.&lt;/p&gt;
&lt;p&gt;It&apos;s a social-validation feedback loop ... exactly the kind of thing that a hacker like myself would come up with, because you&apos;re exploiting a vulnerability in human psychology.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This may be why you&apos;ve seen irrelevant, low-value, and possibly embarrassing content on your social media feeds that you&apos;d really rather not be shown. You might want to &apos;correct&apos; the recommendations manually, but sadly social media platforms give you very limited control over the recommendations you receive in your newsfeeds. You might be able to specify you&apos;d rather not see certain posts, but you usually need to do this consistently to get the recommendations to reflect your preferences. This requires consistent effort because recommendation systems are imperfect and have other goals beyond providing you with a perfect newsfeed.&lt;/p&gt;
&lt;p&gt;Maybe you&apos;ve accepted inaccurate recommendations that are occasionally not in your interest as a necessary cost. But with RSS, you can control what you see without having to work against your platform of choice to do so.&lt;/p&gt;
&lt;h3 id=&quot;you-control-your-data-and-preferences&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#you-control-your-data-and-preferences&quot; aria-label=&quot;you control your data and preferences permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;You control your data and preferences&lt;/h3&gt;
&lt;p&gt;You might have addressed the above problem somewhat by diligently blocking certain accounts, &lt;a href=&quot;https://dl.acm.org/doi/10.1145/2858036.2858494&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;being careful only to like certain pages and posts&lt;/a&gt;, etc. and so have developed a carefully configured newsfeed that you can live with. That is, until Facebook/Instagram/YouTube/etc decides to change their system. Then, there won&apos;t be much you can do except protest and live with the new changes. This is because you don&apos;t actually control your data on social media platforms -- you may be able to view it and change it in small ways using the controls the platforms reluctantly give you, but you can&apos;t export it in its entirety and move permanently to a new platform. Nor can you request the platform permanently delete all traces of any content. Unless forced to comply with legislation such as the GDPR&apos;s &apos;right to be forgotten&apos;, the platforms &lt;a href=&quot;https://www.zdnet.com/article/facebook-does-not-erase-user-deleted-content/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;rarely actually delete the content&lt;/a&gt; and certainly don&apos;t retrain their machine-learning models to account for the removal of the data.&lt;sup id=&quot;fnref-8&quot;&gt;&lt;a href=&quot;#fn-8&quot; class=&quot;footnote-ref&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;These changes happens regularly, and users have very little recourse when the changes aren&apos;t to their liking. The Instagram newsfeed algorithm has been criticised for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ranking popular social media accounts and influencers above personal contacts&lt;/li&gt;
&lt;li&gt;Hiding posts from users that you don&apos;t engage with (but which you might nonetheless want to see&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Besides posting angrily on those same social media platforms, there is very little users can do about these changes. And since social media platforms have largely been successful in locking users in and usage is very sticky, they need not pay much attention to what users think.&lt;/p&gt;
&lt;p&gt;One of the few ways to actually effect change is to vote with your feet and leave the platform. But because of lock-in, this comes at a very high cost. If you want to migrate from Facebook to a new platform, NotFacebook™ (that promises not to profit from conspiracy theories or sell your data) for instance, you&apos;d largely have to start from zero. There&apos;s no way to bring over all your friends, all the pages you&apos;ve liked or accounts you&apos;ve followed, or the carefully configured newsfeed you previously had. You&apos;ll have to start strategically liking and blocking to rebuild your news feed from scratch again. The barriers to switching also make it difficult for alternative platforms to compete, so there will likely be few alternatives to choose from. The issues with data migration will likely also mean that your initial experience will be worse than it was at Facebook because NotFacebook™ won&apos;t have all the data that you accumulated on your old platform.&lt;/p&gt;
&lt;p&gt;RSS addresses this problem because it&apos;s an open protocol which anyone can use and build apps for. Unlike with proprietary platforms, you can easily export your data (i.e. the feeds you follow) and migrate to another RSS reader seamlessly.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; There&apos;s no lock-in. Many alternatives will exist and you can choose to leave at any time.&lt;/p&gt;
&lt;h2 id=&quot;why-you-shouldnt-use-rss&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#why-you-shouldnt-use-rss&quot; aria-label=&quot;why you shouldnt use rss permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Why you shouldn&apos;t use RSS&lt;/h2&gt;
&lt;p&gt;Admittedly, RSS is not for everyone. RSS may not be you if any of the following apply:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You ♥ Facebook/Instagram/Twitter/TikTok/etc. and know that you&apos;ll never in a million years move to another platform no matter how the platform changes + are very confident the platform will exist for as long as you want to use it&lt;/li&gt;
&lt;li&gt;It&apos;s very important to you that you read news and consume content in the same feed that you read to keep up to date with your friends&apos; personal developments. It&apos;s possible to use RSS to read your friends&apos; private feeds, but it&apos;s not straightforward to set this up. Most people use RSS for news and public content (e.g. YouTube channels, blogs, etc.) and use other means to read updates from friends.&lt;/li&gt;
&lt;li&gt;Time is of the essence to you and you must be able to read new content as soon as it is published. RSS is primarily a &apos;pull&apos; system, meaning your RSS reader will periodically check if there is new content (as opposed to content being &apos;pushed&apos; to it once published).&lt;sup id=&quot;fnref-5&quot;&gt;&lt;a href=&quot;#fn-5&quot; class=&quot;footnote-ref&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; It may do so every few hours or possibly a few times an hour, but whatever it is, there will be a bit of a delay. If you need to see new content within minutes of it being published, then RSS may not be for you.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is a common myth that RSS is esoteric, difficult to use, or highly technical. This is not the case today. Few people interact directly with the raw RSS files. Using one of the many polished RSS clients such as Feedly (covered below) is just as easy and convenient as using any popular social media app.&lt;/p&gt;
&lt;h2 id=&quot;getting-started&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#getting-started&quot; aria-label=&quot;getting started permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;The easiest way to get started with RSS in 2021 is by using Feedly. It&apos;s a cross-platform RSS reader that&apos;s very easy to use, looks pretty, and has a generous free tier. You can get started either on a laptop or on your iOS/Android device. This will take you less than 5 minutes.&lt;/p&gt;
&lt;p&gt;Visit &lt;a href=&quot;https://feedly.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;feedly.com&lt;/a&gt; or download the &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.devhd.feedly&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Android&lt;/a&gt; or &lt;a href=&quot;https://apps.apple.com/us/app/feedly-smart-news-reader/id396069556&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;iOS&lt;/a&gt; Feedly app. Sign up and start adding feeds.&lt;/p&gt;
&lt;p&gt;You can pick from a list of available sources from various categories, e.g. for the technology category:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971084.189229674363/tech.avif&quot; alt=&quot;tech category&quot;&gt;&lt;/p&gt;
&lt;p&gt;Or you can search for and add a source of your choosing:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971083.189229674347/cna.avif&quot; alt=&quot;cna&quot;&gt;&lt;/p&gt;
&lt;p&gt;You can often get more fine-grained control over the content you receive. For instance, if you simply followed The Guardian&apos;s Twitter account, you&apos;d see a selection of all their articles on your Twitter feed. By contrast, on Feedly, you can choose to follow a category feed and see only their book reviews, or only their UK news articles.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971083.189229674356/guardian.avif&quot; alt=&quot;guardian&quot;&gt;&lt;/p&gt;
&lt;p&gt;The feeds you follow are listed on the left sidebar, and you can group them in folders if you like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971083.189229674350/folders.avif&quot; alt=&quot;folders&quot;&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s it, really. Not too difficult. Whenever you visit a website that you want to subscribe to, just pop the URL into Feedly, and it&apos;ll just work almost all of the time (try it with this site?).&lt;/p&gt;
&lt;h2 id=&quot;faq&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#faq&quot; aria-label=&quot;faq permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;FAQ&lt;/h2&gt;
&lt;p&gt;Some questions you might have after reading all this and using Feedly for a bit.&lt;/p&gt;
&lt;h3 id=&quot;what-are-the-limits-on-feedlys-free-tier&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#what-are-the-limits-on-feedlys-free-tier&quot; aria-label=&quot;what are the limits on feedlys free tier permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;What are the limits on Feedly&apos;s free tier?&lt;/h3&gt;
&lt;p&gt;The main limitation is that you can only follow 100 feeds. This will probably be enough for many people. You might hit the limits if you realise RSS is very useful for horizon-scanning or if you follow many individual blogs and social media accounts using RSS like I do. Feedly&apos;s pricing plans are pretty reasonable. The Pro plan is USD 6 / month and allows you to follow up to a thousand sources.&lt;/p&gt;
&lt;h3 id=&quot;are-there-other-rss-readers-besides-feedly&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#are-there-other-rss-readers-besides-feedly&quot; aria-label=&quot;are there other rss readers besides feedly permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Are there other RSS readers besides Feedly?&lt;/h3&gt;
&lt;p&gt;Yes. Other popular RSS readers include &lt;a href=&quot;https://www.inoreader.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;InoReader&lt;/a&gt;, &lt;a href=&quot;https://newsblur.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NewsBlur&lt;/a&gt;, &lt;a href=&quot;https://theoldreader.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;The Old Reader&lt;/a&gt;, and &lt;a href=&quot;https://bazqux.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;BazQux&lt;/a&gt;, which aims to replicate the Google Reader experience.&lt;/p&gt;
&lt;p&gt;I&apos;ve used Feedly as well as &lt;a href=&quot;https://tt-rss.org/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;TinyTinyRSS&lt;/a&gt;, a &lt;a href=&quot;https://github.com/hueyy/tinytinyrss-docker&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;self-hosted&lt;/a&gt; RSS reader (the setup process is a bit more involved). But Feedly was a bit limited and TinyTinyRSS&apos;s creator made some changes that were incompatible with my usual hosting setup, so now I use &lt;a href=&quot;https://bazqux.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;BazQux&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;how-do-i-migrate-to-another-rss-reader&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#how-do-i-migrate-to-another-rss-reader&quot; aria-label=&quot;how do i migrate to another rss reader permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;How do I migrate to another RSS reader?&lt;/h3&gt;
&lt;p&gt;On the &quot;Organise Sources&quot; page on Feedly (you can find this on the web version by clicking your profile image at the bottom right corner), click the right arrow at the top-right corner of the page. This will export all your RSS feeds as an OPML file which you can then import into any RSS reader.&lt;/p&gt;
&lt;h3 id=&quot;how-do-i-sort-feed-items-by-popularity&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#how-do-i-sort-feed-items-by-popularity&quot; aria-label=&quot;how do i sort feed items by popularity permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;How do I sort feed items by popularity?&lt;/h3&gt;
&lt;p&gt;Feedly has various sorting options available. The default option places a few of the most popular items (i.e. the ones that Feedly users click on the most) at the top, and arranges the remaining items in descending chronological order. But if you click the three dots icon at the top right corner, you can change this to your liking:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971084.189229674360/sort.avif&quot; alt=&quot;sort&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;how-do-i-see-comments-on-my-feed-items&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#how-do-i-see-comments-on-my-feed-items&quot; aria-label=&quot;how do i see comments on my feed items permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;How do I see comments on my feed items?&lt;/h3&gt;
&lt;p&gt;It can be eye-opening and occasionally amusing to read the comments on items in your social media news feeds. Neither Feedly nor the RSS protocol itself has comments built-in, but it&apos;s still pretty straightforward to view comments on specific feed items if you&apos;d like. There are a number of open-source browser extensions that essentially search social media platforms by URL to find comments for certain webpages.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For Reddit, there&apos;s &lt;a href=&quot;https://addons.mozilla.org/en-GB/firefox/addon/reddit-submission-finder/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Reddit Submission Finder&lt;/a&gt; for Firefox and &lt;a href=&quot;https://chrome.google.com/webstore/detail/find-on-reddit/jbcdpeekakanklckgooknpbonojhjncm&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;find-on-reddit&lt;/a&gt; for Chrome&lt;sup id=&quot;fnref-4&quot;&gt;&lt;a href=&quot;#fn-4&quot; class=&quot;footnote-ref&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;For HN, there&apos;s What HN says for &lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/what-hacker-news-says/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Firefox&lt;/a&gt; and for &lt;a href=&quot;https://chrome.google.com/webstore/detail/what-hacker-news-says/khgegkjchclhgpglloficdmdannlpmoi&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Chrome&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can of course also do this manually on Facebook or Instagram if you like.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-6&quot;&gt;There are technically two separate formats: RSS and Atom. But they are very similar and almost all RSS readers will support Atom feeds as well, so for most practical purposes they are equivalent.&lt;a href=&quot;#fnref-6&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;For the technically-inclined, it&apos;s just a XML file with special fields that contains all the latest new content. RSS readers periodically fetch this XML file.&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;Often because the publishing software they use generates RSS feeds by default automatically (because it&apos;s so easy to do and the performance and complexity cost is low). Some smaller news outlets may not even be aware these feeds exist.&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-7&quot;&gt;I&apos;ve lightly edited this to make it more readable and remove comments.&lt;a href=&quot;#fnref-7&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-8&quot;&gt;Zuck himself &lt;a href=&quot;https://www.commerce.senate.gov/public/_cache/files/9d8e069d-2670-4530-bcdc-d3a63a8831c4/7C8DE61421D13E86FC6855CC2EA7AEA7.senate-commerce-committee-combined-qfrs-06.11.2018.pdf&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;has confirmed this&lt;/a&gt;. When asked, &quot;how does Facebook determine whether and for how long to store user data or delete user data?&quot;, he answered &quot;In general, when a user deletes their account, we delete things &lt;strong&gt;they have posted&lt;/strong&gt;, such as their photos and status updates, and they won’t be able to recover that information later (Information that others have shared about them isn’t part of their account and won’t be deleted.)&quot; Facebook may delete the content you explicitly provide them, but it doesn&apos;t delete the data it has gathered about you and the inferences it has made.&lt;a href=&quot;#fnref-8&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-1&quot;&gt;It&apos;s a simple protocol, so you could even build your own (and many people have).&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-5&quot;&gt;But this is slowly changing. See &lt;a href=&quot;https://en.wikipedia.org/wiki/WebSub&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;WebSub&lt;/a&gt; (formerly PubSubHubbub), which is already supported by major blogging platforms and some news sites.&lt;a href=&quot;#fnref-5&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;Note that &lt;a href=&quot;https://chrome.google.com/webstore/detail/reddit-check/mllceaiaedaingchlgolnfiibippgkmj&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;reddit-check&lt;/a&gt; for Chrome appears to send every URL you open to Reddit, which has some privacy implications, and may not be what you want. You probably want to use &lt;a href=&quot;https://chrome.google.com/webstore/detail/find-on-reddit/jbcdpeekakanklckgooknpbonojhjncm&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;find-on-reddit&lt;/a&gt; instead, which only sends the URL open in the active tab when you activate the extension.&lt;a href=&quot;#fnref-4&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Automatic OSCOLA Citations with Juris-M]]></title><description><![CDATA[How to manage and cite cases, legislation, commentary, etc.

Citing legal sources in OSCOLA is more straightforward than in many other citation styles. Citations are short, fairly intuitive, and…]]></description><link>https://huey.xyz/posts/2020-10-30-legal-citations-juris-m</link><guid isPermaLink="false">7b17e8fae117e993dca6bafcfde8d0f240165d94e19030366fbd70b86157290f</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Fri, 30 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;How to manage and cite cases, legislation, commentary, etc.&lt;/h2&gt;&lt;p&gt;Citing legal sources in OSCOLA is more straightforward than in many other citation styles. Citations are short, fairly intuitive, and usually can be copied directly from the material being cited. Each citation is a standalone footnote, and no bibliography is required. Problems arise if you cross-reference between footnotes (e.g. using ibid, or &quot;n 6&quot;, etc.) and later do heavy editing, because you then have to keep the numbering straight. But if you&apos;re willing to be more verbose, and keep all your citations independent, those problems can be avoided.&lt;/p&gt;
&lt;p&gt;What is unavoidable, however, is the overhead involved when keeping track of a large number of citations. This is not a big deal for short-form legal writing. But where your citations run well into the double-digits, this can quickly become unwieldy. You might find yourself looking up the same citation for the same source again and again, or keeping many documents open just to copy-and-paste your citations. And if you&apos;re in the habit of copying-and-pasting from a previous footnote, one uncaught typo in a major source can quickly multiply across the whole document.&lt;/p&gt;
&lt;p&gt;Citation managers offer a solution to this problem. The general concept is you collect sources when doing research and reading, creating a personal (or project-specific) database of sources. Later, when you write, you can cite from an autocompleted list of sources populated from this database.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971082.189229674334/juris-m-initial.avif&quot; alt=&quot;juris-m screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;A number of citation managers exist: Zotero, Mendeley, OneNote, etc. But there is only one I am aware of that supports non-American legal citations. It is a fork of Zotero known as &lt;a href=&quot;https://juris-m.github.io&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Juris-M&lt;/a&gt;. &lt;a href=&quot;https://culturalexpertise.net/frank-bennet/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Frank Bennett&lt;/a&gt;, an Associate Professor of Law at Nagoya University, Japan, forked Zotero to add support for multilingual citations and jurisdictions. These added features are quite essential because legal writing often involves references to related caselaw and commentary on similar issues in other jurisdictions. There will also often be many layers of law overlapping with national law. In monist systems, international law has direct effect, and so treaties and international caselaw may need to be cited directly. Even in dualist systems, these legal sources will often be used to interpret the relevant implementing national law. In other words, a citation manager with support only for the American Bluebook will be a woefully inadequate one.&lt;/p&gt;
&lt;h2 id=&quot;juris-m-workflow&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#juris-m-workflow&quot; aria-label=&quot;juris m workflow permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Juris-M Workflow&lt;/h2&gt;
&lt;p&gt;Citing sources using Juris-M is similar to &apos;hand-crafted&apos; &lt;code class=&quot;language-text&quot;&gt;Ctrl-C&lt;/code&gt;-&lt;code class=&quot;language-text&quot;&gt;Ctrl-V&lt;/code&gt; citations. It involves the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Locate your sources&lt;/li&gt;
&lt;li&gt;Add your source to Juris-M (you can do this manually, by creating an entry and keying in a few fields, or by clicking a button in your web browser)&lt;/li&gt;
&lt;li&gt;Cite your source in your text editor (e.g. Microsoft Word) by clicking a button in the editor&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;installation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#installation&quot; aria-label=&quot;installation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Installation&lt;/h2&gt;
&lt;p&gt;There are 3 components to Juris-M. Only the client is compulsory.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Juris-M client — install this from the &lt;a href=&quot;https://juris-m.github.io/release/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Juris-M website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Web Browser &apos;Connector&apos; — this is a browser extension that helps you quickly add sources to Juris-M; install it from &lt;a href=&quot;https://juris-m.github.io/release/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the Juris-M website&lt;/a&gt; as well or from the client after you install it&lt;/li&gt;
&lt;li&gt;Text Editor &apos;Add-On&apos; — this is an add-on for your preferred text editor; the client will prompt you to install this&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;creating-entries&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#creating-entries&quot; aria-label=&quot;creating entries permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Creating Entries&lt;/h2&gt;
&lt;p&gt;Adding and citing entries using Juris-M/Zotero is fairly intuitive. What I found less obvious was how to cite specific types of sources manually. This is important where the source is not available online (and so the Connector can&apos;t help me do it automatically), or the Connector simply doesn&apos;t support the source yet. For this reason I&apos;ve set out instructions for citing various types of legal sources below, across the EU, UK, Singapore, and neutral citations for Hong Kong, Australia, and New Zealand.&lt;/p&gt;
&lt;p&gt;Much of this will be repetitive, so I won&apos;t bother providing screenshots or step-by-step instructions for each type of source. I&apos;ll simply set out the source &lt;code class=&quot;language-text&quot;&gt;type&lt;/code&gt;, the fields to be filled, and what information to put in those.&lt;/p&gt;
&lt;p&gt;The source type is also known as the item type — it&apos;s the type of item in Zotero / Juris-M. When you create a new item, it&apos;s the field right at the top. You specify the item type when creating an item by clicking the green plus icon, then the item type.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971083.189229674337/juris-m-item-type.avif&quot; alt=&quot;Juris-M item type&quot;&gt;&lt;/p&gt;
&lt;p&gt;The fields to which I will refer are those listed on the right panel in the Juris-M interface. These may change in future Zotero / Juris-M versions. Feel free to let me know if I neglect to update the guidance here.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971082.189229674331/juris-m-fields.avif&quot; alt=&quot;Juris-M fields&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;european-union-caselaw-cjeu&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#european-union-caselaw-cjeu&quot; aria-label=&quot;european union caselaw cjeu permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;European Union Caselaw (CJEU)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Type: Case&lt;/li&gt;
&lt;li&gt;Case Name: the title of the case, e.g. &quot;Rewe-Zentral AG v Bundesmonopolverwaltung für Branntwein&quot;&lt;/li&gt;
&lt;li&gt;Short Title: if applicable, the commonly-used title, e.g. &lt;em&gt;Cassis de Dijon&lt;/em&gt;, or &lt;em&gt;KitKat II&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Jurisdiction: &quot;EU.INT|Court of Justice&quot;&lt;/li&gt;
&lt;li&gt;Docker Number: the case citation, e.g. C-120/78&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This produces:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Case C-120/78 &lt;em&gt;Rewe-Zentral AG v Bundesmonopolverwaltung für Branntwein&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Besides the case reference, you can also include an ECLI identifier by putting it in the &quot;Reporter&quot; field.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Case C-120/78 &lt;em&gt;Rewe-Zentral AG v Bundesmonopolverwaltung für Branntwein&lt;/em&gt; ECLI:EU:C:1979:42&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Journal citations don&apos;t seem to be supported elegantly, but you can shoehorn one in if you like by putting it in the Reporter field (e.g. [1979] 3 CMLR 494)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Case C-120/78 &lt;em&gt;Rewe-Zentral AG v Bundesmonopolverwaltung für Branntwein&lt;/em&gt; [1979] 3 CMLR 49&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;england-and-wales-uk&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#england-and-wales-uk&quot; aria-label=&quot;england and wales uk permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;England and Wales (UK)&lt;/h3&gt;
&lt;h4 id=&quot;legislation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#legislation&quot; aria-label=&quot;legislation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Legislation&lt;/h4&gt;
&lt;p&gt;Acts of Parliament and secondary legislation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Type: Statute&lt;/li&gt;
&lt;li&gt;Name: Name of the Act, Regulation, etc. (e.g. Salmon Act 1986)&lt;/li&gt;
&lt;li&gt;Short Title: if applicable&lt;/li&gt;
&lt;li&gt;Jurisdiction: United Kingdom|GB&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You probably want to cite a specific section or paragraph in the Schedule of the legislation rather than the whole thing. In that case, you&apos;ll need to use &apos;pinpoints&apos;. In the Juris-M citation interface, specify the relevant section you want to cite. If you want to cite a rule, order, regulation, Schedule, etc. that isn&apos;t specified in the dropdown list, you can put your pinpoint citation in the suffix field (e.g. &quot;, Sch 1 para 1(1)(a)&quot;)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971083.189229674340/juris-m-section-cite.avif&quot; alt=&quot;juris-m-section-cite&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Salmon Act 1986, s 32&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;caselaw&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#caselaw&quot; aria-label=&quot;caselaw permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Caselaw&lt;/h4&gt;
&lt;p&gt;This works with both neutral citations and law report citations.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Type: Case&lt;/li&gt;
&lt;li&gt;Name: name of the case (e.g. &lt;em&gt;Interlego v Tyco&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Short Title: if applicable&lt;/li&gt;
&lt;li&gt;Year As Vol: the year for your neutral citation / law report citation (e.g. 1988)&lt;/li&gt;
&lt;li&gt;Reporter: neutral / law journal abbreviation (e.g. UKPC, AC, All ER, etc.)&lt;/li&gt;
&lt;li&gt;First Page: first page on which the case appears (e.g. 3)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Interlego v Tyco&lt;/em&gt; [1988] UKPC 3&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pinpoints can be placed by specifying a paragraph to be cited, or by using the suffix field.&lt;/p&gt;
&lt;h3 id=&quot;commonwealth-caselaw&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#commonwealth-caselaw&quot; aria-label=&quot;commonwealth caselaw permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Commonwealth Caselaw&lt;/h3&gt;
&lt;p&gt;Caselaw from other Commonwealth jurisdictions can be cited in the same manner as England &amp;#x26; Wales caselaw if the jurisdiction is set to &quot;United Kingdom|GB&quot;. Setting the jurisdiction to the correct jurisdiction (e.g. &lt;code class=&quot;language-text&quot;&gt;Hong Kong | HK&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Singapore|SG&lt;/code&gt;) causes formatting problems, probably because the formatting hasn&apos;t been correctly configured for these Commonwealth jurisdictions yet.&lt;/p&gt;
&lt;h4 id=&quot;hong-kong&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#hong-kong&quot; aria-label=&quot;hong kong permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Hong Kong&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Type: Case&lt;/li&gt;
&lt;li&gt;Name: &lt;em&gt;Oriental Press Group v Fevaworks Solutions&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Short Title: &lt;em&gt;Oriental Press&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Year As Vol: 2013&lt;/li&gt;
&lt;li&gt;Reporter: HKCFA&lt;/li&gt;
&lt;li&gt;First Page: 47&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Oriental Press v Fevaworks Solutions&lt;/em&gt; [2013] 1 HKCFA 47&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Setting jurisdiction to &lt;code class=&quot;language-text&quot;&gt;GB|Hong Kong&lt;/code&gt; also works.&lt;/p&gt;
&lt;h4 id=&quot;singapore&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#singapore&quot; aria-label=&quot;singapore permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Singapore&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Type: Case&lt;/li&gt;
&lt;li&gt;Name: &lt;em&gt;Quoine v B2C2&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Year As Vol: 2020&lt;/li&gt;
&lt;li&gt;Reporter: SGCA(I)&lt;/li&gt;
&lt;li&gt;First Page: 2&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Quoine v B2C2&lt;/em&gt; [2020] SGCA(I) 2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;australia&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#australia&quot; aria-label=&quot;australia permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Australia&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Type: Case&lt;/li&gt;
&lt;li&gt;Name: &lt;em&gt;Dow Jones v Gutnick&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Year As Vol: 2002&lt;/li&gt;
&lt;li&gt;Reporter: HCA&lt;/li&gt;
&lt;li&gt;First Page: 56&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Dow Jones v Gutnick&lt;/em&gt; [2002] HCA 56&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;new-zealand&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#new-zealand&quot; aria-label=&quot;new zealand permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;New Zealand&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Type: Case&lt;/li&gt;
&lt;li&gt;Name: &lt;em&gt;Loosley v Powell&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Year As Vol: 2018&lt;/li&gt;
&lt;li&gt;Reporter: NZCA&lt;/li&gt;
&lt;li&gt;First Page: 3&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Loosley v Powell&lt;/em&gt; [2018] NZCA 3&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Combining multiple drives on Linux]]></title><description><![CDATA[with the magic of mergerfs

is a very useful tool where you have multiple, small, drives of varying sizes and want to use them as a single composite drive. Installation…]]></description><link>https://huey.xyz/posts/2020-06-12-disc-pooling-with-mergerfs</link><guid isPermaLink="false">f93b778b8cfe13711071465de62557348a442b623cdbc0272d55e89071e5b06f</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Fri, 12 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;with the magic of mergerfs&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/trapexit/mergerfs&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mergerfs&lt;/code&gt;&lt;/a&gt; is a very useful tool where you have multiple, small, drives of varying sizes and want to use them as a single composite drive.&lt;/p&gt;
&lt;h2 id=&quot;installation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#installation&quot; aria-label=&quot;installation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Installation&lt;/h2&gt;
&lt;p&gt;Get the latest release &lt;a href=&quot;https://github.com/trapexit/mergerfs/releases/latest&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;off GitHub&lt;/a&gt; and install it.&lt;/p&gt;
&lt;h2 id=&quot;configuration&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#configuration&quot; aria-label=&quot;configuration permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Configuration&lt;/h2&gt;
&lt;p&gt;Mount your various drives. For instance, if you have Drives A, B, and C, your &lt;code class=&quot;language-text&quot;&gt;/etc/fstab&lt;/code&gt; might look like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/dev/sda  /media/Drive-A ntfs    defaults,uid=huey,file_mode=0777,dir_mode=0777  0       0
/dev/sdb  /media/Drive-B  ntfs    defaults,uid=huey,file_mode=0777,dir_mode=0777  0       0
/dev/sdc  /media/Drive-C  ntfs    defaults,uid=huey,file_mode=0777,dir_mode=0777  0       0&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add a &lt;code class=&quot;language-text&quot;&gt;mergerfs&lt;/code&gt; mount line to your &lt;code class=&quot;language-text&quot;&gt;/etc/fstab&lt;/code&gt; to create a composite drive:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/media/Drive-A:/media/Drive-B:/media/Drive-C  /media/CompositeDrive fuse.mergerfs allow_other,direct_io,use_ino,category.create=lfs,moveonenospc=true,minfreespace=20G,fsname=yourCompositeDrive&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;behind-the-abstraction&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#behind-the-abstraction&quot; aria-label=&quot;behind the abstraction permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Behind the Abstraction&lt;/h2&gt;
&lt;p&gt;It&apos;s all FUSE so any kind of drive works — you can mix network drives with physical SATA drives, and possibly even your &lt;a href=&quot;https://github.com/joe42/CloudFusion&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Dropbox&lt;/a&gt; or &lt;a href=&quot;https://github.com/astrada/google-drive-ocamlfuse&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Google Drive&lt;/a&gt; mounted as a FUSE filesystem.&lt;/p&gt;
&lt;p&gt;You can specify FUSE function policies in the &lt;code class=&quot;language-text&quot;&gt;mergerfs&lt;/code&gt; line in &lt;code class=&quot;language-text&quot;&gt;/etc/fstab&lt;/code&gt; to configure various behaviour. By default, files are created in accordance with the &lt;code class=&quot;language-text&quot;&gt;epmfs&lt;/code&gt; (existing path, most free space) policy, meaning they are created in the drive where the parent directory already exists (if applicable), otherwise on the drive with the most free space at the time. You can set &lt;code class=&quot;language-text&quot;&gt;func.category.action=eplfs&lt;/code&gt;, for instance, to create files on the drive with the least free space instead.&lt;/p&gt;
&lt;p&gt;Each file and directory exists on a single drive and is not spread out across the various drives. &lt;code class=&quot;language-text&quot;&gt;mergerfs&lt;/code&gt; functions by creating a union of the filesystems within the various drives, and is akin to creating symlinks between the various drive and the composite virtual drive. This means that if one drive fails, only the files and directories stored on that drive are lost. The overall file structure is unaffected.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Read PDFs on a tablet with ZotFile]]></title><description><![CDATA[and sync the annotations back to Zotero

Zotero is very useful for keeping track of academic reading material (articles, chapters, etc.) and automatically generating citations. I…]]></description><link>https://huey.xyz/posts/2020-06-09-reading-pdfs-on-a-tablet-with-zotfile</link><guid isPermaLink="false">ce03f6888c5bc2a29f0576ea5830a07994bd1d65922c3fbc09d156ced3ca82a6</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Tue, 09 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;and sync the annotations back to Zotero&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://zotero.org&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Zotero&lt;/a&gt; is very useful for keeping track of academic reading material (articles, chapters, etc.) and automatically generating citations.&lt;/p&gt;
&lt;p&gt;I prefer Zotero to EndNote or Wizfolio because it&apos;s open source. This means it will very likely remain available and free to use (at least in its current form) for a long time to come. Users of closed-source software are subject to the whims of the owners and developers of the software. If the company becomes insolvent or &lt;a href=&quot;https://killedbygoogle.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;simply decides to retire the product&lt;/a&gt;, the software will be unsupported, and may even stop functioning completely (e.g. if it depends on a server). Closed-source software also tends to have proprietary file formats, mandatory registration, and other questionable features that prevent you from easily switching away.&lt;/p&gt;
&lt;p&gt;I add articles to Zotero via the Zotero Connector browser extension, which is available for both Firefox and Chrome. By default it includes automatic snapshotting of any webpages you save. This is useful for ensuring you have a copy of the content, even if it is later taken down. However, this does slow down the saving process a fair bit, and if you&apos;re saving multiple pages, can potentially cause your browser to freeze for a bit. I disabled it and manually snapshot articles if and when I think there&apos;s a need to.&lt;/p&gt;
&lt;p&gt;To read your PDFs on a tablet, you first need to decide on a file-syncing solution. &lt;a href=&quot;https://dropbox.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Dropbox&lt;/a&gt;, &lt;a href=&quot;https://box.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Box&lt;/a&gt;, &lt;a href=&quot;https://onedrive.live.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;OneDrive&lt;/a&gt;, &lt;a href=&quot;https://drive.google.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Google Drive&lt;/a&gt;, &lt;a href=&quot;https://nextcloud.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;NextCloud&lt;/a&gt;, or even just a network drive will do the job. Just make sure your solution has a functional app on the platform you want to read on.&lt;/p&gt;
&lt;p&gt;I use Google Drive to sync PDFs between my laptop, phone, and an Android tablet.&lt;/p&gt;
&lt;h2 id=&quot;zotfile&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#zotfile&quot; aria-label=&quot;zotfile permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;ZotFile&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://zotfile.com/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;ZotFile&lt;/a&gt; is a Zotero add-on which is very useful for managing PDFs. Download and install it.&lt;/p&gt;
&lt;p&gt;ZotFile can automatically associate PDFs in a certain folder with items you add to Zotero. Under Tools &gt; ZotFile Preferences &gt; General Settings, set the source folder for attaching new files to your Downloads folder or whatever other folder the PDFs you download are stored in.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971082.189229674322/source_folder.avif&quot; alt=&quot;screenshot of source folder setting&quot;&gt;&lt;/p&gt;
&lt;p&gt;ZotFile allows you to store PDFs separately from the main Zotero database. Under the same tab, set the Location of Files to Custom Location, and browse to the synced folder you configured above.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971082.189229674319/location_of_files.avif&quot; alt=&quot;screenshot of location of files&quot;&gt;&lt;/p&gt;
&lt;p&gt;Under the renaming rules tab, configure ZotFile to rename your PDFs as you like. I use the &lt;code class=&quot;language-text&quot;&gt;{%a}, {%t} ({%y})&lt;/code&gt; format.&lt;/p&gt;
&lt;h3 id=&quot;reading&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#reading&quot; aria-label=&quot;reading permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Reading&lt;/h3&gt;
&lt;p&gt;Find some PDFs to read and add them to Zotero. To read them on a mobile device, right click on them and select Manage Attachments &gt; Send to Tablet. This places a copy of the PDF in the synced folder where your chosen syncing solution will automatically sync it to your mobile devices.&lt;/p&gt;
&lt;p&gt;On your phone/tablet, open the PDF using your chosen syncing solution. I use Google Drive, so I would open the Google Drive app, navigate to the Zotero folder, and open the PDF to read. On Android, I like &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.xodo.pdf.reader&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Xodo PDF Reader&lt;/a&gt; because it&apos;s fast, free, and does annotations well.&lt;/p&gt;
&lt;p&gt;The Android Google Drive app handles open-with well, so when I close the PDF in Xodo, it is automatically saved and synced. Back on my laptop, I go back to Zotero, right click the item again, and select Manage Attachments &gt; Get From Tablet to add the annotated PDF back to my Zotereo library. I imagine the process is similar on iOS.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Multilevel numbered headers in Word]]></title><description><![CDATA[for academic articles, legal documents, etc.

It's not immediately obvious how to create multilevel numbered headers in Word. Adding the standard numbered list formatting to a header…]]></description><link>https://huey.xyz/posts/2020-06-05-multilevel-numbered-headers-in-word</link><guid isPermaLink="false">1747cdb1fbe1bcf7ef16cc380e438fa93de1e7bea4f5614be7b684cdba8c8363</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Fri, 05 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;for academic articles, legal documents, etc.&lt;/h2&gt;&lt;p&gt;It&apos;s not immediately obvious how to create multilevel numbered headers in Word. Adding the standard numbered list formatting to a header works for that particular header level, but fails to number subheaders appropriately.&lt;/p&gt;
&lt;p&gt;It seems the best way to go about numbering headers is first, to use the built-in styles (customised to your liking) rather than formatting headers and body text manually.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971082.189229674314/styled-document.avif&quot; alt=&quot;styled document&quot;&gt;&lt;/p&gt;
&lt;p&gt;The key is to format the headers with multilevel list formatting rather than the standard numbered list formatting.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971082.189229674308/multilevel-lists.avif&quot; alt=&quot;multilevel lists&quot;&gt;&lt;/p&gt;
&lt;p&gt;That magically formats the headers and subheaders the way you want it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971082.189229674311/multilevel-numbered-headers.avif&quot; alt=&quot;multilevel numbered headers&quot;&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The built-in reading time calculator in gatsby-transformer-remark]]></title><description><![CDATA[You probably don't need gatsby-remark-reading-time

In the ECMAScript world, there's a module for everything. A common, and well-documented way to calculate a Medium-style estimated reading…]]></description><link>https://huey.xyz/posts/2020-06-01-timetoread-in-gatsby</link><guid isPermaLink="false">2a4189c580a0ee9baa0989d46155a920e26ad3d74e5654e9f357aaa908dac3e1</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Mon, 01 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;You probably don&apos;t need gatsby-remark-reading-time&lt;/h2&gt;&lt;p&gt;In the ECMAScript world, &lt;a href=&quot;https://github.com/ninest/drink-if-exists&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;there&apos;s a module for everything&lt;/a&gt;. A common, and well-documented way to calculate a Medium-style estimated reading time in Gatsby is to use the &lt;a href=&quot;https://www.gatsbyjs.org/packages/gatsby-remark-reading-time/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gatsby-remark-reading-time&lt;/code&gt;&lt;/a&gt; plugin. This works great, but is probably unnecessary, because if you&apos;re using &lt;code class=&quot;language-text&quot;&gt;gatsby-transformer-remark&lt;/code&gt; (as you probably are, if you&apos;re parsing &lt;code class=&quot;language-text&quot;&gt;.md&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;.mdx&lt;/code&gt; files), you can use built-in &lt;code class=&quot;language-text&quot;&gt;timeToRead&lt;/code&gt; field.&lt;/p&gt;
&lt;p&gt;This field doesn&apos;t appear to have been explicitly documented yet, but it is referenced in &lt;a href=&quot;https://www.gatsbyjs.org/docs/gatsby-internals-terminology/&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the rundown of Gatsby&apos;s internals&lt;/a&gt;. It&apos;s also clearly defined in the &lt;a href=&quot;https://github.com/johnrichter/gatsby/blob/4a49b335a47c14f57f40fd307d11b89802cbd3dd/packages/gatsby-transformer-remark/src/extend-node-type.js#L585&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gatsby-transformer-remark&lt;/code&gt; source code&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber 0&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token literal-property property&quot;&gt;timeToRead&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;markdownNode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHTML&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;markdownNode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; timeToRead &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pureText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sanitizeHTML&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;html&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;allowTags&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; avgWPM &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;265&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wordCount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
        _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pureText&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
        _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pureText&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;[\p{sc=Katakana}\p{sc=Hiragana}\p{sc=Han}]&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;gu&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length
      timeToRead &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wordCount &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; avgWPM&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;timeToRead &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        timeToRead &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; timeToRead
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There appears to have been &lt;a href=&quot;https://github.com/gatsbyjs/gatsby/pull/19763&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;an attempt to allow the average WPM and the text counted to be configured&lt;/a&gt;, but this was later rolled back due to &lt;a href=&quot;https://github.com/gatsbyjs/gatsby/issues/23614&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;unexpectedly high memory usage&lt;/a&gt; and &lt;a href=&quot;https://github.com/gatsbyjs/gatsby/issues/23714&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;slow builds&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Public key authentication for multiple private Github repositories]]></title><description><![CDATA[without using ssh-agent

Authenticating with Github using a single public key for all private repositories is straightforward enough: just follow Github's guide to…]]></description><link>https://huey.xyz/posts/2020-05-14-public-key-authentication-for-multiple-private-github-repositories</link><guid isPermaLink="false">9df73209e196ca39f0c4bb816259246f5aef0aac8d2ab9c1c8904d56de75c2c1</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Thu, 14 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;without using ssh-agent&lt;/h2&gt;&lt;p&gt;Authenticating with Github using a single public key for all private repositories is straightforward enough: just &lt;a href=&quot;https://help.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;follow Github&apos;s guide to authenticating with SSH&lt;/a&gt; and configure your &lt;code class=&quot;language-text&quot;&gt;~/.ssh/config&lt;/code&gt; appropriately:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;properties&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-properties line-numbers&quot;&gt;&lt;code class=&quot;language-properties&quot;&gt;&lt;span class=&quot;token key attr-name&quot;&gt;Host&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;github.com&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  Hostname&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;github.com&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  User&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;git&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  IdentityFile&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;~/.ssh/your_private_key&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But things get more tricky if you don&apos;t want to use the same public key for all your private repositories, but instead want to use specific deploy keys for one or more of them. This can be done relatively easily by taking advantage of the &lt;code class=&quot;language-text&quot;&gt;Host&lt;/code&gt; field in &lt;code class=&quot;language-text&quot;&gt;~/.ssh/config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The trick here is to configure each Github repository to use a different hostname. Rather than &lt;code class=&quot;language-text&quot;&gt;github.com/username/repo_name&lt;/code&gt;, set it to &lt;code class=&quot;language-text&quot;&gt;repo_name.username&lt;/code&gt;, or &lt;code class=&quot;language-text&quot;&gt;repo_name.github.com&lt;/code&gt;, or something. What&apos;s important is that it doesn&apos;t clash with any existing domain you might want to access.&lt;/p&gt;
&lt;p&gt;Set the hostname in your &lt;code class=&quot;language-text&quot;&gt;.git/config&lt;/code&gt; on each repository:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;remote &lt;span class=&quot;token string&quot;&gt;&quot;origin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ssh://git@repo_name1.username/alice/repo1.git&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;toml&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-toml line-numbers&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;remote &lt;span class=&quot;token string&quot;&gt;&quot;origin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ssh://git@repo_name2.username/alice/repo1.git&quot;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, in your &lt;code class=&quot;language-text&quot;&gt;~/.ssh/config&lt;/code&gt;, map your made-up hostname to an actual host, with an actual identity file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;properties&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-properties line-numbers&quot;&gt;&lt;code class=&quot;language-properties&quot;&gt;&lt;span class=&quot;token key attr-name&quot;&gt;Host&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;repo_name1.username&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  HostName&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;github.com&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  User&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;git&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  IdentityFile&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;~/.ssh/your_1st_public_key&lt;/span&gt;

&lt;span class=&quot;token key attr-name&quot;&gt;Host&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;repo_name2.username&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  HostName&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;github.com&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  User&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;git&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;  IdentityFile&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;~/.ssh/your_2nd_public_key&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Mounting does nothing]]></title><description><![CDATA[no drive is mounted, yet no error is thrown

I recently encountered an odd issue when trying to mount an external drive. When I ran  or  with the appropriate configuration in , nothing…]]></description><link>https://huey.xyz/posts/2020-05-05-mounting-does-nothing</link><guid isPermaLink="false">08d7579d4fffdda2401958f10b47ec85ba036c4659d522ba23bd0ba4fbddf8a3</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Tue, 05 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;no drive is mounted, yet no error is thrown&lt;/h2&gt;&lt;p&gt;I recently encountered an odd issue when trying to mount an external drive. When I ran &lt;code class=&quot;language-text&quot;&gt;sudo mount /dev/sdb1 /media/Drive&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;sudo mount -a&lt;/code&gt; with the appropriate configuration in &lt;code class=&quot;language-text&quot;&gt;/etc/fstab&lt;/code&gt;, nothing would happen. The drive was not mounted, &lt;code class=&quot;language-text&quot;&gt;/media/Drive&lt;/code&gt; would be empty, yet no warning or error was displayed.&lt;/p&gt;
&lt;p&gt;Completely unmounting and remounting the drive did not help. The drive was already unmounted.&lt;/p&gt;
&lt;p&gt;It was reloading the &lt;code class=&quot;language-text&quot;&gt;systemd&lt;/code&gt; process that solved this for me:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;command-line-prompt&quot;&gt;&lt;span data-user=huey data-host=machine&gt;&lt;/span&gt;&lt;span data-user=huey data-host=machine&gt;&lt;/span&gt;&lt;/span&gt;systemctl daemon-reload
systemctl daemon-reexec&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Adding your UCL Timetable to your main calendar]]></title><description><![CDATA[How to tell your calendar that your life extends beyond UCL

Classes and other UCL events are helpfully compiled into a central UCL timetable, which can be viewed at the Common Timetable (timetable.ucl…]]></description><link>https://huey.xyz/posts/2019-09-30-ucl-timetable</link><guid isPermaLink="false">4b7adc7f842a83472fd316ca15c0d2e4084a837b9bdd5a0d92e0a57a933a5cb4</guid><dc:creator><![CDATA[hello@huey.xyz (Huey)]]></dc:creator><pubDate>Mon, 30 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;How to tell your calendar that your life extends beyond UCL&lt;/h2&gt;&lt;p&gt;Classes and other UCL events are helpfully compiled into a central UCL timetable, which can be viewed at &lt;a href=&quot;https://timetable.ucl.ac.uk/tt/homePage.do&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;the Common Timetable (timetable.ucl.ac.uk)&lt;/a&gt;, &lt;a href=&quot;https://uclapi.com/marketplace/uclassistant&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;UCL Assistant&lt;/a&gt;, or &lt;a href=&quot;https://www.ucl.ac.uk/isd/services/websites-apps/ucl-go&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;UCL Go!&lt;/a&gt;. This is nice, but not terribly helpful if you don&apos;t use these as your timetable app, or if you want to include non-UCL events on your timetable.&lt;/p&gt;
&lt;p&gt;If you are an Organised Person™, you might use &lt;a href=&quot;https://calendar.google.com&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Google Calendar&lt;/a&gt;, the &lt;a href=&quot;https://en.wikipedia.org/wiki/Calendar_(Apple)&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Calendar app on your Mac/iPhone&lt;/a&gt;, or the &lt;a href=&quot;https://office.live.com/start/Calendar.aspx&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;Office 365 / Outlook calendar&lt;/a&gt;. Fortunately, the Common Timetable generates an iCalendar link to your personal timetable that makes it easy to import into (almost) any other calendar app, even &lt;code class=&quot;language-text&quot;&gt;org-mode&lt;/code&gt;.&lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Log into &lt;a href=&quot;https://timetable.ucl.ac.uk/tt/homePage.do&quot; target=&quot;_self&quot; rel=&quot;nofollow noopener&quot;&gt;timetable.ucl.ac.uk&lt;/a&gt; and open your personal timetable.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/1776002971079.189229674297/screenshot1.avif&quot; alt=&quot;subscribe button&quot;&gt;&lt;/p&gt;
&lt;p&gt;Click the &quot;Subscribe&quot; button.&lt;/p&gt;
&lt;p&gt;Copy the &lt;code class=&quot;language-text&quot;&gt;webcal&lt;/code&gt; link. It should look something like this: &lt;code class=&quot;language-text&quot;&gt;webcal://www.ucl.ac.uk/timetable/ics/PONIBF332NKJB&lt;/code&gt;. Import this into your calendar app.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;If &lt;code class=&quot;language-text&quot;&gt;org-mode&lt;/code&gt; is your calendar, you probably know how to do this already.&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item></channel></rss>