~humaid/huma.id

49a17d364e2431530a8fa5e0b4e1387b074ba085 — Humaid AlQassimi 2 years ago
Open-source release
115 files changed, 3809 insertions(+), 0 deletions(-)

A .gitignore
A LICENSE
A archetypes/default.md
A config.toml
A content/_index.md
A content/blog/_index.md
A content/blog/best-articles-2018.md
A content/blog/gopher.md
A content/blog/gopher/gopher.png
A content/blog/hall-of-fame.md
A content/blog/kudu-two-year.md
A content/blog/kudu-two-year/artifacts.jpg
A content/blog/kudu-two-year/old-cable.jpg
A content/blog/own-distro-p1.md
A content/blog/own-distro-p1/desktop.png
A content/blog/own-distro-p1/output.png
A content/blog/qnap.md
A content/blog/status-update-1.md
A content/blog/status-update-1/notes-overflow-alpha.png
A content/blog/welcome.md
A content/blog/yubi.md
A content/contact/pgp.txt
A content/contribution/_index.md
A content/contribution/c-contribution.md
A content/contribution/code-of-conduct.md
A content/contribution/go-contribution.md
A content/contribution/mailing.md
A content/gallery-faq.md
A content/gallery/_index.md
A content/gallery/apply-rot.sh
A content/gallery/artis-zoo.md
A content/gallery/edinburgh-citycentre.md
A content/gallery/holyrood.md
A content/gallery/hortus-botanicus.md
A content/gallery/make-thumbs.sh
A content/gallery/morning-heriot-watt.md
A content/gallery/optimise.sh
A content/gallery/rijksmuseum.md
A content/gallery/stedelijk.md
A content/now/_index.md
A content/projects/4DG.md
A content/projects/CowChina.md
A content/projects/G1MDecompiler.md
A content/projects/JukeboxHopperMod.md
A content/projects/Questions.md
A content/projects/SpongePluginsArchive.md
A content/projects/WhatsMorse.md
A content/projects/XMath.md
A content/projects/_index.md
A content/projects/bmo.md
A content/projects/bmo/blushing.gif
A content/projects/bmo/happy.png
A content/projects/bmo/happyblink.gif
A content/projects/bmo/simplesmile.png
A content/projects/bmo/simplesmileblink.gif
A content/projects/bmo/sleeping.gif
A content/projects/bmo/straightface.png
A content/projects/bmo/worried.png
A content/projects/cloudflare-ddns-client.md
A content/projects/f27wd-cw2-nonamewebteam.md
A content/projects/ff-format-patch.md
A content/projects/ff-format-patch/ff
A content/projects/ff-format-patch/steps-format-v1.patch
A content/projects/godoc2markdown.md
A content/projects/hmsh.md
A content/projects/horse-site.md
A content/projects/hstatus.md
A content/projects/iglu.md
A content/projects/learning-bot.md
A content/projects/neatnote.md
A content/projects/ns2-trace-go.md
A content/projects/oww-prot.md
A content/projects/pew-pew-shooter.md
A content/projects/pomodoro.md
A content/projects/screenshots/4DG.gif
A content/projects/screenshots/4DG.png
A content/projects/screenshots/JukeboxHopperMod.gif
A content/projects/screenshots/JukeboxHopperMod.png
A content/projects/screenshots/WhatsMorse.gif
A content/projects/screenshots/WhatsMorse.png
A content/projects/screenshots/ns2-analysis.png
A content/projects/screenshots/yabfig.jpg
A content/projects/shopsheet.md
A content/projects/sifrOS.md
A content/projects/xmath/XMath.aia
A content/projects/yabfig.md
A content/xmath-pp/_index.md
A static/favicon.png
A static/humans.txt
A static/img/me-2020-fulldef.jpg
A static/img/me-2020.jpg
A static/pkg.go.dev-reference-blue.svg
A static/robots.txt
A themes/humaidq-theme/archetypes/default.md
A themes/humaidq-theme/layouts/404.html
A themes/humaidq-theme/layouts/_default/list.html
A themes/humaidq-theme/layouts/_default/single.html
A themes/humaidq-theme/layouts/_internal/pagination.html
A themes/humaidq-theme/layouts/blog/list.html
A themes/humaidq-theme/layouts/blog/single.html
A themes/humaidq-theme/layouts/gallery/list.html
A themes/humaidq-theme/layouts/gallery/single.html
A themes/humaidq-theme/layouts/language/list.html
A themes/humaidq-theme/layouts/partials/footer.html
A themes/humaidq-theme/layouts/partials/header.html
A themes/humaidq-theme/layouts/projects/list.html
A themes/humaidq-theme/layouts/projects/single.html
A themes/humaidq-theme/static/css/main.css
A themes/humaidq-theme/static/css/main.min.css
A themes/humaidq-theme/static/css/normalize-8.0.1.min.css
A themes/humaidq-theme/static/css/webring.css
A themes/humaidq-theme/static/css/webring.min.css
A themes/humaidq-theme/theme.toml
A usability.txt
A webring-in.html
A  => .gitignore +8 -0
@@ 1,8 @@
public/
*.log
*.iso*
*.bz2
content/gallery/*/
layouts/partials/webring-out.html
layouts/partials/webring-out.html
Makefile

A  => LICENSE +378 -0
@@ 1,378 @@
All code (any source code or scripts) on this repository is licensed under
BSD-2 Clause license, unless stated otherwise. License code is included below.

	BSD 2-Clause License

	Copyright (c) 2020, Humaid AlQassimi. All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	* Redistributions of source code must retain the above copyright notice, this
	  list of conditions and the following disclaimer.

	* Redistributions in binary form must reproduce the above copyright notice,
	  this list of conditions and the following disclaimer in the documentation
	  and/or other materials provided with the distribution.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
	FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
	DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
	OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
	OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

All content (Markdown files, images, videos, etc) on this repository is
licensed under the CC BY-SA 4.0, unless stated otherwise. License code is
included below.

	By exercising the Licensed Rights (defined below), You accept and agree
	to be bound by the terms and conditions of this Creative Commons
	Attribution-ShareAlike 4.0 International Public License ("Public
	License"). To the extent this Public License may be interpreted as a
	contract, You are granted the Licensed Rights in consideration of Your
	acceptance of these terms and conditions, and the Licensor grants You
	such rights in consideration of benefits the Licensor receives from
	making the Licensed Material available under these terms and
	conditions.


	Section 1 -- Definitions.

	  a. Adapted Material means material subject to Copyright and Similar
		 Rights that is derived from or based upon the Licensed Material
		 and in which the Licensed Material is translated, altered,
		 arranged, transformed, or otherwise modified in a manner requiring
		 permission under the Copyright and Similar Rights held by the
		 Licensor. For purposes of this Public License, where the Licensed
		 Material is a musical work, performance, or sound recording,
		 Adapted Material is always produced where the Licensed Material is
		 synched in timed relation with a moving image.

	  b. Adapter's License means the license You apply to Your Copyright
		 and Similar Rights in Your contributions to Adapted Material in
		 accordance with the terms and conditions of this Public License.

	  c. BY-SA Compatible License means a license listed at
		 creativecommons.org/compatiblelicenses, approved by Creative
		 Commons as essentially the equivalent of this Public License.

	  d. Copyright and Similar Rights means copyright and/or similar rights
		 closely related to copyright including, without limitation,
		 performance, broadcast, sound recording, and Sui Generis Database
		 Rights, without regard to how the rights are labeled or
		 categorized. For purposes of this Public License, the rights
		 specified in Section 2(b)(1)-(2) are not Copyright and Similar
		 Rights.

	  e. Effective Technological Measures means those measures that, in the
		 absence of proper authority, may not be circumvented under laws
		 fulfilling obligations under Article 11 of the WIPO Copyright
		 Treaty adopted on December 20, 1996, and/or similar international
		 agreements.

	  f. Exceptions and Limitations means fair use, fair dealing, and/or
		 any other exception or limitation to Copyright and Similar Rights
		 that applies to Your use of the Licensed Material.

	  g. License Elements means the license attributes listed in the name
		 of a Creative Commons Public License. The License Elements of this
		 Public License are Attribution and ShareAlike.

	  h. Licensed Material means the artistic or literary work, database,
		 or other material to which the Licensor applied this Public
		 License.

	  i. Licensed Rights means the rights granted to You subject to the
		 terms and conditions of this Public License, which are limited to
		 all Copyright and Similar Rights that apply to Your use of the
		 Licensed Material and that the Licensor has authority to license.

	  j. Licensor means the individual(s) or entity(ies) granting rights
		 under this Public License.

	  k. Share means to provide material to the public by any means or
		 process that requires permission under the Licensed Rights, such
		 as reproduction, public display, public performance, distribution,
		 dissemination, communication, or importation, and to make material
		 available to the public including in ways that members of the
		 public may access the material from a place and at a time
		 individually chosen by them.

	  l. Sui Generis Database Rights means rights other than copyright
		 resulting from Directive 96/9/EC of the European Parliament and of
		 the Council of 11 March 1996 on the legal protection of databases,
		 as amended and/or succeeded, as well as other essentially
		 equivalent rights anywhere in the world.

	  m. You means the individual or entity exercising the Licensed Rights
		 under this Public License. Your has a corresponding meaning.


	Section 2 -- Scope.

	  a. License grant.

		   1. Subject to the terms and conditions of this Public License,
			  the Licensor hereby grants You a worldwide, royalty-free,
			  non-sublicensable, non-exclusive, irrevocable license to
			  exercise the Licensed Rights in the Licensed Material to:

				a. reproduce and Share the Licensed Material, in whole or
				   in part; and

				b. produce, reproduce, and Share Adapted Material.

		   2. Exceptions and Limitations. For the avoidance of doubt, where
			  Exceptions and Limitations apply to Your use, this Public
			  License does not apply, and You do not need to comply with
			  its terms and conditions.

		   3. Term. The term of this Public License is specified in Section
			  6(a).

		   4. Media and formats; technical modifications allowed. The
			  Licensor authorizes You to exercise the Licensed Rights in
			  all media and formats whether now known or hereafter created,
			  and to make technical modifications necessary to do so. The
			  Licensor waives and/or agrees not to assert any right or
			  authority to forbid You from making technical modifications
			  necessary to exercise the Licensed Rights, including
			  technical modifications necessary to circumvent Effective
			  Technological Measures. For purposes of this Public License,
			  simply making modifications authorized by this Section 2(a)
			  (4) never produces Adapted Material.

		   5. Downstream recipients.

				a. Offer from the Licensor -- Licensed Material. Every
				   recipient of the Licensed Material automatically
				   receives an offer from the Licensor to exercise the
				   Licensed Rights under the terms and conditions of this
				   Public License.

				b. Additional offer from the Licensor -- Adapted Material.
				   Every recipient of Adapted Material from You
				   automatically receives an offer from the Licensor to
				   exercise the Licensed Rights in the Adapted Material
				   under the conditions of the Adapter's License You apply.

				c. No downstream restrictions. You may not offer or impose
				   any additional or different terms or conditions on, or
				   apply any Effective Technological Measures to, the
				   Licensed Material if doing so restricts exercise of the
				   Licensed Rights by any recipient of the Licensed
				   Material.

		   6. No endorsement. Nothing in this Public License constitutes or
			  may be construed as permission to assert or imply that You
			  are, or that Your use of the Licensed Material is, connected
			  with, or sponsored, endorsed, or granted official status by,
			  the Licensor or others designated to receive attribution as
			  provided in Section 3(a)(1)(A)(i).

	  b. Other rights.

		   1. Moral rights, such as the right of integrity, are not
			  licensed under this Public License, nor are publicity,
			  privacy, and/or other similar personality rights; however, to
			  the extent possible, the Licensor waives and/or agrees not to
			  assert any such rights held by the Licensor to the limited
			  extent necessary to allow You to exercise the Licensed
			  Rights, but not otherwise.

		   2. Patent and trademark rights are not licensed under this
			  Public License.

		   3. To the extent possible, the Licensor waives any right to
			  collect royalties from You for the exercise of the Licensed
			  Rights, whether directly or through a collecting society
			  under any voluntary or waivable statutory or compulsory
			  licensing scheme. In all other cases the Licensor expressly
			  reserves any right to collect such royalties.


	Section 3 -- License Conditions.

	Your exercise of the Licensed Rights is expressly made subject to the
	following conditions.

	  a. Attribution.

		   1. If You Share the Licensed Material (including in modified
			  form), You must:

				a. retain the following if it is supplied by the Licensor
				   with the Licensed Material:

					 i. identification of the creator(s) of the Licensed
						Material and any others designated to receive
						attribution, in any reasonable manner requested by
						the Licensor (including by pseudonym if
						designated);

					ii. a copyright notice;

				   iii. a notice that refers to this Public License;

					iv. a notice that refers to the disclaimer of
						warranties;

					 v. a URI or hyperlink to the Licensed Material to the
						extent reasonably practicable;

				b. indicate if You modified the Licensed Material and
				   retain an indication of any previous modifications; and

				c. indicate the Licensed Material is licensed under this
				   Public License, and include the text of, or the URI or
				   hyperlink to, this Public License.

		   2. You may satisfy the conditions in Section 3(a)(1) in any
			  reasonable manner based on the medium, means, and context in
			  which You Share the Licensed Material. For example, it may be
			  reasonable to satisfy the conditions by providing a URI or
			  hyperlink to a resource that includes the required
			  information.

		   3. If requested by the Licensor, You must remove any of the
			  information required by Section 3(a)(1)(A) to the extent
			  reasonably practicable.

	  b. ShareAlike.

		 In addition to the conditions in Section 3(a), if You Share
		 Adapted Material You produce, the following conditions also apply.

		   1. The Adapter's License You apply must be a Creative Commons
			  license with the same License Elements, this version or
			  later, or a BY-SA Compatible License.

		   2. You must include the text of, or the URI or hyperlink to, the
			  Adapter's License You apply. You may satisfy this condition
			  in any reasonable manner based on the medium, means, and
			  context in which You Share Adapted Material.

		   3. You may not offer or impose any additional or different terms
			  or conditions on, or apply any Effective Technological
			  Measures to, Adapted Material that restrict exercise of the
			  rights granted under the Adapter's License You apply.


	Section 4 -- Sui Generis Database Rights.

	Where the Licensed Rights include Sui Generis Database Rights that
	apply to Your use of the Licensed Material:

	  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
		 to extract, reuse, reproduce, and Share all or a substantial
		 portion of the contents of the database;

	  b. if You include all or a substantial portion of the database
		 contents in a database in which You have Sui Generis Database
		 Rights, then the database in which You have Sui Generis Database
		 Rights (but not its individual contents) is Adapted Material,

		 including for purposes of Section 3(b); and
	  c. You must comply with the conditions in Section 3(a) if You Share
		 all or a substantial portion of the contents of the database.

	For the avoidance of doubt, this Section 4 supplements and does not
	replace Your obligations under this Public License where the Licensed
	Rights include other Copyright and Similar Rights.


	Section 5 -- Disclaimer of Warranties and Limitation of Liability.

	  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
		 EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
		 AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
		 ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
		 IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
		 WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
		 PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
		 ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
		 KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
		 ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.

	  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
		 TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
		 NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
		 INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
		 COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
		 USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
		 ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
		 DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
		 IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.

	  c. The disclaimer of warranties and limitation of liability provided
		 above shall be interpreted in a manner that, to the extent
		 possible, most closely approximates an absolute disclaimer and
		 waiver of all liability.


	Section 6 -- Term and Termination.

	  a. This Public License applies for the term of the Copyright and
		 Similar Rights licensed here. However, if You fail to comply with
		 this Public License, then Your rights under this Public License
		 terminate automatically.

	  b. Where Your right to use the Licensed Material has terminated under
		 Section 6(a), it reinstates:

		   1. automatically as of the date the violation is cured, provided
			  it is cured within 30 days of Your discovery of the
			  violation; or

		   2. upon express reinstatement by the Licensor.

		 For the avoidance of doubt, this Section 6(b) does not affect any
		 right the Licensor may have to seek remedies for Your violations
		 of this Public License.

	  c. For the avoidance of doubt, the Licensor may also offer the
		 Licensed Material under separate terms or conditions or stop
		 distributing the Licensed Material at any time; however, doing so
		 will not terminate this Public License.

	  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
		 License.


	Section 7 -- Other Terms and Conditions.

	  a. The Licensor shall not be bound by any additional or different
		 terms or conditions communicated by You unless expressly agreed.

	  b. Any arrangements, understandings, or agreements regarding the
		 Licensed Material not stated herein are separate from and
		 independent of the terms and conditions of this Public License.


	Section 8 -- Interpretation.

	  a. For the avoidance of doubt, this Public License does not, and
		 shall not be interpreted to, reduce, limit, restrict, or impose
		 conditions on any use of the Licensed Material that could lawfully
		 be made without permission under this Public License.

	  b. To the extent possible, if any provision of this Public License is
		 deemed unenforceable, it shall be automatically reformed to the
		 minimum extent necessary to make it enforceable. If the provision
		 cannot be reformed, it shall be severed from this Public License
		 without affecting the enforceability of the remaining terms and
		 conditions.

	  c. No term or condition of this Public License will be waived and no
		 failure to comply consented to unless expressly agreed to by the
		 Licensor.

	  d. Nothing in this Public License constitutes or may be interpreted
		 as a limitation upon, or waiver of, any privileges and immunities
		 that apply to the Licensor or You, including from the legal
		 processes of any jurisdiction or authority.

A  => archetypes/default.md +6 -0
@@ 1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---


A  => config.toml +85 -0
@@ 1,85 @@
baseURL = "https://humaidq.ae/"
languageCode = "en-us"
title = "Humaid AlQassimi's Website"
theme = "humaidq-theme"
preserveTaxonomyNames = true
pygmentsUseClasses = true
pygmentsCodeFences = true
enableGitInfo = true
disableHugoGeneratorInject = true
#canonifyURLs = true
[Params]
	images = ["img/me.jpg"]
	ISO8601 = "2006-01-02T15:04:05GMT"
  	profilePicEnabled = true

sectionPagesMenu = "main"

paginate = 5
paginatePath = ""

[privacy]
  [privacy.disqus]
    disable = true
  [privacy.googleAnalytics]
    disable = true
  [privacy.instagram]
    disable = true
  [privacy.twitter]
    disable = true
  [privacy.vimeo]
    disable = true
  [privacy.youtube]
    disable = true

[menu]
  [[menu.main]]
    identifier = "home"
    name = "Home"
    url = "/"
    weight = 10
  [[menu.main]]
    identifier = "now"
    name = "Now"
    url = "/now/"
    weight = 11
  [[menu.main]]
    identifier = "projects"
    name = "Projects"
    url = "/projects/"
    weight = 20
  [[menu.main]]
    identifier = "blog"
    name = "Blog"
    url = "/blog/"
    weight = 30
  [[menu.main]]
    identifier = "gallery"
    name = "Gallery"
    url = "/gallery/"
    weight = 40
  [[menu.main]]
    identifier = "xmath-pp"
    url = "/xmath-pp/"
    weight = -100
  [[menu.main]]
    identifier = "contribution"
    url = "/contribution/"
    weight = -100

[taxonomies]
#    license = "license"
    location = "location"
#    language = "language"

[blackfriday]
  hrefTargetBlank = true
  noreferrerLinks = true

[markup]
	[markup.tableOfContents]
		startLevel = 3
	[markup.goldmark]
		[markup.goldmark.renderer]
			unsafe = true
			xHTML = true

A  => content/_index.md +30 -0
@@ 1,30 @@
---
title: "Home"
description: "An Emirati who likes writing open-source software."
menu: projects
---

Welcome to my personal website. You can find my open-source projects, blog,
gallery, and other works on this website.

I like writing minimalist software which solves problems. Most of my projects
are written in [Go](https://golang.org), and I am always trying to learn new
things.

## My top projects

Here are some projects I am proud of.

- [Neat Note](/projects/neatnote): a website for students to share resources,
  notes, and start discussions. With [Lobsters](https://lobste.rs)-like voting
  system on posts.
- [Learning Bot](/projects/learning-bot/): a GitLab bot for providing
    programming advice for university students.
- [godoc2markdown](/projects/godoc2markdown/): a program which converts Go Doc
	output to Markdown.

## Contact

Email me and introduce yourself. My email is public<span style="display:none;"> (REMOVE THIS) </span>@humaidq.<span style="display:none;"> (deletethis) </span>ae, and I respond to all emails.  

My PGP key is [`C4350A2D`](/contact/pgp.txt), which I also use to sign commits.

A  => content/blog/_index.md +4 -0
@@ 1,4 @@
---
title: Blog
description: "Humaid's blog on computer and technology related topics"
---

A  => content/blog/best-articles-2018.md +24 -0
@@ 1,24 @@
---
title: "Best articles I read in 2018"
date: 2019-01-08
---

I have read many great articles related to programming and Computer
Science in 2018, I have gathered articles which I enjoyed most. Some of
these are articles are over a decade old, but I find it essential
that every programmer or computer scientist reads these articles.  
<!--more-->
- How To Become A Hacker by Eric Raymond - http://www.catb.org/~esr/faqs/hacker-howto.html  
- A lightning talk by Gary Bernhardt - https://www.destroyallsoftware.com/talks/wat  
- Beating the averages by Paul Graham - http://www.paulgraham.com/avg.html
- Revenge of the nerds by Paul Graham - http://www.paulgraham.com/icad.html
- The Hundred-Year Language by Paul Graham - http://www.paulgraham.com/hundred.html
- The perils of JavaSchools by Joel Spolsky - https://www.joelonsoftware.com/2005/12/29/the-perils-of-javaschools-2/
- How Lisp Became God's Own Programming Language by Sinclair Target - https://twobithistory.org/2018/10/14/lisp.html
- Stop writing code by Emily Maier - https://emilymaier.net/words/stop-writing-code/
- How to Design for the Modern Web by Casper Beyer - https://medium.com/commitlog/how-to-design-for-the-modern-web-52eaa926bae2
- Dos and don'ts on designing for accessibility by Karwai Pun - https://accessibility.blog.gov.uk/2016/09/02/dos-and-donts-on-designing-for-accessibility/
- tour-de-babel by Steve Yegge - https://sites.google.com/site/steveyegge2/tour-de-babel
- Why WhatsApp Only Needs 50 Engineers for Its 900M Users by Cade Metz - https://www.wired.com/2015/09/whatsapp-serves-900-million-users-50-engineers/
- On the usefulness of Linux by my professor, Jamie - http://gabbay.org.uk/blog/interrogated.html


A  => content/blog/gopher.md +17 -0
@@ 1,17 @@
---
title: "My Gopher Site"
date: 2019-11-06
---

A Gopher version of my website is available! You can access it by visiting
<gopher://humaidq.ae> with a browser that supports it, such as [lynx]. Or 
alternatively, view the site with [Floodgap](https://gopher.floodgap.com/gopher/gw?humaidq.ae)
on a modern browser. This is how it looks with lynx:

![A screenshot of my Gopher page, showing the same description of my main
HTTPS website, loaded on the lynx browser](gopher.png)

In the future, I may extend it to be a closer copy of my current website, and
to include the blog, projects, among other things.

[lynx]: https://lynx.browser.org/

A  => content/blog/gopher/gopher.png +0 -0
A  => content/blog/hall-of-fame.md +41 -0
@@ 1,41 @@
---
title: "My favourite software"
date: 2019-08-12
Summary: "This is a list of software which improved the way I used my computer,
the list includes software for backing up, text editing and document
processing, Linux/Unix utilities and programs, and desktop environment and
applications."
---

This is a list of software which improved the way I use my computer.

**Backing up**

> I use [Borg](https://www.borgbackup.org/) which allows me to efficiently
> backup my files, it supports encryption and deduplication of files, allowing
> me to use a fraction of space compared to a traditional method.

**Text editing & document processing**

> I use [neovim](https://neovim.io/) because it is fast, minimal and just works.
> Editors like VS Code and Atom sucks, a text editor shouldn't be using
> 500-700MB of RAM to open a small text file.

> I usually write my notes and reports in Markdown, which is then converted to
> PDF (through LaTeX) with [pandoc](https://pandoc.org/). [LaTeX](https://www.latex-project.org/)
> is used when I need more control over the document.

**Linux/Unix utilities and programs**

- [maim](https://github.com/naelstrof/maim): a simple command-line based screenshot program.
- [zsh](http://zsh.sourceforge.net/)/[Oh My Zsh](https://ohmyz.sh/): my favourite shell environment setup.
- [sxiv](https://github.com/muennich/sxiv): a perfect, minimal image viewer.
- [zathura](https://pwmt.org/projects/zathura/): a light PDF viewer which uses Vi keyboard shortcuts.
- [Claws Mail](https://www.claws-mail.org/): a mail client which is lightweight and delightful to use.

**Desktop environment**

- My window manager is dwm, modified to support volume, brightness, display and
  pomodoro (`spt`) support, and theme colour changed. I like the way dwm
  arranges windows (compared to i3wm).
- My terminal emulator is st, which seems to just work well.

A  => content/blog/kudu-two-year.md +91 -0
@@ 1,91 @@
---
title: "System76 Kudu4: After two years"
date: 2019-11-16
---

Two years and three months ago, I have purchased the [Kudu4 laptop] from
[System76], which is essentially a rebranded [Clevo] N870HZ laptop for Linux. I have enjoyed
using the laptop so far, and it has gone through a lot of use and abuse,
especially with my rough handling of my laptop in my backpack. 
The laptop stood well in the past two years in most aspects, the build quality
is solid (although heavy). I am surprised that the keyboard has almost no wear
(no shine whatsoever), and the keyboard is still as great to use since when I
first got it. And the same could be said with the touchpad.  

There are a few aspects which I did not like about the laptop, such as the
speaker sound quality, which is really bad compared to other devices I use.
As well as the fans, which make whining sounds randomly when idle, and it
sounds like a plane which is about to takeoff when doing any intensive task
(such as browsing).  

A year and a half after using my laptop as a daily driver, I have noticed that
the screen started acting up. Sometimes, the screen would be black and I have to
close the lid and open it again. At first I thought it was an issue with my
system, but it soon started to get worse. Random artifacts started to appear on
the screen as I used it, and it started to occur more often over time.

![A picture of my laptop screen, showing random horizontal artifacts across
different sections of the screen, with different colours](artifacts.jpg)

This would get worse as I use my laptop often as I go to my different lectures,
opening and closing my laptop lid while I take my laptop out of my backpack.

After contacting System76's support, and going through and diagnosing the
issue, they have suggested that it may be either an issue with LCD panel or the
LCD cable. Reseating the LCD cable didn't help much, so I had them ship me
an LCD cable. It costed me $103.10 USD (out of which, $30 is cable cost, $54 is
diagnostics fee, and rest is shipping), I found the $54 diagnostics fee a bit
ridiculous.

While waiting for the LCD cable shipment to arrive, the screen completely gave
up. The cable eventually arrived, and I got it replaced. But getting the cable
to go through the hinges was one of the most difficult thing I have done (maybe
I'm doing it wrong?). Here's a picture of the old cable:

![A picture of the old LCD cable, which looks slightly crooked](old-cable.jpg)  

----

After replacing the cable 6 months ago, I haven't experienced any problems with
the screen. Except that the cable for the Webcam and Mic seem to have a
similar issues, where the camera feed goes black whenever I move the screen. So
I am expecting the screen cable would end up disintegrating again in about a
year if I continue to use the laptop in the same way I did the past two years.

The battery life is really inadequate with this laptop, it would barely last 5 hours
from full charge, which is a problem especially that not all lecture theatres
have sockets for charging. I didn't realise this was really bad until I have
seen how long other laptops can last, which is about as double. When
purchasing the laptop, I have opted in buying an extra battery, but I haven't
been using it as I don't want to be carrying the extra load. But it has been
useful as the lithium-ion battery's capacity has degraded drastically over
time.

Other than that, the laptop is a solid computer (albeit the headache-inducing
fan). And months after receiving the laptop, System76 issued a firmware update
to disable Intel's
Management Engine (ME) which is notoriously known about its security flaws and
vulnerabilities[^1]. This made me feel like the computer is safer, although I am
not sure whether it actually made a difference (other than the performance
sacrifice).

----

This model of the laptop is no longer sold since late 2018, there are newer
model laptops on the website which I found although nice, they aren't as
aesthetically pleasing as the Kudu.

I have recently ordered a ThinkPad T590 to replace my current laptop (which has
yet to arrive), while I am giving the Kudu to a family member,
where it would (hopefully) not get as much abuse as it does currently, and live
a longer and happy life. ThinkPads have a reputation of durability, and they
are certified for use in the International Space Station[^2], which I think is
cool. I wouldn't have ordered a new laptop if the System76 laptop was more
reliable, it is sad that I wouldn't be using this laptop as long as I wanted.

[^1]: [Security vulnerabilities of the Intel Management Engine](https://en.wikipedia.org/wiki/Intel_Management_Engine#Security_vulnerabilities), Wikipedia
[^2]: [IBM ThinkPads in space](https://www.ibm.com/ibm/history/exhibits/space/space_thinkpad.html), IBM Archives

[Kudu4 laptop]: https://web.archive.org/web/20171130005456/https://system76.com/laptops/kudu
[System76]: https://system76.com
[Clevo]: https://web.archive.org/web/20170417013400/http://www.clevo.com.tw/clevo_prodetail.asp?id=1017&lang=en

A  => content/blog/kudu-two-year/artifacts.jpg +0 -0
A  => content/blog/kudu-two-year/old-cable.jpg +0 -0
A  => content/blog/own-distro-p1.md +306 -0
@@ 1,306 @@
---
title: "Building your own Linux distribution (part 1, Xubuntu)"
date: 2020-05-01
---


In this post we will cover how to build your own derivative based on any Linux
distribution, but we will be using Xubuntu 20.04 in this post as an example.
I'll not cover how to make your own Linux distribution from scratch, if you
want to do that check out [Linux From Scratch] \(or [tldrlfs]). There are many
ways to customise a Linux distribution, in this post we will only cover one
way, which is by customising the live CD.

Some of the reasons why you might want to create your own Linux distribution are:

- For having a system customised to your liking whenever you need to reformat
  your computer, and having a post-installation script is just boring.
- You are at a company/school/organisation and you have to have applications
  setup in a specific way (and preseeding the installer is not enough).
- Create a modern version of [Hannah Montana Linux].
- You are bored due to the quarantine and want to do something.

I assume that you will be sensible and responsible to the distribution you are
willing to fork, and to its community. Ubuntu owns the trademark to their
names, so you cannot use their trademark in your derivative[^1]. Be sure to
familiarise yourself with the policy and guidelines of the distribution you are
willing to use.

### Prerequisites

It is important to know which kind of distribution you are deriving from, some
distributions such as Arch Linux are bootstrapped using their package manager.
This requires you to create your own mirror with your own version of the `base`
package. Newer distributions have build scripts available which allows you to
customise the installation image[^2]. Modifying these distributions ISO files
will only change the live CD environment, which may not be what you want.

Our focus is customising Xubuntu 20.04, as Ubuntu and Ubuntu-based
distributions are easy to customise. The Ubuntu installer uses the ISO files,
so the customisations made to the ISO image will be applied to the installed
system.  Before we continue, make sure you have the following packages on your
system: `proot`, `squashfs-tools`, `rsync`, `qemu`, and `xorriso`. We can then
[download the Xubuntu ISO](http://xubuntu.org/getxubuntu/) we want to
customise. There are many Ubuntu-specific parts in the following scripts, I'll
note these so you may adapt it to whatever distribution your are customising.

### Writing the scripts

We will be automating building our distribution in a shell script, this makes
building our derivative reproducible. So let's start with a basic script called
`build.sh`.

```sh
#!/bin/sh

# We define the global variables
BASEDIR=`pwd` # this is the base working directory, in case we need to go back to it
MOUNT="mnt" # this is the mount directory for the ISO file
EXTRACT="extract-cd" # this is where the ISO will be extracted to
CHROOT="edit" # this is where the root partition (squashfs) will be extracted to
ORIG_FILE="xubuntu-20.04-desktop-amd64.iso" # this is the file we will be customising
DIST_NAME="pinguOS"
DIST_FILE="$DIST_NAME-$(date +%Y%m%d).iso" # this is the final file

# We make sure that the ISO file exists before we continue
if [ ! -f $ORIG_FILE ]; then
	echo "The file ${ORIG_FILE} doesn't exist. Be sure to download it first."
	exit
fi

# We clean up the files from previous runs
rm -rf $CHROOT $EXTRACT $MOUNT

# Now we run the scripts
. ./scripts/extract.sh
. ./scripts/customise.sh
. ./scripts/build.sh
```

In our shell script, we are splitting the process in three steps.

- extract: We extract the contents of the ISO file.
- customise: We modify the extracted contents to our liking.
- build: We build a new ISO file based on the changes we have made.

#### Extracting the ISO

Let's start with `./scripts/extract.sh`.

```sh
# We make the mount directory and mount the ISO to it
mkdir $MOUNT $EXTRACT
mount -o loop xubuntu-18.04.1-desktop-amd64.iso $MOUNT
# Now we copy the ISO contents to our extract directory
rsync --exclude=/casper/filesystem.squashfs -a ${MOUNT}/ $EXTRACT
# The filesystem is in a read-only compressed filesystem which we need to extract
unsquashfs mnt/casper/filesystem.squashfs
mv squashfs-root $CHROOT
# We can now unmount and delete that directory
umount $MOUNT
rm -rf $MOUNT
```

**Note:** With other distributions you may have to slightly tweak the code
above, files such as `filesystem.squash` may be somewhere else with another
name.

#### Customising the files

This should extract the root file system in the directory `./edit`. At this
stage we can run `chroot` on our `./edit` directory, but we usually need to
`mount --bind` our system directories such as `/dev`, `/proc`, `/sys`, and
other files so the programs run properly in the `chroot` environment[^3]. To
simplify this, we are going to use [PRoot]. Let's write `./scripts/customise.sh`.

```sh
proot \
	-R ${PWD}/${CHROOT}/ \
	-w / \
	-b /proc/ \
	-b /dev/ \
	-b /sys/ \
	-b /etc/resolv.conf \
	-0 \
	/bin/bash
```

PRoot will also automatically mount/unmount these directories (defined with
`-b`) in our chroot environment when we are done with it, which reduces the
hassle of manually mounting and unmounting these directories. We can now test
it out by running our build script as root.

```sh
# sh ./build.sh
```

![Screenshot of the output of the shell script, showing Ubuntu as the output of
lsb\_release](output.png)

As you see in the screenshot, we get a prompt. This is the Xubuntu 20.04
environment which we can interact with and modify the system to our liking.

Let's do something really simple, and add a hello world text file on the
desktop. On Linux, there is a directory called `/etc/skel` which contains
files that are automatically copied to new users on the system. Let's append
this to `./scripts/customise.sh`.

```sh
mkdir ${CHROOT}/etc/skel/Desktop
echo "Welcome to my Linux distribution" > ${CHROOT}/etc/skel/Desktop/hello.txt
```

We'll add upon this file later to further customise our distribution, let's now
focus on building our new ISO image.

#### Building the new ISO file

Let's write `./scripts/build.sh`.

```sh
# we have to update the manifest file to contain the latest list of packages.
chmod +w $EXTRACT/casper/filesystem.manifest
proot \
	-R ${PWD}/${CHROOT}/ \
	-w / \
	-b /proc/ \
	-b /dev/ \
	-b /sys/ \
	-0 \
	dpkg-query -W --showformat='${Package} ${Version}\n' > $EXTRACT/casper/filesystem.manifest
cp $EXTRACT/casper/filesystem.manifest $EXTRACT/casper/filesystem.manifest-desktop
# we have to make a new squashfs compressed filesystem based on the changes we did
mksquashfs $CHROOT $EXTRACT/casper/filesystem.squashfs
# we put the size of the filesystem for casper
printf $(du -sx --block-size=1 edit | cut -f1) > $EXTRACT/casper/filesystem.size
# we also have to update the md5sum list of the files
cd $EXTRACT
rm md5sum.txt
find -type f -print0 | xargs -0 md5sum | grep -v isolinux/boot.cat > md5sum.txt
# now build the ISO
xorriso -as mkisofs \
	-r -V "$DIST_NAME amd64" \
	--protective-msdos-label \
	-b isolinux/isolinux.bin \
	-no-emul-boot -boot-load-size 4 -boot-info-table \
	--grub2-boot-info --grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \
	--efi-boot "boot/grub/efi.img" -efi-boot-part --efi-boot-image \
	-o ../$DIST_FILE .
cd $BASEDIR
```

**Note:** We do generate some files like the md5sum of the files, and the
package listing. Some of these are based on Ubuntu's live CD customisation
guide and other sources[^4].

We can now try to build again, and try to boot it using `qemu`.

```sh
# sh ./build.sh
...
$ qemu-system-x86_64 -m 2G -cdrom pinguOS-<date>.iso
```

![Screenshot of the desktop with the hello.txt file open](desktop.png)

Violà!

#### Further customisations

There are still Xubuntu/Ubuntu branding which we have to change if we want to
redistribute our new fork. So let's try to replace the branding with ours by
adding the following to the `./scripts/customise.sh` file.

```sh
sed -i -e 's/Xubuntu/'$DIST_NAME'/g' $EXTRACT/isolinux/txt.cfg
sed -i -e 's/Xubuntu/'$DIST_NAME'/g' $EXTRACT/boot/grub/grub.cfg
sed -i -e 's/Xubuntu/'$DIST_NAME'/g' $EXTRACT/boot/grub/loopback.cfg
sed -i -e 's/Xubuntu 20.04 LTS "Focal Fossa"/'$DIST_NAME'/g' $EXTRACT/README.diskdefines
sed -i -e 's/Xubuntu/'$DIST_NAME'/g' $EXTRACT/boot/grub/grub.cfg
rm $EXTRACT/.disk/release_notes_url
echo -n "$DIST_NAME  - Release amd64 (`date +%Y%m%d`)" > $EXTRACT/.disk/info
echo '$DIST_NAME \n \l' > $CHROOT/etc/issue
echo '$DIST_NAME' > $CHROOT/etc/issue.net
echo > $CHROOT/etc/legal

# The lsb-release file
cat <<EOF> $CHROOT/etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=$(date +%Y%m%d)
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="$DIST_NAME"
EOF

# The os-release file
cat <<EOF> $CHROOT/etc/os-release
NAME="$DIST_NAME"
VERSION="$(date +%Y%m%d)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="$DIST_NAME"
VERSION_ID="$(date +%Y%m%d)"
HOME_URL="https://humaidq.ae/blog"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
EOF
```

The `sed` commands basically does search and replace in the given files. And
other files such as the `/etc/issue` we completely overwrite. That's most of
the files we need to modify. Now we might want to install our own packages or
run other commands. Let's modify the `proot` command at the top of the
`./scripts/customise.sh` script.

```sh
proot \
	-R ${PWD}/${CHROOT}/ \
	-w / \
	-b /proc/ \
	-b /dev/ \
	-b /sys/ \
	-b /etc/resolv.conf \
	-0 \
	/bin/bash <<EOF

export HOME=/root
export LC_ALL=C

apt update
apt upgrade -y --allow-downgrades

# TODO: You might want to install/purge packages here, or add your PPA.
# You might want to remove the plymouth branded boot screen too.


apt autoremove --purge -y

EOF
```

Other places of interest may be:

- `/usr/lib/ubiquity`: Installer Python source
- `/usr/share/ubiquity-slideshow`: Installer slideshow files
- `/etc/update-motd.d`: System message of the day

The possibilities are endless.

In the second part of this blog series we will be creating our custom
Raspbian Lite image, which is slightly different as we are dealing with an
image file with partitions rather than an ISO file.

[Linux From Scratch]: http://www.linuxfromscratch.org/lfs/
[tldrlfs]: https://github.com/Sweets/tldrlfs
[Hannah Montana Linux]: http://hannahmontana.sourceforge.net/
[PRoot]: https://proot-me.github.io/

[^1]: Check Ubuntu's [DerivativeDistroHowto wiki page](https://wiki.ubuntu.com/DerivativeDistroHowto#Trademarks),
  it contains examples of some things you should and shouldn't do.
[^2]: For example Alpine's [abuild](https://git.alpinelinux.org/abuild/) or
  Void's [void-mklive](https://github.com/void-linux/void-mklive).
[^3]: We mount these so that the applications which rely on the existence of
  these directories can work in the chroot environment.
[^4]: You can go into more detail at Ubuntu's [LiveCDCustomisation wiki page](https://help.ubuntu.com/community/LiveCDCustomization),
  but some information might be outdated. I have also learned from reading
  [Pop!\_OS ISO production](https://github.com/pop-os/iso) source code, which
  filled some gaps.

A  => content/blog/own-distro-p1/desktop.png +0 -0
A  => content/blog/own-distro-p1/output.png +0 -0
A  => content/blog/qnap.md +56 -0
@@ 1,56 @@
---
title: "Installing Linux on my QNAP TS-459"
date: 2020-04-28
draft: true
---

About four years ago I got the QNAP TS-459 as a NAS so I can store family
pictures and backups of our devices. It came with QNAP QTS, which is the NAS
user interface. I came across many issues with the responsiveness of this UI,
as it tries to replicate a desktop environment with windows (as in panes, not
the operating system). This UI is sometimes slow, confusing to navigate as I
have to learn yet another interface, and has bugs (such as when the backup
program wizard always hangs).

I wished to have a standard Linux system which I can operate, rather than using
this interface with their proprietary software.

Recently, one of the four hard drives on the RAID5 array failed, and it isn't
long until failures pile up. This is when I regretted having a ClamAV scan run
every week, which was very pointless and wreckful to the wear and tear of the
drives.

The drives installed were 5TB Seagate Enterprise Capacity 3.5 HDD (v4), and
since it is a bad idea to keep using these drives, I am ordering new ones after
installing Linux on the machine. Luckily, the manufacturer did not disable the
BIOS, and allows users to boot from a USB for recovery[^1]. I am a big fan of
[Void Linux] as it is simple to use and fast, the [runit] init scheme allows me
to define services as simple shell scripts, rather than INI files[^2].

Luckily the NAS drive has an HDMI output for the media center. Pressing `Del`
while booting the system loads the BIOS, where I could specify the boot order.
Unfortunately, I was not able to find the key which opens the boot menu
directly, and the BIOS doesn't allow me to boot directly to a device. So I set
the USB device to have priority over the internal flash storage.

After booting Void Linux, I found three partitions on the system. These show on
Void as:

- `/dev/loop1` (730M): This is where the root parition of the system is stored.
- `/dev/loop2`: This contains an archive of the firmware, which I assume is
  used for a firmware reset.
- `/dev/sdb` (429M): This contains the boot loader.

On the QNAP wiki, it shows these drives appear as `/dev/mtdblock{1,2,3}` (as in
Memory Technology Devices). I am clueless to why two of the devices
automatically load as loop devices.


[^1]: QNAP also provides a wiki page on [booting a recovery disk](https://wiki.qnap.com/wiki/Firmware_Recovery#Instructions_for_NAS_Recovery)
  and [installing Debian](https://wiki.qnap.com/wiki/Debian_Installation_On_QNAP)
  on their systems.
[^2]: systemd uses INI files for configuration, which I find less
  comprehensible compared to a simple shell script.

[Void Linux]: https://voidlinux.org/
[runit]: http://smarden.org/runit/

A  => content/blog/status-update-1.md +63 -0
@@ 1,63 @@
---
title: Status update, October 2019
date: 2019-10-19
---

A lot has been happening the last month, we have started working on the
largest group software development project at the University. We are a team
of six people, and have decided to choose [Go](/languages/go/) as our language
of choice for the implementation of the smart home system we are building.  

We have spend the first couple of weeks setting up the group in [GitLab] and
get continuous integration running (so we can have LaTeX PDF builds, and wiki
site deployed automatically). While setting up all the documentation for the
team and project, and specifying the software development process of the team,
we realised that there is no simple way and neat way to generate a Go project
documentation automatically -- something like JavaDoc or Doxygen. Using the
`go doc -all` command to generate documentation isn't great, as it simply
dumps the documentation in plain text, with no option to change the format.  

Some solutions I have found on the Internet is to run the `godoc` server
(which is what hosts Go's project homepage), then to use `wget` to download
the HTML pages. The downside of this process is:

1. Customising the template or layout of the pages is difficult, requiring
you to fork the project and change many lines of code.
2. The project has to be located in the `GOPATH`, otherwise it will not be
detected. Our project is usually hosted outside of the `GOPATH`, as we are
using Go modules.

I tried to find a documentation generator, and sadly Doxygen doesn't support 
Go -- which may be a good thing (some project members simply didn't like the
style of it). And we cannot use the [GoDoc] website as the projects are hosted
on a private GitLab group.[^1]

After some more searching, I found a project called [godoc2md] by Dave Cheney,
which promised to do exactly what I have wanted to do. After trying to get it
compiled and running, I have encountered many compilation errors, mostly due to
changes to the GoDoc package which the project depends on. So this seems like a
dead end.  

I have noticed the output of `go doc -all` is easily parsable, different lines
are formatted differently, which allows me to easily identify which section of
the documentation is a function declaration, description, etc. With this I can
write a simple program, using some regular expressions to detect different
parts and format them correspondingly. And [godoc2markdown] is born, although
it has some quirks which I am ironing out as the project progresses.  

I'll leave you with a picture of a project I have been working on, more details
to be released soon.

![A picture of a website, called Notes Overflow, with a list of University
courses, below it a number of the posts. On the navigation menu there is a
title of the website, and a login link.](notes-overflow-alpha.png)

That's all for this month!

[^1]: As we aren't allowed to post the project source publicly until the end of the course.

[GoDoc]: https://godoc.org/
[godoc2md]: https://github.com/davecheney/godoc2md
[godoc2markdown]: /projects/godoc2markdown/
[GitLab]: https://gitlab.com


A  => content/blog/status-update-1/notes-overflow-alpha.png +0 -0
A  => content/blog/welcome.md +45 -0
@@ 1,45 @@
---
title: My new website & blog
date: 2018-07-23
---
Welcome to my newly designed website, which includes a Git projects page, a blog, a gallery and my contact information.
The website used to run on a web server which I wrote using the Go programming language, and had a login page with GitHub
authentication. But I do not have a reason anymore to have a dynamic website[^1], it is possible to have a website which is
static and be able to host all the content I need. The website you are accessing now is a static website generated using an
amazing generator called [Hugo]. This helps me focus more on the content of the website rather than maintaining the web server code.

### The changes in the redesign
The previous website used Bootstrap, a bunch of JavaScript libraries and a couple of fonts. This makes my simple website heavy.
In my redesigned website, all the CSS is written minimally to keep the website simple and fast.  

The new redesign is over a thousand times lighter than my older version (when loading a page), but contains more content
than my older website. It seems like everyday websites are "upgrading" their website design to make it heavier to load, which
is a bad trend. I would like to prove that it is possible to have a light website without compromising content and design.  

### My new projects page
GitHub used to be where all my open-source projects are hosted, and I was using their services as early as 2013. It was the perfect
place to host my projects and to collaborate. However when Microsoft bought GitHub in June 2017[^2], I immediately moved away. Microsoft 
waged a war against Linux and the open-source software movement in the past[^3], which caused my distrust in the company.
~~Self-hosting my own repositories seems like a better option for me, even though it is not the perfect solution to the problem.~~
I have migrated all my git repositories to [SourceHut] which is a great and
powerful alternative.

### The gallery
I have deleted my Instagram account over a month ago, as the service is becoming more "Facebook". Instagram used to be a good place to
host pictures years ago. With my new website generated with Hugo, I am able to easily create a gallery and host pictures on my website.
This allows me to categorise and tag my pictures any way I want, license my pictures under a Creative Commons license, and even allow
people to download the full image file -- something I cannot do using Instagram. Having everything hosted on my website allows more control
on how the content is displayed and presented.  

### The blog and other posts
I always wanted to have a blog, but I was not satisfied with all the solutions available and I didn't have enough time to make a proper solution.
Hugo solves this problem, all my website is written in either Markdown or Emacs org-mode -- including my blog. This makes managing the content on
my entire site easier. Now my projects are categorised depending on the
language used and license, and implementing that was trivial with Hugo.


[Hugo]: https://gohugo.io/
[SourceHut]: https://sourcehut.org
[^1]: As in [server-side dynamic web pages](https://en.wikipedia.org/wiki/Dynamic_web_page)
[^2]: You can find more information about the acquisition at [The GitHub Blog](https://blog.github.com/2018-06-04-github-microsoft/)
[^3]: There is a good web page explaining this on [cosmicpenguin.com](https://web.archive.org/web/20190412193814/http://www.cosmicpenguin.com/linux/MICROSOFTS_WAR_AGAINST_LINUX.html)

A  => content/blog/yubi.md +38 -0
@@ 1,38 @@
---
title: "Setting up a Yubikey on Void Linux"
date: 2020-06-03
draft: true
---

I recently got a [Yubikey], which is a hardware authentication device. It has
multiple functions, the Yubikey 4 has two slots which you can configure.
Getting the device to work on Void Linux wasn't obvious, this is a simple guide
on how to get a Yubikey working on [Void Linux].

First you need to install `dbus`, `eudevd`, and `elogind` if you haven't
installed it yet.

```sh
# xbps-install -Sy dbus eudevd elogind
``

You have to enable those services.

``sh
# ln -s /etc/sv/{dbus,eudevd,elogind} /var/service/
``

Now you need to install Yubikey packages:

```sh
# xbps-install -Sy u2f-hidraw-policy ykpers ykpers-gui
```

Now you'll have to restart your system. You can then plug in your key, and run
the `ykpers-gui` utility (or `ykpers` if you prefer the command-line).

The [Arch Wiki Yubikey article](https://wiki.archlinux.org/index.php/Yubikey)
has detailed examples on how you could setup your key.

[Yubikey]: https://en.wikipedia.org/wiki/YubiKey
[Void Linux]: https://voidlinux.org/

A  => content/contact/pgp.txt +63 -0
@@ 1,63 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBFuFw44BEACRFq6haZtCTQ4GmNEQmrjJwv5eqvYNLkZlarD8iaj3wxw5w7Gz
hqkkjCYfY57cyrjAF9TrtHzijVtflbEMo+Ju3hAeLfZqgdLPTMUMPjMmXugdsENH
IprBrVaK75+C5brd5JHeM1VqjEHVT75NkWx5aDhZQxU9AmCbSH4LqWSi6PcTkX6O
s9GvxxjVNn/ofTdkQJjLluu/3nfXT/+9P2CtdOzVenAcOiRYwmSHtKCWjTJwVlWz
LJmpXAA/sXLeruGr10ybyd0F5Lx4r9yAgi+GO4bn5fTFCAGh6+sq//kVJp2FyOg0
9BtEog60TYBQGrEel2fEbDyyKXeX0z/EIRU96S0RII7WC4VeE9gSnzxREKWmAkcz
u2roPxaD+ghaNAEfX/45SoBy1uVFU3NulWECrH7+H3+FWgj/VtNPgkq/TC3qhPLQ
UralBpSHy9kVQUMbF25HxNyWaxXFFOcVS9GvuudEcRXpesZqXGtuPIOiH3fcu/Tu
Gfzwef31GQVwBAmjTbG80pIIhM++XGZ8QblDO0wMhuuXPIkfGrtYgq4nYnbbUli7
dhKhbjZcOzIiDyi2eGJ288FYD6bVbHhPTwl5IINts+ifTTgp0MzQ2UmCTM8EiArV
j74PANJDLm1SDXiNKeer5W6NIOOuktw00jkOLsIAylqg+DjEBVWDHPqCDQARAQAB
tCBIdW1haWQgQWxRYXNzaW1pIDxtZUBodW1haWRxLmFlPokCOAQTAQIAIgUCW4XD
jgIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQB9U1vMQ1Ci11eA//ZwvJ
PGnBPKMLRFncsuFakHPkd9BjlJRM5YcVm2W2bQngSTiqYgV2bINF3cSV6o+PkXah
mohsx0lv7048j4UIC2qIgJV+14iVY/5borcCnWUlmzPLKO1qwF8F9ihcu6szxGZU
af60AFtoLa7rTBCXGk3m2yBg/Us6uyTr38OdGPhOhHuBpwNN6QYRDQK6HBKGePDT
98KA3T7hORWcmS0SYNz5tBhtjpRo8uSQyA59Wl90oNaOTTTRpCYYyctzhvUqJ3di
S4wFSprba3p3i+rBsjnlOwbBZ2rDTToS3OVCZvWB7rn6QDfQPQV/zLZO/xTWViPs
Z2jqVJFn7dRzmNEz1JK/T5/WlGbIm9xfhMtlLZpSdk0Wauzi/1FPVZcSA5PXvdHL
DUIe1ul13pjRTdI/EubfHu+BU5t1NTNe1chwTiGV/3hmb4Q1ujEBNFUGnpXjr72x
itqOEMKTbepqvYbU7ETdCsJAFYiBZrhSkuyz3roxgT711lL1UcWtYdzSpQb/3Wgn
OIbqDhZ/lUYwzxMc8Vll1TJDk2uOwSDJaJ3DwbpzV7D49SXFAuRTmytxC2kxezuz
ylhWwL8Xd0Z4gt0UG2wIIukCtbCfB7PycxkA4ogJv2hxA/mpRXK7BbTOb5ylUXY/
0Ofpw6N13WB/haIfW1y7+EaUKNN1X08OG6HXwIG0IUh1bWFpZCBBbFFhc3NpbWkg
PGdpdEBodW1haWRxLmFlPokCOAQTAQIAIgUCXkP/TwIbAwYLCQgHAwIGFQgCCQoL
BBYCAwECHgECF4AACgkQB9U1vMQ1Ci3+Xw//a33thoRCyAXkN7tN1xWyKl4+JCxc
fzimTBrltpPhKtP4Y7yo6TFqfiBm2z93bJwnXyySfGFvKkOIv1y6RkXX3kNuyM4t
/Jm5RkxK5MsgIo/X5yft9In+FBNMsQiA6KY6aMuWV1rvY35HlkC0aexwjqbKqAPl
IcS1keudTgnBAF9PYRPS3LwfJkrIFEgPAabR2SLZyJ3kGTVdJCUXcuRH/6FaCGD/
7pficXNYh+RfxE/rxbKtnDXNcJixnyK2PBh7FvQUz386uKiMcpQLC9gdhgzoSwak
jvsjyp4+VVnz9EDXiJR01VW9iJk6eJa6DmydzdsoHE/4XTEwOoBvYxTpTZy7he85
+4MFgpz2+OV9rnsiDtWOf28GfCGG8TJkpu1In1SX9SK2vvlRrN3U+LL0ylSYD+kT
NVJVa+sfwsjuy6WVZjy4G0AcKnihlQghSVdOwxvr20dC+oMc3ycZ4eZevBAXQbKw
7/fAtT8y53Tzgfd6U+bfMr7DBE5el4ovnHA4IRmGG/uxkJTJdNIAZomAVp7AVmjp
jsTBnxJh66XBpvr+rssGixJ8Pht+MD18yA6OBEhsloMiEEnccLlu8XMtii0p6rZb
JZIr9JewuqPh7enlOL5CbL9IGAuJ70GhGykKb86GMqDAH2EskxDH30ahFDOnJfJO
RrlFSq22aw2O4+q5Ag0EW4XDjgEQAL/tVaQ+C/92um+0TBo8D4K6uCdAahwGFL11
JrxirUsrud2eupLFVKzguXshtXykH18YGO21aDHQMegUmOjhRJylFeGuNTxYyHz1
fxtTV0TCG5JIk+0I7XX4LY7VBD6Ms+9CHHHS78AW0wE5Xl9nrTyAs9ymIkAOWCAz
97lnKcqle0okWcvTCok9357708NE5rywhYWma/JiVKmAe6rUqkUnOOnpuewILrQb
uOM2Rw2tuQz2b1Bk6AAopGEL3DPd6TnInXA4JL+AmJQ+P363gTr7D1J5yTZrueL7
fuuH+VWs1NychqJkOmYCNVsUaGeH1EEGth2NJ4e4t5yCNpns4yPfqVUDQKWOpL4j
A0iXX4Y1UmFh84CM1dym9eYCF2MTmDmy/pl7XzyfSZ7qHu4BiR/3P/v/B0JkA3bM
O3z9BID4XqnBQ/GsKqm99FUTgK9mQdXOKDAZ8vr2Lu7UBiNSllzp2ZA8QYNBbhos
8BDODaXSuHoNOAw162ojz6eX53sY8/PcqL6obyivIJ/YmdCFxzjjTc/FXH1w3w/K
MSxHjT2MX/2LoV8C5o0pH+CymRBAuC6iDQCQTlqLkkC13DWt/KthBVTJ6MYpiQvy
wpNoGPuewF/yqQ19cDHqLpuotcjqh7w1yEqL+YenjFWWPMU6Wzggyz/9+LdsVXde
hVPlDrQtABEBAAGJAh8EGAECAAkFAluFw44CGwwACgkQB9U1vMQ1Ci1FrQ/9GOco
cJdUNOGdY1Q0jxYpm8CNtnbZCqGMOnnGWHqDPKJZ+yoty14wCrrQImnYypE/V9S5
40S7OOupLSAVgCaf6EqV6BFv03swogbhzIdTXjeIZ9bghQWYet9TLFkmK5TeqfgL
65ivFNxowRw1YHw8Vf75+P9HROeAvrA1J5+KkWLmP22BBwwNSEEfXXmG1A5/uCjt
92tT4D7WHZ/fUW/HPzhscJ3eeY5+m6Ifgc4LAEs/eIp30htQdMISFlrv4NBpIBxi
dXFqn9ksRB/iHeR0CROjwXAMxgHHEg5T7UqoW0Z2K06DXut+L42nzwpNrYU7vM2d
Vz6pdcEzGBcoPVLzi97jmFKOef6O6Lra8AWxr/+v1hXg735xKPN137JR7d/Zfzh1
VG6HUVf6ITv5ZLKzGlZ4UD2sECwb700UMQ7/HxzPszQ/IsiCoqWnvMuyfxJ5E4p/
DSDB0/bQI88oubUe/1kV4XO7frevMEwn6/TX9q0D8ynVu7VPbXTHPhInFMK0aYkU
Czd0W0/Jvyq5pZMk2dW5b3soI/DBahxryzYl0dH239/R6kkPWISnn+qwRN1JvB9Z
zj4PCC6GiMizIqdYIjpnfaOLtxmymle1K+24hia9ATA/GxVEsPV+SkE+kn1uYBLG
fyU5GBw/k58LkEPzAmhkqF0O9vl8qtnGIe0K84o=
=WTxG
-----END PGP PUBLIC KEY BLOCK-----

A  => content/contribution/_index.md +23 -0
@@ 1,23 @@
---
title: Contribution Guide
description: "Guide on contributing to my projects"
---

To contribute to any of my projects, be sure to familiarise yourself
with [git](https://git-scm.com/) as this is what the projects use
for [version control](https://en.wikipedia.org/wiki/Version_control).  

Once you are familiar with git and have commited your changes. Make
sure git is setup to send patches by email, check out this tutorial
for an interactive guide on setting up email with git!  

<https://git-send-email.io/>

Make sure to send the patch to the appropriate mailing list, as
listed on the project's page. **Note:** Sending patches using your
email client or other means than `git send-email` will break your
patches, making it difficult to apply!  

Contribution is highly appreciated!  

You can view other guides below.

A  => content/contribution/c-contribution.md +9 -0
@@ 1,9 @@
---
title: Contribution Guidelines for C projects
BackNav: 1
---

Read [Rob Pike's Notes on Programming in
C](http://doc.cat-v.org/bell_labs/pikestyle).

Be sure not to include binary blobs with your commit.

A  => content/contribution/code-of-conduct.md +59 -0
@@ 1,59 @@
---
title: Code of Conduct
BackNav: 1
---

All projects (including mailing lists) follow [The Lunduke Code of Conduct](http://lunduke.com/pages/codeofconduct/).

Below is the complete text of the Code of Conduct.

## The Lunduke Code of Conduct

Be Excellent to Each Other.


### FAQ

Q: Wait. That's it?

A: Yup.

Q: But... but... it's only 5 words!

A: It is? Cool!

Q: Isn't that too short to be a viable Code of Conduct?

A: Nah.

Q: It's too vague! How would you enforce this?!?

A: By being excellent to each other.

Q: What if someone violates this Code of Conduct?

A: I trust you to figure it out.

Q: What if someone talks about politics I disagree with?!?!!?

A: I know a guy who votes for Papa Smurf in every Presidential election. He's a pretty cool dude.

Q: I'm super angry about something! And a person likes the thing making me angry! What do I do?

A: I dunno. Try *hugs*?

Q: Are virtual hugs (such as "*hugs*" and animated .GIFs of teddy bears hugging) excellent?

A: Most excellent.

Q: Huh. Seems so simple!

A: I know, right?

Q: I like you!

A: I like you, too!



The Lunduke Code of Conduct is free for you to use however you like. I [Bryan Lunduke] kinda just copied it from Bill & Ted's Excellent Adventure, anyway. 

A  => content/contribution/go-contribution.md +16 -0
@@ 1,16 @@
---
title: Contribution Guidelines for Go projects
BackNav: 1
---

Make sure to run '`go fmt ./...`' in the project's root
directory before committing your changes. This formats
your code according to Go's formatting style automatically.  

Many of the Go projects hosted have a `Makefile` which automatically
does the formatting, so you should make sure to run `make` before committing,
making sure the project is formatted properly, and the tests/build are
successful.

Be sure to document exported variables and functions, so documentation could
be generated.

A  => content/contribution/mailing.md +16 -0
@@ 1,16 @@
---
title: Mailing list guide
BackNav: 1
---

When sending emails in the mailing list, make sure that;


- your emails are plain text, HTML emails are rejected by the server
- when you reply, cut parts which you are not directly responding to
- the lines in your email does not exceed 72 characters
- if you use PGP, attach your PGP signature instead of including it inline



_This is a tl;dr of the mailing list ettiquette found [here](https://man.sr.ht/lists.sr.ht/etiquette.md)._

A  => content/gallery-faq.md +35 -0
@@ 1,35 @@
---
title: Gallery FAQ
---

[Go back to the gallery](/gallery)

### Are the pictures downloaded from the web?

No, I have took all of the pictures and released them under a
creative commons license.

### Which camera do you use?

I use my Samsung Galaxy Note 8 to take all of the photos.

### Why don't you use something like Instagram or Flickr?

These services do not fit my need, Instagram by Facebook is a
social media platform which compresses images to a lower quality 
and doesn't provide an option to download them. While Flickr
started deleting pictures of non-paying users, requiring them
to pay an expensive subscription[^1].

It makes more sense to self-host my gallery than to rely on a
service that can shut down my account or delete my images at any point.

### Why are faces blurred?

According to UAE laws, you need consent before taking a picture of someone. So
all pictures of faces are blurred.

If you have a problem in any of the photos in my gallery, contact me
via my email: me @ this domain and I'll do my best to resolve the issue.

[^1]: <https://www.theguardian.com/technology/2018/nov/02/flickr-delete-millions-photos-reduce-allowance-free-users>

A  => content/gallery/_index.md +11 -0
@@ 1,11 @@
---
title: "Gallery"
description: "Random pictures around the world"
---

Welcome to my gallery! Here is where I post high-resolution (uncompressed) travel pictures.
All photos are released under a Creative Commons license, which 
means you can reuse the pictures as long as you link back and it is not for commercial purposes.

> [Frequently Asked Questions](/gallery-faq)


A  => content/gallery/apply-rot.sh +4 -0
@@ 1,4 @@
#!/bin/sh
cd $1
mogrify -auto-orient *.jpg


A  => content/gallery/artis-zoo.md +13 -0
@@ 1,13 @@
---
title: Artis Royal Zoo
date: 2019-08-22
license: CC-BY-NC-SA-4.0
location: ["Amsterdam", "Netherlands"]
lat: 52.366111
lon: 4.916667
---

My visit to the Artis Royal Zoo, which is
founded in 1838 and has some 900 animal species.
It is one of the oldest zoos of Europe.


A  => content/gallery/edinburgh-citycentre.md +12 -0
@@ 1,12 @@
---
title: Visiting Edinburgh for the first time
date: 2018-07-16
license: CC-BY-NC-SA-4.0
location: ["Edinburgh", "United Kingdom"]
lat: 55.9514
lon: -3.2001
---

Edinburgh is the capital city of Scotland, which is a country on the northern 
part of the United Kingdom. I took these pictures when visiting Edinburgh for
the first time.

A  => content/gallery/holyrood.md +11 -0
@@ 1,11 @@
---
title: Over the cliffs of Holyrood Park
date: 2018-07-23
license: CC-BY-NC-SA-4.0
location: ["Holyrood Park", "Edinburgh", "United Kingdom"]
lat: 55.9496
lon: -3.1714
---

Holyrood Park is a public royal park in central Edinburgh. In this gallery, you
will see pictures of Arthur's Seat and a view of the city from the edge of the cliffs.

A  => content/gallery/hortus-botanicus.md +12 -0
@@ 1,12 @@
---
title: Hortus Botanicus (botanical garden)
date: 2019-08-28
license: CC-BY-NC-SA-4.0
location: ["Amsterdam", "Netherlands"]
lat: 52.3668
lon: 4.9079
---

My visit to the botanical garden in Amsterdam, which was
established in 1638. The garden has a cafe which uses some
ingredients from the garden.

A  => content/gallery/make-thumbs.sh +7 -0
@@ 1,7 @@
#!/bin/bash
cd $1
mkdir thumbs
for filename in *.jpg; do
  convert -define jpeg:size=720x400 $filename \
          -thumbnail '720x400>' thumbs/$filename
done

A  => content/gallery/morning-heriot-watt.md +11 -0
@@ 1,11 @@
---
title: Early Morning at Heriot-Watt University
date: 2018-10-08
license: CC-BY-NC-SA-4.0
location: ["Heriot-Watt University", "Edinburgh", "United Kingdom"]
lat: 55.9110702
lon: -3.3188644
---

These pictures were taking at Heriot-Watt University Edinburgh (Riccarton)
campus at 7am (before sunrise).

A  => content/gallery/optimise.sh +3 -0
@@ 1,3 @@
#!/bin/bash
cd $1
jpegoptim *.jpg

A  => content/gallery/rijksmuseum.md +10 -0
@@ 1,10 @@
---
title: Rijksmuseum (Dutch National Museum)
date: 2019-08-18
license: CC-BY-NC-SA-4.0
location: ["Amsterdam", "Netherlands"]
lat: 52.36
lon: 4.885278
---

My visit to the Rijksmuseum in Amsterdam.

A  => content/gallery/stedelijk.md +11 -0
@@ 1,11 @@
---
title: Stedelijk Museum Amsterdam (contemporary arts museum)
date: 2019-08-20
license: CC-BY-NC-SA-4.0
location: ["Amsterdam", "Netherlands"]
lat: 52.358056
lon: 4.879722
---

My visit to the Stedelijk Museum Amsterdam, which displays modern
and contemporary arts.

A  => content/now/_index.md +15 -0
@@ 1,15 @@
---
title: What I'm Doing Now
---

*This is a [now page](https://nownownow.com/about), which is where I write a
summary of what I am doing right now.*

**Last updated:** 15th May 2020

I'm currently a Computer Science student at Heriot-Watt University, stuck at
home working on internships, enjoying my last summer break of my undergraduate
study. All the work done during my current internships will be released under
an open-source license, more details coming soon.

I also try to manage my time and work on my existing open-source projects.

A  => content/projects/4DG.md +59 -0
@@ 1,59 @@
---
title: 4DG
GitURL: _4dg
section: "Web Applications"
MailingList: general
License: "GPL-3.0-only"
Language: Go
date: 2018-05-16
GoDoc: true
HasBuilds: true
Screenshot: "4DG.gif"
Description: "A 4D movie scripting program which runs on a Raspberry Pi using GPIO."
Usability: 1
---

### 1. Purpose
![A picture of 4DG control panel](../screenshots/4DG.gif)

The goal of this program is to allow anyone to create a 4D movie script. When run on a Raspberry Pi, the program will allow you to control Raspberry Pi's GPIO pins.  

The program can be controlled using a web interface, and is written in Go.  

### 2. Requirements

The following packages must be installed on your system.

- Go
- Git

A Raspberry Pi is also preferred, otherwise the program would
run in simulation mode.

### 3. Copying and contributing

This program is written by Humaid AlQassimi, and is distributed under
the GPLv3.


### 4. Download and install

```sh
$ go get -u git.sr.ht/~humaid/_4dg
$ go install git.sr.ht/~humaid/_4dg
```

### 5. Usage
If running on a Raspberry Pi, the program should run as
root, otherwise GPIO couldn't be accessed.

```sh
$ _4dg run
```

### 6. To-Do

- [ ] Unit testing
- [ ] Finish player interface
- [ ] Add different position format


A  => content/projects/CowChina.md +78 -0
@@ 1,78 @@
---
title: CowChina
GitURL: cowchina
MailingList: general
section: "Command-line Tools"
License: MIT
Language: Go
date: 2017-05-28
GoDoc: true
HasBuilds: true
Description: "CowChina is a logger for a variant of Spades called Hokm. It detects invalid moves (cheating) and winners."
Usability: 2
---

### 1. Description
CowChina is a logger for a variant of the Spades playing card game. It logs the moves, invalid cards (cheating) and winners.  

This could only be used with our variant of Spades, called Hokm.  

### 2. Requirements

The following packages must be installed on your system.

- Go
- Git

### 3. Copying and contributing

This program is written by Humaid AlQassimi, and is distributed
under the MIT license.  


### 4. Download and install

```sh
$ go get -u git.sr.ht/~humaid/cowchina
$ go install git.sr.ht/~humaid/cowchina
```

### 5. Usage

To run the program:
```sh
$ cowchina
```

To begin, the names of the four players, the
highest bid, bidding suit chosen, and highest bidding team is
entered.  

Then the each card is inputed. Below is a cheat sheet of possible
inputs.

#### 5.1. Input cheat sheet

| Input | Description |
| ---- | ----- |
| `ca` | Ace of Clubs |
| `da` | Ace of Diamonds |
| `ha` | Ace of Hearts |
| `sa` | Ace of Spades |
| `c{6-9}` | Clubs 6 to 9 |
| `s{6-9}` | Diamonds 6 to 9 |
| `h{6-9}` | Hearts 6 to 9 |
| `s{6-9}` | Spades 6 to 9 |
| `c{j,q,k}` | Clubs {jack, queen, king} |
| `d{j,q,k}` | Diamonds {jack, queen, king} |
| `h{j,q,k}` | Hearts {jack, queen, king} |
| `s{j,q,k}` | Spades {jack, queen, king} |
| `z` | Black Joker |
| `x` | Red Joker |
| `{enter}` | PASS |
| `{tab}` | Go back **(TODO)** |
| `:<id>` | Jump to player **(TODO)** |





A  => content/projects/G1MDecompiler.md +49 -0
@@ 1,49 @@
---
title: G1M Decompiler
GitURL: g1mdecompiler
section: "Command-line Tools"
MailingList: general
License: MIT
Language: Go
date: 2017-04-26
GoDoc: true
HasBuilds: true
Description: "A simple Casio Basic decoder for '.g1m' files generated by Casio calculators."
Usability: 3
---

### 1. Purpose
The goal of G1M Decompiler is to allow programmers to decode Casio Basic's "`.g1m`"
file into a readable text similarly what is shown on the calculator. I have
created this because the only available program to read G1M (Casio Basic) files
does not run on Linux, and there is no way to read the files.  

This is a one-way converter, and not all symbols are supported by this program (most
common symbols are).  

### 2. Requirements

The following packages must be installed on your system

- Go
- Git

You also need a Casio Basic file to decode.

### 3. Copying and contributing

This program is written by Humaid AlQassimi, and is distributed under
the MIT license.  

### 4. Download and install

```sh
$ go get -u git.sr.ht/~humaid/g1mdecompiler
$ go install git.sr.ht/~humaid/g1mdecompiler
```

### 5. Usage
The program outputs the decoded program to standard output.
```sh
$ g1mdecompiler [file] > [output]
```

A  => content/projects/JukeboxHopperMod.md +46 -0
@@ 1,46 @@
---
title: 'Jukebox Hopper Mod'
GitURL: jukeboxhopper
MailingList: general
section: "Games"
License: None
Language: Java
date: 2018-12-17
Screenshot: "JukeboxHopperMod.gif"
Description: "A simple Minecraft mod which allows you to use hoppers to insert records into jukeboxes."
Usability: 4
---

### 1. Description
![Picture of mod in-game](../screenshots/JukeboxHopperMod.gif)

This is a simple Minecraft mod which allows players to use
a hopper to insert a record into a Jukebox.  

### 2. Requirements

Requirements of using this mod:

- [Mod Coder Pack](https://minecraft.gamepedia.com/Programs_and_editors/Mod_Coder_Pack) for 1.12
- [Minecraft](https://minecraft.net) 1.12
- Java 8

### 3. Installation

1. Copy the `src` directory into your MCP workspace.
2. Locate the method `transferItemsOut()` in `net.minecraft.tileentity`.
3. Add the following snippet at the beginning of the method:

```java
// Make sure to import the package
if(JukeboxHopperMod.canTransferRecord(this)){
    JukeboxHopperMod.transferRecord(this);
    return true;
}
```

You should be able to have compile and run the game.  

This is tested to work with Minecraft 1.12, it is possible to use
this mod with other versions but may require some alternations
to the code.

A  => content/projects/Questions.md +77 -0
@@ 1,77 @@
---
title: Question (.NET)
GitURL: question
section: "Libraries"
License: MIT
Language: dotNET
date: 2015-02-10
NotAccepting: true
Description: "A library of classes which allows you to create questions easily for Console Applications."
Usability: 4
---

### 1. Description

Question is a simple class which allows you to create a questionaire in C#.NET or VB.NET.  
This is done as a school project in early 2015, and is released under the MIT license.

### 2. Requirements

This software might require proprietary software to run, which I no longer use. It may be possible to use Mono Runtime.

### 3. Usage

#### 3.1 Visual Basic

```basic
' Clone the object
Dim MyQuestion As Question

' Initialize
MyQuestion = New Question(
1, '  Question number/ID, will be displayed to user
"What is CIL?", ' The Question
"Code Intermedia Language", ' Option A
"Common Interface Locale", ' Option B
"Common Intermediate Language", ' Option C (Correct answer)
"Common Integer Language", ' Option D
Question.QuestionOption.C) ' The correct answer (In the case, C)

' Display the question
MyQuestion.Run()

' Check if the user passed that question
If MyQuestion.Passed Then
    Console.WriteLine("Good job!")
Else
    Console.WriteLine("You could do better next time!")
End If
```
#### 3.2 C Sharp

```c#
// Clone the object
Question myQuestion;

// Initialize
myQuestion = new Question(
    1, // Question number/ID, will be displayed to user
    "What is CIL?", // The Question
    "Code Intermedia Language", // Option A
    "Common Interface Locale", // Option B
    "Common Intermediate Language", // Option C (Correct answer)
    "Common Integer Language", // Option D
    Question.QuestionOption.C); // The correct answer (In this case, C)

// Display the question
myQuestion.Run();

// Check if the user passed that question
if (myQuestion.passed())
{
    Console.WriteLine("Good Job!");
} 
else {
    Console.WriteLine("You could do better next time!");
}
```

A  => content/projects/SpongePluginsArchive.md +20 -0
@@ 1,20 @@
---
title: Sponge Plugins Archive
GitURL: SpongePluginsArchive
section: "Games"
License: MIT
Language: Java
date: 2016-05-31
NotAccepting: true
Description: "Archive repository of my Sponge plugins."
Usability: 4
---
This is an archive repository to my three old Sponge plugins, which I am sure no longer works in the current version of Sponge server.

This repository includes;  

- PlayerLogger: A simple Sponge plugin which logs player events. 
- ChatLimiter: A simple Sponge plugin which allows you to limit the rate of chat messages and commands.
- SignColours: A simple plugin that colours signs with permissions.

All of which are released under the MIT license. The code was last updated in 2015.

A  => content/projects/WhatsMorse.md +50 -0
@@ 1,50 @@
---
title: WhatsMorse
GitURL: whatsmorse
MailingList: general
section: "Web Applications"
License: MIT
Language: Go
date: 2018-01-06
site: https://morse.hmksq.ae
GoDoc: true
HasBuilds: true
Screenshot: "WhatsMorse.gif"
Description: "A morse code web messaging application written in a two-hour hackaton."
Usability: 4
---
### 1. Description
![Screenshot of WhatsMorse page](../screenshots/WhatsMorse.gif)

WhatsMorse is a web messaging application which translates all your messages to morse code written in a two hour ["Stupid" Hackathon by Transcend](https://www.meetup.com/transcenddubai/events/245505285/) in January of 2018.
The goal of the hackathon was to create something useless (can be anything, not limited to computer software).  

The web app can be accessed from the URL of the project above.

### 2. Requirements

The following packages must be installed on your system.

- Go
- Git

### 3. Copying and contributing

This program is written by Humaid AlQassimi, and is distributed
under the MIT license.  

### 4. Download and install

```sh
$ go get -u git.sr.ht/~humaid/whatsmorse
$ go install git.sr.ht/~humaid/whatsmorse
```

### 5. Usage
To run the web app, `$PORT` must be set in the enviornment.
```sh
$ export PORT=8080
$ whatsmorse
```
The web app will be accessible at `http://localhost:8080`.


A  => content/projects/XMath.md +31 -0
@@ 1,31 @@
---
title: XMath
section: "Mobile Applications"
date: 2017-12-06
site: https://play.google.com/store/apps/details?id=appinventor.ai_humaid_andr.XMath&hl=en_US
Description: "A tiny learning management system for Android."
Usability: 3
---

This is a coursework project for the Interactive System (F27IS) course at Heriot-Watt
University. This Android application is made using MIT App Inventor 2, and below
is the description of the application as published on the Google Play Store.  

Download the App Inventor file: [`XMath.aia`](XMath.aia) *(160K)*

----------

XMath is a tiny learning management system application for Android, it helps
teachers and tutors to setup mathematical questions. The questions can be setup
and solved on the same device, or can be setup over Bluetooth so that the
instructor could beam the questions to students devices. And then students can
send back the answers to the instructor's device.

The application has two accounts, a student's account and an instructor's
account. The instructor is able to set up the quiz and review the answers
Student are able to solve the quiz if it is set up. And the instructor has
options to host a Bluetooth server for devices setup on Bluetooth mode.

You can have up to ten times tables questions (for historical reasons). And the
instructor is required to set up a new quiz each time a quiz is finished, or
receive the quiz over Bluetooth if it is setup on Bluetooth mode.

A  => content/projects/_index.md +11 -0
@@ 1,11 @@
---
title: Projects
description: "A list of my open-source projects"
---
Below is a list of my projects, most of which are released under
an open-source license. Usage and installation instructions are included
in each of the projects page.  

Check out the [contribution guide](/contribution).
Contribution is welcome and accepted. If you use any of my projects,
I wish to hear what you think of it.

A  => content/projects/bmo.md +47 -0
@@ 1,47 @@
---
title: bmo Robot Animations
section: "Others"
GitURL: bmo
Language: PHP
License: None
date: 2018-11-12
GoDoc: false
NotAccepting: true
Description: "Robot's face animations for Interaction Design expo project."
---

### Description

This repository contains the files used in our Interaction Design expo
project, where BMO (Best Medical Operator) is a medicine dispensing
robot for the elderly. It also has a simple PHP application to allow
the "wizard" to control the robot's facial expression.  

Images and animations are created using GIMP.  

Below is a list of BMO's facial expression images and animations.  

#### sleeping.gif
![BMO Sleeping Animation](sleeping.gif)

#### straightface.png
![BMO Straight Face](straightface.png)

#### simplesmile.png
![BMO Simple Smile Face](simplesmile.png)

#### simplesmileblink.gif
![BMO Simple Smile Face with Blinking](simplesmileblink.gif)

#### happy.png
![BMO Happy Face](happy.png)

#### happyblink.gif
![BMO Happy Face with Blinking](happyblink.gif)

#### blushing.gif
![BMO Blushing Animated Face](blushing.gif)

#### worried.png
![BMO Worried Face](worried.png)


A  => content/projects/bmo/blushing.gif +0 -0
A  => content/projects/bmo/happy.png +0 -0
A  => content/projects/bmo/happyblink.gif +0 -0
A  => content/projects/bmo/simplesmile.png +0 -0
A  => content/projects/bmo/simplesmileblink.gif +0 -0
A  => content/projects/bmo/sleeping.gif +0 -0
A  => content/projects/bmo/straightface.png +0 -0
A  => content/projects/bmo/worried.png +0 -0
A  => content/projects/cloudflare-ddns-client.md +40 -0
@@ 1,40 @@
---
title: Cloudflare DDNS Client
GitURL: cloudflare-ddns-client
section: "Command-line Tools"
MailingList: general
License: BSD-2-Clause
Language: Go
date: 2020-06-10
GoDoc: false
IssueTracker: false
Description: "A simple Cloudflare Dynamic DNS Client."
Usability: 4
---

### 1. Description

This is a simple Cloudflare Dynamic DNS client, which updates a record to the
current public IP address. I have created this as I couldn't find a very simple
solution to this very simple problem.

### 2. Requirements

The following packages must be installed on your system.

- Go *(tested with 1.14)*

### 3. Installation and Usage

```
$ go install git.sr.ht/~humaid/cloudflare-ddns-client
$ export APIKey=<API KEY here>
$ export Zone=<Zone ID here>
$ export RecordName=<Full record name here, e.g. foo.example.com>
$ cloudflare-ddns-client
```

You will have to [create an API token](https://dash.cloudflare.com/profile/api-tokens)
which has the permission to edit zone DNS (`Zone.DNS`).

This program will check every minute unless interrupted.

A  => content/projects/f27wd-cw2-nonamewebteam.md +10 -0
@@ 1,10 @@
---
title: F27WD Coursework 2 Submission
GitURL: f27wd-cw2-nonamewebteam
License: None
Language: PHP
date: 2018-03-25
NotAccepting: true
Description: "Heriot-Watt University F27WD CW2 Submission"
hidden: true
---

A  => content/projects/ff-format-patch.md +95 -0
@@ 1,95 @@
---
title: Fast-Forward with steps formatting
GitURL: ff-format-patch
section: "Command-line Tools"
MailingList: general
License: "GPL-2.0-or-later"
Language: C
date: 2019-10-24
IssueTracker: true
Description: "A patch for FF v2.3 to allow steps to be formatted for humans."
Usability: 4
---

### 1. Description

This is a patch for [Fast-Forward](https://fai.cs.uni-saarland.de/hoffmann/ff.html)
which allows the steps to be formatted in a human-readable way, by providing a
'format file' as a parameter.

### 2. Requirements

The following packages must be installed on your system.

- Unix patch utility
- GNU Make
- A C compiler (defaults to gcc)
- GNU Bison
- flex

This patch is written for FF v2.3, and will probably not work with later
versions.

### 3. Copying and contributing

Fast-Forward is released under the GNU General Public License version 2 or
later, and so is the patch.

### 4. Downloading and patching

- [`steps-format-v1.patch`](steps-format-v1.patch) *(12K)*
- [`FF-v2.3.tgz`](https://fai.cs.uni-saarland.de/hoffmann/ff/FF-v2.3.tgz)
	*(72K)*

Extract FF, and copy the patch file in the extracted directory. Then run the
following command to apply the patch and compile:

```sh
$ patch < steps-format-v1.patch
$ make
```
Then you will have a binary with the patch.

### 5. Example Usage

The patch adds an additional parameter `-h` to the program, which allows you
to pass a 'format file.' For example:

```sh
$ ./ff -o domain.pddl -f prob.pddl -h problem-format.txt
```

And let's say we have a particular `personWalk` action:
```lisp
(:action personWalk
	:parameters
	(?from   - room
	 ?to     - room
	 ?person - person)
```
To format the output of this action, we can add the following to our format
file:
```text
PERSONWALK $2 walks from the $0 to the $1
```
Now that we run the command, we should get:
```text
[...]
ff: found legal plan as follows

step    0: PERSONWALK HUMAID walks from the KITCHEN to the LIVING-ROOM
[...]
```

### 6. Binary builds

Binary compiled and linked on `Linux kudu 4.19.0-6-amd64 #1 SMP Debian
4.19.67-2+deb10u1 (2019-09-20) x86_64 GNU/Linux`. Should work on most modern
Linux x86_64 glibc systems.  

- [`ff`](ff) *(936K)*

### 7. Change log

- v0.1 *(Oct 24 2019)*
  - Initial release

A  => content/projects/ff-format-patch/ff +0 -0
A  => content/projects/ff-format-patch/steps-format-v1.patch +288 -0
@@ 1,288 @@
diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/ff.h FF-v2.3-step-format/ff.h
--- FF-v2.3/ff.h	2016-10-04 12:31:46.000000000 +0100
+++ FF-v2.3-step-format/ff.h	2019-10-24 11:36:39.523041142 +0100
@@ -357,6 +357,7 @@
   char path[MAX_LENGTH];
   char ops_file_name[MAX_LENGTH];
   char fct_file_name[MAX_LENGTH];
+  char format_file_name[MAX_LENGTH];
   int display_info;
   int debug;
 
diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/format.c FF-v2.3-step-format/format.c
--- FF-v2.3/format.c	1970-01-01 01:00:00.000000000 +0100
+++ FF-v2.3-step-format/format.c	2019-10-24 11:36:39.523041142 +0100
@@ -0,0 +1,82 @@
+#include "format.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+StepFormatNode * headStepFormat;
+StepFormatNode * tailStepFormat;
+
+void addStepFormat(StepFormat *format) {
+	if (format == NULL)
+		return;
+
+	StepFormatNode *newNode = malloc(sizeof(StepFormatNode));
+	newNode->node = format;
+	newNode->next = NULL;
+
+	if (tailStepFormat == NULL) {
+		tailStepFormat = newNode;
+		headStepFormat = newNode;
+	} else {
+		tailStepFormat->next = newNode;
+		tailStepFormat = newNode;
+	}
+}
+
+StepFormat * getAction(char *name) {
+	if (headStepFormat == NULL || name == NULL)
+		return NULL;
+	
+	StepFormatNode * tempNode = headStepFormat;
+	while(tempNode  != NULL) {
+		if(strcmp(name, tempNode->node->actionName)==0) {
+			return tempNode->node;
+		}
+		tempNode = tempNode->next;
+	}
+	return NULL;
+}
+
+int loadFormatFile(FILE *f) {
+	headStepFormat = NULL;
+	tailStepFormat = NULL;
+	char last[128];
+	size_t charPointer = 0;
+	int formatsCount = 0;
+
+	char ch = getc(f);
+	while (ch != EOF) {
+		if (ch != '\n') {
+			if (charPointer < sizeof(last)){
+				last[charPointer++] = ch;
+			}
+		} else {
+			if(charPointer < sizeof(last))
+				last[charPointer] = '\0';
+
+			if(charPointer >0) {
+				StepFormat *newFormat = malloc(sizeof(StepFormat));
+				memset(newFormat, '\0', sizeof(StepFormat));
+				// Get the action name and format
+				char *ptr = strtok(last, " ");
+				char * actionName = malloc(sizeof(last));
+				strcpy(actionName, ptr);
+				newFormat->actionName = actionName;
+				size_t size = strnlen(actionName, sizeof(last));
+				ptr = ptr +size;
+				ptr++;
+				char * stepFormat = malloc(sizeof(last));
+				strcpy(stepFormat, ptr);
+				newFormat->stepFormat = stepFormat;
+				// Add to linked list
+				addStepFormat(newFormat);
+				formatsCount++;
+				//printf("action: %s\n", newFormat->actionName);
+				//printf("format: %s\n", newFormat->stepFormat);
+			}
+			charPointer = 0;
+		}
+		ch = getc(f);
+	}
+	return formatsCount;
+}
diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/format.h FF-v2.3-step-format/format.h
--- FF-v2.3/format.h	1970-01-01 01:00:00.000000000 +0100
+++ FF-v2.3-step-format/format.h	2019-10-24 11:36:39.523041142 +0100
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+typedef struct StepFormat StepFormat;
+typedef struct StepFormatNode StepFormatNode;
+
+struct StepFormat {
+	char *actionName;
+	char *stepFormat;
+};
+
+struct StepFormatNode {
+	StepFormat *node;
+	StepFormatNode *next;
+};
+
+void addStepFormat(StepFormat * format);
+int loadFormatFile(FILE *f);
+StepFormat * getAction(char *name);
diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/main.c FF-v2.3-step-format/main.c
--- FF-v2.3/main.c	2015-11-05 08:59:14.000000000 +0000
+++ FF-v2.3-step-format/main.c	2019-10-24 11:36:39.523041142 +0100
@@ -73,7 +73,7 @@
 
 #include "relax.h"
 #include "search.h"
-
+#include "format.h"
 
 
 
@@ -493,6 +493,8 @@
   /* same for fct file 
    */
   char fct_file[MAX_LENGTH] = "";
+
+  char format_file[MAX_LENGTH] = "";
   
   struct tms start, end;
 
@@ -532,7 +534,14 @@
    */
   sprintf(ops_file, "%s%s", gcmd_line.path, gcmd_line.ops_file_name);
   sprintf(fct_file, "%s%s", gcmd_line.path, gcmd_line.fct_file_name);
+  printf("file: %s\n", gcmd_line.format_file_name);
+  if (gcmd_line.format_file_name[0] != '\0') {
+	printf("ff: loading custom format file...\n");
+  	sprintf(format_file, "%s%s", gcmd_line.path, gcmd_line.format_file_name);
+	FILE *f = fopen(gcmd_line.format_file_name, "r");
 
+	printf("ff: loaded formats for %d actions!\n", loadFormatFile(f));
+  }
 
   /* parse the input files
    */
@@ -832,7 +841,8 @@
   printf("\nOPTIONS   DESCRIPTIONS\n\n");
   printf("-p <str>    path for operator and fact file\n");
   printf("-o <str>    operator file name\n");
-  printf("-f <str>    fact file name\n\n");
+  printf("-f <str>    fact file name\n");
+  printf("-h <str>    format file name\n\n");
   printf("-i <num>    run-time information level( preset: 1 )\n");
   printf("      0     only times\n");
   printf("      1     problem name, planning process infos\n");
@@ -893,6 +903,7 @@
   
   memset(gcmd_line.ops_file_name, 0, MAX_LENGTH);
   memset(gcmd_line.fct_file_name, 0, MAX_LENGTH);
+  memset(gcmd_line.format_file_name, 0, MAX_LENGTH);
   memset(gcmd_line.path, 0, MAX_LENGTH);
 
   while ( --argc && ++argv ) {
@@ -919,6 +930,9 @@
 	case 'd':
 	  sscanf( *argv, "%d", &gcmd_line.debug );
 	  break;
+	case 'h':
+	  strncpy( gcmd_line.format_file_name, *argv, MAX_LENGTH );
+	  break;
 	default:
 	  printf( "\nff: unknown option: %c entered\n\n", option );
 	  return FALSE;
diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/output.c FF-v2.3-step-format/output.c
--- FF-v2.3/output.c	2016-10-04 12:31:46.000000000 +0100
+++ FF-v2.3-step-format/output.c	2019-10-24 11:36:39.523041142 +0100
@@ -57,7 +57,7 @@
 #include "ff.h"
 
 #include "output.h"
-
+#include "format.h"
 
 
 
@@ -729,14 +729,75 @@
        !a->pseudo_action ) {
     printf("REACH-GOAL");
   } else {
-    printf("%s", a->name ); 
-    for ( i = 0; i < a->num_name_vars; i++ ) {
-      printf(" %s", gconstants[a->name_inst_table[i]]);
-    }
+	StepFormat *format = getAction(a->name);
+	printf("%s", a->name ); 
+	if (format != NULL) {
+		char *formatted = malloc(sizeof(char)*256);
+		char *repChar = malloc(sizeof(char)*12);
+		strcpy(formatted, format->stepFormat);
+		for ( i = 0; i < a->num_name_vars; i++ ) {
+		  sprintf(repChar, "$%d", i);
+		  formatted = str_replace(formatted, repChar,
+				  gconstants[a->name_inst_table[i]]);
+		}
+		printf(" %s", formatted);
+		free(repChar);
+	} else {
+		for ( i = 0; i < a->num_name_vars; i++ ) {
+		  printf(" %s", gconstants[a->name_inst_table[i]]);
+		}
+	}
   }
 
 }
 
+// from: https://stackoverflow.com/a/779960
+// You must free the result if result is non-NULL.
+char *str_replace(char *orig, char *rep, char *with) {
+    char *result; // the return string
+    char *ins;    // the next insert point
+    char *tmp;    // varies
+    int len_rep;  // length of rep (the string to remove)
+    int len_with; // length of with (the string to replace rep with)
+    int len_front; // distance between rep and end of last rep
+    int count;    // number of replacements
+
+    // sanity checks and initialization
+    if (!orig || !rep)
+        return NULL;
+    len_rep = strlen(rep);
+    if (len_rep == 0)
+        return NULL; // empty rep causes infinite loop during count
+    if (!with)
+        with = "";
+    len_with = strlen(with);
+
+    // count the number of replacements needed
+    ins = orig;
+    for (count = 0; tmp = strstr(ins, rep); ++count) {
+        ins = tmp + len_rep;
+    }
+
+    tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
+
+    if (!result)
+        return NULL;
+
+    // first time through the loop, all the variable are set correctly
+    // from here on,
+    //    tmp points to the end of the result string
+    //    ins points to the next occurrence of rep in orig
+    //    orig points to the remainder of orig after "end of rep"
+    while (count--) {
+        ins = strstr(orig, rep);
+        len_front = ins - orig;
+        tmp = strncpy(tmp, orig, len_front) + len_front;
+        tmp = strcpy(tmp, with) + len_with;
+        orig += len_front + len_rep; // move to next "end of rep"
+    }
+    strcpy(tmp, orig);
+    return result;
+}
 
 
 
diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/output.h FF-v2.3-step-format/output.h
--- FF-v2.3/output.h	2010-06-21 09:38:27.000000000 +0100
+++ FF-v2.3-step-format/output.h	2019-10-24 11:36:39.523041142 +0100
@@ -77,7 +77,7 @@
 void print_Fact( Fact *f ); 
 void print_ft_name( int index );
 void print_op_name( int index );
-
+char *str_replace(char *orig, char *rep, char *with);
 
 
 void print_plan( void );


A  => content/projects/godoc2markdown.md +60 -0
@@ 1,60 @@
---
title: godoc2markdown
GitURL: godoc2markdown
section: "Command-line Tools"
License: BSD-2-Clause
Language: Go
date: 2019-10-11
GoDoc: true
LatestVersion: v0.1
HasBuilds: true
MailingList: general
IssueTracker: true
Description: "A program which converts Go Doc output to Markdown."
Usability: 3
---

### 1. Description

This is a simple Unix-like tool which allows you to pipe the output of `go doc`
to generate Markdown.

The purpose of this tool is to allow private Go projects generate Markdown
documentation, where websites like [GoDoc](https://godoc.org) has no access
to the repository.

### 2. Requirements

The following packages must be installed on your system.

- Go
- Git
- GNU Make

### 3. Copying and contributing

This program is written by Humaid AlQassimi,
and is distributed under the BSD 2 Clause license.  

### 4. Download and install

```sh
$ git clone https://git.sr.ht/~humaid/godoc2markdown
$ cd godoc2markdown
$ make install
```

### 5. Example Usage

If you want to generate a Markdown of the package in the current directory,
and save it to a file, you can run.

```sh
$ go doc -all . | godoc2markdown > DOCUMENTATION.md
```

### 6. Change log

- v0.1 *(Oct 11 2019)*
  - Initial release


A  => content/projects/hmsh.md +50 -0
@@ 1,50 @@
---
title: hmsh
GitURL: hmsh-go
section: "Command-line Tools"
MailingList: general
License: BSD-2-Clause
Language: Go
date: 2019-04-13
GoDoc: true
HasBuilds: true
IssueTracker: true
LatestVersion: v0.2
Description: "Humaid's un-POSIX-compliant shell."
Usability: 2
---

### 1. Description

hmsh is a very minimal shell, it still doesn't support all built-in shell commands.

This program is rewritten in Go in September 2019, you can still find the old C source at
[git.sr.ht/~humaid/hmsh](https://git.sr.ht/~humaid/hmsh).


### 2. Requirements

The following packages must be installed on your system.

- go

### 3. Copying and contributing

This program is written by Humaid AlQassimi,
and is distributed under the BSD 2 Clause license.  

### 4. Download and compile

```sh
$ git clone git.sr.ht/~humaid/hmsh-go
$ cd hmsh-go
$ go build
```

### 5. Change log

- v0.1 *(Apr 14 2019)*
  - Initial release.
- v0.2 *(Sep 15 2019)*
  - Rewrite in Go.


A  => content/projects/horse-site.md +23 -0
@@ 1,23 @@
---
title: Horse Riding Scheduler
date: 2018-08-01
section: "Web Applications"
site: https://haro.team
proprietary: true
Description: "A web application for Equestrian Clubs to manage daily schedule of trainers and riders."
draft: true
---

This is a web application for equestrian clubs to manage their daily schedule of trainers and riders. It
allows the club to keep track of the horses and riders, generate reports and print formatted schedules.
This project is written by me and my peers from university as a part of a small web development team.  

The goal of this application is to make it easier for clubs to manage schedules using a modern web-based
solution, which is fast and reliable, and can run on any browser. Our focus is on making the app easy-to-use
and platform-independent but remain still as powerful as traditional schedule management software.

Team members who are involved in this project:

- Humaid (me)
- Akilan Selvacoumar ([website](http://akilan.io))
- Rikesh Makwana ([website](http://rikeshmm.com))

A  => content/projects/hstatus.md +62 -0
@@ 1,62 @@
---
title: hstatus
GitURL: hstatus
section: "Others"
License: BSD-2-Clause
Language: Rust
date: 2020-04-12
LatestVersion: v0.1
HasBuilds: true
MailingList: general
IssueTracker: false
Description: "A dwm status monitor updater with multiple timezones and COVID19 stats."
Usability: 4
---

### 1. Description

hstatus is a simple dwm status monitor updater. It currently includes:

- Multiple timezones (Local and UK time, using [chrono])
- Battery status
- Load status
- COVID19 status (with [caching], updates every 6 hours)

The reason for creating this project was to learn [Rust].

[chrono]: https://crates.io/crates/chrono
[caching]: https://crates.io/crates/cached
[Rust]: https://www.rust-lang.org/

### 2. Requirements

The following packages must be installed on your system.

- Rust and Cargo
- Git
- libX11-devel
- dwm _(obviously)_

And if you decide to keep the COVID19 status:

- libressl-devel (or your system's equivalent)
- curl

### 3. Copying and contributing

This program is written by Humaid AlQassimi,
and is distributed under the BSD 2 Clause license.  

### 4. Download and build

```sh
$ git clone https://git.sr.ht/~humaid/hstatus
$ cd hstatus
$ cargo build
```

### 6. Change log

- v0.1 *(Apr 12 2020)*
  - Initial release


A  => content/projects/iglu.md +90 -0
@@ 1,90 @@
---
title: iglü
section: "Others"
date: 2020-04-23
site: https://github.com/Nacdlow
Description: "A smart home system of the future (group project)."
Usability: 4
---

### What is this?

[**Check out our documentary (YouTube)**](https://www.youtube.com/watch?v=KMfItuTf2jQ)

As a part of a two-semester long Software Engineering project at Heriot-Wat
University, we (a group of six students) have been asked to create a fictitious
software engineering company which is building a smart home system of the
future to a client. During the 7 months we have built:

- A smart home system with a [plugin API (over RPC)](https://github.com/hashicorp/go-plugin)
  as a responsive (progressive) web application.
	- Includes a simulation module for testing.
- A Minecraft server ([Spigot]) plugin for testing and demonstrating the
  smart home system on an environment which we can control. Hooked using our
  plugin API.
- An internal wiki with training/learning material, log and recording of
  meetings, style guides, member roles, research and brainstorming, etc.
- A tool to allow us to generate Markdown documentation based on `go doc`, as
  no good solution exists.
- A custom DNS server which allows us to have specific responses to specific
  domains (for testing on mobile devices).
- A testing payments gateway with [Stripe].
- A custom Raspbian distribution for use with our Raspberry Pi (enclosed in our
  custom 3D-printed case), this enables iglü as a system service, and adds
  debugging functionality (Ethernet gadget, serial console, pre-setup WPA2
  Enterprise with wpa\_supplicant, etc).
- A plugin packager (with GUI) which speeds up cross-compiling, compressing and
  packaging plugins directly for the marketplace.
- A marketplace website, generated with a static website generator ([Hugo]).

### What tools were used?

The core parts of the project (such as the web application server and plugin
API) is written in [Go], but other languages have been used in different parts
of the project, such as Java for the Minecraft plugin, [LaTeX] for
collaborating on requirements specifications. Getting the e-ink display to work
required us to modify the [Waveshare driver](https://github.com/waveshare/e-Paper)
so we can display the output upside-down, which was a bit tricky. The program
to update the e-ink display was written in Python.

We even used tools such as [Adobe XD] for prototyping and usability testing,
[Tinkercad] for creating the iglü case which was 3D printed (thanks to
Edinburgh Hacklab). Other tools used were GIMP, Adobe Lightroom, Photoshop,
After Effects, Premiere Pro, and Illustrator, these were used in making
graphics, banners, logos, promotional video and other forms of artwork. We are
lucky to have a group with a diverse range of skills.

### Our group

The group consists of:

- [Alakbar Zeynalzade]\: Reporter and Organisational Manager
- [Amaanullah Akram]\: Organisational and Technical Manager
- [Humaid AlQassimi]\: Leader and Technical Manager
- [Mark S Bird]\: Liaison
- [Numan Ali]\: Technical Manager
- [Ruaridh Mollica]\: Organisational Manager


### Open-sourcing

The projects are still pending to be released under an open-source license.

The projects' source code can be found on our [GitHub organisation](https://github.com/Nacdlow).

[Alakbar Zeynalzade]: https://www.linkedin.com/in/alakbarzeynalzade/
[Amaanullah Akram]: https://www.linkedin.com/in/amaanakram/
[Humaid AlQassimi]: https://humaidq.ae
[Mark S Bird]: https://www.linkedin.com/in/mark-bird-/
[Numan Ali]: https://github.com/n-ali1
[Ruaridh Mollica]: https://www.linkedin.com/in/ruaridhmollica/

[LaTeX]: https://www.latex-project.org/
[Adobe XD]: https://www.adobe.com/products/xd.html
[Spigot]: https://www.spigotmc.org/wiki/about-spigot/
[Hugo]: https://gohugo.io
[Go]: https://go.dev
[Tinkercad]: https://www.tinkercad.com/
[Stripe]: https://stripe.com/

[AGPL license]: https://tldrlegal.com/license/gnu-affero-general-public-license-v3-(agpl-3.0)

A  => content/projects/learning-bot.md +34 -0
@@ 1,34 @@
---
title: Learning Bot
date: 2019-06-04
section: "Web Applications"
site: https://github.com/peergramming/learning-bot
Description: "A GitLab bot for providing programming advice based on code repair tools."
Language: Go
License: AGPL-3.0-only
Usability: 4
---

### Overview

The aim of this project is to create a GitLab bot which would download students
code and generate a report containing advice on repairing issues found in the source code.  

This project is developed as an internship project at Heriot-Watt University.  

### Description

This program uses [checkstyle] list the issues found in the students' code. The
program parses that output and generates a report, posting it in the GitLab
issue tracker of that project.

Configuration is simple, and no database is required (when using SQLite). A bot
user has to be created first on GitLab, and it must be added to the Learning
Bot configuration.

The Learning Bot checks multiple repositories concurrently, and the maximum
number of workers can be defined in the configuration file.

More details on setting up is available on the [GitHub project page](https://github.com/peergramming/learning-bot).

[checkstyle]: https://checkstyle.org/

A  => content/projects/neatnote.md +128 -0
@@ 1,128 @@
---
title: Neat Note
GitURL: neatnote
MailingList: general
section: "Web Applications"
License: AGPL-3.0-only
Language: Go
date: 2019-12-29
GoDoc: true
HasBuilds: true
IssueTracker: true
Description: "A Lobsters-like web app for university students to post notes and question."
LatestVersion: v0.3.3
Usability: 4
---
### 1. Description

This is a web app which allows students to share their lecture notes, helpful
resources, start discussions, or ask questions. This site is separated into
different sections for different courses.

Users are authenticated by emailing the users a one-time password to their
university email address, which also confirms that they are either students or
faculty of that university.

Markdown, HTML, and LaTeX are supported in comments and posts, so students are
able to write notes in any way they are comfortable with. [goldmark] is used
for rendering Markdown, and [bluemonday] sanitizes the output which includes
user added HTML. LaTeX is rendered using [MathJax] on the client side.

Users are able to upvote posts, and posts with more upvotes (called iota), will
appear on top. This is somewhat similar to upvoting in Hacker News or Reddit,
which many are familiar with.

### 2. Requirements

The following packages must be installed on your system.

- Go *(tested with 1.13)*
- Git
- GNU Make

### 3. Copying and contributing

This program is written by Humaid AlQassimi, and is distributed under the
AGPL 3.0 only license. This means if you make your
own fork of this app, you must release its source to its users under the
same license.

### 4. Downloading and running

```sh
$ git clone https://git.sr.ht/~humaid/neatnote
$ cd neatnote
$ make
```

### 5. Setup & Usage
Running the web server will automatically generate a configuration file
(`config.toml`) if it is not yet created.
```sh
$ ./neatnote run
```
The program will exit when run for the first time, prompting you to configure
the program. Check out the [configuration documentation](https://godoc.org/git.sr.ht/~humaid/neatnote/modules/settings#DatabaseConfiguration).

If you are using the MySQL driver you must create a table with the same name as
the user. You will have to also add the `session` table:

```sql
CREATE TABLE `session` (
    `key`       CHAR(16) NOT NULL,
    `data`      BLOB,
    `expiry`    INT(11) UNSIGNED NOT NULL,
    PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
```

You should then run the web server again, and login with your account. You can
set your account as admin by running the following command:
```sh
$ ./neatnote set-admin admin@example.com
```

You may revoke the admin status by using the `--status false` flag.

The last thing to do is to add the courses needed on the web interface, using
the admin account.

### 6. Change log

- v0.3.3 *(Feb 10 2020)*
	- Fixes [a security issue](https://lists.sr.ht/~humaid/general/%3C20200210185437.338764ef%40serow%3E).
- v0.3.2 *(Jan 13 2020)*
	- Nicely format blockquotes and code blocks.
	- Make badge radio button labels clickable in the profile.
	- Fix issues with transparent images in dark mode and large images in
	  mobile view.
- v0.3.1 *(Jan 12 2020)*
	- Rename login validation to verification.
	- Show badges in the registered users listing in admin dashboard.
	- Show comments in request data, and hide empty fields.
- v0.3 *(Jan 12 2020)*
	- Add an admin dashboard, with option to suspend and view users.
	- Add lite/print page for posts.
	- Mobile friendlyness and dark theme improvements.
	- Redirect for mismatching post/course ID.
	- Other styling tweaks.
	- Other templating and routing improvements.
- v0.2 *(Jan 11 2020)*
	- Revamp design to be more modern.
	- Moved access control and context initialisation to middlewares to reduce
		code duplication.
	- Other improvements and bug fixes.
- v0.1.1 *(Jan 10 2020)*
	- Fixed bug where posts don't load for non-logged in users.
- v0.1.0 *(Jan 9 2020)*
	- Initial release.
	- Has basic features such as:
		- Authentication.
		- Posting, editing posts and comments.
		- Deleting posts and comments (admin).
		- Voting and sorting.
		- Badges, display names, anonymous posting.

[goldmark]: https://github.com/yuin/goldmark
[bluemonday]: https://github.com/microcosm-cc/bluemonday
[MathJax]: https://www.mathjax.org/

A  => content/projects/ns2-trace-go.md +74 -0
@@ 1,74 @@
---
title: NS2 Trace File Analysis Tool
GitURL: ns2-trace-go
MailingList: general
section: "Web Applications"
License: AGPL-3.0-only
Language: Go
date: 2019-11-24
site: https://ns2.humaidq.ae
GoDoc: true
HasBuilds: true
LatestVersion: v0.1
IssueTracker: true
Screenshot: "ns2-analysis.png"
Description: "A trace analysis web app for Network Simulator 2 (ns2) trace files"
Usability: 3
draft: true
---
### 1. Description
![Screenshot of the analysis page showing statistics of the trace file and
a table of connections with buttons to view jitter](../screenshots/ns2-analysis.png)

This web application allows you to analyse [trace files](http://nile.wpi.edu/NS/analysis.html)
generated by [ns2](https://www.isi.edu/nsnam/ns/) (Network Simulator 2). It
will generate the following:

- Jitter graphs for all segments of the network
- Number of:
  - Received packets
  - Dropped packets
  - Lost packets.
  - Collisions in the network
  - Average hops
  - Total active nodes
  - Trace file entries (which are `tcp`, `udp`, or `cbr`)
- Average delay
- Total bandwidth used
- Total network time
- Network throughput

### 2. Requirements

The following packages must be installed on your system.

- Go
- Git

You also need to have a trace file so use on the web application.

### 3. Copying and contributing

This program is written by Humaid AlQassimi, and is distributed under the
AGPL 3.0 only license. This means if you make your
own version of this tool, you must release its source under the same license.

### 4. Downloading and building

```sh
$ git clone https://git.sr.ht/~humaid/ns2-trace-go
$ cd ns2-trace-go
$ go build *.go
```

### 5. Usage
You can optionally set the port, by setting the `PORT` environment variable.
```sh
$ ns2-trace-go
```
By default, it will use port `:4000`.

### 6. Change log

- v0.1 *(26 Nov 2019)*
  - Initial release

A  => content/projects/oww-prot.md +33 -0
@@ 1,33 @@
---
title: The Oww Protocol
date: 2019-12-15
Description: "A joke application protocol allowing users to send \"Oww\" messages to the server."
---

As the Great [Akilan](https://akilan.io) always said... "Oww". This protocol
allows people to post message on a messaging board "the Oww board".  

There are two methods in this protocol. You can either:

- Post a message in the following format:  
	`<Name>: Oww <optional message>`  
	e.g.  
	`Humaid: Oww that's cool`  

	All messages must start with "Oww" (case-insensitive), and the server should
	always respond with an `Oww` if the request is successful.
- Read the Oww board:  
	`Owws`


You can give it a try if you have the `nc` (netcat) tool installed.

```sh
$ echo "Naeem: Oww" | nc humaidq.ae 1999
$ echo "Owws" | nc humaidq.ae 1999
```

### Server Information

The server is implemented in [Go](https://golang.org), you can [view the source
here](https://git.sr.ht/~humaid/oww-prot/tree/master/main.go).

A  => content/projects/pew-pew-shooter.md +49 -0
@@ 1,49 @@
---
title: "Pew Pew Shooter: Return of the Pews"
GitURL: pew-pew-shooter
section: "Games"
License: GPL-3.0-only
Language: Lua
date: 2019-07-09
LatestVersion: v0.2.1
Description: "A programming-themed space shooter game written in Lua with LÖVE framework."
Usability: 3
---

### 1. Description

Pew Pew Shooter is a programming-themed space shooter game which allows you to
shoot code and errors to enemies.

This game is developed by me and [Abdelrahman Elkabbany](https://github.com/a9800)
as to learn a new language and framework.

### 2. Requirements

The following packages must be installed on your system.

- Git
- Lua
- LOVE *(tested with 0.9.1 and 11.2)*

### 3. Copying and contributing

This program is written by Humaid AlQassimi and Abdelrahman Elkabbany,
and is distributed under the GPL 3.0 license.  

### 4. Download and running

```sh
$ git clone https://git.sr.ht/~humaid/pew-pew-shooter
$ cd pew-pew-shooter
$ love .
```
## 5. Change log

- v0.2.1 *(Aug 26 2019)*
  - Added license file
- v0.2 *(Aug 26 2019)*
  - Randomise enemies/bullets images.
  - Add pew sounds..
- v0.1 *(Jul 9 2019)*
  - Initial release.

A  => content/projects/pomodoro.md +57 -0
@@ 1,57 @@
---
title: Pomodoro
GitURL: c-pomodoro
section: "Command-line Tools"
MailingList: general
License: BSD-2-Clause
Language: C
date: 2019-04-07
GoDoc: false
IssueTracker: true
LatestVersion: v0.1
Description: "A suckless pomodoro application written in C."
Usability: 1
draft: true
---

### 1. Description

This is a suckless pomodoro command-line application I created, as I couldn't
find any good pomodoro command-line application.

### 2. Requirements

The following packages must be installed on your system.

- tcc (you need to modify Makefile to use a different compiler)
- make
- git

### 3. Copying and contributing

This program is written by Humaid AlQassimi,
and is distributed under the BSD 2 Clause license.  

### 4. Download and make

```sh
$ git clone git.sr.ht/~humaid/c-pomodoro
$ cd c-pomodoro
$ make all
```

### 5. Usage

```sh
$ ./pomodoro
```

### 6. Configuration

To configure the timing, you have to modify the values in the header file
`pomodoro.h`, and recompile.

### 7. Change log

- v0.1 *(Apr 7 2019)*
  - Initial release

A  => content/projects/screenshots/4DG.gif +0 -0
A  => content/projects/screenshots/4DG.png +0 -0
A  => content/projects/screenshots/JukeboxHopperMod.gif +0 -0
A  => content/projects/screenshots/JukeboxHopperMod.png +0 -0
A  => content/projects/screenshots/WhatsMorse.gif +0 -0
A  => content/projects/screenshots/WhatsMorse.png +0 -0
A  => content/projects/screenshots/ns2-analysis.png +0 -0
A  => content/projects/screenshots/yabfig.jpg +0 -0
A  => content/projects/shopsheet.md +64 -0
@@ 1,64 @@
---
title: ShopSheet
GitURL: shopsheet
MailingList: general
Section: "Web Applications"
License: AGPL-3.0-only
Language: Go
date: 2019-06-30
GoDoc: true
LatestVersion: v0.1
HasBuilds: true
Description: "An instant ecommerce website generator based on a spreadsheet file."
Usability: 3
---

### 1. Description

ShopSheet is a web app written in Go that converts a spreadsheet file
into an ecommerce website instantly.  

This web app is developed by me and [Akilan Selvacoumar](https://akilan.io)
as a challenge, we ended up implementing a working app in six hours.  

We chose this idea to tackle as a challenge because it solves a problem,
most people know how to use and are familiar with using spreadsheets, so why not build
an ecommerce website generator based on spreadsheets?

### 2. Requirements

The following packages must be installed on your system.

- Go *(tested with 1.12)*
- Git
- LibreOffice *(program uses `soffice` to convert spreadsheets to csv files)*

### 3. Copying and contributing

This program is written by Humaid AlQassimi and Akilan Selvacoumar,
and is distributed under the AGPL 3.0 license.  

### 4. Download and install

```sh
$ go get -u git.sr.ht/~humaid/shopsheet
$ go install git.sr.ht/~humaid/shopsheet
```

### 5. Usage

Run with `go run main.go`.

### 6. Change log

- v0.1 *(Jun 30 2019)*
  - Initial release

### 7. To-do

- [ ] Deploy to Heroku
- [ ] Use [X]ORM
- [ ] Template changes/fixes
  - [ ] Clear cart when changing sites
  - [ ] Allow custom templates
  - [ ] Show add to cart confirmation

A  => content/projects/sifrOS.md +57 -0
@@ 1,57 @@
---
title: sifrOS
GitURL: sifros-mklive
section: "Others"
MailingList: general
License: BSD-2-Clause
Language: Bash
date: 2018-06-22
Description: "A secure and minimal Linux distribution."
Usability: 2
---

### 1. Purpose
The goal of sifrOS is to be a Linux distribution (based on 
[Void](https://voidlinux.org)) with more secure default configuration.  

Documentation of installation and configuration is planned.

**Note**: This is not maintained and not very usable of yet. There are future
plans in making this a more installable system.

#### 1.1. Features and Goals

- Few pre-installed packages (~130)
- Uses minimal software, such as;
	- musl (libc) instead of glibc ([comparison](https://www.etalabs.net/compare_libcs.html))
	- runit instead of systemd
	- [xbps](https://github.com/void-linux/xbps)
- A clear and easy to follow documentation, that explains; *(TODO)*
	- installation (with btrfs + LUKS full-disk encryption)
	- setting up networking and ntp
	- setting up a desktop environment (xorg, dwm, st)

### 2. Requirements for building

The following packages must be installed on your system.

- xbps
- xbps-reconfigure
- qemu-user-static
- squashfs-tools
- xorriso

### 3. Copying and contributing

This is a fork of [Void Linux live image maker](github.com/void-linux/void-mklive)
which is written by Juan RP, Dave Elusive and 
[Void contributors](https://github.com/orgs/void-linux/people) and is distributed 
under the BSD 2 Clause license.

### 4. Building

To build a sifrOS iso, run build script as root.

```sh
# ./build-sifrOS.sh
```

A  => content/projects/xmath/XMath.aia +0 -0
A  => content/projects/yabfig.md +106 -0
@@ 1,106 @@
---
title: yabfig
GitURL: yabfig
section: "Command-line Tools"
MailingList: general
License: BSD-2-Clause
Language: Go
date: 2019-03-08
GoDoc: true
LatestVersion: v0.3
HasBuilds: true
Screenshot: "yabfig.jpg"
Description: "A simple BF interpreter, debugger and linter written in Go."
Usability: 4
---

### 1. Description
![Screenshot](../screenshots/yabfig.jpg)

yabfig is a [BF](https://en.wikipedia.org/wiki/brainfuck) 
interpreter written in Go. It has also been extended to lint
code (by removing un-interpreted characters) and to include a gdb-style
interpreter.



### 2. Requirements

The following packages must be installed on your system.

- Go *(tested with 1.12)*
- Git

### 3. Copying and contributing

This program is written by Humaid AlQassimi,
and is distributed under the BSD 2 Clause license.  

### 4. Download and install

```sh
$ go get -u git.sr.ht/~humaid/yabfig
$ go install git.sr.ht/~humaid/yabfig
```

### 5. Usage

```sh
Usage: yabfig [option] <file>
Options:
	-lint		Lint (format) a Brainfuck file by removing spaces and non-instruction characters and output it to standard output.
	-debug		Run an interactive gdb-style debugger.
```
To run the example program `hello-world.bf`:
```sh
$ yabfig programs/hello-world.bf
```
Using the debugger to set breakpoints:
```sh
$ yabfig -debug programs/hello-world.bf
yabfig debugger for Brainfuck.
Commands are similar to gdb, type "help" for a list of compatible commands.
(yabfig-dbg) help
List of commands:

run -- Run the program
print [pos] -- Print value at memory position
next [count] -- Execute next instruction[s]
jump [pos] -- Jump to a program position and resume
break [pos] -- Add breakpoint at program position
clear [pos] -- Delete breakpoint at program position
watch [n = x] -- Set watchpoint when memory position n is x
kill -- Kill program execution
(yabfig-dbg) b 98
Breakpoint #1 at position 98
(yabfig-dbg) b 102
Breakpoint #2 at position 102
(yabfig-dbg) b 106
Breakpoint #3 at position 106
(yabfig-dbg) r
Running program: programs/hello-world.bf
Hello WorldBreakpoint hit at position 98
(yabfig-dbg) c
!Breakpoint hit at position 102
(yabfig-dbg) c

Breakpoint hit at position 106
(yabfig-dbg) c
Program exited
(yabfig-dbg) 
```

### 6. Change log

- v0.1 *(Mar 8 2019)*
  - Initial release
- v0.2 *(Mar 18 2019)*
  - Added linter
  - Added unit tests
  - Interpreter as a struct with methods
- v0.2.1 *(Mar 18 2019)*
  - Add GoDoc
  - Move Interpreter to a separate package
- v0.3 *(Mar 22 2019)*
  - Add a simple gdb-style debugger
  - Improve interpreter functions

A  => content/xmath-pp/_index.md +21 -0
@@ 1,21 @@
---
title: XMath Privacy Policy
date: 2017-12-05
---

XMath does not collect or transmit any personal information.

The student and instructor names are stored on the device locally, and is not transmitted over the Internet.

The instructor name and the student's answers may be transmitted over Bluetooth.

Music is downloaded from incompetech servers (when played), they may log connections.

The application does not contain advertising or analytics.

*rev 0 - 5 Dec 2017*

---

This is the privacy policy of an Android application made for a course in my first year of university.  
You can download the application on the [Play Store](https://play.google.com/store/apps/details?id=appinventor.ai_humaid_andr.XMath&hl=en_US) ([project page](/projects/xmath)).  

A  => static/favicon.png +0 -0
A  => static/humans.txt +3 -0
@@ 1,3 @@
/* SITE */
Generator: Hugo <https://gohugo.io>
Software: neovim, rsync, apache, gnu make, tdewolff's minify, git

A  => static/img/me-2020-fulldef.jpg +0 -0
A  => static/img/me-2020.jpg +0 -0
A  => static/pkg.go.dev-reference-blue.svg +1 -0
@@ 1,1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="134" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="134" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h71v20H0z"/><path fill="#007ec6" d="M71 0h63v20H71z"/><path fill="url(#b)" d="M0 0h134v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="365" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="610">pkg.go.dev</text><text x="365" y="140" transform="scale(.1)" textLength="610">pkg.go.dev</text><text x="1015" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">reference</text><text x="1015" y="140" transform="scale(.1)" textLength="530">reference</text></g> </svg>

A  => static/robots.txt +3 -0
@@ 1,3 @@
# robots.txt for https://humaidq.ae
Sitemap: https://humaidq.ae/sitemap.xml


A  => themes/humaidq-theme/archetypes/default.md +4 -0
@@ 1,4 @@
---
title: ''
date: ''
---

A  => themes/humaidq-theme/layouts/404.html +1 -0
@@ 1,1 @@
404
\ No newline at end of file

A  => themes/humaidq-theme/layouts/_default/list.html +11 -0
@@ 1,11 @@
{{ partial "header.html" . }}
{{if not .IsHome }}<h2>{{ .Title }}</h2>{{end}}
{{if and (.IsHome) ($.Site.Params.profilePicEnabled) }}<img
src="/img/me-2020.jpg" class="me" alt="A picture of Humaid smiling, not
	 while looking at the camera. Possibly in a discussion with people
	 off-screen." />{{end}}
{{ .Content }}
{{if not .IsHome }}<ul>
	{{ range .Data.Pages }}<li><a href="{{ .URL }}">{{ .Title }}</a></li>{{ end }}
</ul>{{ end }}
{{ partial "footer.html" . }}

A  => themes/humaidq-theme/layouts/_default/single.html +5 -0
@@ 1,5 @@
{{ partial "header.html" . }}
{{ if .Params.BackNav }}<p><a href="{{ .Parent.Permalink }}">&lt; Go back</a></p>{{ end }}
<h2>{{ .Title }}</h2>
{{.Content}}
{{ partial "footer.html" . }}

A  => themes/humaidq-theme/layouts/_internal/pagination.html +9 -0
@@ 1,9 @@
{{ if or (.Paginator.HasPrev) (.Paginator.HasNext)}}<hr />{{end}}
{{ if gt (.Paginator.TotalPages) 0 }}<p class="center-text">Page {{.Paginator.PageNumber}} of {{.Paginator.TotalPages}}</p>{{end}}
{{ if .Paginator.HasPrev }}
<a rel="prev" href="{{.Paginator.Prev.URL}}">&lt; Previous</a>
{{ end }}
{{ if .Paginator.HasNext }}
<a rel="next" class="right-text" href="{{.Paginator.Next.URL}}">Next &gt;</a>
{{ end }}
{{ if or (.Paginator.HasPrev) (.Paginator.HasNext)}}<br />{{end}}

A  => themes/humaidq-theme/layouts/blog/list.html +13 -0
@@ 1,13 @@
{{ partial "header.html" . }}
<h2>{{ .Title }} <small><a href="{{ "blog/index.xml" | absURL }}">(rss)</a></small></h2>
{{ .Content }}
{{if not .IsHome }}
  {{ range (where .Data.Pages "Section" "!=" "") }}
  <div class="entry"><span class="date">{{ .Date.Format "2 Jan 2006" }}</span>
	<a href="{{ .URL }}">{{ .Title }}</a>
	<div class="meta"><p>{{.Summary}}</p></div></div>
  {{ end }}
    
{{ end }}
{{ partial "webring-out.html"}}
{{ partial "footer.html" . }}

A  => themes/humaidq-theme/layouts/blog/single.html +14 -0
@@ 1,14 @@
{{ partial "header.html" . }}
<p><a href="{{ .Parent.Permalink }}">&lt; Go back</a></p>
<h2>{{ .Title }}</h2>
<p>{{ dateFormat "Jan 2, 2006" .Params.date }} &middot; {{.ReadingTime}} min read</p>
<div class="blog">
    {{.Content}}
<hr>
<p>Would like to comment on the blog post? Feel free to
<a href="mailto:~humaid/general@lists.sr.ht?Subject=Re: {{.Title}}">start a discussion</a> on my
<a href="https://lists.sr.ht/~humaid/general" target="_blank">public general mailing list</a>.</p>
</div>

{{ partial "webring-out.html"}}
{{ partial "footer.html" . }}

A  => themes/humaidq-theme/layouts/gallery/list.html +12 -0
@@ 1,12 @@
{{ partial "header.html" . }}
<h2>{{ .Title }}</h2>
{{ .Content }}
{{if not .IsHome }}
  {{ range (where .Data.Pages "Section" "!=" "") }}
  <div class="entry"><span class="date">{{ .Date.Format "2 Jan 2006" }}</span>
	<a href="{{ .URL }}">{{ .Title }}</a>
	<div class="meta"><p>{{.Summary}}</p></div></div>
  {{ end }}
    
{{ end }}
{{ partial "footer.html" . }}

A  => themes/humaidq-theme/layouts/gallery/single.html +21 -0
@@ 1,21 @@
{{ partial "header.html" . }}
<h1>{{ .Title }}</h1>
<p><a href="{{ .Parent.Permalink }}">&lt; Go back</a></p>
<div class="meta">
<p>Date: {{ dateFormat "Monday, 2 January 2006" .Params.date }}</p>
  <p>Licensed under: {{ .Params.License }}</p>
  <p>Location: {{ range .Params.location }}<a href="{{ "/location/" | relLangURL }}{{ . | urlize }}">{{ . }}</a> {{ end }}</p>
  <p>Coordinates: <a href="https://mapper.acme.com/?ll={{.Params.lat}},{{.Params.lon}}&z=19&t=M&marker0={{.Params.lat}},{{.Params.lon}},{{.Title}}">{{.Params.lat}},{{.Params.lon}}</a></p>
</div>
{{.Content}}
{{- $path := print "content/gallery/" $.File.TranslationBaseName -}}
{{- $files := readDir $path -}}

<div class="gal">
	{{- range $files }}{{if not (eq .Name "thumbs")}}<a href="{{ .Name }}"><img src="thumbs/{{ .Name }}" alt="An image of {{$.Title}}" /></a>
{{end}}{{- end }}
</div>



{{ partial "footer.html" . }}

A  => themes/humaidq-theme/layouts/language/list.html +10 -0
@@ 1,10 @@
{{ partial "header.html" . }}
{{if not .Params.top}}<p><a href="/language">&lt; View languages</a></p>{{end}}
<h2>{{ .Title }}</h2>
{{ .Content }}
{{if not .Params.top}}<p>{{ if .Params.LanguageURL }}Learn more about this language <a href="{{ .Params.LanguageURL }}">on Wikipedia</a>. {{ end }}Below is a list of projects which use this programming language.</p>{{ end }}
{{if not .IsHome }}<ul>
  {{ range .Data.Pages }}<li><a href="{{ .URL }}">{{ .Title }}</a></li>
  {{ end }}
</ul>{{ end }}
{{ partial "footer.html" . }}

A  => themes/humaidq-theme/layouts/partials/footer.html +14 -0
@@ 1,14 @@
			</div>
		</main>
		<div class="footer">
			<p>Copyright &copy; 2013-2020 Humaid AlQassimi</p>
      <p>The content of this site is CC BY-SA 4.0. The code of this site
        is BSD 2-Clause.
         <a target="sitesource" href="https://git.sr.ht/~humaid/humaidq.ae/tree/master/LICENSE">View license file</a></p>
      {{if $.GitInfo }}
      <p>Build <a target="sitesource" href="https://git.sr.ht/~humaid/humaidq.ae">{{$.GitInfo.AbbreviatedHash}}</a></p>
      <!--<small>This page is last modified on
        {{dateFormat "Jan 2, 2006" $.GitInfo.AuthorDate}}</small>-->{{end}}
		</div>
	</body>
</html>

A  => themes/humaidq-theme/layouts/partials/header.html +28 -0
@@ 1,28 @@
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
<meta http-equiv="Cache-control" content="public">
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		{{ range .AlternativeOutputFormats -}}
			{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
		{{ end -}}
		{{if .Site.IsServer}}<link rel="stylesheet" href="{{ "/css/main.css" | relURL }}" />{{else}}<link rel="stylesheet" href="{{ "/css/main.min.css" | relURL }}?v=4" />{{end}}
		{{if eq .Type "blog"}}<link rel="stylesheet" href="{{ "/css/webring.min.css" | relURL }}" />{{end}}
		<title>{{if .Title}}{{ .Title }} - {{end}}Humaid AlQassimi</title>
		{{if .Description}}<meta name="description" content="{{.Description}}" />{{else if .Summary}}
		<meta name="description" content="{{.Summary}}" />{{end}}
		<meta property="og:site_name" content="Humaid AlQassimi's site" />
		<meta property="og:image" content="{{.Site.BaseURL}}img/me-2020.jpg" />
		<link rel="icon" type="image/jpeg" href="/favicon.png?v=2" />
	</head>
	<body>
		<header>
			<h1 class="title">Humaid AlQassimi</h1>
		</header>
		<nav class="nav">
			{{ $currentPage := . }}{{ range .Site.Menus.main }}{{ if not (eq .Name "") }}<a href="{{.URL | absLangURL }}" class="nav-item{{if or ($currentPage.IsMenuCurrent "main" .) ($currentPage.HasMenuCurrent "main" .) }} active{{ end }}">{{.Name}}</a>
			{{ end }}{{ end }}
		</nav>
		<main>
			<div class="content">

A  => themes/humaidq-theme/layouts/projects/list.html +12 -0
@@ 1,12 @@
{{ partial "header.html" . }}
<h2>{{ .Title }}</h2>
{{ .Content }}
{{if not .IsHome }}
{{ range .Pages.GroupByParam "Section" }}
<h3>{{.Key}}</h3>
{{ range .Pages }}<div class="entry"><b><a href="{{ .URL }}">{{ .Title }}</a></b>
{{ if .Params.LatestVersion }}<small>({{.Params.LatestVersion}})</small>{{end}}{{if .Params.Language}} {{.Params.Language}}{{end}}
<div class="meta">
{{if .Params.Description}}<p>{{.Params.Description}}</p>{{end}}
</div></div>{{ end }}{{ end }}{{ end }}
{{ partial "footer.html" . }}

A  => themes/humaidq-theme/layouts/projects/single.html +29 -0
@@ 1,29 @@
{{ partial "header.html" . }}
<p><a href="{{ .Parent.Permalink }}">&lt; Go back</a></p>
<h2>{{ .Title }}</h2>
<div class="meta">
  {{if .Params.GitURL}}<p>Clone with HTTPS: 
  <a href="https://git.sr.ht/~humaid/{{ .Params.GitURL }}" rel="noreferrer" target="_blank">https://git.sr.ht/~humaid/{{ .Params.GitURL }}</a></p>{{end}}
  {{if .Params.Language}}<p>Written in {{.Params.Language}}{{if .Params.License}}, licensed under
  the <a href="https://spdx.org/licenses/{{.Params.License}}.html" target="_blank" rel="noreferrer noopener">{{.Params.License}}</a> license{{end}}{{end}}
  {{if .Params.NotAccepting }}<p><b>Notice:</b> This project is not accepting any contributions.</p>{{end}}
  {{if .Params.Site }}<p>Project URL: <a href="{{.Params.Site}}" rel="noreferrer" target="_blank">{{.Params.Site}}</a></p>{{end}}
  {{if .Params.Proprietary}}<p><b>Notice:</b> The source of this project is not publicly available.</p>{{end}}
  {{if .Params.MailingList}}<p>Mailing list: <a href="mailto:~humaid/{{.Params.MailingList}}@lists.sr.ht" target="_blank">~humaid/{{.Params.MailingList}}@lists.sr.ht</a> 
  (<a href="mailto:~humaid/{{.Params.MailingList}}+subscribe@lists.sr.ht?subject=subscribe&body=subscribe%20me">subscribe</a>, <a href="https://lists.sr.ht/~humaid/{{.Params.MailingList}}" rel="noreferrer" target="_blank">archive</a>)</p>{{end}}
  {{if .Params.IssueTracker }}<p>Issue tracker: <a href="https://todo.sr.ht/~humaid/{{.Params.GitURL}}">view tickets</a> (<a href="mailto:~humaid/{{.Params.GitURL}}@todo.sr.ht">submit ticket via email</a>)</p>{{end}}
  <p>{{if .Params.GoDoc }}<a href="https://pkg.go.dev/git.sr.ht/~humaid/{{.Params.GitURL }}{{if .Params.LatestVersion}}@{{ .Params.LatestVersion}}{{end}}?tab=doc"
	  target="_blank">
  <img src="/pkg.go.dev-reference-blue.svg"
  alt="pkg.go.dev reference"/></a>{{end}}
  {{if .Params.HasBuilds}}<a href="https://builds.sr.ht/~humaid/{{.Params.GitURL}}?" rel="noreferrer" target="_blank"><img src="https://builds.sr.ht/~humaid/{{.Params.GitURL}}.svg" alt="builds.sr.ht status" /></a>{{end}}
  </p>
</div>
<aside>
    <header>
    <h2>Table of Contents</h2>
    </header>
    {{.TableOfContents}}
</aside>
{{.Content}}
{{ partial "footer.html" . }}

A  => themes/humaidq-theme/static/css/main.css +190 -0
@@ 1,190 @@
/* Page style */
html {
  overflow-y: scroll;
  scroll-behavior: smooth;
}

body {
  font-family: "Source Sans Pro", "Lucidia Grande", "Segoe UI", "Roboto", sans-serif;
  font-size: 14pt;
  line-height: 1.4;
  background-color: #fff;
  max-width: 1250px;
  margin: 0 auto;
}

/* Typography */
h1, h2, h3, h4, h5, h6 {
  color: #333;
  margin: 10px 0;
  line-height: 1;
}

.title {
  font-size: 2.5rem;
  text-align: center;
  margin-top: 30px;
  margin-bottom: 30px;
  padding: 0 30px;
}

a {
 color: #052ba0;
}

.entry {
  display: block;
  width: 100%;
  padding: 5px 15px;
}

.entry a {
  color: #0b47bf;
  font-weight: bold;
  text-decoration: none;
}

.meta a {
  padding: 0;
}

.meta p {
  margin: 0 0 0 25px;
}

.content {
  padding: 20px 30px;
}

.footer {
  padding: 1rem;
  text-align: center;
  color: #2f2f2f;
}

.footer p {
  margin: 5px;
}

/* Images and Gallery */
img {
  max-width: 100%;
}

.me {
  width: 200px;
  float:right;
  border-radius: 20px;
  margin: 20px;
}

.gal {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
}

.gal img {
  max-width: 95%;
  max-height: 220px;
}

/* Code blocks */
pre code {
  display: inline-block;
  padding: 3.5px;
  font-size: .8em;
  border-radius: 2px;
  white-space: pre-wrap;
}

code {
  font-family: "SFMono-Regular","Menlo","Consolas","Liberation Mono","Courier New",monospace;
  font-size: .9em;
}

aside {
  border: 2px solid #777;
  background-color: #eee;
  padding: .5em 2.5em;
  max-width: 400px;
  float: right;
  margin: 10px 0;
}

aside ul {
  padding-left: 1em;
}

/* Responsiveness */
@media only screen and (max-width: 780px) {
  .gal {
    grid-template-columns: none;
  }
  .gal img {
    display: block;
    max-height: 100%;
    margin-left: auto;
    margin-right: auto;
  }
  body {
    font-size: 1.1em;
  }
  .me {
    width: 100px;
  }
  aside {
    float: none;
  }
}

@media only screen and (min-width: 960px) {
  .blog {
    padding: 0 10%;
  }
}

/* Navigation bar */
.nav {
  overflow: hidden;
  text-align: center;
  padding-bottom: 1rem;
  border-bottom: 2px solid #4f4f4f;
}

.nav-item {
  text-decoration: none;
  font-weight: bold;
  padding: .5em;
  margin: 3px;
  font-size: 1.4rem;
}

.nav-item:hover {
  text-decoration: underline;
  color: #000;
}

.nav-item:focus {
  outline: none;
}

@media (prefers-color-scheme: dark) {
  body {
    background-color: #202125;
    color: #cfcfcf;
  }
  h1, h2, h3, h4, h5, h6, .footer {
    color: #ccc;
  }
  a, .entry a {
    color: #6b96db;
  }
  a:hover, .nav-item:hover {
    color: #ccc;
  }
  aside {
    border: 2px solid #000;
    background-color: #222;
  }
}

A  => themes/humaidq-theme/static/css/main.min.css +1 -0
@@ 1,1 @@
html{overflow-y:scroll;scroll-behavior:smooth}body{font-family:source sans pro,lucidia grande,segoe ui,roboto,sans-serif;font-size:14pt;line-height:1.4;background-color:#fff;max-width:1250px;margin:0 auto}h1,h2,h3,h4,h5,h6{color:#333;margin:10px 0;line-height:1}.title{font-size:2.5rem;text-align:center;margin-top:30px;margin-bottom:30px;padding:0 30px}a{color:#052ba0}.entry{display:block;width:100%;padding:5px 15px}.entry a{color:#0b47bf;font-weight:700;text-decoration:none}.meta a{padding:0}.meta p{margin:0 0 0 25px}.content{padding:20px 30px}.footer{padding:1rem;text-align:center;color:#2f2f2f}.footer p{margin:5px}img{max-width:100%}.me{width:200px;float:right;border-radius:20px;margin:20px}.gal{display:grid;grid-template-columns:repeat(3,1fr);grid-gap:10px}.gal img{max-width:95%;max-height:220px}pre code{display:inline-block;padding:3.5px;font-size:.8em;border-radius:2px;white-space:pre-wrap}code{font-family:sfmono-regular,menlo,consolas,liberation mono,courier new,monospace;font-size:.9em}aside{border:2px solid #777;background-color:#eee;padding:.5em 2.5em;max-width:400px;float:right;margin:10px 0}aside ul{padding-left:1em}@media only screen and (max-width:780px){.gal{grid-template-columns:none}.gal img{display:block;max-height:100%;margin-left:auto;margin-right:auto}body{font-size:1.1em}.me{width:100px}aside{float:none}}@media only screen and (min-width:960px){.blog{padding:0 10%}}.nav{overflow:hidden;text-align:center;padding-bottom:1rem;border-bottom:2px solid #4f4f4f}.nav-item{text-decoration:none;font-weight:700;padding:.5em;margin:3px;font-size:1.4rem}.nav-item:hover{text-decoration:underline;color:#000}.nav-item:focus{outline:none}@media(prefers-color-scheme:dark){body{background-color:#202125;color:#cfcfcf}h1,h2,h3,h4,h5,h6,.footer{color:#ccc}a,.entry a{color:#6b96db}a:hover,.nav-item:hover{color:#ccc}aside{border:2px solid #000;background-color:#222}}
\ No newline at end of file

A  => themes/humaidq-theme/static/css/normalize-8.0.1.min.css +1 -0
@@ 1,1 @@
/*!normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css*/html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
\ No newline at end of file

A  => themes/humaidq-theme/static/css/webring.css +40 -0
@@ 1,40 @@
.webring {
 margin-top:3rem
}
.webring .articles {
 display:flex;
 flex-wrap:wrap;
 margin:-.5rem
}
.webring .title {
 font-size: 1.5rem;
 margin:0
}
.webring .article {
 flex:1 1 0;
 display:flex;
 flex-direction:column;
 margin:.5rem;
 padding:.5rem;
 background:#eee;
 min-width:10rem;
 border-radius:6px
}
.webring .summary {
 font-size:.8rem;
 flex:1 1 0
}
.webring .attribution {
 text-align:right;
 font-size:.8rem;
 color:#555
}
@media (prefers-color-scheme: dark) {
  .webring .article {
    background-color: #222;
    border: 1px solid #000;
  }
  .webring .attribution {
    color: #eee;
  }
}

A  => themes/humaidq-theme/static/css/webring.min.css +1 -0
@@ 1,1 @@
.webring{margin-top:3rem}.webring .articles{display:flex;flex-wrap:wrap;margin:-.5rem}.webring .title{font-size:1.5rem;margin:0}.webring .article{flex:1 1 0;display:flex;flex-direction:column;margin:.5rem;padding:.5rem;background:#eee;min-width:10rem;border-radius:6px}.webring .summary{font-size:.8rem;flex:1 1 0}.webring .attribution{text-align:right;font-size:.8rem;color:#555}@media(prefers-color-scheme:dark){.webring .article{background-color:#222;border:1px solid #000}.webring .attribution{color:#eee}}
\ No newline at end of file

A  => themes/humaidq-theme/theme.toml +15 -0
@@ 1,15 @@
# theme.toml template for a Hugo theme
# See https://github.com/gohugoio/hugoThemes#themetoml for an example

name = "Humaidq Theme"
license = "MIT"
licenselink = "https://humaidq.ae"
description = ""
homepage = "https://humaidq.ae"
tags = []
features = []
min_version = "0.41"

[author]
  name = "Humaid"
  homepage = "https://humaidq.ae"

A  => usability.txt +6 -0
@@ 1,6 @@
Each project usability can be divided into these sections:
- 0: Completely unusable
- 1: Barely usable. May have severe bugs, or might not work out of the box.
- 2: Somewhat usable. May work out of the box, but has some issues.
- 3: Very usable. Works well, but you may stumble upon some issues.
- 4: "Production-ready".

A  => webring-in.html +23 -0
@@ 1,23 @@
<section class="webring">
  <h3>Articles from blogs I follow around the net</h3>
  <p><small>These articles do not represent my opinions or views.</small></p>
  <section class="articles">
    {{range .Articles}}
    <div class="article">
      <h4 class="title">
        <a href="{{.Link}}" target="_blank" rel="noopener noreferrer">{{.Title}}</a>
      </h4>
      <p class="summary">{{.Summary}}</p>
      <small class="source">
        via <a href="{{.SourceLink}}">{{.SourceTitle}}</a>
      </small>
      <small class="date">{{.Date | date}}</small>
    </div>
    {{end}}
  </section>
  <p class="attribution">
    Generated by
    <a href="https://git.sr.ht/~sircmpwn/openring" target="_blank"
      rel="noopener noreferrer">openring</a>
  </p>
</section>