<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Caius&#x27; Lab - 3D Printing</title>
      <link>https://caius.dev/</link>
      <description></description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://caius.dev/tags/3d-printing/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Thu, 11 Jun 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Making a Digital Clock; An Attempt at Integrating Hardware, Software and 3D Printing</title>
          <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
          <author>Caius Brindescu</author>
          <link>https://caius.dev/blog/digital-clock/</link>
          <guid>https://caius.dev/blog/digital-clock/</guid>
          <description xml:base="https://caius.dev/blog/digital-clock/">&lt;p&gt;For the last few years, we&#x27;ve been using a Comcast TV Box as a clock for the living room.
It hasn&#x27;t been used for its original purpose in years, but the clock was very useful, so it lived on for this reason alone.
To save some space (and power), I decommissioned that box about a month ago to make room for a networking mini-rack.&lt;&#x2F;p&gt;
&lt;p&gt;However, my partner really missed the illuminted clock in the living room.
Whatever clocks we had lying around were not illuminated as they were battery powered, so none were a good replacement because of this.
To fix this, I decided to try and build one using off the shelf components, and a 3D printed case.
The final result can be seen below.&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;clock.2bd5b9bd3436fef1.jpg&quot; alt=&quot;Final clock as built&quot;
     width=&quot;1280&quot; height=&quot;829&quot;
     sizes=&quot;(min-width: 920px) 784px, (min-width: 700px) calc(82vw + 46px), calc(100vw - 40px)&quot; 
     srcset=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;clock.9133aa6e386b7906.jpg 640w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;clock.82d13f1e04d706c6.jpg 784w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;clock.2482963dfc43bc4d.jpg 1280w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;clock.5cdd81d4f6378c0a.jpg 1920w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;clock.65152d760ffe02b5.jpg 2560w&quot;
     loading=&quot;lazy&quot;&gt;
&lt;h1 id=&quot;inspiration-and-design&quot;&gt;Inspiration and design&lt;a class=&quot;post-anchor&quot; href=&quot;#inspiration-and-design&quot; aria-label=&quot;Anchor link for: inspiration-and-design&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The clock was inspired by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.printables.com&#x2F;model&#x2F;1344276-esptimecast-wifi-clock-weather-display&quot;&gt;this 3D Model&lt;&#x2F;a&gt;.
However, I wanted a different look, and the project seemed easy enough to try out by myself.&lt;&#x2F;p&gt;
&lt;p&gt;The design goals were, as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Illuminated&lt;&#x2F;li&gt;
&lt;li&gt;Powered externally. I don&#x27;t need another thing in my life that needs charging.&lt;&#x2F;li&gt;
&lt;li&gt;Self adjusting, so I don&#x27;t have to worry about setting the correct time and DST changes.&lt;&#x2F;li&gt;
&lt;li&gt;Shows the local temperature; because why not.&lt;&#x2F;li&gt;
&lt;li&gt;Decent aesthetic (at least as far as my design skills go).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;parts&quot;&gt;Parts&lt;a class=&quot;post-anchor&quot; href=&quot;#parts&quot; aria-label=&quot;Anchor link for: parts&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;I had a set of off-brand WeMos D1 Mini-style ESP dev boards I got off Amazon.
They have WiFi, so they seemed as the perfect candidate for the brains of the project.&lt;&#x2F;p&gt;
&lt;p&gt;The display is a 4 module MAX7219, with red LEDs, giving me a resolution of 32x8 pixels.
I bought &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;dp&#x2F;B09CGWZRYG&quot;&gt;a cheap set of 3 from Amazon&lt;&#x2F;a&gt;, so I had a few tries in case the assembly went wrong.
To wire it all permanently, the idea was to use a protoboard to solder everything into one assembly.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;typeface&quot;&gt;Typeface&lt;a class=&quot;post-anchor&quot; href=&quot;#typeface&quot; aria-label=&quot;Anchor link for: typeface&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The goal was to have a typeface that could show all 10 digits, in a 3x6 size.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;moonbench.xyz&#x2F;projects&#x2F;tiny-pixel-art-fonts&#x2F;&quot;&gt;This blog post&lt;&#x2F;a&gt; provides fantastic examples, and the 3x6 examples posted were a great starting point.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the design for the 10 digits that I landed on:&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;typeface.dab2fb5fc9fdd53e.png&quot; alt=&quot;3x6 bitmap typeface&quot;
     width=&quot;468&quot; height=&quot;96&quot;
     sizes=&quot;(min-width: 920px) 784px, (min-width: 700px) calc(82vw + 46px), calc(100vw - 40px)&quot; 
     srcset=&quot;&quot;
     loading=&quot;lazy&quot;&gt;
&lt;p&gt;The glyphs are legible, and they cannot be confused with one another.
Two of the digits proved to be problematic, in particular 4 and 9.
The original design was the following:&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;4-and-9.769239de4cf93c6f.png&quot; alt=&quot;Original designs for 4 and 9 glyphs.&quot;
     width=&quot;84&quot; height=&quot;96&quot;
     sizes=&quot;(min-width: 920px) 784px, (min-width: 700px) calc(82vw + 46px), calc(100vw - 40px)&quot; 
     srcset=&quot;&quot;
     loading=&quot;lazy&quot;&gt;
&lt;p&gt;However, the 4 looks like a 9 that has lost a pixel, either because it&#x27;s out, or because I messed up the encoding.
The final design of a more traditional 4, and a 9 that&#x27;s the same glyph as 6, rotated 180 degrees looks a lot better, and leaves no room for confusion.
At this resolution, it works well enough.&lt;&#x2F;p&gt;
&lt;p&gt;The 5 used to be a 180 degree rotated variant of the 2 glyph.
However, I didn&#x27;t like the shape of it, so I added one more pixel, and it makes all the difference.
You can see here the old and new 5 glyphs, side by side:&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;5-old-new.ca090c9559597ab5.png&quot; alt=&quot;Original and new design for the 5 glyph.&quot;
     width=&quot;84&quot; height=&quot;96&quot;
     sizes=&quot;(min-width: 920px) 784px, (min-width: 700px) calc(82vw + 46px), calc(100vw - 40px)&quot; 
     srcset=&quot;&quot;
     loading=&quot;lazy&quot;&gt;
&lt;h1 id=&quot;ui-considerations&quot;&gt;UI considerations&lt;a class=&quot;post-anchor&quot; href=&quot;#ui-considerations&quot; aria-label=&quot;Anchor link for: ui-considerations&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;layout&quot;&gt;Layout&lt;a class=&quot;post-anchor&quot; href=&quot;#layout&quot; aria-label=&quot;Anchor link for: layout&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Now that I had the the glyphs design, the next step was to come up with a layout.
I went with a 3 pixel wide typeface, because this gives me room for 7 digits on the 32 wide display, including the colon for the time, and 1 pixel to represent degree symbol.
All characters are spaced 1 pixel apart.&lt;&#x2F;p&gt;
&lt;p&gt;The final layout looks like this:&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;face-layout.e9ba5ee4a9eed8ea.png&quot; alt=&quot;Layout of the clock face.&quot;
     width=&quot;384&quot; height=&quot;96&quot;
     sizes=&quot;(min-width: 920px) 784px, (min-width: 700px) calc(82vw + 46px), calc(100vw - 40px)&quot; 
     srcset=&quot;&quot;
     loading=&quot;lazy&quot;&gt;
&lt;p&gt;The temperature is left aligned, so under normal weather conditions in the Pacific Northwest, only the left 2 digits are used for the majority of the time.
The left digit will be used for a minus sign if the temperatures go negative.
Luckily, I don&#x27;t have to worry about that over here, if I stick to Fahrenheit&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;animation&quot;&gt;Animation&lt;a class=&quot;post-anchor&quot; href=&quot;#animation&quot; aria-label=&quot;Anchor link for: animation&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Since I have a grid display, and a microcontroller, having the digits just change would be quite boring.
I think having a nice animation when changing digits would be a nice touch.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;blog&#x2F;digital-clock&#x2F;assets&#x2F;animation.gif&quot; alt=&quot;Digit change animation.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;feedback-and-error-conditions&quot;&gt;Feedback and error conditions&lt;a class=&quot;post-anchor&quot; href=&quot;#feedback-and-error-conditions&quot; aria-label=&quot;Anchor link for: feedback-and-error-conditions&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;To avoid having to manually set the time, and to compensate for the known not-so-great quality of the RTC on the board, the clock will synchronize with NTP once hourly&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.
When this is happening, the display will not update, as the update is synchronous.&lt;&#x2F;p&gt;
&lt;p&gt;This presents 2 challenges.
First, any animation would &quot;freeze&quot; or not work while the sync is in progress.
This is an easy fix, as I don&#x27;t allow update to happen within 10 seconds from the top of the minute.
This means that time updates can only happen between seconds 10 and 50 of every minute, avoiding a display freeze in the middle of an animation should the 2 coincide at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;The second issue of the display freezing, is that I will not know if it&#x27;s frozen because of a problem, or because it&#x27;s synchronizing.
This is fixed, by adding a synchronization symbol to the clock face.
The symbol is a &quot;double height&quot; colon.
It blends in nicely aesthetically, and doesn&#x27;t interfere with the main function.&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;synchronizing-display.e830d45224402cc7.png&quot; alt=&quot;Layout of the clock face when a sync is in progress.&quot;
     width=&quot;204&quot; height=&quot;96&quot;
     sizes=&quot;(min-width: 920px) 784px, (min-width: 700px) calc(82vw + 46px), calc(100vw - 40px)&quot; 
     srcset=&quot;&quot;
     loading=&quot;lazy&quot;&gt;
&lt;p&gt;The double height colon also serves as an indicator that the time sync failed on the last attempt.
The colon will blink every second (like the normal state).
This still allows the clock to function, while signalling that the displayed time might not be accurate.
This state will persist until a time sync is successful.
When the sync fails, we&#x27;ll keep retrying every 10 minutes, to minimize the time when we have &quot;degraded time.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;The final piece of the puzzle is the temperature.
If the clock fails to fetch it, the temperature display will be removed from the clock face until we have data.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;caiusb&#x2F;clock&quot;&gt;full code for the firmware is up on GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;case-design&quot;&gt;Case design&lt;a class=&quot;post-anchor&quot; href=&quot;#case-design&quot; aria-label=&quot;Anchor link for: case-design&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The case design was probably the more challenging part of the project.
First, this is the first integrated electronics project that I have tackled from scratch.
Secondly, and crucially, I&#x27;m still learning CAD.
Having a &quot;full&quot; assembly was a good way to learn a few tricks.&lt;&#x2F;p&gt;
&lt;p&gt;The electronics will be retained in the clock through friction.
A few test prints showed that the diffuser part fits snugly enough that this would be fine.
Also, since I was using off-the-shelf components in ways they probably never were designed to integrate, coming up with a different mounting solution looked quite daunting.&lt;&#x2F;p&gt;
&lt;p&gt;To aid with 3D printing, the case should also require minimal, to no supports.
The end result requires no supports, so I&#x27;m happy with the result.
The final designed is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.printables.com&#x2F;model&#x2F;1749367-mimimalist-digital-clock&quot;&gt;shared on Printables&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;display-diffuser&quot;&gt;Display Diffuser&lt;a class=&quot;post-anchor&quot; href=&quot;#display-diffuser&quot; aria-label=&quot;Anchor link for: display-diffuser&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;For the diffuser, one solution was to 3D print a thin 2-3 layer cover that goes over the display.
The gaps in the layers would still allow the digits to be seen, while aiding readability by improving contrast.
I did a few test prints, however the end result was too dim for my liking, and I had to power the LEDs at full brightness for the contrast to be decent.
So I needed something more transparent.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily I had some transparent PETG that I bought years ago, and never opened.
Printing a 3 layer diffuser over the display removed the background &quot;noise&quot; of the turned off pixels and allowed most of the light to shine through.
The display is still legible in bright daylight, even at the lowest setting, without turning the room red at night.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;integration&quot;&gt;Integration&lt;a class=&quot;post-anchor&quot; href=&quot;#integration&quot; aria-label=&quot;Anchor link for: integration&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;The final integration was mostly around getting the electronics all sorted out.
The most challenging part was removing the existing 90 degree header from the display module, so I could use a straight header to connect to the protoboard that was carrying the MCU.&lt;&#x2F;p&gt;
&lt;p&gt;Once that hurdle was over, the wiring was done on a piece of proto board, and then everything was soldered together as one unit.
I didn&#x27;t have any Kapton tape, so electrical tape had to do to avoid any shortcircuits between the stacked headers.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, at the last minute, I added a 10K potentiometer to control the brightness, without having to reupload the firmware, together with the code to make this work.
This will allow me to easily tune the brightness when it&#x27;s installed.&lt;&#x2F;p&gt;
&lt;p&gt;Below are 2 images: one of the final electronics assembly, and one with the electronics assembled inside the case.&lt;&#x2F;p&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics.3269b31825e44669.jpg&quot; alt=&quot;Electronics module as fully assembled&quot;
     width=&quot;1280&quot; height=&quot;960&quot;
     sizes=&quot;(min-width: 920px) 784px, (min-width: 700px) calc(82vw + 46px), calc(100vw - 40px)&quot; 
     srcset=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics.b6cfd3426cb3d780.jpg 640w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics.ceefe5a6bd09efb9.jpg 784w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics.2645c3217800e8b9.jpg 1280w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics.162ae93e4af4e1f6.jpg 1920w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics.e046c0fb1077edcf.jpg 2560w&quot;
     loading=&quot;lazy&quot;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics-in-case.2f4df965e1c1feaa.jpg&quot; alt=&quot;Electronics module installed in the case&quot;
     width=&quot;1280&quot; height=&quot;960&quot;
     sizes=&quot;(min-width: 920px) 784px, (min-width: 700px) calc(82vw + 46px), calc(100vw - 40px)&quot; 
     srcset=&quot;https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics-in-case.23dca298423d7940.jpg 640w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics-in-case.12d6d1bb4929939c.jpg 784w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics-in-case.e2827c9d292b03bb.jpg 1280w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics-in-case.6da156947c3a4b89.jpg 1920w,
             https:&#x2F;&#x2F;caius.dev&#x2F;processed_images&#x2F;electronics-in-case.1c22d37af939a36f.jpg 2560w&quot;
     loading=&quot;lazy&quot;&gt;
&lt;h1 id=&quot;final-results&quot;&gt;Final results&lt;a class=&quot;post-anchor&quot; href=&quot;#final-results&quot; aria-label=&quot;Anchor link for: final-results&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;It&#x27;s been living under the TV for well over a week now.
It works pretty well for a clock.
The time is accurate, and I haven&#x27;t seen any synchronizing issues.
Finally, I only saw one issue with the temperature update, and that also behaved as expected by dropping the temperature from the display.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusions&quot;&gt;Conclusions&lt;a class=&quot;post-anchor&quot; href=&quot;#conclusions&quot; aria-label=&quot;Anchor link for: conclusions&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;p&gt;It was a fun build.
It pushed my coding skills, as it&#x27;s been a while since I&#x27;ve written C++, or worked extensively with microcontrollers&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-3-1&quot;&gt;&lt;a href=&quot;#fn-3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.
Coming up with a parametric design that had 4 total pieces (front bezel, diffuser, main body, and the rear cover) was challenging.
It worked out in the end, and only one hole was misaligned!&lt;&#x2F;p&gt;
&lt;p&gt;The end product meets 100% of my original design criteria, and is a fully functional and setup-free clock.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;errata&quot;&gt;Errata&lt;a class=&quot;post-anchor&quot; href=&quot;#errata&quot; aria-label=&quot;Anchor link for: errata&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2026-06-11&lt;&#x2F;strong&gt;: Updated the face layout images to use the correct 8 glyph.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Negative temperatures below 99 degrees (F or C) are intentionally not supported. I think I&#x27;ll have other things to worry about if that&#x27;s ever needed. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;The once hourly part has been arbitrarily chosen. I did not measure the precision of the on-board RTC, but it seems reasonable that it keep to within a minute for one hour. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;An LLM was used to speed up the coding part. &lt;a href=&quot;#fr-3-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</description>
      </item>
    </channel>
</rss>
