<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Patrick Chong</title>
  <subtitle>A Christian with a passion for technology, music, food and sustainability</subtitle>
  <link href="https://www.patrickxchong.com"/>
  <link href="https://www.patrickxchong.com/feed.xml" rel="self"/>
  <updated>2022-06-11T13:07:17Z</updated>
  <id>https://www.patrickxchong.com/</id>
  <author>
    <name>Patrick Chong</name>
    <email>mail@patrickxchong.com</email>
  </author>
    
    <entry>
      <title>Deploy websites and APIs (for free)</title>
      <link href="https://www.patrickxchong.com/deploy-websites-and-apis-for-free/"/>
      <updated>2021-10-16T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/deploy-websites-and-apis-for-free/</id>
      <content type="html">&lt;p&gt;Personally have tried most of the platforms here. All platforms have a generous free tier, with different limitations.&lt;/p&gt;
&lt;h3 id=&quot;website-%2B-api-%2B-database&quot;&gt;Website + API + Database &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/deploy-websites-and-apis-for-free/#website-%2B-api-%2B-database&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.deta.sh/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Deta&lt;/a&gt; - Totally free. Something quite new that I found out, still exploring and built a couple of prototypes with it. Apparently they will have an &lt;a href=&quot;https://docs.deta.sh/docs/home#how-are-you-going-to-make-money&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;alternative way to generate revenue&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Fly&lt;/a&gt; - generous free plan, able to host three servers with Heroku style buildpacks or using docker, 3GB storage/postgres databases, no slow-startup issue&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://railway.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Railway&lt;/a&gt; - generous free plan, able to host 2-3 postgres databases and servers&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/apps-script&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Google Apps Script&lt;/a&gt; (if we consider Google Sheets as a database) (Javascript only)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://glitch.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Glitch&lt;/a&gt; (JavaScript only)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://render.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Render&lt;/a&gt; - very limited free plan, PG database expires after 90 days, not recommended&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;website-%2B-api&quot;&gt;Website + API &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/deploy-websites-and-apis-for-free/#website-%2B-api&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vercel.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Vercel&lt;/a&gt; - Currently most of my projects are hosted here thanks to Vercel’s generous free plan, this website is on hosted Vercel too!&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://netlify.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Netlify&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;database-%2B-static-file-storage&quot;&gt;Database + Static File Storage &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/deploy-websites-and-apis-for-free/#database-%2B-static-file-storage&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://supabase.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Supabase&lt;/a&gt; (PostgreSQL)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;database-only&quot;&gt;Database only &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/deploy-websites-and-apis-for-free/#database-only&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mongodb.com/cloud/atlas&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;MongoDB Atlas&lt;/a&gt; (NoSQL)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.getgrist.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Grist&lt;/a&gt; (Spreadsheet-like)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.airtable.com/pricing&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Airtable&lt;/a&gt; (Spreadsheet-like)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;website-only&quot;&gt;Website only &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/deploy-websites-and-apis-for-free/#website-only&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://surge.sh/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Surge&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;dns-service&quot;&gt;DNS service &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/deploy-websites-and-apis-for-free/#dns-service&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cloudflare.com/dns/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Cloudflare&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Also has &lt;a href=&quot;https://www.cloudflare.com/ssl/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;free SSL&lt;/a&gt; service&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;online-ides&quot;&gt;Online IDEs &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/deploy-websites-and-apis-for-free/#online-ides&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codepen.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;CodePen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://codetasty.com/pricing&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;CodeTasty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://codesandbox.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;CodeSandBox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gitpod.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Gitpod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://replit.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Repl.it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackblitz.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Stackblitz&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- https://dev.to/fayaz/this-free-tools-for-developers-are-45p3 --&gt;
&lt;!-- https://free-for.dev/ --&gt;
&lt;!-- https://appydev.co/ --&gt;
</content>
    </entry>
    
    <entry>
      <title>Free Design Resources</title>
      <link href="https://www.patrickxchong.com/free-design-resources/"/>
      <updated>2021-11-06T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/free-design-resources/</id>
      <content type="html">&lt;h3 id=&quot;images&quot;&gt;Images &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/free-design-resources/#images&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://unsplash.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://unsplash.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pixabay.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://pixabay.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.pexels.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.pexels.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://picjumbo.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://picjumbo.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.freepik.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.freepik.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://freestocktextures.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://freestocktextures.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://search.creativecommons.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://search.creativecommons.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.publicdomainpictures.net/en/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.publicdomainpictures.net/en/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://designerassets.in/free-photos/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://designerassets.in/free-photos/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;illustrations&quot;&gt;Illustrations &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/free-design-resources/#illustrations&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://designstripe.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://designstripe.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.manypixels.co/gallery&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.manypixels.co/gallery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://2.flexiple.com/scale/all-illustrations&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://2.flexiple.com/scale/all-illustrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blush.design/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://blush.design/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://icons8.com/illustrations&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://icons8.com/illustrations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;icons&quot;&gt;Icons &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/free-design-resources/#icons&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.iconshock.com/freeicons/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.iconshock.com/freeicons/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://icons.getbootstrap.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://icons.getbootstrap.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://iconoir.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://iconoir.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://remixicon.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://remixicon.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tablericons.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://tablericons.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://heroicons.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://heroicons.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://systemuicons.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://systemuicons.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://iconscout.com/free-icons&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://iconscout.com/free-icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://primer.style/octicons/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://primer.style/octicons/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jonsuh.com/hamburgers/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://jonsuh.com/hamburgers/&lt;/a&gt; - Hamburger icons only&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://designerassets.in/freebies/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://designerassets.in/freebies/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;svg&quot;&gt;SVG &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/free-design-resources/#svg&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.svgrepo.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.svgrepo.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://glyphs.fyi/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://glyphs.fyi/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://svgbox.net/iconsets/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://svgbox.net/iconsets/&lt;/a&gt; - svgicon as a service&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://freesvg.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://freesvg.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;transparent-png-images%2Ficons&quot;&gt;Transparent PNG images/Icons &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/free-design-resources/#transparent-png-images%2Ficons&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://pngowl.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://pngowl.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://12png.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://12png.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.flaticon.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.flaticon.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;background-graphics&quot;&gt;Background graphics &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/free-design-resources/#background-graphics&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wweb.dev/resources/css-separator-generator/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://wweb.dev/resources/css-separator-generator/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.heropatterns.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.heropatterns.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bgjar.com/simple-shiny&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://bgjar.com/simple-shiny&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;other-resources&quot;&gt;Other resources &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/free-design-resources/#other-resources&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.canva.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.canva.com/&lt;/a&gt; - Create good looking designs easily, I use this a lot!&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://signature.email/generator&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://signature.email/generator&lt;/a&gt; - Email signature image&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dimmy.club/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://dimmy.club/&lt;/a&gt; - Device mockups&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://shadows.brumm.af/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://shadows.brumm.af/&lt;/a&gt; - CSS Shadows&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://svgco.de/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://svgco.de/&lt;/a&gt; - Image to SVG&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.codepng.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.codepng.app/&lt;/a&gt; - Code to Image&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gifcap.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://gifcap.dev/&lt;/a&gt; - Screen recording to gif&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.screensizes.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.screensizes.app/&lt;/a&gt; - Device screensize and resolutions&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ojoy.zaps.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://ojoy.zaps.dev/&lt;/a&gt; - Upscale images&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://neural.love/video&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://neural.love/video&lt;/a&gt; - Upscale videos and images&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redact.photo/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://redact.photo/&lt;/a&gt; - Redact photos&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cleanup.pictures/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://cleanup.pictures/&lt;/a&gt; - Remove objects from images&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://express.adobe.com/tools/remove-background&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://express.adobe.com/tools/remove-background&lt;/a&gt; - Remove background from images&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://runwayml.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://runwayml.com/&lt;/a&gt; - Remove background from video&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;other-compilations&quot;&gt;Other compilations &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/free-design-resources/#other-compilations&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nodesign.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://nodesign.dev/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Custom Asana ICal Sync to Google Calendar</title>
      <link href="https://www.patrickxchong.com/custom-asana-ical-sync-to-google-calendar/"/>
      <updated>2022-06-11T13:07:17Z</updated>
      <id>https://www.patrickxchong.com/custom-asana-ical-sync-to-google-calendar/</id>
      <content type="html">&lt;nav class=&quot;table-of-contents&quot;&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/custom-asana-ical-sync-to-google-calendar/#asana-to-ical&quot;&gt;Asana to ICal &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/custom-asana-ical-sync-to-google-calendar/#sync-ical-feed-with-google-calendar&quot;&gt;Sync ICal feed with Google Calendar &lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/nav&gt;&lt;h2 id=&quot;asana-to-ical&quot;&gt;Asana to ICal &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/custom-asana-ical-sync-to-google-calendar/#asana-to-ical&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Script below fetches events from Asana and returns formatted ICal Feed. I deployed the function as a lambda on &lt;a href=&quot;https://vercel.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Vercel&lt;/a&gt;.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/patrickxchong/9dbae2f68ad31313c8c824f359dea6e7.js&quot;&gt;&lt;/script&gt;
&lt;h2 id=&quot;sync-ical-feed-with-google-calendar&quot;&gt;Sync ICal feed with Google Calendar &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/custom-asana-ical-sync-to-google-calendar/#sync-ical-feed-with-google-calendar&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The existing Google Calendar ICal sync updates very slow (between 12-24 hours). So I used the script from &lt;a href=&quot;https://github.com/derekantrican/GAS-ICS-Sync&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/derekantrican/GAS-ICS-Sync&lt;/a&gt; to sync events from Asana (through the Vercel lambda API endpoint) to Google Calendar more frequently.&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>Run Grocy On Fly.io</title>
      <link href="https://www.patrickxchong.com/run-grocy-on-flyio/"/>
      <updated>2022-06-10T12:03:15Z</updated>
      <id>https://www.patrickxchong.com/run-grocy-on-flyio/</id>
      <content type="html">&lt;p&gt;I’ve been wanting to try using Grocy to manage some household inventory but couldn’t find a server where I could host PHP for free but is also up to date enough to support SQLite version 3.90 (&lt;a href=&quot;https://github.com/grocy/grocy/issues/1209&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;see Github issue&lt;/a&gt;). When researching the latest platforms that I could &lt;a href=&quot;https://www.patrickxchong.com/deploy-websites-and-apis-for-free/&quot;&gt;deploy websites and APIs (for free)&lt;/a&gt;, I found out about &lt;a href=&quot;https://fly.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Fly&lt;/a&gt;, their generous free plan (no sleep + persistent storage) and their support for Docker containers. Decided to try running Grocy on Fly and it worked beautifully! Here’s the process for anyone who would like to do the same.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create an account on &lt;a href=&quot;https://fly.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Fly&lt;/a&gt; and install Fly command line tool: &lt;a href=&quot;https://fly.io/docs/getting-started/installing-flyctl/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://fly.io/docs/getting-started/installing-flyctl/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Git clone Grocy Docker image (&lt;a href=&quot;https://github.com/linuxserver/docker-grocy&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/linuxserver/docker-grocy&lt;/a&gt;) and open terminal in cloned folder.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run &lt;code&gt;flyctl launch&lt;/code&gt; to generate a fly.toml file with the  &lt;code&gt;app_name&lt;/code&gt; of your choice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update &lt;code&gt;internal_port&lt;/code&gt; in fly.toml from 8080 to 80 because the Docker image is running grocy on port 80.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-toml&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;to&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Create a persistent volume on Fly.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;flyctl volumes create &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;volume_name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; --size &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;volume_size_in_gb&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; --region &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;region_code&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# Example:&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# flyctl volumes create grocy_data --size 1 --region sin&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;Add &lt;code&gt;mount&lt;/code&gt; configuration to fly.toml&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-toml&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;mount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;volume_name&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;destination_folder_name&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;mount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;grocy_data&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/grocy_dir&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;Your final fly.toml file should look something like the following:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-toml&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token key property&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;app_name&gt;&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;kill_signal&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;SIGINT&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;kill_timeout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;processes&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;br /&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;experimental&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key property&quot;&gt;allowed_public_ports&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;br /&gt;  &lt;span class=&quot;token key property&quot;&gt;auto_rollback&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;br /&gt;&lt;br /&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 table class-name&quot;&gt;services&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;br /&gt;  &lt;span class=&quot;token key property&quot;&gt;http_checks&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;br /&gt;  &lt;span class=&quot;token key property&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key property&quot;&gt;processes&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 string&quot;&gt;&quot;app&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key property&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tcp&quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key property&quot;&gt;script_checks&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;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;services.concurrency&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;hard_limit&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;soft_limit&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;connections&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&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 table class-name&quot;&gt;services.ports&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;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;handlers&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 string&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;br /&gt;&lt;br /&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 table class-name&quot;&gt;services.ports&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;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;handlers&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 string&quot;&gt;&quot;tls&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;&lt;br /&gt;&lt;br /&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 table class-name&quot;&gt;services.tcp_checks&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;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;grace_period&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1s&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;interval&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;restart_limit&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key property&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2s&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;mount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;grocy_data&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key property&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/grocy_dir&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;8&quot;&gt;
&lt;li&gt;
&lt;p&gt;Run &lt;code&gt;flyctl deploy&lt;/code&gt; to deploy your app.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After the build is completed, run &lt;code&gt;flyctl ssh console&lt;/code&gt; to ssh into the application server. You’ll see the grocy files in &lt;code&gt;/app/grocy&lt;/code&gt; and that the persistent disk is mounted at &lt;code&gt;&amp;lt;destination_folder_name&amp;gt;&lt;/code&gt; (/grocy_dir in my case).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I tried making the persistent disk &lt;code&gt;/app&lt;/code&gt; so that all the server files are always in the persistent disk, but Fly didn’t seem to like that so I created a Git repo in &lt;code&gt;/grocy_dir/&lt;/code&gt; and manually back up/restore the Grocy database/uploaded files between &lt;code&gt;/app/grocy/data/&lt;/code&gt; and &lt;code&gt;/grocy_dir/&lt;/code&gt; with shell scripts. The backup files are subsequently uploaded to the cloud via Git. The two scripts I used are shared beow and are meant to be run in the root directory.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# backup.sh&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; /app/grocy/data/ &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; -r &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; -A &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;egrep&lt;/span&gt; -v &lt;span class=&quot;token string&quot;&gt;&quot;.htaccess|.gitignore|viewcache|backups&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt; /grocy_dir/data&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# restore.sh&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; -r /grocy_dir/data/* /app/grocy/data/&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;chown&lt;/span&gt; -R abc /app/grocy/data/*&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# required else Grocy can&#39;t read the files somehow&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s all! Thanks for reading and drop a comment below if you have any questions. 😄&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>Sustainability Resources</title>
      <link href="https://www.patrickxchong.com/sustainability-resources/"/>
      <updated>2022-01-30T13:07:17Z</updated>
      <id>https://www.patrickxchong.com/sustainability-resources/</id>
      <content type="html">&lt;h3 id=&quot;videos&quot;&gt;Videos &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/sustainability-resources/#videos&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;WaterBear - Free streaming service for environmental documentaries: &lt;a href=&quot;https://www.waterbear.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.waterbear.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Our Changing Climate: &lt;a href=&quot;https://www.youtube.com/channel/UCNXvxXpDJXp-mZu3pFMzYHQ&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.youtube.com/channel/UCNXvxXpDJXp-mZu3pFMzYHQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;food&quot;&gt;Food &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/sustainability-resources/#food&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reduce food waste: &lt;a href=&quot;https://www.savethefood.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.savethefood.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;environmental-impact-data&quot;&gt;Environmental Impact Data &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/sustainability-resources/#environmental-impact-data&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;IPCC Emissions Factor Database &lt;a href=&quot;https://www.ipcc-nggip.iges.or.jp/EFDB/main.php&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.ipcc-nggip.iges.or.jp/EFDB/main.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Carbon dioxide emissions embodied in international trade: &lt;a href=&quot;https://stats.oecd.org/Index.aspx?DataSetCode=IO_GHG_2021&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://stats.oecd.org/Index.aspx?DataSetCode=IO_GHG_2021&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Database of Food Impacts on the Environment for Linking to Diets: &lt;a href=&quot;https://css.umich.edu/page/datafield&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://css.umich.edu/page/datafield&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Compilation of life cycle databases: &lt;a href=&quot;https://ghgprotocol.org/life-cycle-databases&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://ghgprotocol.org/life-cycle-databases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;take-action&quot;&gt;Take Action &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/sustainability-resources/#take-action&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Take climate action at work: &lt;a href=&quot;https://www.workforclimate.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.workforclimate.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Explore jobs from climate tech companies: &lt;a href=&quot;https://climatebase.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://climatebase.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Innovative pro-climate projects from all over the world: &lt;a href=&quot;https://solarimpulse.com/solutions-explorer&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://solarimpulse.com/solutions-explorer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Stuff I&#39;ve Cooked</title>
      <link href="https://www.patrickxchong.com/stuff-ive-cooked/"/>
      <updated>2021-11-14T13:07:17Z</updated>
      <id>https://www.patrickxchong.com/stuff-ive-cooked/</id>
      <content type="html">&lt;br /&gt;
&lt;p&gt;Various food experiments I&#39;ve done hehe. Not in any particular order.&lt;/p&gt;
&lt;br /&gt;




  &lt;div x-data=&quot;{ imgModalSrc : &#39;&#39;, imgModalTitle : &#39;&#39; }&quot; @img-modal.window=&quot;imgModalSrc = $event.detail.src; imgModalTitle = $event.detail.title; &quot; x-init=&quot;$watch(&#39;imgModalSrc&#39;, value =&gt; { document.body.style.overflow = imgModalSrc? &#39;hidden&#39; : null } )&quot;&gt;
    &lt;template x-if=&quot;imgModalSrc&quot;&gt;
      &lt;div x-transition:enter=&quot;transition ease-out duration-300&quot; x-transition:enter-start=&quot;opacity-0 transform scale-90&quot; x-transition:enter-end=&quot;opacity-100 transform scale-100&quot; x-transition:leave=&quot;transition ease-in duration-300&quot; x-transition:leave-start=&quot;opacity-100 transform scale-100&quot; x-transition:leave-end=&quot;opacity-0 transform scale-90&quot; class=&quot;
				pt-4
				px-2
				fixed
				overflow-auto
				w-full
				h-screen
				inset-0
				z-50
				flex
				justify-center
				items-center
				bg-black bg-opacity-75
			&quot; @click.self=&quot;imgModalSrc = &#39;&#39;&quot;&gt;
        &lt;div class=&quot;flex flex-col w-11/12 max-w-xl h-full&quot; @click.self=&quot;imgModalSrc = &#39;&#39;&quot;&gt;
          &lt;!-- &lt;div class=&quot;z-50&quot;&gt;
            &lt;button type=&quot;button&quot; @click=&quot;imgModalSrc = &#39;&#39;&quot;
              class=&quot;float-right pt-2 pr-2 outline-none focus:outline-none&quot;&gt;
              &lt;svg class=&quot;fill-current text-white &quot;
                xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;18&quot; height=&quot;18&quot;
                viewBox=&quot;0 0 18 18&quot;&gt;
                &lt;path
                  d=&quot;M14.53 4.53l-1.06-1.06L9 7.94 4.53 3.47 3.47 4.53 7.94 9l-4.47 4.47 1.06 1.06L9 10.06l4.47 4.47 1.06-1.06L10.06 9z&quot;&gt;
                &lt;/path&gt;
              &lt;/svg&gt;
            &lt;/button&gt;
          &lt;/div&gt; --&gt;
          &lt;div class=&quot;flex flex-col bg-white&quot;&gt;
            &lt;div class=&quot;flex items-center p-3&quot;&gt;
              &lt;div class=&quot;rounded-full h-12 w-12&quot; style=&quot;background-image: url(&amp;quot;/assets/images/site/patrick-taiwan.jpg&amp;quot;); background-position: center center; background-size: cover;&quot;&gt;&lt;/div&gt;
              &lt;a href=&quot;https://www.instagram.com/patrickxchong/&quot; class=&quot;font-bold ml-3 hover:underline&quot;&gt;
                &lt;p&gt;patrickxchong&lt;/p&gt;
              &lt;/a&gt;
            &lt;/div&gt;
            &lt;img class=&quot;flex-1 object-contain&quot; :src=&quot;imgModalSrc&quot; :alt=&quot;imgModalTitle&quot; /&gt;
            &lt;p x-text=&quot;imgModalTitle&quot; class=&quot;p-3&quot;&gt;&lt;/p&gt;
          &lt;/div&gt;
          &lt;!-- fix bottom padding not showing up with overflow auto --&gt;
          &lt;div class=&quot;pt-4&quot; @click.self=&quot;imgModalSrc = &#39;&#39;&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/template&gt;
  &lt;/div&gt;





  &lt;section x-data=&quot;{}&quot;&gt;
    &lt;div class=&quot;container mx-auto grid gap-2 grid-cols-3&quot;&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Chilli Pan Mee&#39;, src: &#39;/assets/images/cooking/Chilli Pan Mee.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Chilli%20Pan%20Mee.jpg&quot; alt=&quot;Chilli Pan Mee&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Cornbread&#39;, src: &#39;/assets/images/cooking/Cornbread.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Cornbread.jpg&quot; alt=&quot;Cornbread&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Dakgalbi Part 1&#39;, src: &#39;/assets/images/cooking/Dakgalbi1.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Dakgalbi1.jpg&quot; alt=&quot;Dakgalbi Part 1&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Dakgalbi Part 2&#39;, src: &#39;/assets/images/cooking/Dakgalbi2.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Dakgalbi2.jpg&quot; alt=&quot;Dakgalbi Part 2&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Dakgalbi Part 3&#39;, src: &#39;/assets/images/cooking/Dakgalbi3.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Dakgalbi3.jpg&quot; alt=&quot;Dakgalbi Part 3&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Fried Radish Cake&#39;, src: &#39;/assets/images/cooking/Fried Radish Cake.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Fried%20Radish%20Cake.jpg&quot; alt=&quot;Fried Radish Cake&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Jajangmyeon&#39;, src: &#39;/assets/images/cooking/Jajangmyeon.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Jajangmyeon.jpg&quot; alt=&quot;Jajangmyeon&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Japanese Curry + Bun&#39;, src: &#39;/assets/images/cooking/Japanese Curry + Bun.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Japanese%20Curry%20+%20Bun.jpg&quot; alt=&quot;Japanese Curry + Bun&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Mushroom Spinach Pasta&#39;, src: &#39;/assets/images/cooking/Mushroom Spinach Pasta.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Mushroom%20Spinach%20Pasta.jpg&quot; alt=&quot;Mushroom Spinach Pasta&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Nachos&#39;, src: &#39;/assets/images/cooking/Nachos.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Nachos.jpg&quot; alt=&quot;Nachos&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Nangmyeon&#39;, src: &#39;/assets/images/cooking/Nangmyeon.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Nangmyeon.jpg&quot; alt=&quot;Nangmyeon&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Pesto&#39;, src: &#39;/assets/images/cooking/Pesto.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Pesto.jpg&quot; alt=&quot;Pesto&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Ramen and Pork&#39;, src: &#39;/assets/images/cooking/Ramen and Pork.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Ramen%20and%20Pork.jpg&quot; alt=&quot;Ramen and Pork&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Barbecue Ribs&#39;, src: &#39;/assets/images/cooking/Ribs.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Ribs.jpg&quot; alt=&quot;Barbecue Ribs&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;div @click=&quot;$dispatch(&#39;img-modal&#39;, {title: &#39;Saturday Brunch&#39;, src: &#39;/assets/images/cooking/Saturday Brunch.jpg&#39;})&quot; class=&quot;image relative cursor-pointer&quot;&gt;
          &lt;img src=&quot;https://www.patrickxchong.com/assets/images/cooking/Saturday%20Brunch.jpg&quot; alt=&quot;Saturday Brunch&quot; class=&quot;w-full square object-cover object-center&quot; /&gt;
        &lt;/div&gt;&lt;/div&gt;
  &lt;/section&gt;
</content>
    </entry>
    
    <entry>
      <title>Tailwind CSS Components</title>
      <link href="https://www.patrickxchong.com/tailwind-css-components/"/>
      <updated>2021-10-24T13:07:17Z</updated>
      <id>https://www.patrickxchong.com/tailwind-css-components/</id>
      <content type="html">&lt;h3 id=&quot;general-components&quot;&gt;General Components &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/tailwind-css-components/#general-components&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tailwindcomponents.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://tailwindcomponents.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tailwind-kit.com/components&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.tailwind-kit.com/components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tailblocks.cc/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://tailblocks.cc/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gustui.com/docs&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.gustui.com/docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://flowbite.com/docs/components/alerts/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://flowbite.com/docs/components/alerts/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blocks.wickedtemplates.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://blocks.wickedtemplates.com/&lt;/a&gt; (some with Alpine.js)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://postsrc.com/components&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://postsrc.com/components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/narottam04/free-tailwind-components-for-your-next-project-2gka&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;More Tailwind CSS Component resources here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;full-page-demos&quot;&gt;Full Page Demos &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/tailwind-css-components/#full-page-demos&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.creative-tim.com/learning-lab/tailwind-starter-kit/presentation&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.creative-tim.com/learning-lab/tailwind-starter-kit/presentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.wickedtemplates.com/demos&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.wickedtemplates.com/demos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;some-minimal-css-frameworks-as-alternatives-to-tailwind-css&quot;&gt;Some minimal CSS frameworks as alternatives to Tailwind CSS &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/tailwind-css-components/#some-minimal-css-frameworks-as-alternatives-to-tailwind-css&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kognise/water.css&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/kognise/water.css&lt;/a&gt; (3.27kb) - Classless CSS&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/xz/new.css&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/xz/new.css&lt;/a&gt; (4.8kb) - Classless CSS&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/andybrewer/mvp&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/andybrewer/mvp&lt;/a&gt; (8kb) - Classless CSS&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://picturepan2.github.io/spectre/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://picturepan2.github.io/spectre/index.html&lt;/a&gt; (~10KB gzipped) - More of a component framework&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Investment Resources</title>
      <link href="https://www.patrickxchong.com/investment-resources/"/>
      <updated>2021-09-18T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/investment-resources/</id>
      <content type="html">&lt;p&gt;Ongoing collection of resources I found helpful/that I want to refer back to as I begin my investment journey. Contains mixture of Malaysia, US, crypto etc.&lt;/p&gt;
&lt;h2 id=&quot;malaysian-portfolio-updates%2Freference&quot;&gt;Malaysian Portfolio Updates/Reference &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#malaysian-portfolio-updates%2Freference&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dividendmagic.com.my/best-dividend-stocks-in-malaysia/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://dividendmagic.com.my/best-dividend-stocks-in-malaysia/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marcuskeong.com/stock-portfolio-update/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://marcuskeong.com/stock-portfolio-update/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ringgitfreedom.com/category/updates/monthly-review/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://ringgitfreedom.com/category/updates/monthly-review/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mr-stingy.com/tag/portfolio/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.mr-stingy.com/tag/portfolio/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;stock-data-and-charts&quot;&gt;Stock Data and Charts &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#stock-data-and-charts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.klsescreener.com/v2/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.klsescreener.com/v2/&lt;/a&gt; (Malaysia only)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://klse.i3investor.com/index.jsp&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://klse.i3investor.com/index.jsp&lt;/a&gt; (Malaysia only)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://finance.yahoo.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://finance.yahoo.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tradingview.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.tradingview.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.koyfin.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.koyfin.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vig.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://vig.io/&lt;/a&gt; (US only)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;youtube&quot;&gt;Youtube &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#youtube&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ziet Invests: &lt;a href=&quot;https://www.youtube.com/c/ZietInvests&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.youtube.com/c/ZietInvests&lt;/a&gt; (very helpful to starting my investment journey)&lt;/li&gt;
&lt;li&gt;Mr Money TV: &lt;a href=&quot;https://www.youtube.com/c/MrMoneyTV&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.youtube.com/c/MrMoneyTV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SuyinOng: &lt;a href=&quot;https://www.youtube.com/user/SuyinOng26&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.youtube.com/user/SuyinOng26&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Swan Thinks: &lt;a href=&quot;https://www.youtube.com/channel/UCDuyH5z50E8junwzNkCLzDw&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.youtube.com/channel/UCDuyH5z50E8junwzNkCLzDw&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;stock-market-analysis&quot;&gt;Stock Market Analysis &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#stock-market-analysis&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.marketwatch.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.marketwatch.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://seekingalpha.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://seekingalpha.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.investing.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.investing.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.investingnote.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.investingnote.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.dstockmarket.com/stock-market-blog.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;http://www.dstockmarket.com/stock-market-blog.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://finance.yahoo.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://finance.yahoo.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;coding-%2B-trading&quot;&gt;Coding + Trading &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#coding-%2B-trading&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://aroussi.com/tag/python&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://aroussi.com/tag/python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;platforms%2Ftools-i-currently-use%2Fam-exploring&quot;&gt;Platforms/Tools I Currently Use/Am Exploring &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#platforms%2Ftools-i-currently-use%2Fam-exploring&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;malaysia&quot;&gt;Malaysia &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#malaysia&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rakutentrade.my/device/accountopening?referralcode=2e6e1OMLQN&amp;amp;mode=ispeed&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Rakuten&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.stashaway.my/referrals/patrickc69&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Stashaway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://versaapp.onelink.me/1bAf/referral?deep_link_value=LPSGM85Y&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Versa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://promo.fundingsocieties.com.my/referral-program/?r=kql0ek7h&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Funding Societies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;us%2Finternational&quot;&gt;US/International &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#us%2Finternational&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ibkr.com/referral/patrick373&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Interactive Brokers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tdameritrade.com.sg/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;TD Ameritrade Singapore&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;crypto&quot;&gt;Crypto &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/investment-resources/#crypto&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.coinbase.com/join/hua_kj&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Coinbase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Hide Discord Sidebar</title>
      <link href="https://www.patrickxchong.com/hide-discord-sidebar/"/>
      <updated>2021-03-18T15:04:21Z</updated>
      <id>https://www.patrickxchong.com/hide-discord-sidebar/</id>
      <content type="html">&lt;div class=&quot;flex&quot;&gt;
  &lt;a class=&quot;mr-2&quot; href=&quot;https://chrome.google.com/webstore/detail/hide-discord-sidebar/kaaohmdnmbdagpnenakakpkinddjmenp&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img data-eleventy-img=&quot;ignore&quot; src=&quot;https://img.shields.io/chrome-web-store/users/kaaohmdnmbdagpnenakakpkinddjmenp&quot; alt=&quot;Chrome Web Store&quot; /&gt;&lt;/a&gt;
  &lt;a class=&quot;mr-2&quot; href=&quot;https://chrome.google.com/webstore/detail/hide-discord-sidebar/kaaohmdnmbdagpnenakakpkinddjmenp&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img data-eleventy-img=&quot;ignore&quot; src=&quot;https://img.shields.io/chrome-web-store/rating/kaaohmdnmbdagpnenakakpkinddjmenp?label=Chrome&quot; alt=&quot;Chrome Web Store&quot; /&gt;&lt;/a&gt;
  &lt;a class=&quot;mr-2&quot; href=&quot;https://addons.mozilla.org/firefox/addon/hide-discord-sidebar/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img data-eleventy-img=&quot;ignore&quot; src=&quot;https://img.shields.io/amo/rating/hide-discord-sidebar?label=Firefox&quot; alt=&quot;Mozilla Add-ons&quot; /&gt;&lt;/a&gt;
  &lt;a class=&quot;mr-2&quot; href=&quot;https://www.gnu.org/licenses/gpl-3.0&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img data-eleventy-img=&quot;ignore&quot; src=&quot;https://img.shields.io/badge/License-GPLv3-blue.svg&quot; alt=&quot;License: GPL v3&quot; /&gt;&lt;/a&gt;
  &lt;a class=&quot;mr-2&quot; href=&quot;https://github.com/patrickxchong/hide-discord-sidebar&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
    &lt;img data-eleventy-img=&quot;ignore&quot; src=&quot;https://img.shields.io/github/stars/patrickxchong/hide-discord-sidebar.svg?style=social&amp;amp;label=Star&quot; alt=&quot;GitHub stars&quot; /&gt;
  &lt;/a&gt;
  &lt;a class=&quot;mr-2&quot; href=&quot;https://github.com/patrickxchong/hide-discord-sidebar&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
    &lt;img data-eleventy-img=&quot;ignore&quot; src=&quot;https://img.shields.io/github/watchers/patrickxchong/hide-discord-sidebar.svg?style=social&amp;amp;label=Watch&quot; alt=&quot;GitHub watchers&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img data-sizes=&quot;100vw&quot; src=&quot;https://www.patrickxchong.com/assets/images/uploads/hide-discord-sidebar.png&quot; alt=&quot;Hide Discord Sidebar on Chrome screenshot&quot; /&gt;&lt;/p&gt;
&lt;div class=&quot;flex&quot;&gt;
  &lt;a href=&quot;https://bit.ly/Hide-Discord-Bar&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/chrome-webstore.png&quot; alt=&quot;Get Hide Discord Sidebar for Chromium&quot; style=&quot;height: 70px; object-fit: contain&quot; /&gt;
  &lt;/a&gt;
  &lt;a href=&quot;https://addons.mozilla.org/addon/hide-discord-sidebar/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/firefox-get-addon.png&quot; alt=&quot;Get Hide Discord Sidebar for Firefox&quot; style=&quot;height: 70px; object-fit: contain&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;h2 id=&quot;what-is-hide-discord-sidebar%3F&quot;&gt;What is Hide Discord Sidebar? &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/hide-discord-sidebar/#what-is-hide-discord-sidebar%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Hide Discord Sidebar is a Chrome extension for Discord users who find the Discord sidebar too huge and wish to minimize/hide it when they are not using it. This extension minimizes the channels list into a small left sidebar when it is not in use as well as installs a button on the top right corner that hides/shows the Discord server list.&lt;/p&gt;
&lt;h2 id=&quot;how-did-it-come-about%3F&quot;&gt;How did it come about? &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/hide-discord-sidebar/#how-did-it-come-about%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Hide Discord Sidebar a little tool I built to solve a small problem I had. I was using Discord to keep in touch with some friend groups and didn’t like the space taken up by the server and channel sidebars. So I decided to give myself the opportunity to learn how to build a Chrome extension so that I can customize the Discord interface. The code itself is relatively simple. Just some CSS to minimize the channels sidebar initially and to expand it on hover, and a button that hides/shows the server sidebar with Javascript.&lt;/p&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final Thoughts &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/hide-discord-sidebar/#final-thoughts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Fast forward to two years, Hide Discord Sidebar currently has 10000+ users (as of Oct 2023). Although it would require fixing whenever a Discord update breaks it (which happens from time to time), maintaining the extension is relatively painless since I would consider the functionality of the extension to be complete (and so there’s no need to build new features).&lt;/p&gt;
&lt;h2 id=&quot;install-hide-discord-sidebar&quot;&gt;Install Hide Discord Sidebar &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/hide-discord-sidebar/#install-hide-discord-sidebar&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;flex&quot;&gt;
  &lt;a href=&quot;https://bit.ly/Hide-Discord-Bar&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/chrome-webstore.png&quot; alt=&quot;Get Hide Discord Sidebar for Chromium&quot; style=&quot;height: 70px; object-fit: contain&quot; /&gt;
  &lt;/a&gt;
  &lt;a href=&quot;https://addons.mozilla.org/addon/hide-discord-sidebar/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/firefox-get-addon.png&quot; alt=&quot;Get Hide Discord Sidebar for Firefox&quot; style=&quot;height: 70px; object-fit: contain&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Source code: &lt;a href=&quot;https://github.com/patrickxchong/hide-discord-sidebar&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/patrickxchong/hide-discord-sidebar&lt;/a&gt; (Give the repo a star if you like!)&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>Enable Firebase debug mode for Android apps</title>
      <link href="https://www.patrickxchong.com/enable-firebase-debug-mode-for-android-apps/"/>
      <updated>2021-10-02T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/enable-firebase-debug-mode-for-android-apps/</id>
      <content type="html">&lt;ol&gt;
&lt;li&gt;Install Android debug bridge: &lt;a href=&quot;https://www.xda-developers.com/install-adb-windows-macos-linux/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.xda-developers.com/install-adb-windows-macos-linux/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Enable USB debugging on phone (if not already done in step 1): &lt;a href=&quot;https://developer.android.com/studio/command-line/adb#Enabling&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://developer.android.com/studio/command-line/adb#Enabling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Connect your device to your laptop and make sure device shows up in ADB with running this command in the terminal: &lt;code&gt;adb devices&lt;/code&gt; (if not already done in step 1)&lt;/li&gt;
&lt;li&gt;If you don’t know the package name, search for it with the following command:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;adb shell &lt;span class=&quot;token string&quot;&gt;&quot;pm list packages -f &amp;lt;search-term&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Example&lt;/em&gt;&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;adb shell &lt;span class=&quot;token string&quot;&gt;&quot;pm list packages -f telegram&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# output from command&lt;/span&gt;&lt;br /&gt;package:/data/app/org.telegram.messenger-bpV9sE5semiBisZel2YxUA&lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt;/base.apk&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;org.telegram.messenger&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The package name is at the very end of the output(after &lt;code&gt;base.apk=&lt;/code&gt;). In this case, it’s &lt;code&gt;org.telegram.messenger&lt;/code&gt;&lt;/p&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;To enable Firebase debug mode, run this in the terminal:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;adb shell setprop debug.firebase.analytics.app &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;insert package name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Example&lt;/em&gt;&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;adb shell setprop debug.firebase.analytics.app org.telegram.messenger&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;setprop&lt;/code&gt; itself doesn’t output anything, but you can check if the property is set correctly with:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;adb shell getprop debug.firebase.analytics.app&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which should return &lt;code&gt;org.telegram.messenger&lt;/code&gt; if &lt;code&gt;setprop&lt;/code&gt; ran successfully.&lt;/p&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;Congrats, you have successfully enabled Firebase Debug Mode on your device! You can now open the app you’re testing and check Firebase Analytics events sent by your device at the &lt;a href=&quot;https://console.firebase.google.com/project/_/analytics/debugview&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;DebugView page on Firebase&lt;/a&gt;. If you don’t see any events after a few minutes, try restarting the app, that usually triggers the app to start sending debug events.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note: Firebase Debug mode for iOS requires using XCode on a Mac, for more info see here: &lt;a href=&quot;https://firebase.google.com/docs/analytics/debugview&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://firebase.google.com/docs/analytics/debugview&lt;/a&gt;&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>KDE Plasma Notes</title>
      <link href="https://www.patrickxchong.com/kde-plasma-notes/"/>
      <updated>2021-09-04T12:03:14Z</updated>
      <id>https://www.patrickxchong.com/kde-plasma-notes/</id>
      <content type="html">&lt;p&gt;Ongoing list of tips and fixes with KDE Plasma on Manjaro&lt;/p&gt;
&lt;nav class=&quot;table-of-contents&quot;&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#unzip%2Funarchive-files&quot;&gt;Unzip/Unarchive files &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#tiling-window-manager-like-experience-(like-i3)&quot;&gt;Tiling window manager like experience (like i3) &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#open-specific-settings-screens-directly&quot;&gt;Open specific Settings screens directly &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#remember-folder-structure-per-folder-on-dolphin&quot;&gt;Remember folder structure per folder on dolphin &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#windows-like-icon-theme&quot;&gt;Windows like Icon theme &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#xbacklight-command-not-working&quot;&gt;xbacklight command not working &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#launch-.desktop-files-from-command-line&quot;&gt;Launch .desktop files from command line &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#update-application-list-after-creating-.desktop-file&quot;&gt;Update application list after creating .desktop file &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#install-wps-office-and-block-internet&quot;&gt;Install WPS office and block internet &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#setup-fcitx5-for-mandarin-typing-support&quot;&gt;Setup fcitx5 for Mandarin typing support &lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/nav&gt;&lt;h2 id=&quot;unzip%2Funarchive-files&quot;&gt;Unzip/Unarchive files &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#unzip%2Funarchive-files&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of the usual &lt;code&gt;unzip&lt;/code&gt;/&lt;code&gt;tar&lt;/code&gt; commands, KDE has the &lt;code&gt;ark&lt;/code&gt; tool installed to manage archives. &lt;code&gt;ark&lt;/code&gt; is usually accessed via the GUI but can be run in the command line as well. &lt;code&gt;ark&lt;/code&gt; works on various formats such as tar, gzip, bzip2, zip, rar when the appropriate libraries are installed.&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;ark -b -a &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;archive&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&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;/pre&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://metelliuscode.wordpress.com/2009/08/28/tip-of-the-day-quickly-extract-archive-from-command-line-using-ark/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://metelliuscode.wordpress.com/2009/08/28/tip-of-the-day-quickly-extract-archive-from-command-line-using-ark/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.systutorials.com/docs/linux/man/1-ark/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.systutorials.com/docs/linux/man/1-ark/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;tiling-window-manager-like-experience-(like-i3)&quot;&gt;Tiling window manager like experience (like i3) &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#tiling-window-manager-like-experience-(like-i3)&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a href=&quot;https://github.com/esjeon/krohnkite&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Kröhnkite&lt;/a&gt; (KWin Script, take note to follow the instructions in the Enabling User-Configuration and Tips)&lt;/li&gt;
&lt;li&gt;Force windows to start not maximised (so that window borders will show)&lt;br /&gt;
&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/kde-force-not-maximised.png&quot; alt=&quot;Force window not maximised&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Install &lt;a href=&quot;https://www.opencode.net/nightreveller/kwin-move-window-and-focus-to-desktop/-/tree/master/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Move Window and Focus to Desktop&lt;/a&gt; (KWin Script to move window and focus to new desktop in one keyboard shortcut)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are other ways to do this which uses i3 directly (like &lt;a href=&quot;https://www.reddit.com/r/unixporn/comments/64mihc/i3_kde_plasma_a_match_made_in_heaven/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;this Reddit post&lt;/a&gt;), but I couldn’t find a way minimise Zoom to show the mini window (see below) on i3 so I decided to use Kröhnkite instead.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/zoom-mini-window.jpeg&quot; alt=&quot;Zoom Mini Window&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Zoom mini window (image source: &lt;a href=&quot;https://www.law.hawaii.edu/sites/www.law.hawaii.edu/files/Zoom%20Training%20Final.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.law.hawaii.edu/sites/www.law.hawaii.edu/files/Zoom Training Final.pdf&lt;/a&gt;)&lt;/p&gt;
&lt;h2 id=&quot;open-specific-settings-screens-directly&quot;&gt;Open specific Settings screens directly &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#open-specific-settings-screens-directly&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Bluetooth: &lt;code&gt;systemsettings5 bluetooth&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;remember-folder-structure-per-folder-on-dolphin&quot;&gt;Remember folder structure per folder on dolphin &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#remember-folder-structure-per-folder-on-dolphin&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Hamburger button&lt;/code&gt; &amp;gt; &lt;code&gt;Configure&lt;/code&gt; &amp;gt; &lt;code&gt;Configure Dolphin&lt;/code&gt; &amp;gt; &lt;code&gt;General&lt;/code&gt; &amp;gt; &lt;code&gt;Behaviour&lt;/code&gt; &amp;gt; &lt;code&gt;View&lt;/code&gt; &amp;gt; &lt;code&gt;Remember display style for each folder&lt;/code&gt; (as at Dolphin 21.08.0)&lt;/p&gt;
&lt;p&gt;Adapted from: &lt;a href=&quot;https://askubuntu.com/questions/1195505/how-to-change-how-files-are-sorted-in-different-folders-in-dolphin&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://askubuntu.com/questions/1195505/how-to-change-how-files-are-sorted-in-different-folders-in-dolphin&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;windows-like-icon-theme&quot;&gt;Windows like Icon theme &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#windows-like-icon-theme&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://store.kde.org/p/1367155&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;PlasmaXLight&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;xbacklight-command-not-working&quot;&gt;xbacklight command not working &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#xbacklight-command-not-working&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Solution: &lt;a href=&quot;https://askubuntu.com/a/1060843&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://askubuntu.com/a/1060843&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;launch-.desktop-files-from-command-line&quot;&gt;Launch .desktop files from command line &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#launch-.desktop-files-from-command-line&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Helpful to debug/test .desktop files&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;kioclient5 &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;path of .desktop file&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;update-application-list-after-creating-.desktop-file&quot;&gt;Update application list after creating .desktop file &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#update-application-list-after-creating-.desktop-file&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Either of these commands would work depending on the use case&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo update-desktop-database&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;update-desktop-database ~/.local/share/applications&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kbuildsycoca5&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Source: &lt;a href=&quot;https://forum.kde.org/viewtopic.php?f=14&amp;amp;t=167056&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://forum.kde.org/viewtopic.php?f=14&amp;amp;t=167056&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;install-wps-office-and-block-internet&quot;&gt;Install WPS office and block internet &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#install-wps-office-and-block-internet&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most people find success with the &lt;a href=&quot;https://snapcraft.io/wps-2019-snap&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Snap package&lt;/a&gt; that already disables internet, but it seems to only suport Gnome DE (&lt;a href=&quot;https://github.com/cyrpaut/wps-2019-snap/issues/5&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Github issue&lt;/a&gt;). After trying many methods (including setting up &lt;a href=&quot;https://github.com/evilsocket/opensnitch&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;OpenSnitch&lt;/a&gt;), I finally found an easy solution that works well: Install the &lt;a href=&quot;https://flathub.org/apps/details/com.wps.Office&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;flatpak version of WPS Office&lt;/a&gt; and block internet access in the flatpak configuration.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# install flatpak&lt;/span&gt;&lt;br /&gt;flatpak &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; flathub com.wps.Office&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# revoke internet access&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; flatpak override com.wps.Office --unshare&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;network&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;#########################################################&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# if necessary, enable internet access&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; flatpak override com.wps.Office --share&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;network&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;setup-fcitx5-for-mandarin-typing-support&quot;&gt;Setup fcitx5 for Mandarin typing support &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/kde-plasma-notes/#setup-fcitx5-for-mandarin-typing-support&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://jeffreytse.net/computer/2020/11/19/how-to-use-fcitx5-elegantly-on-arch-linux.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://jeffreytse.net/computer/2020/11/19/how-to-use-fcitx5-elegantly-on-arch-linux.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.desktop files can be found at &lt;code&gt;/var/lib/flatpak/exports/share/applications&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I can’t seem to get the flatpak apps to run in GTK+ UI (based on the steps provided at &lt;a href=&quot;https://wiki.archlinux.org/title/WPS_Office#Use_GTK+_UI&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://wiki.archlinux.org/title/WPS_Office#Use_GTK+_UI&lt;/a&gt;), running &lt;code&gt;env GTK2_RC_FILES=/usr/share/themes/Breath/gtk-2.0/gtkrc flatpak run com.wps.Office -style=gtk+&lt;/code&gt; still opens WPS Office in Qt mode, suggestions on how to fix that are welcome!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Sources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://flathub.org/apps/details/com.wps.Office&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://flathub.org/apps/details/com.wps.Office&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://askubuntu.com/a/1320083&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://askubuntu.com/a/1320083&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Data Science Resources</title>
      <link href="https://www.patrickxchong.com/data-science-resources/"/>
      <updated>2021-09-24T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/data-science-resources/</id>
      <content type="html">&lt;p&gt;Ongoing collection of resources I found helpful/that I want to refer back to as I begin my data science journey.&lt;/p&gt;
&lt;h2 id=&quot;tutorials&quot;&gt;Tutorials &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/data-science-resources/#tutorials&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://machinelearningmastery.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://machinelearningmastery.com/&lt;/a&gt; - online blog tutorials&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jovian.ai/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://jovian.ai/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://paperswithcode.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://paperswithcode.com/&lt;/a&gt; - research papers with code&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.freecodecamp.org/learn/machine-learning-with-python/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.freecodecamp.org/learn/machine-learning-with-python/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;nlp&quot;&gt;NLP &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/data-science-resources/#nlp&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://huggingface.co/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://huggingface.co/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Malay based models: &lt;a href=&quot;https://huggingface.co/malay-huggingface/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://huggingface.co/malay-huggingface/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Malay based datasets: &lt;a href=&quot;https://github.com/huseinzol05/malay-dataset&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/huseinzol05/malay-dataset&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;keras-hyperparameter-optimisation&quot;&gt;Keras Hyperparameter Optimisation &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/data-science-resources/#keras-hyperparameter-optimisation&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://towardsdatascience.com/hyperparameter-optimization-with-keras-b82e6364ca53&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://towardsdatascience.com/hyperparameter-optimization-with-keras-b82e6364ca53&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;datasets-(for-machine-learning-practice)&quot;&gt;Datasets (for machine learning practice) &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/data-science-resources/#datasets-(for-machine-learning-practice)&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://archive.ics.uci.edu/ml/datasets.php&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://archive.ics.uci.edu/ml/datasets.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jbrownlee/Datasets&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/jbrownlee/Datasets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Consumer Complaint Database (&lt;a href=&quot;https://www.consumerfinance.gov/data-research/consumer-complaints/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;website&lt;/a&gt;, &lt;a href=&quot;https://files.consumerfinance.gov/ccdb/complaints.csv.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;zip&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;malaysian-datasets&quot;&gt;Malaysian Datasets &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/data-science-resources/#malaysian-datasets&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tindakmalaysia&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/tindakmalaysia&lt;/a&gt; - GeoJSON and election data&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/syazwimazli/my-shapefile&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/syazwimazli/my-shapefile&lt;/a&gt; - GeoJSON data&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/MoH-Malaysia/covid19-public&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/MoH-Malaysia/covid19-public&lt;/a&gt; / &lt;a href=&quot;https://github.com/CITF-Malaysia/citf-public&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/CITF-Malaysia/citf-public&lt;/a&gt; - COVID data&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;others&quot;&gt;Others &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/data-science-resources/#others&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://home.work.caltech.edu/telecourse&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://home.work.caltech.edu/telecourse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kdnuggets.com/data_mining_course/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.kdnuggets.com/data_mining_course/index.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Create Trello Cards from Google Form Responses</title>
      <link href="https://www.patrickxchong.com/create-trello-cards-from-google-form-responses/"/>
      <updated>2021-08-31T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/create-trello-cards-from-google-form-responses/</id>
      <content type="html">&lt;p&gt;The &lt;a href=&quot;https://zapier.com/apps/google-forms/integrations/trello/11016/create-trello-cards-from-new-google-forms-responses&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Zapier integration between Google Form and Trello&lt;/a&gt; only allows one to add color labels and custom text labels separately, but the custom text labels added by Trello were not matched with the right color label. To circumvent that, I created a custom google-apps-script that emails the Google Form response as a card to Trello directly (guide to set up Trello Board email &lt;a href=&quot;https://help.trello.com/article/809-creating-cards-by-email&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;here&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;The script below is used by a feedback form which supports 3 types of feedback: Feature Request, Bug Report, or Other. &lt;code&gt;#Other #Yellow&lt;/code&gt; would create a yellow colored Other label.&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onSubmitHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&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;br /&gt;	&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; itemResponses &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getItemResponses&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;br /&gt;	&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&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;&lt;span class=&quot;token function&quot;&gt;getResponse&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;br /&gt;	&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&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 punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getResponse&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;br /&gt;	&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&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 function&quot;&gt;getResponse&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;br /&gt;	&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; subject&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		attachments &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;br /&gt;&lt;br /&gt;	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Other&#39;&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;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; title &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&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 function&quot;&gt;getResponse&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;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; feedback &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&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 function&quot;&gt;getResponse&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;br /&gt;		subject &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;[Other] &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; #Other #Yellow&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		body &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;&lt;br /&gt;## Message&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;feedback&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&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 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Bug Report&#39;&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;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; title &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&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 function&quot;&gt;getResponse&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;br /&gt;		subject &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;[Bug] &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; #Bug_Report #Red&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;		body &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;&lt;br /&gt;## Description&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&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 function&quot;&gt;getResponse&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 operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;br /&gt;## Device, Operating System, Browser&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&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 function&quot;&gt;getResponse&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 operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;br /&gt;## Additional Context&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&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 function&quot;&gt;getResponse&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 operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&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;br /&gt;			itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&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 function&quot;&gt;getResponse&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 function&quot;&gt;forEach&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 parameter&quot;&gt;fileId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&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;br /&gt;				attachments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DriveApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFileById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fileId&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;getBlob&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;br /&gt;			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&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 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Feature Request&#39;&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;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; title &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&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 function&quot;&gt;getResponse&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;br /&gt;		subject &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;[Feat] &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;title&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; #Feature_Request #Blue&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;		body &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;&lt;br /&gt;## Problem&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&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 function&quot;&gt;getResponse&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 operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;br /&gt;## What feature do you think could help solve that problem?&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&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 function&quot;&gt;getResponse&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 interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;br /&gt;## How would you use the feature you have described?&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&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 function&quot;&gt;getResponse&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 operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;email&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&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;br /&gt;			itemResponses&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&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 function&quot;&gt;getResponse&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 function&quot;&gt;forEach&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 parameter&quot;&gt;fileId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&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;br /&gt;				attachments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DriveApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFileById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fileId&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;getBlob&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;br /&gt;			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;	MailApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendEmail&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;br /&gt;		name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;GForm to Trello&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		to&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;Insert Trello Board Email&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		subject&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		attachments&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;notes&quot;&gt;Notes &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/create-trello-cards-from-google-form-responses/#notes&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Data returned by Google Form’s On Form Submit trigger: &lt;a href=&quot;https://developers.google.com/apps-script/guides/triggers/events?hl=en#form-submit_1&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://developers.google.com/apps-script/guides/triggers/events?hl=en#form-submit_1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Seems like the data could be easier to manipulate through the use of the &lt;code&gt;namedValues&lt;/code&gt; field when setup with a &lt;a href=&quot;https://developers.google.com/apps-script/guides/triggers/events?hl=en#form-submit&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Form Submit trigger on &lt;strong&gt;Google Sheets&lt;/strong&gt;&lt;/a&gt; instead, but I’ve not tried that yet.&lt;/li&gt;
&lt;li&gt;DriveApp.getFileById(fileId).getBlob() - used to handle File Upload fields on the Google Form, and the files would be attached to the Trello card created by the email. More details &lt;a href=&quot;https://developers.google.com/apps-script/reference/drive/drive-app#getfilebyidid&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;MailApp.sendEmail does the final step of emailing the form to Trello.&lt;/li&gt;
&lt;/ol&gt;
</content>
    </entry>
    
    <entry>
      <title>Automating Daily Site Rebuilds</title>
      <link href="https://www.patrickxchong.com/automating-daily-site-rebuilds/"/>
      <updated>2021-08-24T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/automating-daily-site-rebuilds/</id>
      <content type="html">&lt;h2 id=&quot;steps&quot;&gt;Steps &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#steps&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new project at &lt;a href=&quot;https://script.google.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://script.google.com/&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Paste one of the scripts below into &lt;code&gt;Code.gs&lt;/code&gt;.&lt;br /&gt;
a. &lt;a href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#simple-daily&quot;&gt;Simple Daily&lt;/a&gt;&lt;br /&gt;
b. &lt;a href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#complex-daily&quot;&gt;Complex Daily&lt;/a&gt;&lt;br /&gt;
c. &lt;a href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#complex-generic&quot;&gt;Complex Generic&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modify as desired with URLs/webhooks from &lt;a href=&quot;https://vercel.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Vercel&lt;/a&gt;/&lt;a href=&quot;https://netlify.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Netlify&lt;/a&gt; etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test code by running dailyCron function from editor (will be prompted to authenticate on the first time).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to &lt;strong&gt;Triggers&lt;/strong&gt; on the left sidebar (has the clock icon).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select Add Trigger and modify the settings based on the image below:&lt;br /&gt;
&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/daily-cron-trigger-settings.png&quot; alt=&quot;Daily Cron trigger settings&quot; width=&quot;50%&quot; height=&quot;100%&quot; style=&quot;min-width: 280px&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hit &lt;strong&gt;Save&lt;/strong&gt; and you’re done!&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;simple-daily&quot;&gt;Simple Daily &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#simple-daily&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; dailyList &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 string&quot;&gt;&#39;&amp;lt;insert url&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dailyCron&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;br /&gt;	dailyList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&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 parameter&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&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;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;			method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;get&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; UrlFetchApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;		Logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&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; url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response &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 comment&quot;&gt;// log the URL and the response&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;complex-daily&quot;&gt;Complex Daily &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#complex-daily&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; dailyList &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;		url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;insert url&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;			method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;get&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;		url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;insert url&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;			method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;post&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;			contentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;application/json&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;			payload&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&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;br /&gt;				message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;hello world&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&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;br /&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dailyCron&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;br /&gt;	dailyList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&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 parameter&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&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;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; UrlFetchApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;		Logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&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; url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;complex-generic&quot;&gt;Complex Generic &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#complex-generic&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; dailyList &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;		url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;insert url&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;			method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;get&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;		url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;insert url&gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;		options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;			method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;post&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;			contentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;application/json&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;			payload&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&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;br /&gt;				message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;hello world&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&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;br /&gt;		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; monthlyList &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token comment&quot;&gt;/* similar structure to dailyList */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dailyCron&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;br /&gt;	&lt;span class=&quot;token function&quot;&gt;cronHelper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dailyList&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;monthlyCron&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;br /&gt;	&lt;span class=&quot;token function&quot;&gt;cronHelper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;monthlyList&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cronHelper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;list&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;br /&gt;	list&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&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 parameter&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&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;br /&gt;		&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; UrlFetchApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;		Logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&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; url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;notes&quot;&gt;Notes &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#notes&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Inspired by &lt;a href=&quot;https://www.11ty.dev/docs/quicktips/netlify-ifttt/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Trigger a Netlify Build Every Day with IFTTT&lt;/a&gt;. Created the code in google-apps-script so that it’s more flexible/extensible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the desire is to save the results, then creating the script in connection to Google Sheets would work better.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Function is named dailyCron/monthlyCron after the Linux &lt;a href=&quot;https://en.wikipedia.org/wiki/Cron&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;cron&lt;/a&gt; utility&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An webtool that works for simple use cases is: &lt;a href=&quot;https://cron-job.org/en/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://cron-job.org/en/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;limitations-of-google-apps-script&quot;&gt;Limitations of google-apps-script &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/automating-daily-site-rebuilds/#limitations-of-google-apps-script&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Script runtime: 6 min/execution (all accounts)&lt;/li&gt;
&lt;li&gt;URL Fetch calls: 20,000/day (normal Google accounts), 100,000/day (Google Workspace accounts)&lt;/li&gt;
&lt;li&gt;Source: &lt;a href=&quot;https://developers.google.com/apps-script/guides/services/quotas&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://developers.google.com/apps-script/guides/services/quotas&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Why I rebuilt my blog with Eleventy</title>
      <link href="https://www.patrickxchong.com/why-i-rebuilt-my-blog-with-eleventy/"/>
      <updated>2021-08-15T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/why-i-rebuilt-my-blog-with-eleventy/</id>
      <content type="html">&lt;p&gt;My first intro to Javascript frontend frameworks is through &lt;a href=&quot;https://github.com/vuejs/vue&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Vue.js&lt;/a&gt; in 2017. I really like Vue’s &lt;a href=&quot;https://vuejs.org/v2/guide/single-file-components.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Single File Components&lt;/a&gt; and how similar the Vue syntax is to HTML. Naturally, I transitioned to the batteries loaded &lt;a href=&quot;https://github.com/nuxt/nuxt.js&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Nuxt.js&lt;/a&gt; that already sets up Vue Router, Vuex, SSR etc under the hood. In fact I built the first iteration of this blog with Nuxt’s &lt;a href=&quot;https://nuxtjs.org/docs/2.x/concepts/static-site-generation&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;static mode&lt;/a&gt; and the very helpful &lt;a href=&quot;https://github.com/nuxt/content&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Nuxt Content&lt;/a&gt; module.&lt;/p&gt;
&lt;p&gt;As much as the status quo works, I’ve never been very happy with the long Javascript build process, the large Javascript bundles that are created (and have to be downloaded), and the Vue.js hydration process that needs to happen on the client-side. Given these limitations, I started looking for better alternatives. After all, the main reason why I like Vue is because I could create reusable components. For the most part, I was looking for &lt;strong&gt;templating&lt;/strong&gt;, not &lt;strong&gt;reactivity&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;There are already common templating languages such as &lt;a href=&quot;https://github.com/pugjs/pug&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Pug&lt;/a&gt;, &lt;a href=&quot;https://github.com/handlebars-lang/handlebars.js&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Handlebars&lt;/a&gt; and &lt;a href=&quot;https://www.npmjs.com/package/mustache&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Mustache&lt;/a&gt;, but they’re often used with servers like &lt;a href=&quot;https://github.com/expressjs/express&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Express&lt;/a&gt;, and there aren’t a ton of places to host a server for free with no downtime/cold starts. I’m sure there’s a way to prerender a site using Express with one of the template languages above and some Markdown files, it doesn’t seem to be a very common solution.&lt;/p&gt;
&lt;p&gt;Hence I began my SSG exploration! I tried &lt;a href=&quot;https://github.com/gohugoio/hugo&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Hugo&lt;/a&gt; and &lt;a href=&quot;https://github.com/11ty/eleventy&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Eleventy&lt;/a&gt;. Hugo because it is touted as the &lt;a href=&quot;https://css-tricks.com/comparing-static-site-generator-build-times&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;most performant solution&lt;/a&gt;. Eleventy because it has gathered a lot of traction despite being quite new, and is currently powering &lt;a href=&quot;https://web.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;web.dev&lt;/a&gt;, &lt;a href=&quot;https://www.a11yproject.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;A11y Project&lt;/a&gt; and &lt;a href=&quot;https://eslint.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;eslint.org&lt;/a&gt;, organisations that care a lot about best practices (which I assume to mean that Eleventy does conform to their definition of best practices).&lt;/p&gt;
&lt;p&gt;My limited experience with &lt;em&gt;Hugo&lt;/em&gt; was quite confusing. I tried and retried a couple of starter templates but felt stuck trying to understand Hugo’s &lt;code&gt;config.toml&lt;/code&gt; and templating syntax, as well as working out a development process with asset compilation in the theme folder and Hugo’s own site generation process. Overall my takeaway was that &lt;strong&gt;It’s hard to customise a Hugo site, especially with limited Go experience&lt;/strong&gt;. Since I do want to be able to customise freely, and didn’t want to spend too much time trying to figure out Go, I decided to not pursue Hugo for now (though I’m pretty sure I’ll revisit it someday).&lt;/p&gt;
&lt;p&gt;Which leads me to Eleventy, which was much easier to understand since it’s all Javascript. I did run into some teething troubles, mostly with trying to recreate Vue Single File components in Eleventy (There’s &lt;a href=&quot;https://github.com/11ty/eleventy-plugin-vue&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;eleventy-plugin-vue&lt;/a&gt;, but I wasn’t too keen on trying that as it’s pretty experimental). I ended up using the &lt;a href=&quot;https://github.com/mozilla/nunjucks&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Nunjucks&lt;/a&gt; template language because it’s similar to Python’s &lt;a href=&quot;https://github.com/pallets/jinja/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Jinja2&lt;/a&gt; that I have experience with. Nunjuck’s &lt;a href=&quot;https://mozilla.github.io/nunjucks/templating.html#macro&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Macros&lt;/a&gt; and Eleventy’s &lt;a href=&quot;https://www.11ty.dev/docs/shortcodes/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;shortcodes + paired shortcodes&lt;/a&gt; provided a functional way to create components, although I definitely wish for a nicer syntax to create universal components/paired shortcodes in Eleventy instead of declaring them in Javascript strings. I was stuck with slow rebuilds in development with the starter template that I used, but that gave me an opportunity to peek under the hood of how Eleventy works, and it’s really suprising how &lt;strong&gt;easy&lt;/strong&gt; it was to create an &lt;a href=&quot;https://github.com/patrickxchong/eleventy-plugin-svg-sprite&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Eleventy plugin&lt;/a&gt; with the fix that I came up with (blog post coming soon on that).&lt;/p&gt;
&lt;p&gt;And there we have it, why I ended up rebuilding this blog with Eleventy. Appreciate the very supportive Eleventy community on Discord who have helped me with my questions. Eleventy isn’t perfect, but it’s pretty good at its job right now and it’s still improving. I look forward to how much more awesome it will be when V1 is launched! 😍&lt;/p&gt;
&lt;p&gt;Edit 1:&lt;br /&gt;
I use &lt;a href=&quot;https://github.com/alpinejs/alpine&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Alpine.js&lt;/a&gt; as a replacement for Vue.js on this blog. I’ve not mixed Alpine components with Nunjucks macros yet, but I do foresee possible issues with code duplication when declaring Alpine components with the &lt;a href=&quot;https://alpinejs.dev/globals/alpine-data&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Alpine Data&lt;/a&gt; syntax. Will have to explore further on this.&lt;/p&gt;
&lt;p&gt;P.S. It was pretty exciting to get a 100 Lighthouse score on mobile, not surprising since Eleventy itself doesn’t inject any scripts, and &lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Eleventy Img&lt;/a&gt; handles image processing so well. Thankfully &lt;a href=&quot;https://github.com/alpinejs/alpine&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Alpine.js&lt;/a&gt; and the &lt;a href=&quot;https://github.com/tailwindlabs/tailwindcss&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Tailwind CSS&lt;/a&gt; (with PurgeCSS) have minimal impact on the site’s load time.&lt;/p&gt;
&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/lighthouse-100.png&quot; alt=&quot;Patrick Chong blog lighthouse score&quot; width=&quot;100%&quot; height=&quot;100%&quot; /&gt;
</content>
    </entry>
    
    <entry>
      <title>Just Hang In There</title>
      <link href="https://www.patrickxchong.com/just-hang-in-there/"/>
      <updated>2021-08-07T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/just-hang-in-there/</id>
      <content type="html">&lt;blockquote&gt;
&lt;p&gt;Just hang in there&lt;br /&gt;
You will get there&lt;br /&gt;
It’s fine to shed a little tear&lt;br /&gt;
When things are just too much to bear &lt;br /&gt;&lt;br /&gt;
Just hang in there&lt;br /&gt;
You will get there&lt;br /&gt;
It’s fine to share your fears and struggles&lt;br /&gt;
With the people that you care&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lyrics for this song came to me in one of my lower moments. I just finished an exam, and was walking home in the dark in the middle of the winter to join a Zoom meeting. It’s been a tiring and busy season, but as I trudged home, the words ‘Just hang in there’ were stuck in my head.&lt;/p&gt;
&lt;p&gt;As I experimented with rhyming, the verses started to form: &lt;code&gt;&amp;quot;It’s fine to shed a little tear when things are just too much to bear&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;It’s fine to share your fears and struggles with the people that you care&amp;quot;&lt;/code&gt;, an apt reflection of my feelings at that moment. A melody started to form as I continued to walk and by the time I arrive home I couldn’t wait to find the right chords to the song in my mind.&lt;/p&gt;
&lt;p&gt;The vibe of the song is quite influenced by &lt;a href=&quot;https://www.youtube.com/channel/UCdAFRh3rxx0Q_xxkS2_N2PA&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Jayesslee&lt;/a&gt;’s more jazzy songs like &lt;a href=&quot;https://open.spotify.com/track/47vHy3Z7oTrCyjHZmkKn4M?si=74f8b7f2c1b947f4&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Officially Missing You&lt;/a&gt; with a more bossa nova vibe. Here are two versions of the song produced so far:&lt;/p&gt;
&lt;h4 id=&quot;version-produced-by-patrick&quot;&gt;Version produced by Patrick &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/just-hang-in-there/#version-produced-by-patrick&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;166&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/542798061&amp;color=%23ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;show_teaser=true&quot;&gt;&lt;/iframe&gt;
&lt;h4 id=&quot;version-produced-with-fools-for-thought&quot;&gt;Version produced with Fools For Thought &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/just-hang-in-there/#version-produced-with-fools-for-thought&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;iframe src=&quot;https://open.spotify.com/embed/track/5vqCAqdMGUiADyEGFVhflg&quot; width=&quot;100%&quot; height=&quot;80&quot; frameBorder=&quot;0&quot; allowtransparency=&quot;true&quot; allow=&quot;encrypted-media&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;PS. I’ve been trying to write verses to the chorus but have yet to find anything that really resonates. Do drop a comment below if you have any ideas!&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>Battery Notifications in Linux</title>
      <link href="https://www.patrickxchong.com/battery-notifications-in-linux/"/>
      <updated>2021-07-10T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/battery-notifications-in-linux/</id>
      <content type="html">&lt;h2 id=&quot;bash-script&quot;&gt;Bash Script &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/battery-notifications-in-linux/#bash-script&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Put this anywhere and make the script file executable with with &lt;code&gt;chmod +x&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# watch --interval=5&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;CAPACITY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; /sys/class/power_supply/BAT0/capacity&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;STATUS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; /sys/class/power_supply/BAT0/status&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;if&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 variable&quot;&gt;${CAPACITY}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${STATUS}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Charging&quot;&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;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;&lt;br /&gt;  /usr/bin/notify-send -u critical &lt;span class=&quot;token string&quot;&gt;&quot;Battery&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Disconnect Charger. Battery is above 80%&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;elif&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 variable&quot;&gt;${CAPACITY}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${STATUS}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Discharging&quot;&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;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;&lt;br /&gt;  /usr/bin/notify-send -u critical &lt;span class=&quot;token string&quot;&gt;&quot;Connect Charger. Battery&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Battery is below 20%&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;crontab-script&quot;&gt;Crontab script &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/battery-notifications-in-linux/#crontab-script&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Schedule to run script every 2 minutes&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# for notify-send to work&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;DISPLAY&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;:0.0&lt;br /&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;XAUTHORITY&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/home/&lt;span class=&quot;token environment constant&quot;&gt;$LOGNAME&lt;/span&gt;/.Xauthority&lt;br /&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;DBUS_SESSION_BUS_ADDRESS&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;unix:path&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/run/user/1000/bus&lt;br /&gt;&lt;br /&gt;*/2 * * * * &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;location of script&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Guide: &lt;a href=&quot;https://crontab.guru/#*/2_*_*_*_*&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://crontab.guru/#*/2_*_*_*_*&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;why-keep-laptop-battery-between-80-20-percent&quot;&gt;Why keep laptop battery between 80-20 percent &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/battery-notifications-in-linux/#why-keep-laptop-battery-between-80-20-percent&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Have to admit that I had a hard time finding reputable sources, but I guess it could be true if many sources are saying the same thing?&lt;/p&gt;
&lt;p&gt;Example Sources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.wired.co.uk/article/how-to-improve-battery-life-tips-myths-smartphones&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.wired.co.uk/article/how-to-improve-battery-life-tips-myths-smartphones&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.choice.com.au/electronics-and-technology/phones/mobile-phones/articles/how-to-care-for-phone-and-laptop-lithium-batteries&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.choice.com.au/electronics-and-technology/phones/mobile-phones/articles/how-to-care-for-phone-and-laptop-lithium-batteries&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;bonus%3A-windows-powershell-battery-notification-script&quot;&gt;Bonus: Windows PowerShell Battery Notification script &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/battery-notifications-in-linux/#bonus%3A-windows-powershell-battery-notification-script&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Not experienced with PowerShell at all, but managed to hack this to work on my Windows installation. Use at your own risk!&lt;/p&gt;
&lt;pre class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Requires -Version 3.0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$lowBattery&lt;/span&gt; = 21&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$chargedBattery&lt;/span&gt; = 80&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$delayIntervalMinutes&lt;/span&gt; = 2&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;Add-Type&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;AssemblyName System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Windows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Forms&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;Add-Type&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;AssemblyName PresentationFramework&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# Doesn&#39;t seem like there&#39;s a powershell way to do this,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;Add-Type&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ReferencedAssemblies @&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;System.Windows.Forms&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;System.Drawing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;TypeDefinition @&lt;span class=&quot;token string&quot;&gt;&quot;&lt;br /&gt;    using System;&lt;br /&gt;    using System.Drawing;&lt;br /&gt;    using System.Windows.Forms;&lt;br /&gt;    public static class TextNotifyIcon&lt;br /&gt;    {&lt;br /&gt;        // it&#39;s difficult to call DestroyIcon() with powershell only...&lt;br /&gt;        [System.Runtime.InteropServices.DllImport(&quot;&lt;/span&gt;user32&lt;span class=&quot;token string&quot;&gt;&quot;)]&lt;br /&gt;        private static extern bool DestroyIcon(IntPtr hIcon);&lt;br /&gt;&lt;br /&gt;        public static void UpdateIcon(NotifyIcon notifyIcon, string text)&lt;br /&gt;        {&lt;br /&gt;            using (var b = new Bitmap(16, 16))&lt;br /&gt;            using (var g = Graphics.FromImage(b))&lt;br /&gt;            using (var font = new Font(FontFamily.GenericMonospace, 8))&lt;br /&gt;            {&lt;br /&gt;                g.DrawString(text, font, Brushes.White, 0, 0);&lt;br /&gt;&lt;br /&gt;                var icon = b.GetHicon();&lt;br /&gt;                try&lt;br /&gt;                {&lt;br /&gt;                    notifyIcon.Icon = Icon.FromHandle(icon);&lt;br /&gt;                } finally&lt;br /&gt;                {&lt;br /&gt;                    DestroyIcon(icon);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&quot;&lt;/span&gt;@&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;= &lt;span class=&quot;token function&quot;&gt;New-Object&lt;/span&gt; System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Windows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Forms&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;NotifyIcon&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Visible = &lt;span class=&quot;token boolean&quot;&gt;$true&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BalloonTipIcon = &lt;span class=&quot;token namespace&quot;&gt;[System.Windows.Forms.ToolTipIcon]&lt;/span&gt;::Warning&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; showBalloon&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$text&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;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BalloonTipTitle = &lt;span class=&quot;token variable&quot;&gt;$title&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BalloonTipText = &lt;span class=&quot;token variable&quot;&gt;$text&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ShowBalloonTip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;20000&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; showMessageBox&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$text&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;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;$ButtonType&lt;/span&gt; = &lt;span class=&quot;token namespace&quot;&gt;[System.Windows.MessageBoxButton]&lt;/span&gt;::OK&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;$MessageIcon&lt;/span&gt; = &lt;span class=&quot;token namespace&quot;&gt;[System.Windows.MessageBoxImage]&lt;/span&gt;::Error&lt;br /&gt;  &lt;span class=&quot;token variable&quot;&gt;$Result&lt;/span&gt; = &lt;span class=&quot;token namespace&quot;&gt;[System.Windows.MessageBox]&lt;/span&gt;::Show&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ButtonType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$MessageIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; checkBattery&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;br /&gt;    &lt;span class=&quot;token variable&quot;&gt;$batteryLevel&lt;/span&gt; = &lt;span class=&quot;token function&quot;&gt;Get-CimInstance&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ClassName Win32_Battery &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Measure-Object&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Property EstimatedChargeRemaining &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Average &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Select-Object&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ExpandProperty Average&lt;br /&gt;    &lt;span class=&quot;token variable&quot;&gt;$charging&lt;/span&gt; = &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Get-CimInstance&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ClassName Win32_Battery &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Select-Object&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ExpandProperty BatteryStatus&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-ne&lt;/span&gt; 1&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$charging&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-and&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$batteryLevel&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-ge&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$chargedBattery&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; 5&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;br /&gt;        showMessageBox &lt;span class=&quot;token string&quot;&gt;&quot;Battery at 85%&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Please unplug charger&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;#done charging&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$charging&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-and&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$batteryLevel&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-ge&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$chargedBattery&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;br /&gt;        showBalloon &lt;span class=&quot;token string&quot;&gt;&quot;Battery at 80%&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Please unplug charger&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;#low battery warning&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;elseif&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$charging&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-and&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$batteryLevel&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-le&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$lowBattery&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;br /&gt;        showBalloon &lt;span class=&quot;token string&quot;&gt;&quot;Battery at 20%&quot;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Please plug in charger&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token comment&quot;&gt;# $notifyIcon.Text = &quot;Battery $batteryLevel%&quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;# $batteryLevel = [DateTime]::Now.Second.ToString()&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token namespace&quot;&gt;[TextNotifyIcon]&lt;/span&gt;::UpdateIcon&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$batteryLevel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; exitApp&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;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;# $balmsg.dispose()&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token variable&quot;&gt;$delayTimer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dispose&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token variable&quot;&gt;$contextMenu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dispose&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dispose&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;# $appContext.dispose()&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;Stop-Process&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$PID&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token namespace&quot;&gt;[system.gc]&lt;/span&gt;::Collect&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token comment&quot;&gt;# Exit&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$contextMenu&lt;/span&gt; = &lt;span class=&quot;token function&quot;&gt;New-Object&lt;/span&gt; System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Windows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Forms&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContextMenu&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$notifyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContextMenu = &lt;span class=&quot;token variable&quot;&gt;$contextMenu&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;#Add Trigger MenuItem&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$menuTrigger&lt;/span&gt; = &lt;span class=&quot;token function&quot;&gt;New-Object&lt;/span&gt; System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Windows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Forms&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MenuItem &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ArgumentList &lt;span class=&quot;token string&quot;&gt;&quot;Trigger&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$menuTrigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_Click&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    checkBattery&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$contextMenu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MenuItems&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AddRange&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$menuTrigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;#Add Exit MenuItem&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$menuExit&lt;/span&gt; = &lt;span class=&quot;token function&quot;&gt;New-Object&lt;/span&gt; System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Windows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Forms&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MenuItem &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ArgumentList &lt;span class=&quot;token string&quot;&gt;&quot;Exit&quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$menuExit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_Click&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    exitApp&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$contextMenu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MenuItems&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AddRange&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$menuExit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;#timer&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$delayTimer&lt;/span&gt; = &lt;span class=&quot;token function&quot;&gt;New-Object&lt;/span&gt; System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Windows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Forms&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Timer&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$delayTimer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Interval = &lt;span class=&quot;token variable&quot;&gt;$delayIntervalMinutes&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; 60 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; 1000&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$delayTimer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;add_Tick&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;checkBattery&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$delayTimer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;start&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;br /&gt;&lt;br /&gt;checkBattery&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# Create an application context for it to all run within.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# This helps with responsiveness, especially when clicking Exit.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token variable&quot;&gt;$appContext&lt;/span&gt; = &lt;span class=&quot;token function&quot;&gt;New-Object&lt;/span&gt; System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Windows&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Forms&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ApplicationContext&lt;br /&gt;&lt;span class=&quot;token namespace&quot;&gt;[void]&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;[System.Windows.Forms.Application]&lt;/span&gt;::Run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$appContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content>
    </entry>
    
    <entry>
      <title>Prayer</title>
      <link href="https://www.patrickxchong.com/prayer/"/>
      <updated>2020-10-18T16:13:28Z</updated>
      <id>https://www.patrickxchong.com/prayer/</id>
      <content type="html">&lt;ul&gt;
&lt;li&gt;Prayer exposes sin. Just like any rightful worship of god should magnify His glory and our need for his grace. It requires commitment and repentance. (Paul E. Miller, A Praying Life)&lt;/li&gt;
&lt;li&gt;Pray about what your mind is wandering to. Maybe it is something that is important to you. Maybe the Spirit is nudging you to think about something else. (Paul E. Miller, A Praying Life)&lt;/li&gt;
&lt;li&gt;When you know that you (like Jesus) can’t do life on your own, then prayer makes perfect sense. (Paul E. Miller, A Praying Life)&lt;/li&gt;
&lt;li&gt;If you are not praying, then you are quietly confident that time, money and talent are all your need in life. You’ll always be a little too tired, a little too busy. But if, like Jesus, you realize you can’t do life on your own, then no matter how busy, no matter how tired you are, you will find time to pray. (Paul E. Miller, A Praying Life)&lt;/li&gt;
&lt;li&gt;If we think we can do life on our own, we will not take prayer seriously.&lt;/li&gt;
&lt;li&gt;Our failure to pray will always feel like something else - a lack of discipline or too many obligations. (Paul E. Miller, A Praying Life)&lt;/li&gt;
&lt;li&gt;To become more like Jesus is to feel increasingly unable to do life, increasingly wary of your heart. (Paul E. Miller, A Praying Life)&lt;/li&gt;
&lt;li&gt;The prayer of a Christian is not an attempt to force God’s hand, but a humble acknowledgment of helplessness and dependence. When we are on our knees, we know that it is not we who control the world; it is not in our power, therefore, to supply our needs by our own independent efforts; every good thing that we desire for ourselves and for others must be sought from God, and will come, if it comes at all, as a gift from his hands. If this is true even of our daily bread (and the Lord’s Prayer teaches us that it is), much more is it true of spiritual benefits. This is all luminously clear to us when we are actually praying, whatever we may be betrayed into saying in argument afterward. In effect, therefore, what we do every time we pray is to confess our own impotence and God’s sovereignty. The very fact that a Christian prays is thus proof positive that he believes in the lordship of his God. (J. I. Packer, Evangelism and the Sovereignty of God)&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Remove file extensions from path when querying with @nuxt/content</title>
      <link href="https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/"/>
      <updated>2020-09-09T08:13:52Z</updated>
      <id>https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/</id>
      <content type="html">&lt;nav class=&quot;table-of-contents&quot;&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/#problem&quot;&gt;Problem &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/#what-happened%3F&quot;&gt;What happened? &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/#solution&quot;&gt;Solution &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/#final-thoughts&quot;&gt;Final Thoughts &lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/nav&gt;&lt;h2 id=&quot;problem&quot;&gt;Problem &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/#problem&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I was migrating this blog from &lt;a href=&quot;https://github.com/hmsk/frontmatter-markdown-loader&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;hmsk/frontmatter-markdown-loader&lt;/code&gt;&lt;/a&gt; to &lt;a href=&quot;https://github.com/nuxt/content&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;@nuxt/content&lt;/code&gt;&lt;/a&gt; to make use of &lt;code&gt;@nuxt/content&lt;/code&gt;’s powerful Markdown query features and faced a weird bug when I was setting things up. I adapted the code from &lt;a href=&quot;https://content.nuxtjs.org/fetching&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://content.nuxtjs.org/fetching&lt;/a&gt; but got:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/nuxt_content_request_failed.png&quot; alt=&quot;Nuxt content request failed&quot; /&gt;&lt;/p&gt;
&lt;p&gt;But when I visited the url at &lt;code&gt;http://localhost:3000/_content/pages/home.md&lt;/code&gt;, I see the Markdown file&lt;br /&gt;
&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/nuxt_content_request_successful.png&quot; alt=&quot;Nuxt content request successful&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-happened%3F&quot;&gt;What happened? &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/#what-happened%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After trying everything from disabling buildModules/modules/loaders to referring to the example at &lt;a href=&quot;https://github.com/nuxt-company/demo-blog-nuxt-content&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/nuxt-company/demo-blog-nuxt-content&lt;/a&gt; to setting up a new Nuxt project with the content module enabled with yarn create nuxt-app. I finally realized what I did wrong.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@nuxt/content&lt;/code&gt;’s API is &lt;code&gt;$content(path, options?)&lt;/code&gt;, and the properties of &lt;code&gt;path&lt;/code&gt; listed on their &lt;a href=&quot;https://content.nuxtjs.org/fetching#contentpath-options&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;documentation&lt;/a&gt; is:&lt;/p&gt;
&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Type: String&lt;br /&gt;Default: /&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which I took to be the full path of the file (in this case &lt;code&gt;pages/home.md&lt;/code&gt;). So I ended up doing&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// pages/index.vue&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;asyncData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $content&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error &lt;span class=&quot;token punctuation&quot;&gt;}&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;$content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pages/home.md&quot;&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 function&quot;&gt;fetch&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;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      page&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function&quot;&gt;error&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; statusCode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Post not found&#39;&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;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&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;br /&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;/pre&gt;
&lt;p&gt;Which led to the weird situation where the markdown file wasn’t fetched in asyncData, but somehow worked when I visited the request URL directly (this is likely a bug/not expected behaviour since the &lt;a href=&quot;https://content.nuxtjs.org/advanced#api-endpoint&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;documentation&lt;/a&gt; also specifies that the API endpoint should be queried without the file extensions.&lt;/p&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/#solution&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The fix was simple. All I had to do was to remove the file extension from the page and everything worked beautifully!&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// pages/index.vue&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;$content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;pages/home&#39;&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 function&quot;&gt;fetch&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;/pre&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final Thoughts &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/remove-file-extensions-from-path-when-querying-with-nuxt/content/#final-thoughts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Despite wasting more than half a day trying to figure out this lame if-only-I-understood-the-docs better/if-only-the-docs-had-better-examples bug, I was quite happy with how easily I can query, filter, sort through the markdown files with the &lt;code&gt;@nuxt/content&lt;/code&gt; API. It’s way better compared to the queries I wrote last time to power this blog. &lt;code&gt;@nuxt/content&lt;/code&gt; plays very well with Netlify CMS as well, quite excited to add in features (like search) with the capabilities of &lt;code&gt;@nuxt/content&lt;/code&gt;!&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>Convert Vue To Android with Ionic Capacitor And CircleCI</title>
      <link href="https://www.patrickxchong.com/convert-vue-to-android-with-ionic-capacitor-and-circleci/"/>
      <updated>2020-06-20T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/convert-vue-to-android-with-ionic-capacitor-and-circleci/</id>
      <content type="html">&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I would recommend anyone using Vue.js and wants to turn their webapp into a mobile app to checkout &lt;a href=&quot;https://quasar.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Quasar&lt;/a&gt;. They do it very well out of the box!&lt;/p&gt;
&lt;h2 id=&quot;what-is-ionic-capacitor%3F&quot;&gt;What is Ionic Capacitor? &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/convert-vue-to-android-with-ionic-capacitor-and-circleci/#what-is-ionic-capacitor%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Capacitor is a cross-platform app runtime that makes it easy to build web apps that run natively on iOS, Android, and the web. - From &lt;a href=&quot;https://capacitor.ionicframework.com/docs/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Capacitor Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Capacitor is created by the Ionic framework (which is why I refer to it as Ionic Capacitor) In this case, I will use Capacitor compile a Vue.js app into a native Android debug apk that can be installed into Android phones.&lt;/p&gt;
&lt;h2 id=&quot;what-is-circleci%3F&quot;&gt;What is CircleCI? &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/convert-vue-to-android-with-ionic-capacitor-and-circleci/#what-is-circleci%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;CircleCI automates your software builds, tests, and deployments. - From &lt;a href=&quot;https://circleci.com/docs/2.0/about-circleci/#section=getting-started&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;CircleCI Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;CircleCI integrates really well with Github and allows users to build executables, run tests and release software.&lt;/p&gt;
&lt;h2 id=&quot;demo-source&quot;&gt;Demo Source &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/convert-vue-to-android-with-ionic-capacitor-and-circleci/#demo-source&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For the purposes of this demonstration, I made a fork from an existing Hackernews clone built by Vue at &lt;a href=&quot;https://github.com/vuejs/vue-hackernews-2.0&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/vuejs/vue-hackernews-2.0&lt;/a&gt; and made some modifications to it so that it uses vue-cli-service instead of SSR.&lt;/p&gt;
&lt;p&gt;I then built the project with &lt;code&gt;yarn build&lt;/code&gt; (which calls &lt;code&gt;vue-cli-service build&lt;/code&gt;) which compiles the project as an spa into the &lt;code&gt;/dist&lt;/code&gt; folder.&lt;/p&gt;
&lt;h2 id=&quot;adding-capacitor&quot;&gt;Adding Capacitor &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/convert-vue-to-android-with-ionic-capacitor-and-circleci/#adding-capacitor&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add Capacitor to the Vue.js project, run &lt;code&gt;yarn add @capacitor/core @capacitor/cli&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then &lt;code&gt;npx cap init&lt;/code&gt; to initalize the Capacitor project.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/npx-cap-init.png&quot; alt=&quot;Output of npx cap init&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The command will create a &lt;code&gt;capacitor.config.json&lt;/code&gt; in the root of the project. Here is the defaults in &lt;code&gt;capacitor.config.json&lt;/code&gt; after running &lt;code&gt;npx cap init&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// capacitor.config.json&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;appId&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;com.hackernews.vue&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;appName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vue-hackernews-2.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;bundledWebRuntime&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;npmClient&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;yarn&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;webDir&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;www&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;plugins&quot;&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;br /&gt;    &lt;span class=&quot;token string&quot;&gt;&quot;SplashScreen&quot;&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;br /&gt;      &lt;span class=&quot;token string&quot;&gt;&quot;launchShowDuration&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;cordova&quot;&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;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT!!!&lt;/strong&gt; The webDir in our case using Vue is &lt;code&gt;/dist&lt;/code&gt; so we’ll have to change it from &lt;code&gt;www&lt;/code&gt; to &lt;code&gt;dist&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To enable android in our project, run &lt;code&gt;npx cap add android&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This creates an &lt;code&gt;/android&lt;/code&gt; folder and adds &lt;code&gt;@capacitor/android&lt;/code&gt; as a dependency in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For now I don’t see a good reason to keep the android folder in version control since the contents will change whenever the project is updated so I added &lt;code&gt;android&lt;/code&gt; into &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I then run &lt;code&gt;npx cap sync&lt;/code&gt; to update android dependencies, and copy web assets into the Android project.&lt;/p&gt;
&lt;p&gt;And just like that, the webapp is Android ready!&lt;/p&gt;
&lt;p&gt;One can run &lt;code&gt;npx cap open android&lt;/code&gt; to open the project in Android Studio if Android Studio is installed.&lt;/p&gt;
&lt;h2 id=&quot;adding-circleci&quot;&gt;Adding CircleCI &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/convert-vue-to-android-with-ionic-capacitor-and-circleci/#adding-circleci&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since I don’t have Android Studio installed on my laptop (and I wasn’t interested to do so since Android Studio is pretty large), I decided to try using CircleCI to build the project. There are 3 main parts to the script I made:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;build_yarn: install dependencies and run &lt;code&gt;npx cap add android&lt;/code&gt; and &lt;code&gt;npx cap sync&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;build_android: build debug apk with &lt;code&gt;gradlew&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;publish-github-release: publish debug apk as a release on Github&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note 1: I created a config file at &lt;code&gt;/config/Android/AndroidManifest.xml&lt;/code&gt; which will be copied into the &lt;code&gt;/android&lt;/code&gt; folder during the build time on CircleCI so that I can reduce the number of permissions that the app requests. (Have to remember to change the package name in &lt;code&gt;AndroidManifest.xml&lt;/code&gt; else the app will not open)&lt;/p&gt;
&lt;p&gt;Note 2: I set up the use of &lt;code&gt;ghr&lt;/code&gt; in &lt;code&gt;publish-github-release&lt;/code&gt; based on the tutorial here: &lt;a href=&quot;https://circleci.com/blog/publishing-to-github-releases-via-circleci/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://circleci.com/blog/publishing-to-github-releases-via-circleci/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The completed script is as follows&lt;/p&gt;
&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# .circleci/config.yml&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token key atrule&quot;&gt;workflows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;build-test-and-deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&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;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; build_yarn&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;build_android&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;requires&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; build_yarn&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;publish-github-release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;requires&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; build_android&lt;br /&gt;&lt;br /&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;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;build_yarn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; circleci/node&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;10&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;browsers&lt;br /&gt;    &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;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; checkout&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;restore_cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&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; Restore Node Modules Cache&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; yarn&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;modules&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; checksum &quot;yarn.lock&quot; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ls node_modules &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; yarn install &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;frozen&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;lockfile&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;save_cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&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; Save Node Modules Cache&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; yarn&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;modules&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; checksum &quot;yarn.lock&quot; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; node_modules&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; yarn build&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npx cap add android&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; npx cap sync&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;persist_to_workspace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; android&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ./*&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;build_android&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; circleci/android&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;api&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;29&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token key atrule&quot;&gt;JVM_OPTS&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;Xmx3200m&lt;br /&gt;    &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;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; checkout&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;attach_workspace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token comment&quot;&gt;# Must be absolute path or relative path from working_directory&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; android&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;restore_cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&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; Restore Node Modules Cache&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; yarn&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;modules&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; checksum &quot;yarn.lock&quot; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;restore_cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; jars&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; checksum &quot;android/build.gradle&quot; &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; checksum  &quot;android/build.gradle&quot; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &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;br /&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; Chmod permissions &lt;span class=&quot;token comment&quot;&gt;#if permission for Gradlew Dependencies fail, use this.&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sudo chmod +x ./android/gradlew&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &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;br /&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; Download Dependencies&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cd android &lt;span class=&quot;token important&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./gradlew androidDependencies &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;debug&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;save_cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ~/.gradle&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; jars&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; checksum &quot;android/build.gradle&quot; &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; checksum  &quot;android/build.gradle&quot; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &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;br /&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; Copy configuration files&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cp config/Android/AndroidManifest.xml android/app/src/main/AndroidManifest.xml&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &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 comment&quot;&gt;# https://developer.android.com/studio/build/building-cmdline This creates an APK named module_name-debug.apk in project_name/module_name/build/outputs/apk/&lt;/span&gt;&lt;br /&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; Build debug APK and release APK&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;command&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 scalar string&quot;&gt;&lt;br /&gt;            cd android&lt;br /&gt;            ./gradlew :app:assembleDebug&lt;br /&gt;            ./gradlew :app:assembleRelease&lt;br /&gt;            ./gradlew :app:assembleDebugAndroidTest&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &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;br /&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; Run Tests&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cd android &lt;span class=&quot;token important&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./gradlew lint test&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;store_artifacts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# for display in Artifacts: https://circleci.com/docs/2.0/artifacts/&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; android/app/build/reports&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; reports&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;store_artifacts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# for display in Artifacts: https://circleci.com/docs/2.0/artifacts/&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; android/app/build/outputs/apk&lt;br /&gt;      &lt;span class=&quot;token comment&quot;&gt;# - store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token comment&quot;&gt;#     path: android/app/src/main/assets/public&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;store_test_results&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; android/app/build/test&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;results&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;persist_to_workspace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; android/app/build/outputs&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ./apk/*&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token key atrule&quot;&gt;publish-github-release&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token key atrule&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cibuilds/github&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.10&lt;/span&gt;&lt;br /&gt;    &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;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;attach_workspace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ./android&lt;br /&gt;      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &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;br /&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; &lt;span class=&quot;token string&quot;&gt;&#39;Publish Release on GitHub&#39;&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token key atrule&quot;&gt;command&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 scalar string&quot;&gt;&lt;br /&gt;            mv android/apk/debug/app-debug.apk android/apk&lt;br /&gt;            mv android/apk/release/app-release-unsigned.apk android/apk&lt;br /&gt;            ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_BUILD_NUM} ./android/apk/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The debug apk which can be installed into any Android phone can be found here: &lt;a href=&quot;https://github.com/patrickxchong/vue-hackernews-2.0/releases/tag/8&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/patrickxchong/vue-hackernews-2.0/releases/tag/8&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;All in all I’m pretty pleased with how it turned out! It has quite a native look and feel to it. It was a good opportunity for me to work with CircleCI and learn the differences between caches, workspaces and artifacts on the platform as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://capacitor.ionicframework.com/docs/getting-started&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://capacitor.ionicframework.com/docs/getting-started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://capacitor.ionicframework.com/docs/android&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://capacitor.ionicframework.com/docs/android&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    </entry>
    
    <entry>
      <title>Domain Name and Personal Branding</title>
      <link href="https://www.patrickxchong.com/domain-name-and-personal-branding/"/>
      <updated>2020-05-20T01:07:05Z</updated>
      <id>https://www.patrickxchong.com/domain-name-and-personal-branding/</id>
      <content type="html">&lt;p&gt;After getting a good part of this site together, I thought that it would be cool to get a personal domain name for the site. A quick search on popular domain name providers brought me to &lt;a href=&quot;https://www.namecheap.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Namecheap&lt;/a&gt; where I found out that a .com domain only costs USD8.88 for a year! 😮 That’s about the price of a cheap meal in the US, or in the case of Malaysia, USD 8.88 = ~RM36 which is about the price of 4 decent meals. The price is incredible. Also, since generally registering a new domain name is cheaper than renewing it (on Namecheap it’s $8.88 to register and $12.98 to renew). I decided to buy the domain name for 10 years to save more money upfront.&lt;/p&gt;
&lt;p&gt;While looking at domain hosting options, I did a price comparison with &lt;a href=&quot;https://godaddy.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;GoDaddy&lt;/a&gt; which is another popular option and found out that Namecheap is MUCH CHEAPER. Below is the cost comparison between the two:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GoDaddy&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Namecheap&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RM639.50&lt;/td&gt;
&lt;td&gt;Cost of domain for 10 years&lt;/td&gt;
&lt;td&gt;USD88.80 (~RM360)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RM399.90&lt;/td&gt;
&lt;td&gt;WHOIS Guard (to protect your personal information attached to the domain name) for 10 years&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RM1101.76&lt;/td&gt;
&lt;td&gt;Total with taxes and fees&lt;/td&gt;
&lt;td&gt;USD90.60 (~RM393.52)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Going with Namecheap saves me up to ~RM700 (~USD 160), which in my opinion is quite a decent amount of money. With the domain registrar settled, I then went on a long quest of what domain name I should use. I did want to stick with a .com domain because it’s the cheapest but given how long the .com domain has existed, A LOT of names have been taken. These are some of the ones that I’ve considered but were taken:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;patrickchong.com (of course)&lt;/li&gt;
&lt;li&gt;pa3ck.com (Pa - three - ck, get it? heh)&lt;/li&gt;
&lt;li&gt;pa3k.com (same logic as above)&lt;/li&gt;
&lt;li&gt;patrickc.com&lt;/li&gt;
&lt;li&gt;cpatrick.com&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After checking off all the names that were taken, this was the shortlist that I ended up with, and the reasons why I disqualified the respective possible domain names:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chongpatrick.com (seems a lil weird)&lt;/li&gt;
&lt;li&gt;patrickcjh.com (not a fan of the shortform)&lt;/li&gt;
&lt;li&gt;pa3kchong.com (all the ones with the numbers start looking more like a spam site and less professional/smart when it’s meshed up with other words)&lt;/li&gt;
&lt;li&gt;p3kweb.com&lt;/li&gt;
&lt;li&gt;pa3fy.com&lt;/li&gt;
&lt;li&gt;patriqchong.com (works, but a little lame)&lt;/li&gt;
&lt;li&gt;patrick-chong.com (not a fan of the dash in there)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://patrickxchong.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;patrickxchong.com&lt;/a&gt; (the domain I bought!)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All in all I decided to go with &lt;a href=&quot;http://patrickxchong.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;patrickxchong.com&lt;/a&gt; because&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;One of my first emails was patrickxchong[at]gmail[dot]com, and I still use it to this day.&lt;/li&gt;
&lt;li&gt;It doesn’t look too bad with the ‘x’ in there and it still carries a professional look if I have it on my namecard/resume.&lt;/li&gt;
&lt;li&gt;After checking with &lt;a href=&quot;https://namechk.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Namechk&lt;/a&gt;, it seems like patrickxchong is not quite a common username on a lot of platforms yet. So I took it as an opportunity for me to build a consistent personal brand under the &lt;code&gt;patrickxchong&lt;/code&gt; name.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So with those thoughts, I bought my personal domain name of &lt;a href=&quot;http://patrickxchong.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;patrickxchong.com&lt;/a&gt; on Namecheap!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/namecheap-domain-registration.png&quot; alt=&quot;Image of patrickxchong.com domain registration on Namecheap&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Only time will tell whether this investment in personal branding with pay off, or if it’s necessary at all. Aside from Twitter, I’ve found that I could change my username on most major platforms to &lt;code&gt;patrickxchong&lt;/code&gt;. A list of all the platforms that I have an account with can be found at the &lt;a href=&quot;https://www.patrickxchong.com/contact&quot;&gt;Contact&lt;/a&gt; page.&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>Scrabble Text</title>
      <link href="https://www.patrickxchong.com/scrabble-text/"/>
      <updated>2020-05-12T02:31:10Z</updated>
      <id>https://www.patrickxchong.com/scrabble-text/</id>
      <content type="html">&lt;p&gt;I was quite into the scrabble theme after &lt;a href=&quot;https://www.patrickxchong.com/patrickxchong-site-favicon/&quot;&gt;making the favicon for this site&lt;/a&gt; and hence decided to build on it by creating scrabble theme headings! I believe it can be better/made more dynamic by making the padding sizes more responsive to the font size. I’ll try to do that before incorporating it as a vue component on this site. Check the Codepen below for what I have right now:&lt;/p&gt;
&lt;iframe height=&quot;288&quot; style=&quot;width: 100%;&quot; scrolling=&quot;no&quot; title=&quot;Scrabble Text&quot; src=&quot;https://codepen.io/patrickxchong/embed/mdeLLjo?height=288&amp;theme-id=dark&amp;default-tab=css,result&quot; frameborder=&quot;no&quot; allowtransparency=&quot;true&quot; allowfullscreen=&quot;true&quot;&gt;
  See the Pen &lt;a href=&quot;https://codepen.io/patrickxchong/pen/mdeLLjo&quot;&gt;Scrabble Text&lt;/a&gt; by Patrick Chong Jin Hua
  (&lt;a href=&quot;https://codepen.io/patrickxchong&quot;&gt;@patrickxchong&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io/&quot;&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;</content>
    </entry>
    
    <entry>
      <title>Crash Nitro Kart Rescore</title>
      <link href="https://www.patrickxchong.com/crash-nitro-kart-rescore/"/>
      <updated>2020-04-26T06:12:39Z</updated>
      <id>https://www.patrickxchong.com/crash-nitro-kart-rescore/</id>
      <content type="html">&lt;section class=&quot;py-4 border-t-4 border-b-4 sm:py-6 mt-12 mb-12&quot;&gt;
&lt;p class=&quot;m-0 font-bold text-center sm:text-xl&quot;&gt;
Crash and Burn &lt;br /&gt; And do it all over again
&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&quot;inspiration&quot;&gt;Inspiration &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/crash-nitro-kart-rescore/#inspiration&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I’ve always had fond memories of the Crash Bandicoot racing games because they remind me of the days in middle school when I used to play the game with my friends on the Playstation. Here’s a snippet of gameplay footage when four people are playing at the same time:&lt;/p&gt;
&lt;div class=&quot;embed-container&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/5TZL1hyg0k0?t=46&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;If you noticed, the backing track is pretty quiet and simple during the race. There’s just a little percussion to keep the pace of the race going, and the main sounds that the player hears are the exhaust of the cars and sound effects of the power-ups. So I thought, why not try to create a more interesting backing track for the race? For the piece to sound more like the real deal, I decided to take certain motifs from the main theme of Crash Nitro Kart and build on them to create a brand new race track. Here’s the Crash Nitro Kart Theme:&lt;/p&gt;
&lt;div class=&quot;embed-container&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/G_FD6SyEKxY&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h2 id=&quot;composition-process&quot;&gt;Composition Process &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/crash-nitro-kart-rescore/#composition-process&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In terms of the vibe of the game, Crash Nitro Kart is a wacky and fun racing game. I tried my best to stay true to the feel of the theme music, which has a lot of syncopation with a certain funkiness that comes from the C minor pentatonic scale centered note choice.&lt;br /&gt;
I also attempted to imitate the instrumentation of the theme music by using similar sounding marimbas and brass instruments because I felt that they were iconic to the theme, and developed the other instruments around those sounds.&lt;/p&gt;
&lt;h2 id=&quot;software&quot;&gt;Software &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/crash-nitro-kart-rescore/#software&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I used Ableton to do my composition and arrangement. However, I found the drum sounds in Ableton really subpar so I used Garage Band’s Drummer feature on my iPad to create some drum loops that fit what I needed for the track, exported them to Google Drive, and then imported them into Ableton on my laptop. I played all the other instruments (Marimba, Bass, Strings, Brass) using my laptop keyboard.&lt;/p&gt;
&lt;p&gt;I added the gameplay video in because I feel that it gives listeners a good sense of what’s going on. I also found some royalty-free sport car sounds from &lt;a href=&quot;http://zapsplat.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Zapsplat.com&lt;/a&gt; and added them to the track because the “feel” was incomplete without it. What’s a racing game track without the sound of car engines right?&lt;/p&gt;
&lt;p&gt;After I was done with the race track, I decided to try a hand at creating some pre-race sounds and a post-race victory track to make a more holistic video game rescore experience. Here’s the completed piece, enjoy!&lt;/p&gt;
&lt;div class=&quot;embed-container&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/STaOq2fts28&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final Thoughts &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/crash-nitro-kart-rescore/#final-thoughts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I found the rescoring process quite difficult when using existing motifs because it was hard initially to break away from the preexisting melodic lines that I’m used to hearing, but it worked out with some experimentation. Overall I was quite satisfied with what I created, and it was a very refreshing experience sitting in the driver’s seat (pun intended) to dictate how the music should affect the game experience.&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>PatrickxChong Site Favicon</title>
      <link href="https://www.patrickxchong.com/patrickxchong-site-favicon/"/>
      <updated>2020-04-26T04:07:05Z</updated>
      <id>https://www.patrickxchong.com/patrickxchong-site-favicon/</id>
      <content type="html">&lt;p&gt;I’m still in the midst of figuring out the mood/vibe of this site, but a site definitely needs an original favicon. so I decided to experiment with a favicon generator at &lt;a href=&quot;https://favicon.io/favicon-generator/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://favicon.io/favicon-generator/&lt;/a&gt;. The end result is a favicon that looks like a Scrabble tile, which I felt was kinda apt. Scrabble tiles are a bit like a lego pieces. You can build words with them, rearrange them to make another word, there’s endless possibilities! (well one can argue that the number of words are finite, but I’m optimistic that mankind will continue inventing words). Below are the settings that I used to generate the favicon (can also be accessed &lt;a href=&quot;https://favicon.io/favicon-generator/?t=P&amp;amp;ff=Mako&amp;amp;fs=100&amp;amp;fc=%23222&amp;amp;b=rounded&amp;amp;bc=%23FDA&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&quot;favicon-generator-with-color-settings&quot;&gt;Favicon Generator with color settings &lt;a class=&quot;header-anchor&quot; href=&quot;https://www.patrickxchong.com/patrickxchong-site-favicon/#favicon-generator-with-color-settings&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://www.patrickxchong.com/assets/images/uploads/favicon-generator.png&quot; alt=&quot;An image that shows that the favicon generated uses the Mako font with font-size 100, a font color of #222 and background color of #FDA.&quot; /&gt;&lt;/p&gt;
</content>
    </entry>
    
    <entry>
      <title>First Personal Site!</title>
      <link href="https://www.patrickxchong.com/first-personal-site/"/>
      <updated>2020-04-24T02:07:05Z</updated>
      <id>https://www.patrickxchong.com/first-personal-site/</id>
      <content type="html">&lt;p&gt;Yay I finally have a personal site! 😄&lt;/p&gt;
&lt;p&gt;Been on my mind for a good number of years now. I did some digging and found a template at &lt;a href=&quot;https://github.com/Gomah/bluise&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/Gomah/bluise&lt;/a&gt; that uses NuxtJS, Tailwind CSS and Netlify CMS. I’m familiar with Nuxt/Vue.JS and have been wanting to get my hands dirty with Tailwind CSS and Netlify CMS, so this is a pretty cool opportunity. Looking forward to playing around with the site more!&lt;/p&gt;
</content>
    </entry>
</feed>