Compare commits

51 Commits

Author SHA1 Message Date
x0rg f0a576ad8d Remove PGP menu link 2025-03-16 23:18:09 +01:00
x0rg c8462938aa Update matrix contact 2025-03-16 23:11:43 +01:00
x0rg 0c8f5104b4 Delete static/olivier.falcoz.pgp.key.asc
Signed-off-by: Olivier Falcoz <x0rg@noreply.git.9x0rg.com>
2025-03-16 23:10:06 +01:00
x0rg 42aa526a61 Update static/.well-known/security.txt 2025-03-16 23:08:27 +01:00
x0rg 5a787d8490 Update static/.well-known/security.txt
Signed-off-by: Olivier Falcoz <x0rg@noreply.git.9x0rg.com>
2025-03-16 23:07:09 +01:00
x0rg 985d90473d Update README.md
Signed-off-by: Olivier <x0rg@noreply.git.9x0rg.com>
2025-03-16 21:51:47 +01:00
x0rg 9606e54023 Changed description 2025-03-16 21:50:28 +01:00
x0rg b6782a8fa6 Update README.md 2024-04-16 11:12:30 +02:00
x0rg fea7f82b86 Update README.md 2023-11-27 16:07:09 +01:00
x0rg 5d5893f818 Delete content/projects.md 2023-11-27 15:56:28 +01:00
x0rg 0e9794b3c8 Upload files to "content" 2023-11-27 15:56:18 +01:00
x0rg 415b4a4edc Delete content/packages.md 2023-11-27 15:55:59 +01:00
x0rg c43c8bc96b Delete content/contact.md 2023-11-27 15:55:51 +01:00
x0rg 2f252674cc Delete content/about.md 2023-11-27 15:55:43 +01:00
x0rg ec851199de Update static/_headers 2023-11-27 15:54:49 +01:00
x0rg 6b87a7dd88 Upload files to "static" 2023-11-27 15:54:03 +01:00
x0rg f99599f663 Delete static/favicon.ico 2023-11-27 15:53:32 +01:00
x0rg 5a1c8e28b8 Delete static/tommy.asc 2023-11-27 15:53:24 +01:00
x0rg 0ee1a93c81 Delete static/sshkey 2023-11-27 15:53:18 +01:00
x0rg 39add7b6d0 Delete static/safari-pinned-tab.svg 2023-11-27 15:53:07 +01:00
x0rg bdb989719e Delete static/favicon-32x32.png 2023-11-27 15:53:00 +01:00
x0rg 7e037c7d66 Delete static/favicon-16x16.png 2023-11-27 15:52:51 +01:00
x0rg 6c33314ebc Delete static/cortana.png 2023-11-27 15:52:43 +01:00
x0rg 64baaa2753 Delete static/.DS_Store 2023-11-27 15:51:41 +01:00
x0rg 390febf963 Delete static/apple-touch-icon.png 2023-11-27 15:51:20 +01:00
x0rg d26ff90cf9 Upload files to "static/images" 2023-11-27 15:51:04 +01:00
x0rg 0e0546092f Delete static/images/simplex-chat-address.png 2023-11-27 15:49:56 +01:00
x0rg 52cb96bcde Delete static/images/rhcsa.png 2023-11-27 15:49:49 +01:00
x0rg 1bfda32632 Delete static/images/pterodactyl.png 2023-11-27 15:49:42 +01:00
x0rg 66379f441b Delete static/images/privsec.png 2023-11-27 15:49:35 +01:00
x0rg 6b6f8f6f0c Delete static/images/pamac.png 2023-11-27 15:49:28 +01:00
x0rg 335d769874 Delete static/images/matrix.jpg 2023-11-27 15:49:20 +01:00
x0rg 03ffbd7fe0 Delete static/images/fedora-tux.png 2023-11-27 15:49:13 +01:00
x0rg 822858fae6 Delete static/images/fedora-coreos.png 2023-11-27 15:49:06 +01:00
x0rg 1377be72c8 Delete static/images/arcticfoxes.png 2023-11-27 15:49:00 +01:00
x0rg a9d973fee3 Delete static/images/archlinux.jpg 2023-11-27 15:48:53 +01:00
x0rg 7a0b0ac68a Upload files to "static/.well-known" 2023-11-27 15:48:27 +01:00
x0rg dca959e989 Delete static/.well-known/mta-sts.txt 2023-11-27 15:47:50 +01:00
x0rg 8920038907 Update static/.well-known/security.txt 2023-11-27 15:47:33 +01:00
x0rg 0152c4c422 Delete static/.well-known/openpgpkey/policy 2023-11-27 15:46:23 +01:00
x0rg c12be3b7ed Delete static/.well-known/openpgpkey/hu/dj3498u4hyyarh35rkjfnghbjxug6b19 2023-11-27 15:46:15 +01:00
x0rg cc722d2520 Update archetypes/default.md 2023-11-27 15:44:43 +01:00
x0rg 15e65c333e Update config.yml 2023-11-27 15:43:31 +01:00
x0rg ad81ab2988 Delete tommytran.io.code-workspace 2023-11-27 15:42:53 +01:00
x0rg e2d49aea76 Delete cloudflare-build.sh 2023-11-27 15:42:39 +01:00
x0rg 0c9be314db Update README.md 2023-11-27 15:42:23 +01:00
x0rg 4436a6ab5d Update .gitignore 2023-11-27 15:41:26 +01:00
x0rg 8c3b70311a Delete .devcontainer/devcontainer.json 2023-11-27 15:37:57 +01:00
Tommy 266c9e6b98 Opt out of Chrome's Topics API
Signed-off-by: Tommy <contact@tommytran.io>
2023-11-07 00:49:40 -07:00
Tommy eba9e0319c Update content
Signed-off-by: Tommy <contact@tommytran.io>
2023-11-05 03:21:11 -07:00
Tommy 7c03fa92e0 Site Upload 2022-09-02 17:49:44 -04:00
156 changed files with 641 additions and 3240 deletions
+8
View File
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: gitsubmodule
directory: "/"
schedule:
interval: daily
labels:
- "dependency"
+4 -2
View File
@@ -1,2 +1,4 @@
resources/ # Ignore Hugo generated files
.hugo_build.lock public/
resources/
.hugo_build.lock
+3 -4
View File
@@ -1,4 +1,3 @@
[submodule "themes/blowfish"] [submodule "themes/WonderMod"]
path = themes/blowfish path = themes/WonderMod
url = https://github.com/nunocoracao/blowfish.git url = https://github.com/Wonderfall/hugo-WonderMod
branch = main
+9 -6
View File
@@ -1,7 +1,10 @@
## Image sources ## WonderMod theme for Hugo - https://olivier.falcoz.net
- [Background](https://unsplash.com/photos/a-view-of-a-city-with-tall-buildings-iPyailqBGdM) ### What is this?
- [About](https://unsplash.com/photos/cable-network-M5tzZtFCOfs) This is Olivier Falcoz personal website, a fork of the [WonderMod](https://github.com/Wonderfall/hugo-WonderMod.git) theme developed by [Wonderfall](https://github.com/Wonderfall).
- [Projects](https://unsplash.com/photos/a-computer-keyboard-sitting-on-top-of-a-desk-cuzpQne4Tl0)
- [Contact](https://unsplash.com/photos/a-close-up-of-a-cell-phone-near-a-laptop-8e2VsJ0dOPM) ### Credits
- [Hire Me](https://www.pexels.com/photo/rooftop-of-taxi-11368144/) - [WonderMod](https://github.com/Wonderfall/hugo-WonderMod.git) by Wonderfall
See [Hugo documentation](https://gohugo.io/getting-started/configuration-markup#highlight) for more options.
*Note: for some reason, the `guessSyntax` doesn't actually work but is required. Please make your code fences explicit for the time being.*
+5 -5
View File
@@ -1,5 +1,5 @@
+++ ---
date = '{{ .Date }}' title: "{{ replace .Name "-" " " | title }}"
draft = true date: {{ .Date }}
title = '{{ replace .File.ContentBaseName "-" " " | title }}' draft: true
+++ ---
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 KiB

+140
View File
@@ -0,0 +1,140 @@
baseURL: "https://olivier.falcoz.net/"
languageCode: 'en-us'
title: Olivier Falcoz - My landing page
theme: WonderMod
copyright: '© Olivier Falcoz 2022'
# copyright: '[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)'
enableRobotsTXT: true
enableGitInfo: true
disableKinds:
- taxonomy
- term
minify:
disableXML: true
minifyOutput: true
params:
env: production # to enable google analytics, opengraph, twitter-cards and schema.
author: Olivier Falcoz
# author: ["Me", "You"] # multiple authors
description: Risk Management professional, Fraud and Financial crime expert, Infosec,Privacy & FLOSS advocate, MTB addict
keywords: [Privacy, Information Security, Risk Management, Infosec, Fraud, Financial crime, Expert, Privacy, FLOSS, MTB]
defaultTheme: dark # dark, light
disableThemeToggle: false
images: ["/olivier.png"]
ShowReadingTime: true
ShowPostNavLinks: true
ShowBreadCrumbs: true
ShowWordCount: false
ShowToc: true
ShowRssButtonInSectionTermList: false
ShowCodeCopyButtons: true
assets:
disableHLJS: true
disableFingerprinting: false
favicon: "/favicon.ico"
favicon16x16: "/favicon-16x16.png"
favicon32x32: "/favicon-32x32.png"
apple_touch_icon: "/apple-touch-icon.png"
safari_pinned_tab: "/safari-pinned-tab.svg"
label:
text: "Home"
icon: "/olivier.png"
# profile-mode
profileMode:
enabled: true # needs to be explicitly set
title: Olivier Falcoz
subtitle: "Cyber & risk intelligence professional | Infosec | Privacy & FLOSS advocate | MTB addict"
imageUrl: "/olivier.png"
buttons:
- name: About
url: about
- name: Contact
url: contact
- name: Services
url: services
socialIcons:
- name: email
url: "mailto:x0rg |at| 9x0rg d0t com"
- name: matrix
url: "https://matrix.to/#/@oyapok:envs.net"
- name: linkedin
url: "https://www.linkedin.com/in/olivierfalcoz"
# - name: xmpp
# url: "x0rg@disroot.org"
cover:
hidden: false # hide everywhere but not in structured data
hiddenInList: true # hide on list pages and home
hiddenInSingle: false # hide on single page
editPost:
URL: "https://git.9x0rg.com"
Text: "Source" # edit text
appendFilePath: true # to append file path to Edit link
# for search
# https://fusejs.io/api/options.html
fuseOpts:
isCaseSensitive: false
shouldSort: true
location: 0
distance: 1000
threshold: 0.4
minMatchCharLength: 0
keys: ["title", "summary"]
#Enabling Search
outputs:
home:
- HTML
- JSON # is necessary
# Enable Chroma
markup:
highlight:
style: dracula
lineNos: false
noClasses: false
guessSyntax: true
menu:
main:
- identifier: Services
name: Resume
url: /resume/
weight: 10
# - identifier: PGP
# name: PGP
# url: olivier.falcoz.pgp.key.asc
# weight: 10
privacy:
disqus:
disable: true
googleAnalytics:
anonymizeIP: true
disable: true
respectDoNotTrack: true
useSessionStorage: false
instagram:
disable: true
simple: false
twitter:
disable: true
enableDNT: true
simple: false
vimeo:
disable: true
enableDNT: true
simple: false
youtube:
disable: true
privacyEnhanced: true
-58
View File
@@ -1,58 +0,0 @@
theme = "blowfish"
baseURL = "https://www.tommytran.io"
defaultContentLanguage = "en"
enableRobotsTXT = true
summaryLength = 0
buildDrafts = false
buildFuture = false
enableEmoji = true
[pagination]
pagerSize = 100
[imaging]
anchor = "Center"
[taxonomies]
tag = "tags"
category = "categories"
author = "authors"
series = "series"
[sitemap]
changefreq = "daily"
filename = "sitemap.xml"
priority = 0.5
[outputs]
home = [ "HTML", "RSS", "JSON" ]
[related]
threshold = 0
toLower = false
[[related.indices]]
name = "tags"
weight = 100
[[related.indices]]
name = "categories"
weight = 100
[[related.indices]]
name = "series"
weight = 50
[[related.indices]]
name = "authors"
weight = 20
[[related.indices]]
name = "date"
weight = 10
[[related.indices]]
applyFilter = false
name = "fragmentrefs"
type = "fragments"
weight = 10
-42
View File
@@ -1,42 +0,0 @@
disabled = false
languageCode = "en"
languageName = "English"
weight = 1
title = "Tommy's Space"
[params]
displayName = "EN"
isoCode = "en"
rtl = false
dateFormat = "2 January 2006"
description = "Tommy's personal website"
[[params.author.links]]
github = "https://github.com/TommyTran732"
[[params.author.links]]
gitlab = "https://gitlab.metropolis.nexus/Tommy"
[[params.author.links]]
matrix = "https://matrix.to/#/@tommy:metropolis.nexus"
[[params.author.links]]
telegram = "https://t.me/tommytran732"
[[params.author.links]]
x-twitter = "https://x.com/TommyTran732"
[[params.author.links]]
linkedin = "https://www.linkedin.com/in/tommytran732"
[[params.author.links]]
email = "mailto:contact@tommytran.io"
[[params.author.links]]
pgpkey = "/.well-known/pgp-key.txt"
["params.author"]
name = "Tommy Tran"
bio = "System Administrator and Technical Writer"
image = "avatar.png"
headline = "System Administrator and Technical Writer"
-20
View File
@@ -1,20 +0,0 @@
# -- Markup --
# These settings are required for the theme to function.
[goldmark]
[goldmark.renderer]
unsafe = true
[goldmark.extensions]
[goldmark.extensions.passthrough]
enable = true
[goldmark.extensions.passthrough.delimiters]
block = [['\[', '\]'], ['$$', '$$']]
inline = [['\(', '\)']]
[highlight]
noClasses = false
[tableOfContents]
startLevel = 2
endLevel = 4
-35
View File
@@ -1,35 +0,0 @@
[[main]]
none = "none"
[[main]]
name = "About"
pageRef = "posts/about"
identifier = "zGE2YAk94f"
weight = 1
[[main]]
name = "Blog"
url = "https://privsec.dev"
identifier = "ZygO3vLON0"
weight = 2
[[main]]
name = "Projects"
pageRef = "/posts/projects"
identifier = "uePnrAHpNc"
weight = 3
[[main]]
name = "Contact"
pageRef = "/posts/contact"
identifier = "lqA5Rh0hE9"
weight = 4
[[main]]
name = "Hire Me!"
pageRef = "/posts/hire-me"
identifier = "jkB0Rl7UK9"
weight = 5
[[footer]]
none = "none"
View File
-109
View File
@@ -1,109 +0,0 @@
colorScheme = "blowfish"
defaultAppearance = "dark"
autoSwitchAppearance = false
enableA11y = false
enableSearch = true
enableCodeCopy = false
replyByEmail = false
disableImageOptimization = false
disableImageOptimizationMD = false
disableTextInHeader = false
fingerprintAlgorithm = "sha512"
giteaDefaultServer = "https://git.fsfe.org"
forgejoDefaultServer = "https://v11.next.forgejo.org"
firebase = { }
fathomAnalytics = { }
umamiAnalytics = { }
selineAnalytics = { }
buymeacoffee = { }
verification = { }
rssnext = { }
advertisement = { }
defaultBackgroundImage = "background.jpg"
[header]
layout = "fixed"
[footer]
showMenu = true
showCopyright = true
showThemeAttribution = true
showAppearanceSwitcher = false
showScrollToTop = true
[homepage]
layout = "background"
showRecent = true
showRecentItems = "3"
showMoreLink = true
showMoreLinkDest = "/posts/"
cardView = true
cardViewScreenWidth = false
layoutBackgroundBlur = true
disableHeroImageFilter = false
[article]
showDate = false
showViews = false
showLikes = false
showDateOnlyInArticle = false
showDateUpdated = false
showAuthor = true
showHero = false
layoutBackgroundBlur = true
layoutBackgroundHeaderSpace = true
showBreadcrumbs = false
showDraftLabel = true
showEdit = false
editAppendPath = true
seriesOpened = false
showHeadingAnchors = true
showPagination = true
invertPagination = false
showReadingTime = false
showTableOfContents = true
showTaxonomies = false
showCategoryOnly = false
showAuthorsBadges = false
showWordCount = false
showZenMode = false
heroStyle = "background"
showRelatedContent = false
[list]
showHero = false
layoutBackgroundBlur = true
layoutBackgroundHeaderSpace = true
showBreadcrumbs = false
showSummary = false
showViews = false
showLikes = false
showTableOfContents = false
showCards = false
orderByWeight = false
groupByYear = false
cardView = false
cardViewScreenWidth = false
constrainItemsWidth = false
[sitemap]
excludedKinds = [ "taxonomy", "term" ]
[taxonomy]
showTermCount = true
showHero = false
showBreadcrumbs = false
showViews = false
showLikes = false
showTableOfContents = false
cardView = false
[term]
showHero = false
showBreadcrumbs = false
showViews = false
showLikes = false
showTableOfContents = true
groupByYear = false
cardView = false
cardViewScreenWidth = false
+83
View File
@@ -0,0 +1,83 @@
---
title: "About Me"
date: 2022-12-10T03:22:30+01:00
tags: ["about", "olivier falcoz","operational risk management","financial crime","anti-fraud","infosec","cybersecurity","business intelligence","governance","compliance"]
author: "Olivier Falcoz"
canonicalURL: "https://olivier.falcoz.net/about"
hidemeta: true
ShowReadingTime: false
ShowPostNavLinks: true
showtoc: false
---
``$ whoami``
Hi, my name is Olivier Falcoz.
I am currently Executive Director at [AGR Asia Solutions](https://agr.asia) Pte. Ltd. a boutique firm providing strategic intelligence and operational risk mitigation services[^1].
Operational risk management and information systems security are areas in which I have particular expertise.[^2]. I have over 25 years of extensive experience in working with private and government entities across challenging business environments. Over the past 17 years, I have been a partner of choice for SMEs and MNCs across Asia in industries as diverse as electronics, pharmaceuticals, consumer and luxury goods, petrochemicals and construction. I am now based in France.
## Purpose
I help protect cyber, intellectual and physical assets. My role is to assist clients consolidate their existing operations or enter new markets by mitigating operational and information security risks throughout the most critical cycles of their investments, namely *planning*, *execution* and *evaluation*.
I bring my operational risk management approach and strengths to mitigate the risk of financial loss caused by fraudulent activities, financial crime, flawed processes or events that may disrupt business operations.
My expertise goes beyond just risk management; I integrate information systems security and business process security to mitigate the impact of risk on governance and compliance.
Please check out my [Services](/services/) page and [Resume](/resume/) for more information.
---
# Contact
Please [get in touch](#email) if you believe that my skills and expertise could add value to your business, I would be delighted to hear from you. I am on [Linkedin](https://www.linkedin.com/in/olivierfalcoz) should you wish to connect.
## Matrix
Contact me through Matrix[^3] at [@olivier:envs.net](https://matrix.to/#/@olivier:envs.net).
![@olivier:envs.net on Matrix](/images/@olivier.envs.net.png)
*The privacy policy for the envs.net homeserver is available at [this page](https://envs.net/privacy-policy)*.
## Email
Drop me a note at:
```
olivier |at| falcoz d0t net
```
PGP key [``ed25519/0xCAAD364477DA43C8``](/olivier.falcoz.pgp.key.asc)
Key fingerprint
```
26BC C458 2D54 0A23 FE24 0C27 CAAD 3644 77DA 43C8
```
## XMPP/Jabber
You can contact me via XMPP if you were born in the last century:
```
xmpp:x0rg@disroot.org
```
![x0rg@disroot.org XMPP](/images/xmpp.x0rg@disroot.org.png)
#### OMEMO[^4] fingerprints ##
```
837df5e5 b4b216db b1f2df50
2210a37f a40627fe fe953cf6
7c02389b fa3e263e
03ac3a7a 94c6f01a 3c3c69a3
328758f8 ac7dc220 f1ce3002
033ab087 d666ce46
```
[^1]: [Operational risk](https://en.wikipedia.org/wiki/Operational_risk) is the risk of losses caused by flawed or failed processes, policies, systems or events that disrupt business operations (Wikipedia).
[^2]: [Information systems security (Infosec)](https://en.wikipedia.org/wiki/Information_security) (Wikipedia).
[^3]: [Matrix](https://matrix.org/) is a free, open, secure and decentralized protocol for real-time communication
[^4]: See [OMEMO E2E encryption protocol](https://en.wikipedia.org/wiki/OMEMO) (Wikipedia)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 KiB

-15
View File
@@ -1,15 +0,0 @@
---
title: "About Me"
date: 2022-09-02
showHero: true
---
Hello! 👋
I'm Thien, though you may know me as Tommy. With over five years of experience as a Linux system administrator, I specialize in managing a diverse range of Linux distributions, including Red Hat, Debian, SUSE, and Arch Linux. Recently, I've been diving into the world of containers and immutable distributions, which I find both innovative and exciting.
Like most Linux users, I am an open source enthusiast and publish most of the projects made in my free time on [GitHub](https://github.com/tommytran732). I also made a couple of small contributions to various projets as well.
I host several services, such as Matrix and Mastodon, free of charge. If you're curious, feel free to explore [Metropolis.nexus](https://metropolis.nexus), where you might find resources or services that suit your needs.
Together with friends I connected with through GrapheneOS, I co-author a blog, [PrivSec.dev](https://privsec.dev), where we explore topics related to privacy and security.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

-54
View File
@@ -1,54 +0,0 @@
---
title: "Contact Information"
date: 2022-09-02
---
## Matrix
The best way to contact me is through Matrix.
- Primary account: [@tommy:metropolis.nexus](https://matrix.to/#/@tommy:metropolis.nexus)
- Fallback account: [@tommy:grapheneos.org](https://matrix.to/#/@tommy:grapheneos.org)
If you do not have a an account, you can sign up for one on my homeserver [metropolis.nexus](https://metropolis.nexus). I do not ask for your email address or any personal information for registration.
## Email
If you prefer to reach out to me via email, my address is [contact@tommytran.io](mailto:contact@tommytran.io). Aliases:
- [tommy@metropolis.nexus](mailto:tommy@metropolis.nexus)
- [tommy@privsec.dev](mailto:tommy@privsec.dev)
Please use encryption if possible. My PGP key is available [here](https://tommytran.io/tommy.asc).
## Discord
- TommyTran732. I use Discord mostly for software and gaming related purposes. If you want to contact me privately, consider using Matrix or PGP mail.
## Other Accounts
### Telegram
My Telegram is [TommyTran732](https://t.me/tommytran732). I do not check it as often as I do with Matrix or Discord. When contacting me, please use the [Secret Chat](https://telegram.org/faq#q-how-do-i-start-a-secret-chat) feature.
### Twitter
- [@TommyTran732](https://twitter.com/tommytran732)
- [@PrivSec_Dev](https://twitter.com/privsec_dev)
### Linkedin
- [TommyTran732](http://linkedin.com/in/tommytran732).
For employers, please see [Hire Me!](/posts/hire-me)
### Facebook & Instagram
- TommyTran732
I only use Meta services as a fallback communication method with my real life friends. Please do not send me any friend requests unless I really know you. I only list these here for identity verification purposes.
Also, as of this writing (02/04/2026), Instagram E2EE is completely broken, so please do not send me an encrypted message on Instagram as I will not actually receive it.
### Git accounts
- [GitHub](https://github.com/tommytran732)
- [Metropolis GitLab](https://gitlab.metropolis.nexus/tommy)
Please by wary of anyone claiming to be me or using the handle "TommyTran732" reaching out to you. Chances are, they are an impersonator. You can always contact me via Matrix or Email for identity verification.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

-18
View File
@@ -1,18 +0,0 @@
---
title: "I am open to work!"
date: 2025-09-23
---
Im currently open to new opportunities and eager to join a team in the U.S. or Canada as an employee. I do not take on freelance or contract work. For U.S. opportunities, I dont require visa sponsorship at this time, though I may need it in the future. For Canadian opportunities, I will need an employer to apply for a work permit on my behalf. If youre looking for a committed team member, lets connect!
## What I Can Do
As a system administrator with 5 years of experience, I bring extensive expertise working with all three major Linux families—Red Hat, SUSE, and Debian—with a particular preference for Red Hat systems. While I am primarily a Linux administrator, I am also familiar with Windows systems and can handle tasks such as managing Active Directory.
I prioritize creating secure and reliable systems, implementing measures like systemd hardening, container hardening, timely vulnerability patching for containers, attack surface reduction, and protecting systems from both external and internal threats.
Most of my work is open source and available on GitHub. You can explore my server configurations on [Metropolis Nexus's GitHub](https://github.com/metropolis-nexus) to see my approach to system administration. For container security, I specialize in porting containers to Alpine Linux and performing daily rebuilds to ensure the latest patches are applied. Check out my work at [Polarix-Containers](https://github.com/polarix-containers), where I maintain a collection of OCI containers with enhanced protections.
## Qualifications
I hold several professional certifications, including the **Red Hat Certified System Administrator** and **Linux Foundation Certified Sysadmin**, demonstrating my expertise in Linux system administration. For a full list of my certifications, please visit my [LinkedIn profile](https://www.linkedin.com/in/tommytran732). I am committed to continuous learning and plan to pursue additional certifications in the near future to further enhance my skills.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

-71
View File
@@ -1,71 +0,0 @@
---
title: "My Projects"
date: 2022-09-02
---
These are some of my most notable projects. For a complete list, please visit my [GitHub profile](https://github.com/TommyTran732).
## PrivSec.dev
[PrivSec.dev](https://privsec.dev) is a website created by me and a few friends to provide practical privacy and security advice for end users. Think of it as a shared blog focused on this topic.
We emphasize in-depth system configuration, security analysis, and software/hardware recommendations, prioritizing technical merits over ideologies or politics.
## Polarix Containers
[Polarix Containers](https://github.com/Polarix-Containers) is a collection of OCI containers designed to enhance security compared to upstream builds.
Some containers are daily rebuilds of upstream containers, while others are rebuilt from scratch using Alpine Linux or Red Hat UBI with unprivileged users, maintaining upstream compatibility. Most builds include `hardened_malloc` for added security.
Polarix Containers serve as the foundation for my other projects, such as [Metropolis.nexus](https://metropolis.nexus).
## Metropolis.nexus
[Metropolis.nexus](https://metropolis.nexus) is a collection of services I offer free of charge, including but not limited to:
- Matrix
- Mastodon
- Vaultwarden
- Redlib
- Traccar
- Stirling PDF
- Signature PDF
The [Metropolis-nexus GitHub organization](https://github.com/Metropolis-nexus) contains repositories documenting the system's setup. Key subprojects include:
### Linux Setup Scripts
These [setup scripts](https://github.com/Metropolis-nexus/Linux-Setup-Scripts) are used on my Linux systems and include hardening configurations such as:
- Removal of unnecessary packages
- Hardened boot parameters
- Hardened `sysctl` settings
- Kernel module blacklist from [SecureBlue](https://github.com/secureblue/secureblue)
- SSH client and server hardening
- Systemd hardening
- Installation of `hardened_malloc` on Red Hat systems
- NTS setup
### Fedora CoreOS Ignition Files
These [Butane/Ignition configuration files](https://github.com/Metropolis-nexus/Fedora-CoreOS-Ignition) enable rapid deployment of Fedora CoreOS servers with the same hardening as the Linux Setup Scripts.
They also include systemd services to:
- Install and update gVisor at boot
- Update containers in a Docker Compose stack daily
### NGINX Configs
My reverse proxy setup is available in [this repository](https://github.com/Metropolis-nexus/NGINX-Setup). It includes:
- TLS configuration with strong cipher suites
- A robust set of security headers
- Content security policies for various services
- ModSecurity configuration
- Systemd hardening for system services
## Qubes OS scripts
My [Qubes OS scripts](https://github.com/TommyTran732/QubesOS-Scripts) configure Qubes virtual machines with the same hardening as my Linux setup scripts, tailored for Qubes' unique environment. I also provide documentation on how I set up my daily driver — a ThinkPad P53 — with Qubes for maximum privacy and security.
## Microsoft Edge Policies
Microsoft Edge can be one of the best browsers when configured properly, but it is privacy-invasive and has a large attack surface by default. My [list of policies](https://github.com/TommyTran732/Microsoft-Edge-Policies) configures it for improved privacy and security.
+136
View File
@@ -0,0 +1,136 @@
---
title: "Olivier Falcoz - Resume"
date: 2022-12-07T03:22:27+01:00
tags: ["resume","olivier falcoz","operational risk management","financial crime","anti-fraud","infosec","cybersecurity","business intelligence","governance","compliance"]
author: "Olivier Falcoz"
canonicalURL: "https://olivier.falcoz.net/resume"
hidemeta: true
ShowReadingTime: false
ShowPostNavLinks: true
showtoc: false
showtags: false
---
## Snapshot Profile
``$ Linkedin-style``
I provide consultancy services in operational risk management and information systems security to counter fraud, financial crime and other business disruptions. Formerly based in Asia Pacific, I am now based in France.
I am a seasoned professional with 25 years of global risk management experience, including 17 years in Asia, working in challenging and sensitive business environments for both the private sector and government organisations.
I have successfully delivered complex risk intelligence assignments across various sectors, including as resources, manufacturing, retail and energy in Asia and South East Asia. I have also worked in the Balkans, West and Horn of Africa, Brazil, French Guiana and Afghanistan.
Data privacy advocate and former Associate Expert at EDHEC Business School [Criminal Risk Management Chair](https://www.edhec.edu/en/mrc/criminal-risks-management-chair), France.
---
## Skills & Abilities
### Hard Skills
* Extensive experience in implementing operational risk frameworks and practices, conducting defensive risk mitigation strategies, collecting risk intelligence and searching assets,
* Extensive knowledge of the compliance and risk functions and of corruption, bribery and financial risk,
* Information systems security, WebApps audit & vulnerability assessment, data forensics & recovery, cryptography & encryption (GnuPG/PGP, TLS, OMEMO, OTR),
* SysAdmin (server administration: Debian / Nginx / Apache / NextCloud), Arch Linux advanced user,
* WebApps beta-tester ([mailfence.com](https://mailfence.com)), data privacy advocate (FLOSS, LibreOffice, XMPP, Android custom ROMs).
### Soft Skills
* Unique capacity to adapt myself to changing environments, understand corporate cultures and provide C-level executives with actionable intelligence,
* Ability to manage cross-functional teams, increasing engagement by integrating and consolidating multiple practices into a single centralised group function.
* Ability to track and manage complex projects, lead and supervise teams, and react quickly with discretion and good judgment in high-profile and sensitive situations.
* Well sharp reporting, negotiations and decision-making skills; determined and decisive; experienced in working with influencing stakeholders.
### Sport
`Mountain biking` avid Enduro and downhill mountain biker, co-organizer of the first [Enduro Asia MTB](https://enduroasiamtb.tumblr.com/post/55587094114/enduro-mtb-in-asia-our-story) race in Malaysia, [supported by Red Bull](https://www.redbull.com/my-en/riders-unite-enduro-takes-on-malaysia) (2013)
`Muay Thai` years
`Scuba diving` PADI Certified Divemaster (2011)
### Languages
`English:` full professional proficiency
`French:` native
---
## Experience
### Risk & Information Security
→ Conduct risk audits & vulnerability assessments, design contingency & business continuity plans against a variety of possible crisis situations including terrorism for major corporations (*Nestlé Malaysia & Thailand, Lafarge Malaysia*).
→ Take responsibility, as a project manager of large scale or complex international projects in collaboration with the COO (*Beiersdorf, B|Braun, BNP, Carrefour, Diageo, Lafarge, LVMH, Pernod-Ricard, P&G, Pfizer, Tesco, Total SA*).
→ As an expert in the risk management field, take direct responsibility over critical operational projects (security audit of *Sodexo Security Services for China*).
→ Conduct cybersecurity audits, test and harden information systems security policies and tools, perform data recovery & forensic analysis. Implement cyber & operational clients risk management frameworks across various clients business units.
### Risk Mitigation & Intelligence
→ Design & implement market entry/exit strategies and political, country and stakeholders risk mitigation solutions in sensitive environments (*Danone Malaysia, Safran Helicopter Engines SEA*).
→ Perform corporate intelligence search on fraud, criminality, counterfeiting and corruption across finance, production, purchasing and supply chain, advise and implement risks remediation solutions (*B|Braun, DCNS, Cold Storage, Danone Thailand & Cambodia, Tesco*).
→ Management of the stakeholders risk mitigation strategy for a USD2.5B oil project in South East Asia (Technip/JGC Vietnam).
→ Identify and assess new projects in China, Mongolia, Laos, Afghanistan, Qatar, Yemen, Papua New-Guinea, Vietnam, Thailand, Laos.
### Operations & Management
→ In charge of a firms risk strategy consulting practice for Malaysia, Thailand, Vietnam, Cambodia and occasionally other SEA countries. Conduct audits, design and implement complex risk management strategies with a focus on criminal security risks.
→ In charge of the Business Development & Marketing department, take part of the group strategy definition and implementation in 8 Asian countries, take responsibility for business growth and client satisfaction (China, Cambodia, Indonesia, Lao, Malaysia, Singapore, Thailand, Vietnam).
→ Management of *remote site* camp services for oil & gas, mining and construction industries - hospitality services, catering and security in remote and demanding environments (*Ivanhoe Mines Mongolia, EDF Lao, Technip China*).
→ Conduct full project acquisition cycle from tender development to contract negotiation. Plan and budget finance and operations, recruit teams, define staff mobilization programs. Take operational and financial control responsibilities.
→ Company creation and management. Take responsibilities for *greenfield* startup and development in Afghanistan and Laos.
---
## Career History
* Executive Director - [AGR Asia Solutions](https://agr.asia) Pte. Ltd.[^1]
Malaysia, Singapore then France `2019 → present`
* Managing Partner - [AGR Asia](https://agr.asia) Sdn. Bhd.[^2]
Kuala Lumpur, Malaysia `2015 → 2020`
* Company Advisor to [Asia Global Risk](https://asia-global-risk.com) Ltd. & personal projects
Kuala Lumpur, Malaysia `2011 → 2015`
* VP & Business Development Director - [Asia Global Risk](https://asia-global-risk.com) Ltd.
Kuala Lumpur, Malaysia `2009 → 2010`
* Co-Founder & Director - Opus Risk Management HK Ltd.
Shanghai, China `2006 → 2009`
* Managing Director - Operations (Remote Site Division) [Aden Services](https://adenservices.com/en)
Shanghai, China `2003 → 2005`
* Officer - [French Foreign Legion](https://www.legion-etrangere.com/)
Multiple roles from Combat Platoon Leader to Captain Commander of the French Jungle Warfare Center, 3e REI French Guiana. Previously served with the 13DBLE in
Djibouti and the 2REI, France. `1994 → 2003`
---
## Licenses & Certifications
* Executive Certificate, Cybersecurity - Harvard University ``2019``
* PADI Divemaster ``2011``
* [Curso de Operações Na Selva](https://cigs.eb.mil.br/) - CIGS Jungle Warfare Center, Manaus, Brazil ``2001``
---
## Education
- **Infantry Warfare School** - Saint-Cyr Military Academy Graduate by Equivalence, France ``1998``
- **Post-Master Degree of Business Administration (DESS)** - Major in Mergers, Acquisition and Business creation, Bordeaux I University, France ``1994``
- **Master Degree of Business Administration** - Major in Corporate Finance, Mergers & Acquisition, Paris IX Dauphine University, France ``1993``
[^1]: **AGR Asia Solutions Pte. Ltd.** is the successor to both **Asia Global Risk Ltd.**, a company with over 30 years of experience in Asia and **Amarante International Asia Pte. Ltd.**, established in Singapore in 2018. In 2023, it was decided to bring the companies together under a single banner.
[^2]: ex Asia Global Risk Ltd.
+52
View File
@@ -0,0 +1,52 @@
---
title: "Services"
date: 2022-12-09T03:22:29+01:00
tags: ["services", "olivier falcoz","risk intelligence","risk management","cybersecurity","infosec"]
author: "Olivier Falcoz"
canonicalURL: "https://olivier.falcoz.net/services"
hidemeta: true
ShowReadingTime: false
ShowPostNavLinks: true
showtoc: false
---
## Strategic Risk Intelligence
``$ whatis:``
* Identify and mitigate the risk of loss caused by flawed or failed processes, policies, systems or events that may disrupt business operations.
* Identify and mitigate economic, security and criminal risks associated with business operations
* Align asset governance structure with business objectives
* Provide accurate and actionable intelligence, develop and enforce effective intelligence collection policies
* Identify competititors' strategies, regulatory or government interference, corruption, criminality, fraud and intellectual property abuse
* Increase operational resilience and minimise operational disruption to the organisation
``$ howto:``
- Background check, due diligence / enhanced due diligence
- Business counter-intelligence
- Asset tracking & recovery
- IP rights investigation & enforcement
- Fraud & counterfeiting search
- Project risk analysis & remediation
## Protect Cybersecurity Assets
``$ whatis:``
* Secure *mission-critical* and *business-critical* assets e.g. information systems, intellectual property, physical assets
* Enforce the confidentiality, integrity, and availability of information systems and assets
* Reduce the impact of security breaches on information assets
* Strategically align cybersecurity efforts with business strategies to support organizational objectives
* Effectively manage cybersecurity knowledge among staff
``$ howto:``
- Business Impact Analysis : identify critical systems, networks and data
- Threat modeling, identify methods of attack
- Identify systems vulnerabilities; patch systems
- Enhance security posture, test & harden the perimeter
- Adopt defensive strategies
- Design systems & procedures with data security & privacy in mind
- Follow to industry standards, train users
- Raise cybersecurity awareness and staff training
+101
View File
@@ -0,0 +1,101 @@
{{- define "main" }}
{{- if (and site.Params.profileMode.enabled .IsHome) }}
{{- partial "index_profile.html" . }}
{{- else }} {{/* if not profileMode */}}
{{- if not .IsHome | and .Title }}
<header class="page-header">
{{- partial "breadcrumbs.html" . }}
<h1>
{{ .Title }}
{{- if and (or (eq .Kind `term`) (eq .Kind `section`)) (.Param "ShowRssButtonInSectionTermList") }}
<a href="index.xml" title="RSS" aria-label="RSS">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" height="23">
<path d="M4 11a9 9 0 0 1 9 9" />
<path d="M4 4a16 16 0 0 1 16 16" />
<circle cx="5" cy="19" r="1" />
</svg>
</a>
{{- end }}
</h1>
{{- if .Description }}
<div class="post-description">
{{ .Description | markdownify }}
</div>
{{- end }}
</header>
{{- end }}
{{- if .Content }}
<div class="post-content">
{{- if not (.Param "disableAnchoredHeadings") }}
{{- partial "anchored_headings.html" .Content -}}
{{- else }}{{ .Content }}{{ end }}
</div>
{{- end }}
{{- $pages := union .RegularPages .Sections }}
{{- if .IsHome }}
{{- $pages = where site.RegularPages "Type" "in" site.Params.mainSections }}
{{- end }}
{{- $paginator := .Paginate $pages }}
{{- if and .IsHome site.Params.homeInfoParams (eq $paginator.PageNumber 1) }}
{{- partial "home_info.html" . }}
{{- end }}
{{- $term := .Data.Term }}
{{- range $index, $page := $paginator.Pages.ByTitle }}
{{- $class := "post-entry" }}
{{- $user_preferred := or site.Params.disableSpecial1stPost site.Params.homeInfoParams }}
{{- if (and $.IsHome (eq $paginator.PageNumber 1) (eq $index 0) (not $user_preferred)) }}
{{- $class = "first-entry" }}
{{- else if $term }}
{{- $class = "post-entry tag-entry" }}
{{- end }}
<article class="{{ $class }}">
{{- $isHidden := (site.Params.cover.hidden | default site.Params.cover.hiddenInList) }}
{{- partial "cover.html" (dict "cxt" . "IsHome" true "isHidden" $isHidden) }}
<header class="entry-header">
<h2>
{{- .Title }}
{{- if .Draft }}<sup><span class="entry-isdraft">&nbsp;&nbsp;[draft]</span></sup>{{- end }}
</h2>
</header>
{{- if (ne (.Param "hideSummary") true) }}
<div class="entry-content">
<p>{{ .Summary | plainify | htmlUnescape }}{{ if .Truncated }}...{{ end }}</p>
</div>
{{- end }}
{{- if not (.Param "hideMeta") }}
<footer class="entry-footer">
{{- partial "post_meta.html" . -}}
</footer>
{{- end }}
<a class="entry-link" aria-label="post link to {{ .Title | plainify }}" href="{{ .Permalink }}"></a>
</article>
{{- end }}
{{- if gt $paginator.TotalPages 1 }}
<footer class="page-footer">
<nav class="pagination">
{{- if $paginator.HasPrev }}
<a class="prev" href="{{ $paginator.Prev.URL | absURL }}">« {{ i18n "prev_page" }}</a>
{{- end }}
{{- if $paginator.HasNext }}
<a class="next" href="{{ $paginator.Next.URL | absURL }}">{{ i18n "next_page" }} »</a>
{{- end }}
</nav>
</footer>
{{- end }}
{{- end }}{{/* end profileMode */}}
{{- end }}{{- /* end main */ -}}
+62
View File
@@ -0,0 +1,62 @@
{{- $pageurl := .Permalink }}
{{- $title := .Title }}
{{- $.Scratch.Set "tags" ""}}
{{- with .Params.Tags }}
{{- $hashtags := newScratch}}
{{- range . }}{{ $hashtags.Add "tags" (slice (replaceRE "(\\s)" "" . ))}}{{end}}
{{- $.Scratch.Set "tags" (delimit ($hashtags.Get "tags") ",") }}
{{- end -}}
{{- $custom := false }}
{{- $ShareButtons := (.Param "ShareButtons")}}
{{- with $ShareButtons }}{{ $custom = true }}{{ end }}
<div class="share-buttons">
{{- if (cond ($custom) (in $ShareButtons "twitter") (true)) }}
<a target="_blank" rel="noopener noreferrer" aria-label="share {{ $title | plainify }} on twitter"
href="https://twitter.com/intent/tweet/?text={{ $title }}&amp;url={{ $pageurl }}&amp;hashtags={{- $.Scratch.Get "tags" -}}">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-253.927,424.544c135.939,0 210.268,-112.643 210.268,-210.268c0,-3.218 0,-6.437 -0.153,-9.502c14.406,-10.421 26.973,-23.448 36.935,-38.314c-13.18,5.824 -27.433,9.809 -42.452,11.648c15.326,-9.196 26.973,-23.602 32.49,-40.92c-14.252,8.429 -30.038,14.56 -46.896,17.931c-13.487,-14.406 -32.644,-23.295 -53.946,-23.295c-40.767,0 -73.87,33.104 -73.87,73.87c0,5.824 0.613,11.494 1.992,16.858c-61.456,-3.065 -115.862,-32.49 -152.337,-77.241c-6.284,10.881 -9.962,23.601 -9.962,37.088c0,25.594 13.027,48.276 32.95,61.456c-12.107,-0.307 -23.448,-3.678 -33.41,-9.196l0,0.92c0,35.862 25.441,65.594 59.311,72.49c-6.13,1.686 -12.72,2.606 -19.464,2.606c-4.751,0 -9.348,-0.46 -13.946,-1.38c9.349,29.426 36.628,50.728 68.965,51.341c-25.287,19.771 -57.164,31.571 -91.8,31.571c-5.977,0 -11.801,-0.306 -17.625,-1.073c32.337,21.15 71.264,33.41 112.95,33.41Z" />
</svg>
</a>
{{- end }}
{{- if (cond ($custom) (in $ShareButtons "facebook") (true)) }}
<a target="_blank" rel="noopener noreferrer" aria-label="share {{ $title | plainify }} on facebook"
href="https://facebook.com/sharer/sharer.php?u={{ $pageurl }}">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-106.468,0l0,-192.915l66.6,0l12.672,-82.621l-79.272,0l0,-53.617c0,-22.603 11.073,-44.636 46.58,-44.636l36.042,0l0,-70.34c0,0 -32.71,-5.582 -63.982,-5.582c-65.288,0 -107.96,39.569 -107.96,111.204l0,62.971l-72.573,0l0,82.621l72.573,0l0,192.915l-191.104,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Z" />
</svg>
</a>
{{- end }}
{{- if (cond ($custom) (in $ShareButtons "reddit") (true)) }}
<a target="_blank" rel="noopener noreferrer" aria-label="share {{ $title | plainify }} on reddit"
href="https://reddit.com/submit?url={{ $pageurl }}&title={{ $title }}">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-3.446,265.638c0,-22.964 -18.616,-41.58 -41.58,-41.58c-11.211,0 -21.361,4.457 -28.841,11.666c-28.424,-20.508 -67.586,-33.757 -111.204,-35.278l18.941,-89.121l61.884,13.157c0.756,15.734 13.642,28.29 29.56,28.29c16.407,0 29.706,-13.299 29.706,-29.701c0,-16.403 -13.299,-29.702 -29.706,-29.702c-11.666,0 -21.657,6.792 -26.515,16.578l-69.105,-14.69c-1.922,-0.418 -3.939,-0.042 -5.585,1.036c-1.658,1.073 -2.811,2.761 -3.224,4.686l-21.152,99.438c-44.258,1.228 -84.046,14.494 -112.837,35.232c-7.468,-7.164 -17.589,-11.591 -28.757,-11.591c-22.965,0 -41.585,18.616 -41.585,41.58c0,16.896 10.095,31.41 24.568,37.918c-0.639,4.135 -0.99,8.328 -0.99,12.576c0,63.977 74.469,115.836 166.33,115.836c91.861,0 166.334,-51.859 166.334,-115.836c0,-4.218 -0.347,-8.387 -0.977,-12.493c14.564,-6.47 24.735,-21.034 24.735,-38.001Zm-119.474,108.193c-20.27,20.241 -59.115,21.816 -70.534,21.816c-11.428,0 -50.277,-1.575 -70.522,-21.82c-3.007,-3.008 -3.007,-7.882 0,-10.889c3.003,-2.999 7.882,-3.003 10.885,0c12.777,12.781 40.11,17.317 59.637,17.317c19.522,0 46.86,-4.536 59.657,-17.321c3.016,-2.999 7.886,-2.995 10.885,0.008c3.008,3.011 3.003,7.882 -0.008,10.889Zm-5.23,-48.781c-16.373,0 -29.701,-13.324 -29.701,-29.698c0,-16.381 13.328,-29.714 29.701,-29.714c16.378,0 29.706,13.333 29.706,29.714c0,16.374 -13.328,29.698 -29.706,29.698Zm-160.386,-29.702c0,-16.381 13.328,-29.71 29.714,-29.71c16.369,0 29.689,13.329 29.689,29.71c0,16.373 -13.32,29.693 -29.689,29.693c-16.386,0 -29.714,-13.32 -29.714,-29.693Z" />
</svg>
</a>
{{- end }}
{{- if (cond ($custom) (in $ShareButtons "telegram") (true)) }}
<a target="_blank" rel="noopener noreferrer" aria-label="share {{ $title | plainify }} on telegram"
href="https://telegram.me/share/url?text={{ $title }}&amp;url={{ $pageurl }}">
<svg version="1.1" xml:space="preserve" viewBox="2 2 28 28" height="30px" width="30px" fill="currentColor">
<path
d="M26.49,29.86H5.5a3.37,3.37,0,0,1-2.47-1,3.35,3.35,0,0,1-1-2.47V5.48A3.36,3.36,0,0,1,3,3,3.37,3.37,0,0,1,5.5,2h21A3.38,3.38,0,0,1,29,3a3.36,3.36,0,0,1,1,2.46V26.37a3.35,3.35,0,0,1-1,2.47A3.38,3.38,0,0,1,26.49,29.86Zm-5.38-6.71a.79.79,0,0,0,.85-.66L24.73,9.24a.55.55,0,0,0-.18-.46.62.62,0,0,0-.41-.17q-.08,0-16.53,6.11a.59.59,0,0,0-.41.59.57.57,0,0,0,.43.52l4,1.24,1.61,4.83a.62.62,0,0,0,.63.43.56.56,0,0,0,.4-.17L16.54,20l4.09,3A.9.9,0,0,0,21.11,23.15ZM13.8,20.71l-1.21-4q8.72-5.55,8.78-5.55c.15,0,.23,0,.23.16a.18.18,0,0,1,0,.06s-2.51,2.3-7.52,6.8Z" />
</svg>
</a>
{{- end }}
{{- if (cond ($custom) (in $ShareButtons "whatsapp") (true)) }}
<a target="_blank" rel="noopener noreferrer" aria-label="share {{ $title | plainify }} on whatsapp"
href="https://api.whatsapp.com/send?text={{ $title }}%20-%20{{ $pageurl }}">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-58.673,127.703c-33.842,-33.881 -78.847,-52.548 -126.798,-52.568c-98.799,0 -179.21,80.405 -179.249,179.234c-0.013,31.593 8.241,62.428 23.927,89.612l-25.429,92.884l95.021,-24.925c26.181,14.28 55.659,21.807 85.658,21.816l0.074,0c98.789,0 179.206,-80.413 179.247,-179.243c0.018,-47.895 -18.61,-92.93 -52.451,-126.81Zm-126.797,275.782l-0.06,0c-26.734,-0.01 -52.954,-7.193 -75.828,-20.767l-5.441,-3.229l-56.386,14.792l15.05,-54.977l-3.542,-5.637c-14.913,-23.72 -22.791,-51.136 -22.779,-79.287c0.033,-82.142 66.867,-148.971 149.046,-148.971c39.793,0.014 77.199,15.531 105.329,43.692c28.128,28.16 43.609,65.592 43.594,105.4c-0.034,82.149 -66.866,148.983 -148.983,148.984Zm81.721,-111.581c-4.479,-2.242 -26.499,-13.075 -30.604,-14.571c-4.105,-1.495 -7.091,-2.241 -10.077,2.241c-2.986,4.483 -11.569,14.572 -14.182,17.562c-2.612,2.988 -5.225,3.364 -9.703,1.12c-4.479,-2.241 -18.91,-6.97 -36.017,-22.23c-13.314,-11.876 -22.304,-26.542 -24.916,-31.026c-2.612,-4.484 -0.279,-6.908 1.963,-9.14c2.016,-2.007 4.48,-5.232 6.719,-7.847c2.24,-2.615 2.986,-4.484 4.479,-7.472c1.493,-2.99 0.747,-5.604 -0.374,-7.846c-1.119,-2.241 -10.077,-24.288 -13.809,-33.256c-3.635,-8.733 -7.327,-7.55 -10.077,-7.688c-2.609,-0.13 -5.598,-0.158 -8.583,-0.158c-2.986,0 -7.839,1.121 -11.944,5.604c-4.105,4.484 -15.675,15.32 -15.675,37.364c0,22.046 16.048,43.342 18.287,46.332c2.24,2.99 31.582,48.227 76.511,67.627c10.685,4.615 19.028,7.371 25.533,9.434c10.728,3.41 20.492,2.929 28.209,1.775c8.605,-1.285 26.499,-10.833 30.231,-21.295c3.732,-10.464 3.732,-19.431 2.612,-21.298c-1.119,-1.869 -4.105,-2.99 -8.583,-5.232Z" />
</svg>
</a>
{{- end }}
</div>
-17
View File
@@ -1,17 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZYip3xYJKwYBBAHaRw8BAQdAg8efRKSxYv02Xhl7VLCb71duExzKT/U437P8
bpwhvhG0IVRoaWVuIFRyYW4gPGNvbnRhY3RAdG9tbXl0cmFuLmlvPoiWBBMWCAA+
FiEEe7dA9MbjD0PUB28DVVyQKjTslo8FAmWIqd8CGwMFCQWjmoAFCwkIBwIGFQoJ
CAsCBBYCAwECHgECF4AACgkQVVyQKjTslo//6AEAvt58ku/TwB6zIOfvQYa0cYoj
gTdFAou/w3l1yiK6v5YA/09cBI0bWka4HJPuWtACM8WoCzyX9HMQCJhrWz4mNZgD
uDgEZYip3xIKKwYBBAGXVQEFAQEHQHZ640EjKVi0SEjM6K+3EgUnoOpcTquxhw9H
G7heqfEJAwEIB4h+BBgWCAAmFiEEe7dA9MbjD0PUB28DVVyQKjTslo8FAmWIqd8C
GwwFCQWjmoAACgkQVVyQKjTslo8lVwEAtLwM2qecldECFY1Efk6xrcsJr/pF93vb
eBRI1nCA8ywA/0GCG58Qn26aAqsiBv39F8LQ2RojMiydAppWJwnmYBoJuDMEZYiq
aBYJKwYBBAHaRw8BAQdAdSiTCWSCHOVJyT3whkXm+3enb6jorU36HWykQGcETVOI
fgQYFggAJhYhBHu3QPTG4w9D1AdvA1VckCo07JaPBQJliKpoAhsgBQkFo5qAAAoJ
EFVckCo07JaPH2AA/RUAT4KmKXDhru00NOrjvD6G65PSzhkcSGuZDK17xjLTAP9h
gvsQ6ieu4OfN2DVCJMC9na5RtxyRB71vsMzBYyTQCQ==
=XImG
-----END PGP PUBLIC KEY BLOCK-----
-16
View File
@@ -1,16 +0,0 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Contact: https://matrix.to/#/@tommy:metropolis.nexus
Contact: mailto:contact@tommytran.io
Expires: 2028-01-01T00:00:00.000Z
Encryption: https://tommytran.io/.well-known/pgp-key.txt
Preferred-Languages: en-US, vi-VN
Canonical: https://tommytran.io/.well-known/security.txt
-----BEGIN PGP SIGNATURE-----
iHUEARYIAB0WIQR7t0D0xuMPQ9QHbwNVXJAqNOyWjwUCaNrFcgAKCRBVXJAqNOyW
jwJuAP4v/K1orFjd8ZZfo0jvzdc9avMtIQdg4LwLiHuRJCrCTQEAsKSC2nMD7yQ+
+UjruhMebp8J+R1nP4GhvM/bKRPhdAc=
=NURv
-----END PGP SIGNATURE-----
-8
View File
@@ -1,8 +0,0 @@
<!doctype html><html lang=en dir=ltr class=scroll-smooth data-default-appearance=dark data-auto-appearance=false><head><meta charset=utf-8><meta http-equiv=content-language content="en"><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="ie=edge"><meta name=theme-color><title>404 Page not found &#183; Tommy's Space</title><meta name=title content="404 Page not found &#183; Tommy's Space"><meta name=description content="Tommy's personal website"><link rel=canonical href=https://www.tommytran.io/404.html><meta name=author content="Tommy Tran"><link href=https://github.com/TommyTran732 rel=me><link href=https://git.metropolis.nexus/Tommy rel=me><link href=https://matrix.to/#/@tommy:metropolis.nexus rel=me><link href=https://t.me/tommytran732 rel=me><link href=https://x.com/TommyTran732 rel=me><link href=https://www.linkedin.com/in/tommytran732 rel=me><link href=/.well-known/pgp-key.txt rel=me><meta property="og:url" content="https://www.tommytran.io/404.html"><meta property="og:site_name" content="Tommy's Space"><meta property="og:title" content="404 Page not found"><meta property="og:description" content="Tommy's personal website"><meta property="og:locale" content="en"><meta property="og:type" content="website"><meta name=twitter:card content="summary"><meta name=twitter:title content="404 Page not found"><meta name=twitter:description content="Tommy's personal website"><link type=text/css rel=stylesheet href=/css/main.bundle.min.7946532fa78157bafb1b4340d4074792811f18177af35790b3a0cb90566ce1cda3edd782eb92e134849964d14b6d9185c9d4ded2a12dcf5b706cb6a275c0cce0.css integrity="sha512-eUZTL6eBV7r7G0NA1AdHkoEfGBd681eQs6DLkFZs4c2j7deC65LhNISZZNFLbZGFydTe0qEtz1twbLaidcDM4A=="><script type=text/javascript src=/js/appearance.min.6f41174b3a05b680820fe08cadbfa5fb7a7ca347b76a0955cdc68b9d8aca1ce24f0547e138cea33bcc7904d551a90afcb1cc7f2d9fe8557075d501419046c08c.js integrity="sha512-b0EXSzoFtoCCD+CMrb+l+3p8o0e3aglVzcaLnYrKHOJPBUfhOM6jO8x5BNVRqQr8scx/LZ/oVXB11QFBkEbAjA=="></script><script src=/lib/zoom/zoom.min.umd.a527109b68c082a70f3697716dd72a9d5aa8b545cf800cecbbc7399f2ca6f6e0ce3e431f2062b48bbfa47c9ea42822714060bef309be073f49b9c0e30d318d7b.js integrity="sha512-pScQm2jAgqcPNpdxbdcqnVqotUXPgAzsu8c5nyym9uDOPkMfIGK0i7+kfJ6kKCJxQGC+8wm+Bz9JucDjDTGNew=="></script><script defer type=text/javascript id=script-bundle src=/js/main.bundle.min.9df4fc14d50efcc9aa4cfc2b6f348e365f421f5ad491278f8f48c0360cf2f93f08882fda6da162d7ace8e5add57c2df4ac46bd3861306b1d4c452cd31f448d64.js integrity="sha512-nfT8FNUO/MmqTPwrbzSONl9CH1rUkSePj0jANgzy+T8IiC/abaFi16zo5a3VfC30rEa9OGEwax1MRSzTH0SNZA==" data-copy=Copy data-copied=Copied></script><script src=/lib/jquery/jquery.slim.min.b0dca576e87d7eaa5850ae4e61759c065786cdb6489d68fcc82240539eebd5da522bdb4fda085ffd245808c8fe2acb2516408eb774ef26b5f6015fc6737c0ea8.js integrity="sha512-sNylduh9fqpYUK5OYXWcBleGzbZInWj8yCJAU57r1dpSK9tP2ghf/SRYCMj+KsslFkCOt3TvJrX2AV/Gc3wOqA=="></script><link rel=apple-touch-icon sizes=180x180 href=/apple-touch-icon.png><link rel=icon type=image/png sizes=32x32 href=/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=/favicon-16x16.png><link rel=manifest href=/site.webmanifest></head><body class="flex flex-col h-screen m-auto leading-7 max-w-7xl px-6 sm:px-14 md:px-24 lg:px-32 text-lg bg-neutral text-neutral-900 dark:bg-neutral-800 dark:text-neutral scrollbar-thin scrollbar-track-neutral-200 scrollbar-thumb-neutral-400 dark:scrollbar-track-neutral-800 dark:scrollbar-thumb-neutral-600"><div id=the-top class="absolute flex self-center"><a class="px-3 py-1 text-sm -translate-y-8 rounded-b-lg bg-primary-200 focus:translate-y-0 dark:bg-neutral-600" href=#main-content><span class="font-bold text-primary-600 pe-2 dark:text-primary-400">&darr;</span>
Skip to main content</a></div><div class=min-h-[148px]></div><div class="fixed inset-x-0 z-100"><div id=menu-blur class="absolute opacity-0 inset-x-0 top-0 h-full single_hero_background nozoom backdrop-blur-2xl shadow-2xl"></div><div class="relative m-auto leading-7 max-w-7xl px-6 sm:px-14 md:px-24 lg:px-32"><div class="main-menu flex items-center justify-between py-6 md:justify-start gap-x-3 pt-[2px] pr-2 md:pr-4 pb-[3px] pl-0"><div class="flex flex-1 items-center justify-between"><nav class="flex space-x-3"><a href=/ class="text-base font-medium">Tommy&rsquo;s Space</a></nav><nav class="hidden md:flex items-center gap-x-5 md:ml-12 h-12"><a href=/posts/about/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=About title="About Me"><p class="text-base font-medium">About</p></a><a href=https://privsec.dev target=_blank class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Blog title><p class="text-base font-medium">Blog</p></a><a href=/posts/projects/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Projects title="My Projects"><p class="text-base font-medium">Projects</p></a><a href=/posts/contact/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Contact title="Contact Information"><p class="text-base font-medium">Contact</p></a><a href=/posts/hire-me/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Hire Me!" title="I am open to work!"><p class="text-base font-medium">Hire Me!</p></a><a href class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" title></a><button id=search-button aria-label=Search class="text-base hover:text-primary-600 dark:hover:text-primary-400" title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></button></nav><div class="flex md:hidden items-center gap-x-5 md:ml-12 h-12"><span></span>
<button id=search-button-mobile aria-label=Search class="text-base hover:text-primary-600 dark:hover:text-primary-400" title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></button></div></div><div class="-my-2 md:hidden"><div id=menu-button class=block><div class="cursor-pointer hover:text-primary-600 dark:hover:text-primary-400"><span class="relative block icon"><svg viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.33 14.33 64 32 64H416c17.7.0 32 14.33 32 32 0 17.7-14.3 32-32 32H32C14.33 128 0 113.7.0 96zM0 256c0-17.7 14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32H32c-17.67.0-32-14.3-32-32zM416 448H32c-17.67.0-32-14.3-32-32s14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32z"/></svg></span></div><div id=menu-wrapper class="fixed inset-0 z-30 invisible w-screen h-screen m-0 overflow-auto transition-opacity opacity-0 cursor-default bg-neutral-100/50 backdrop-blur-sm dark:bg-neutral-900/50 pt-[5px]"><ul class="flex space-y-2 mt-3 flex-col items-end w-full px-6 py-6 mx-auto overflow-visible list-none text-end max-w-7xl"><li id=menu-close-button><span class="cursor-pointer inline-block align-text-bottom hover:text-primary-600 dark:hover:text-primary-400"><span class="relative block icon"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></span></li><li class=mt-1><a href=/posts/about/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=About title="About Me"><p class="text-bg font-bg">About</p></a></li><li class=mt-1><a href=https://privsec.dev target=_blank class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Blog title><p class="text-bg font-bg">Blog</p></a></li><li class=mt-1><a href=/posts/projects/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Projects title="My Projects"><p class="text-bg font-bg">Projects</p></a></li><li class=mt-1><a href=/posts/contact/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Contact title="Contact Information"><p class="text-bg font-bg">Contact</p></a></li><li class=mt-1><a href=/posts/hire-me/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Hire Me!" title="I am open to work!"><p class="text-bg font-bg">Hire Me!</p></a></li><li class=mt-1><a href class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" title></a></li></ul></div></div></div></div></div></div><script type=text/javascript src=/js/background-blur.min.00a57c73ea12f2cab2980c3c3d649e89f6d82f190f74bbe2b67f2f5e39ab7d032ece47086400ca05396758aace13299da49aca43ea643d2625e62c506267a169.js integrity="sha512-AKV8c+oS8sqymAw8PWSeifbYLxkPdLvitn8vXjmrfQMuzkcIZADKBTlnWKrOEymdpJrKQ+pkPSYl5ixQYmehaQ==" data-blur-id=menu-blur></script><div class="relative flex flex-col grow"><main id=main-content class=grow><h1 class="mb-3 text-4xl font-extrabold">Page Not Found 😕</h1><p class="mt-8 mb-12 text-neutral-400 dark:text-neutral-500">Error 404</p><div class="prose dark:prose-invert"><p>It seems that the page you've requested does not exist.</p></div><div id=scroll-to-top class="fixed bottom-24 end-6 z-50 transform translate-y-4 opacity-0 duration-200"><a href=#the-top class="pointer-events-auto flex h-12 w-12 items-center justify-center rounded-full bg-neutral/50 text-xl text-neutral-700 hover:text-primary-600 dark:bg-neutral-800/50 dark:text-neutral dark:hover:text-primary-400" aria-label="Scroll to top" title="Scroll to top">&uarr;</a></div></main><footer id=site-footer class="py-10 print:hidden"><nav class="flex flex-row pb-4 text-base font-medium text-neutral-500 dark:text-neutral-400 overflow-x-auto py-2"><ul class="flex list-none flex-row"><li class="flex mb-1 text-end sm:mb-0 sm:me-7 sm:last:me-0 me-4"><a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2 flex items-center" href title></a></li></ul></nav><div class="flex items-center justify-between"><p class="text-sm text-neutral-500 dark:text-neutral-400">&copy;
2025
Tommy Tran</p><p class="text-xs text-neutral-500 dark:text-neutral-400">Powered by <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href=https://gohugo.io/ target=_blank rel="noopener noreferrer">Hugo</a> & <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href=https://blowfish.page/ target=_blank rel="noopener noreferrer">Blowfish</a></p></div><script>mediumZoom(document.querySelectorAll("img:not(.nozoom)"),{margin:24,background:"rgba(0,0,0,0.5)",scrollOffset:0})</script><script type=text/javascript src=/js/process.min.ee03488f19c93c2efb199e2e3014ea5f3cb2ce7d45154adb3399a158cac27ca52831db249ede5bb602700ef87eb02434139de0858af1818ab0fb4182472204a4.js integrity="sha512-7gNIjxnJPC77GZ4uMBTqXzyyzn1FFUrbM5mhWMrCfKUoMdsknt5btgJwDvh+sCQ0E53ghYrxgYqw+0GCRyIEpA=="></script></footer><div id=search-wrapper class="invisible fixed inset-0 flex h-screen w-screen cursor-default flex-col bg-neutral-500/50 p-4 backdrop-blur-sm dark:bg-neutral-900/50 sm:p-6 md:p-[10vh] lg:p-[12vh] z-500" data-url=https://www.tommytran.io/><div id=search-modal class="flex flex-col w-full max-w-3xl min-h-0 mx-auto border rounded-md shadow-lg top-20 border-neutral-200 bg-neutral dark:border-neutral-700 dark:bg-neutral-800"><header class="relative z-10 flex items-center justify-between flex-none px-2"><form class="flex items-center flex-auto min-w-0"><div class="flex items-center justify-center w-8 h-8 text-neutral-400"><span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></div><input type=search id=search-query class="flex flex-auto h-12 mx-1 bg-transparent appearance-none focus:outline-dotted focus:outline-2 focus:outline-transparent" placeholder=Search tabindex=0></form><button id=close-search-button class="flex items-center justify-center w-8 h-8 text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400" title="Close (Esc)">
<span class="relative block icon"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></button></header><section class="flex-auto px-2 overflow-auto"><ul id=search-results></ul></section></div></div></div></body></html>
-22
View File
@@ -1,22 +0,0 @@
/*
Cross-Origin-Resource-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Permissions-Policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), bluetooth=(),browsing-topics=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-create=self, publickey-credentials-get=self, screen-wake-lock=(), serial=(), speaker-selection=(), sync-xhr=(), usb=(), xr-spatial-tracking=()
Alt-Svc: h3=":443"; ma=86400
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Access-Control-Max-Age: 600
Referrer-Policy: same-origin
X-Content-Type-Options: nosniff
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 0
X-Frame-Options : DENY
Content-Security-Policy: default-src 'none'; connect-src 'self'; img-src 'self'; manifest-src 'self'; script-src-attr 'unsafe-inline'; script-src-elem 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; form-action 'none'; frame-ancestors 'none'; upgrade-insecure-requests; base-uri 'none'
Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

-8
View File
@@ -1,8 +0,0 @@
<!doctype html><html lang=en dir=ltr class=scroll-smooth data-default-appearance=dark data-auto-appearance=false><head><meta charset=utf-8><meta http-equiv=content-language content="en"><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="ie=edge"><meta name=theme-color><title>Authors &#183; Tommy's Space</title><meta name=title content="Authors &#183; Tommy's Space"><meta name=description content="Tommy's personal website"><link rel=canonical href=https://www.tommytran.io/authors/><link rel=alternate type=application/rss+xml href=/authors/index.xml title="Tommy's Space"><meta name=author content="Tommy Tran"><link href=https://github.com/TommyTran732 rel=me><link href=https://git.metropolis.nexus/Tommy rel=me><link href=https://matrix.to/#/@tommy:metropolis.nexus rel=me><link href=https://t.me/tommytran732 rel=me><link href=https://x.com/TommyTran732 rel=me><link href=https://www.linkedin.com/in/tommytran732 rel=me><link href=/.well-known/pgp-key.txt rel=me><meta property="og:url" content="https://www.tommytran.io/authors/"><meta property="og:site_name" content="Tommy's Space"><meta property="og:title" content="Authors"><meta property="og:description" content="Tommy's personal website"><meta property="og:locale" content="en"><meta property="og:type" content="website"><meta name=twitter:card content="summary"><meta name=twitter:title content="Authors"><meta name=twitter:description content="Tommy's personal website"><link type=text/css rel=stylesheet href=/css/main.bundle.min.7946532fa78157bafb1b4340d4074792811f18177af35790b3a0cb90566ce1cda3edd782eb92e134849964d14b6d9185c9d4ded2a12dcf5b706cb6a275c0cce0.css integrity="sha512-eUZTL6eBV7r7G0NA1AdHkoEfGBd681eQs6DLkFZs4c2j7deC65LhNISZZNFLbZGFydTe0qEtz1twbLaidcDM4A=="><script type=text/javascript src=/js/appearance.min.6f41174b3a05b680820fe08cadbfa5fb7a7ca347b76a0955cdc68b9d8aca1ce24f0547e138cea33bcc7904d551a90afcb1cc7f2d9fe8557075d501419046c08c.js integrity="sha512-b0EXSzoFtoCCD+CMrb+l+3p8o0e3aglVzcaLnYrKHOJPBUfhOM6jO8x5BNVRqQr8scx/LZ/oVXB11QFBkEbAjA=="></script><script src=/lib/zoom/zoom.min.umd.a527109b68c082a70f3697716dd72a9d5aa8b545cf800cecbbc7399f2ca6f6e0ce3e431f2062b48bbfa47c9ea42822714060bef309be073f49b9c0e30d318d7b.js integrity="sha512-pScQm2jAgqcPNpdxbdcqnVqotUXPgAzsu8c5nyym9uDOPkMfIGK0i7+kfJ6kKCJxQGC+8wm+Bz9JucDjDTGNew=="></script><script defer type=text/javascript id=script-bundle src=/js/main.bundle.min.9df4fc14d50efcc9aa4cfc2b6f348e365f421f5ad491278f8f48c0360cf2f93f08882fda6da162d7ace8e5add57c2df4ac46bd3861306b1d4c452cd31f448d64.js integrity="sha512-nfT8FNUO/MmqTPwrbzSONl9CH1rUkSePj0jANgzy+T8IiC/abaFi16zo5a3VfC30rEa9OGEwax1MRSzTH0SNZA==" data-copy=Copy data-copied=Copied></script><script src=/lib/jquery/jquery.slim.min.b0dca576e87d7eaa5850ae4e61759c065786cdb6489d68fcc82240539eebd5da522bdb4fda085ffd245808c8fe2acb2516408eb774ef26b5f6015fc6737c0ea8.js integrity="sha512-sNylduh9fqpYUK5OYXWcBleGzbZInWj8yCJAU57r1dpSK9tP2ghf/SRYCMj+KsslFkCOt3TvJrX2AV/Gc3wOqA=="></script><link rel=apple-touch-icon sizes=180x180 href=/apple-touch-icon.png><link rel=icon type=image/png sizes=32x32 href=/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=/favicon-16x16.png><link rel=manifest href=/site.webmanifest></head><body class="flex flex-col h-screen m-auto leading-7 max-w-7xl px-6 sm:px-14 md:px-24 lg:px-32 text-lg bg-neutral text-neutral-900 dark:bg-neutral-800 dark:text-neutral scrollbar-thin scrollbar-track-neutral-200 scrollbar-thumb-neutral-400 dark:scrollbar-track-neutral-800 dark:scrollbar-thumb-neutral-600"><div id=the-top class="absolute flex self-center"><a class="px-3 py-1 text-sm -translate-y-8 rounded-b-lg bg-primary-200 focus:translate-y-0 dark:bg-neutral-600" href=#main-content><span class="font-bold text-primary-600 pe-2 dark:text-primary-400">&darr;</span>
Skip to main content</a></div><div class=min-h-[148px]></div><div class="fixed inset-x-0 z-100"><div id=menu-blur class="absolute opacity-0 inset-x-0 top-0 h-full single_hero_background nozoom backdrop-blur-2xl shadow-2xl"></div><div class="relative m-auto leading-7 max-w-7xl px-6 sm:px-14 md:px-24 lg:px-32"><div class="main-menu flex items-center justify-between py-6 md:justify-start gap-x-3 pt-[2px] pr-2 md:pr-4 pb-[3px] pl-0"><div class="flex flex-1 items-center justify-between"><nav class="flex space-x-3"><a href=/ class="text-base font-medium">Tommy&rsquo;s Space</a></nav><nav class="hidden md:flex items-center gap-x-5 md:ml-12 h-12"><a href=/posts/about/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=About title="About Me"><p class="text-base font-medium">About</p></a><a href=https://privsec.dev target=_blank class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Blog title><p class="text-base font-medium">Blog</p></a><a href=/posts/projects/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Projects title="My Projects"><p class="text-base font-medium">Projects</p></a><a href=/posts/contact/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Contact title="Contact Information"><p class="text-base font-medium">Contact</p></a><a href=/posts/hire-me/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Hire Me!" title="I am open to work!"><p class="text-base font-medium">Hire Me!</p></a><a href class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" title></a><button id=search-button aria-label=Search class="text-base hover:text-primary-600 dark:hover:text-primary-400" title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></button></nav><div class="flex md:hidden items-center gap-x-5 md:ml-12 h-12"><span></span>
<button id=search-button-mobile aria-label=Search class="text-base hover:text-primary-600 dark:hover:text-primary-400" title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></button></div></div><div class="-my-2 md:hidden"><div id=menu-button class=block><div class="cursor-pointer hover:text-primary-600 dark:hover:text-primary-400"><span class="relative block icon"><svg viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.33 14.33 64 32 64H416c17.7.0 32 14.33 32 32 0 17.7-14.3 32-32 32H32C14.33 128 0 113.7.0 96zM0 256c0-17.7 14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32H32c-17.67.0-32-14.3-32-32zM416 448H32c-17.67.0-32-14.3-32-32s14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32z"/></svg></span></div><div id=menu-wrapper class="fixed inset-0 z-30 invisible w-screen h-screen m-0 overflow-auto transition-opacity opacity-0 cursor-default bg-neutral-100/50 backdrop-blur-sm dark:bg-neutral-900/50 pt-[5px]"><ul class="flex space-y-2 mt-3 flex-col items-end w-full px-6 py-6 mx-auto overflow-visible list-none text-end max-w-7xl"><li id=menu-close-button><span class="cursor-pointer inline-block align-text-bottom hover:text-primary-600 dark:hover:text-primary-400"><span class="relative block icon"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></span></li><li class=mt-1><a href=/posts/about/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=About title="About Me"><p class="text-bg font-bg">About</p></a></li><li class=mt-1><a href=https://privsec.dev target=_blank class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Blog title><p class="text-bg font-bg">Blog</p></a></li><li class=mt-1><a href=/posts/projects/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Projects title="My Projects"><p class="text-bg font-bg">Projects</p></a></li><li class=mt-1><a href=/posts/contact/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Contact title="Contact Information"><p class="text-bg font-bg">Contact</p></a></li><li class=mt-1><a href=/posts/hire-me/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Hire Me!" title="I am open to work!"><p class="text-bg font-bg">Hire Me!</p></a></li><li class=mt-1><a href class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" title></a></li></ul></div></div></div></div></div></div><script type=text/javascript src=/js/background-blur.min.00a57c73ea12f2cab2980c3c3d649e89f6d82f190f74bbe2b67f2f5e39ab7d032ece47086400ca05396758aace13299da49aca43ea643d2625e62c506267a169.js integrity="sha512-AKV8c+oS8sqymAw8PWSeifbYLxkPdLvitn8vXjmrfQMuzkcIZADKBTlnWKrOEymdpJrKQ+pkPSYl5ixQYmehaQ==" data-blur-id=menu-blur></script><div class="relative flex flex-col grow"><main id=main-content class=grow><header class=mt-5><h1 class="mt-5 text-4xl font-extrabold text-neutral-900 dark:text-neutral">Authors</h1><div class="mt-1 mb-2 text-base text-neutral-500 dark:text-neutral-400 print:hidden"><div class="flex flex-row flex-wrap items-center"></div></div></header><section class="flex flex-wrap max-w-prose -mx-2 overflow-hidden"></section><div id=scroll-to-top class="fixed bottom-24 end-6 z-50 transform translate-y-4 opacity-0 duration-200"><a href=#the-top class="pointer-events-auto flex h-12 w-12 items-center justify-center rounded-full bg-neutral/50 text-xl text-neutral-700 hover:text-primary-600 dark:bg-neutral-800/50 dark:text-neutral dark:hover:text-primary-400" aria-label="Scroll to top" title="Scroll to top">&uarr;</a></div></main><footer id=site-footer class="py-10 print:hidden"><nav class="flex flex-row pb-4 text-base font-medium text-neutral-500 dark:text-neutral-400 overflow-x-auto py-2"><ul class="flex list-none flex-row"><li class="flex mb-1 text-end sm:mb-0 sm:me-7 sm:last:me-0 me-4"><a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2 flex items-center" href title></a></li></ul></nav><div class="flex items-center justify-between"><p class="text-sm text-neutral-500 dark:text-neutral-400">&copy;
2025
Tommy Tran</p><p class="text-xs text-neutral-500 dark:text-neutral-400">Powered by <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href=https://gohugo.io/ target=_blank rel="noopener noreferrer">Hugo</a> & <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href=https://blowfish.page/ target=_blank rel="noopener noreferrer">Blowfish</a></p></div><script>mediumZoom(document.querySelectorAll("img:not(.nozoom)"),{margin:24,background:"rgba(0,0,0,0.5)",scrollOffset:0})</script><script type=text/javascript src=/js/process.min.ee03488f19c93c2efb199e2e3014ea5f3cb2ce7d45154adb3399a158cac27ca52831db249ede5bb602700ef87eb02434139de0858af1818ab0fb4182472204a4.js integrity="sha512-7gNIjxnJPC77GZ4uMBTqXzyyzn1FFUrbM5mhWMrCfKUoMdsknt5btgJwDvh+sCQ0E53ghYrxgYqw+0GCRyIEpA=="></script></footer><div id=search-wrapper class="invisible fixed inset-0 flex h-screen w-screen cursor-default flex-col bg-neutral-500/50 p-4 backdrop-blur-sm dark:bg-neutral-900/50 sm:p-6 md:p-[10vh] lg:p-[12vh] z-500" data-url=https://www.tommytran.io/><div id=search-modal class="flex flex-col w-full max-w-3xl min-h-0 mx-auto border rounded-md shadow-lg top-20 border-neutral-200 bg-neutral dark:border-neutral-700 dark:bg-neutral-800"><header class="relative z-10 flex items-center justify-between flex-none px-2"><form class="flex items-center flex-auto min-w-0"><div class="flex items-center justify-center w-8 h-8 text-neutral-400"><span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></div><input type=search id=search-query class="flex flex-auto h-12 mx-1 bg-transparent appearance-none focus:outline-dotted focus:outline-2 focus:outline-transparent" placeholder=Search tabindex=0></form><button id=close-search-button class="flex items-center justify-center w-8 h-8 text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400" title="Close (Esc)">
<span class="relative block icon"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></button></header><section class="flex-auto px-2 overflow-auto"><ul id=search-results></ul></section></div></div></div></body></html>
-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Authors on Tommy's Space</title><link>https://www.tommytran.io/authors/</link><description>Recent content in Authors on Tommy's Space</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2025 Tommy Tran</copyright><atom:link href="https://www.tommytran.io/authors/index.xml" rel="self" type="application/rss+xml"/></channel></rss>
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

-8
View File
@@ -1,8 +0,0 @@
<!doctype html><html lang=en dir=ltr class=scroll-smooth data-default-appearance=dark data-auto-appearance=false><head><meta charset=utf-8><meta http-equiv=content-language content="en"><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="ie=edge"><meta name=theme-color><title>Categories &#183; Tommy's Space</title><meta name=title content="Categories &#183; Tommy's Space"><meta name=description content="Tommy's personal website"><link rel=canonical href=https://www.tommytran.io/categories/><link rel=alternate type=application/rss+xml href=/categories/index.xml title="Tommy's Space"><meta name=author content="Tommy Tran"><link href=https://github.com/TommyTran732 rel=me><link href=https://git.metropolis.nexus/Tommy rel=me><link href=https://matrix.to/#/@tommy:metropolis.nexus rel=me><link href=https://t.me/tommytran732 rel=me><link href=https://x.com/TommyTran732 rel=me><link href=https://www.linkedin.com/in/tommytran732 rel=me><link href=/.well-known/pgp-key.txt rel=me><meta property="og:url" content="https://www.tommytran.io/categories/"><meta property="og:site_name" content="Tommy's Space"><meta property="og:title" content="Categories"><meta property="og:description" content="Tommy's personal website"><meta property="og:locale" content="en"><meta property="og:type" content="website"><meta name=twitter:card content="summary"><meta name=twitter:title content="Categories"><meta name=twitter:description content="Tommy's personal website"><link type=text/css rel=stylesheet href=/css/main.bundle.min.7946532fa78157bafb1b4340d4074792811f18177af35790b3a0cb90566ce1cda3edd782eb92e134849964d14b6d9185c9d4ded2a12dcf5b706cb6a275c0cce0.css integrity="sha512-eUZTL6eBV7r7G0NA1AdHkoEfGBd681eQs6DLkFZs4c2j7deC65LhNISZZNFLbZGFydTe0qEtz1twbLaidcDM4A=="><script type=text/javascript src=/js/appearance.min.6f41174b3a05b680820fe08cadbfa5fb7a7ca347b76a0955cdc68b9d8aca1ce24f0547e138cea33bcc7904d551a90afcb1cc7f2d9fe8557075d501419046c08c.js integrity="sha512-b0EXSzoFtoCCD+CMrb+l+3p8o0e3aglVzcaLnYrKHOJPBUfhOM6jO8x5BNVRqQr8scx/LZ/oVXB11QFBkEbAjA=="></script><script src=/lib/zoom/zoom.min.umd.a527109b68c082a70f3697716dd72a9d5aa8b545cf800cecbbc7399f2ca6f6e0ce3e431f2062b48bbfa47c9ea42822714060bef309be073f49b9c0e30d318d7b.js integrity="sha512-pScQm2jAgqcPNpdxbdcqnVqotUXPgAzsu8c5nyym9uDOPkMfIGK0i7+kfJ6kKCJxQGC+8wm+Bz9JucDjDTGNew=="></script><script defer type=text/javascript id=script-bundle src=/js/main.bundle.min.9df4fc14d50efcc9aa4cfc2b6f348e365f421f5ad491278f8f48c0360cf2f93f08882fda6da162d7ace8e5add57c2df4ac46bd3861306b1d4c452cd31f448d64.js integrity="sha512-nfT8FNUO/MmqTPwrbzSONl9CH1rUkSePj0jANgzy+T8IiC/abaFi16zo5a3VfC30rEa9OGEwax1MRSzTH0SNZA==" data-copy=Copy data-copied=Copied></script><script src=/lib/jquery/jquery.slim.min.b0dca576e87d7eaa5850ae4e61759c065786cdb6489d68fcc82240539eebd5da522bdb4fda085ffd245808c8fe2acb2516408eb774ef26b5f6015fc6737c0ea8.js integrity="sha512-sNylduh9fqpYUK5OYXWcBleGzbZInWj8yCJAU57r1dpSK9tP2ghf/SRYCMj+KsslFkCOt3TvJrX2AV/Gc3wOqA=="></script><link rel=apple-touch-icon sizes=180x180 href=/apple-touch-icon.png><link rel=icon type=image/png sizes=32x32 href=/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=/favicon-16x16.png><link rel=manifest href=/site.webmanifest></head><body class="flex flex-col h-screen m-auto leading-7 max-w-7xl px-6 sm:px-14 md:px-24 lg:px-32 text-lg bg-neutral text-neutral-900 dark:bg-neutral-800 dark:text-neutral scrollbar-thin scrollbar-track-neutral-200 scrollbar-thumb-neutral-400 dark:scrollbar-track-neutral-800 dark:scrollbar-thumb-neutral-600"><div id=the-top class="absolute flex self-center"><a class="px-3 py-1 text-sm -translate-y-8 rounded-b-lg bg-primary-200 focus:translate-y-0 dark:bg-neutral-600" href=#main-content><span class="font-bold text-primary-600 pe-2 dark:text-primary-400">&darr;</span>
Skip to main content</a></div><div class=min-h-[148px]></div><div class="fixed inset-x-0 z-100"><div id=menu-blur class="absolute opacity-0 inset-x-0 top-0 h-full single_hero_background nozoom backdrop-blur-2xl shadow-2xl"></div><div class="relative m-auto leading-7 max-w-7xl px-6 sm:px-14 md:px-24 lg:px-32"><div class="main-menu flex items-center justify-between py-6 md:justify-start gap-x-3 pt-[2px] pr-2 md:pr-4 pb-[3px] pl-0"><div class="flex flex-1 items-center justify-between"><nav class="flex space-x-3"><a href=/ class="text-base font-medium">Tommy&rsquo;s Space</a></nav><nav class="hidden md:flex items-center gap-x-5 md:ml-12 h-12"><a href=/posts/about/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=About title="About Me"><p class="text-base font-medium">About</p></a><a href=https://privsec.dev target=_blank class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Blog title><p class="text-base font-medium">Blog</p></a><a href=/posts/projects/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Projects title="My Projects"><p class="text-base font-medium">Projects</p></a><a href=/posts/contact/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Contact title="Contact Information"><p class="text-base font-medium">Contact</p></a><a href=/posts/hire-me/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Hire Me!" title="I am open to work!"><p class="text-base font-medium">Hire Me!</p></a><a href class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" title></a><button id=search-button aria-label=Search class="text-base hover:text-primary-600 dark:hover:text-primary-400" title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></button></nav><div class="flex md:hidden items-center gap-x-5 md:ml-12 h-12"><span></span>
<button id=search-button-mobile aria-label=Search class="text-base hover:text-primary-600 dark:hover:text-primary-400" title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></button></div></div><div class="-my-2 md:hidden"><div id=menu-button class=block><div class="cursor-pointer hover:text-primary-600 dark:hover:text-primary-400"><span class="relative block icon"><svg viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.33 14.33 64 32 64H416c17.7.0 32 14.33 32 32 0 17.7-14.3 32-32 32H32C14.33 128 0 113.7.0 96zM0 256c0-17.7 14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32H32c-17.67.0-32-14.3-32-32zM416 448H32c-17.67.0-32-14.3-32-32s14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32z"/></svg></span></div><div id=menu-wrapper class="fixed inset-0 z-30 invisible w-screen h-screen m-0 overflow-auto transition-opacity opacity-0 cursor-default bg-neutral-100/50 backdrop-blur-sm dark:bg-neutral-900/50 pt-[5px]"><ul class="flex space-y-2 mt-3 flex-col items-end w-full px-6 py-6 mx-auto overflow-visible list-none text-end max-w-7xl"><li id=menu-close-button><span class="cursor-pointer inline-block align-text-bottom hover:text-primary-600 dark:hover:text-primary-400"><span class="relative block icon"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></span></li><li class=mt-1><a href=/posts/about/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=About title="About Me"><p class="text-bg font-bg">About</p></a></li><li class=mt-1><a href=https://privsec.dev target=_blank class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Blog title><p class="text-bg font-bg">Blog</p></a></li><li class=mt-1><a href=/posts/projects/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Projects title="My Projects"><p class="text-bg font-bg">Projects</p></a></li><li class=mt-1><a href=/posts/contact/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Contact title="Contact Information"><p class="text-bg font-bg">Contact</p></a></li><li class=mt-1><a href=/posts/hire-me/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Hire Me!" title="I am open to work!"><p class="text-bg font-bg">Hire Me!</p></a></li><li class=mt-1><a href class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" title></a></li></ul></div></div></div></div></div></div><script type=text/javascript src=/js/background-blur.min.00a57c73ea12f2cab2980c3c3d649e89f6d82f190f74bbe2b67f2f5e39ab7d032ece47086400ca05396758aace13299da49aca43ea643d2625e62c506267a169.js integrity="sha512-AKV8c+oS8sqymAw8PWSeifbYLxkPdLvitn8vXjmrfQMuzkcIZADKBTlnWKrOEymdpJrKQ+pkPSYl5ixQYmehaQ==" data-blur-id=menu-blur></script><div class="relative flex flex-col grow"><main id=main-content class=grow><header class=mt-5><h1 class="mt-5 text-4xl font-extrabold text-neutral-900 dark:text-neutral">Categories</h1><div class="mt-1 mb-2 text-base text-neutral-500 dark:text-neutral-400 print:hidden"><div class="flex flex-row flex-wrap items-center"></div></div></header><section class="flex flex-wrap max-w-prose -mx-2 overflow-hidden"></section><div id=scroll-to-top class="fixed bottom-24 end-6 z-50 transform translate-y-4 opacity-0 duration-200"><a href=#the-top class="pointer-events-auto flex h-12 w-12 items-center justify-center rounded-full bg-neutral/50 text-xl text-neutral-700 hover:text-primary-600 dark:bg-neutral-800/50 dark:text-neutral dark:hover:text-primary-400" aria-label="Scroll to top" title="Scroll to top">&uarr;</a></div></main><footer id=site-footer class="py-10 print:hidden"><nav class="flex flex-row pb-4 text-base font-medium text-neutral-500 dark:text-neutral-400 overflow-x-auto py-2"><ul class="flex list-none flex-row"><li class="flex mb-1 text-end sm:mb-0 sm:me-7 sm:last:me-0 me-4"><a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2 flex items-center" href title></a></li></ul></nav><div class="flex items-center justify-between"><p class="text-sm text-neutral-500 dark:text-neutral-400">&copy;
2025
Tommy Tran</p><p class="text-xs text-neutral-500 dark:text-neutral-400">Powered by <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href=https://gohugo.io/ target=_blank rel="noopener noreferrer">Hugo</a> & <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href=https://blowfish.page/ target=_blank rel="noopener noreferrer">Blowfish</a></p></div><script>mediumZoom(document.querySelectorAll("img:not(.nozoom)"),{margin:24,background:"rgba(0,0,0,0.5)",scrollOffset:0})</script><script type=text/javascript src=/js/process.min.ee03488f19c93c2efb199e2e3014ea5f3cb2ce7d45154adb3399a158cac27ca52831db249ede5bb602700ef87eb02434139de0858af1818ab0fb4182472204a4.js integrity="sha512-7gNIjxnJPC77GZ4uMBTqXzyyzn1FFUrbM5mhWMrCfKUoMdsknt5btgJwDvh+sCQ0E53ghYrxgYqw+0GCRyIEpA=="></script></footer><div id=search-wrapper class="invisible fixed inset-0 flex h-screen w-screen cursor-default flex-col bg-neutral-500/50 p-4 backdrop-blur-sm dark:bg-neutral-900/50 sm:p-6 md:p-[10vh] lg:p-[12vh] z-500" data-url=https://www.tommytran.io/><div id=search-modal class="flex flex-col w-full max-w-3xl min-h-0 mx-auto border rounded-md shadow-lg top-20 border-neutral-200 bg-neutral dark:border-neutral-700 dark:bg-neutral-800"><header class="relative z-10 flex items-center justify-between flex-none px-2"><form class="flex items-center flex-auto min-w-0"><div class="flex items-center justify-center w-8 h-8 text-neutral-400"><span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></div><input type=search id=search-query class="flex flex-auto h-12 mx-1 bg-transparent appearance-none focus:outline-dotted focus:outline-2 focus:outline-transparent" placeholder=Search tabindex=0></form><button id=close-search-button class="flex items-center justify-center w-8 h-8 text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400" title="Close (Esc)">
<span class="relative block icon"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></button></header><section class="flex-auto px-2 overflow-auto"><ul id=search-results></ul></section></div></div></div></body></html>
-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Categories on Tommy's Space</title><link>https://www.tommytran.io/categories/</link><description>Recent content in Categories on Tommy's Space</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2025 Tommy Tran</copyright><atom:link href="https://www.tommytran.io/categories/index.xml" rel="self" type="application/rss+xml"/></channel></rss>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

-16
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tommy's Space</title><link>https://www.tommytran.io/</link><description>Recent content on Tommy's Space</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2025 Tommy Tran</copyright><lastBuildDate>Tue, 23 Sep 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://www.tommytran.io/index.xml" rel="self" type="application/rss+xml"/><item><title>I am open to work!</title><link>https://www.tommytran.io/posts/hire-me/</link><pubDate>Tue, 23 Sep 2025 00:00:00 +0000</pubDate><guid>https://www.tommytran.io/posts/hire-me/</guid><description/><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://www.tommytran.io/posts/hire-me/featured.jpg"/></item><item><title>About Me</title><link>https://www.tommytran.io/posts/about/</link><pubDate>Fri, 02 Sep 2022 00:00:00 +0000</pubDate><guid>https://www.tommytran.io/posts/about/</guid><description/><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://www.tommytran.io/posts/about/featured.jpg"/></item><item><title>Contact Information</title><link>https://www.tommytran.io/posts/contact/</link><pubDate>Fri, 02 Sep 2022 00:00:00 +0000</pubDate><guid>https://www.tommytran.io/posts/contact/</guid><description/><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://www.tommytran.io/posts/contact/featured.jpg"/></item><item><title>My Projects</title><link>https://www.tommytran.io/posts/projects/</link><pubDate>Fri, 02 Sep 2022 00:00:00 +0000</pubDate><guid>https://www.tommytran.io/posts/projects/</guid><description/><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://www.tommytran.io/posts/projects/featured.jpg"/></item></channel></rss>
@@ -1 +0,0 @@
const sitePreference=document.documentElement.getAttribute("data-default-appearance"),userPreference=localStorage.getItem("appearance");(sitePreference==="dark"&&userPreference===null||userPreference==="dark")&&document.documentElement.classList.add("dark"),document.documentElement.getAttribute("data-auto-appearance")==="true"&&(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches&&userPreference!=="light"&&document.documentElement.classList.add("dark"),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{e.matches?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")})),window.addEventListener("DOMContentLoaded",e=>{const t=document.getElementById("appearance-switcher"),n=document.getElementById("appearance-switcher-mobile");updateMeta(),this.updateLogo?.(getTargetAppearance()),t&&(t.addEventListener("click",()=>{document.documentElement.classList.toggle("dark");var e=getTargetAppearance();localStorage.setItem("appearance",e),updateMeta(),this.updateLogo?.(e)}),t.addEventListener("contextmenu",e=>{e.preventDefault(),localStorage.removeItem("appearance")})),n&&(n.addEventListener("click",()=>{document.documentElement.classList.toggle("dark");var e=getTargetAppearance();localStorage.setItem("appearance",e),updateMeta(),this.updateLogo?.(e)}),n.addEventListener("contextmenu",e=>{e.preventDefault(),localStorage.removeItem("appearance")}))});var updateMeta=()=>{var e=document.querySelector("body"),t=getComputedStyle(e);document.querySelector('meta[name="theme-color"]').setAttribute("content",t.backgroundColor)},getTargetAppearance=()=>document.documentElement.classList.contains("dark")?"dark":"light";window.addEventListener("DOMContentLoaded",e=>{const t=document.getElementById("top-scroller"),n=document.getElementById("site-footer");t&&n&&t.getBoundingClientRect().top>n.getBoundingClientRect().top&&(t.hidden=!0)})
@@ -1 +0,0 @@
const sitePreference=document.documentElement.getAttribute("data-default-appearance"),userPreference=localStorage.getItem("appearance");(sitePreference==="dark"&&userPreference===null||userPreference==="dark")&&document.documentElement.classList.add("dark"),document.documentElement.getAttribute("data-auto-appearance")==="true"&&(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches&&userPreference!=="light"&&document.documentElement.classList.add("dark"),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{e.matches?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")}));var updateMeta,getTargetAppearance,updateMermaidTheme=()=>{if(typeof mermaid!="undefined"){const e=document.documentElement.classList.contains("dark"),t=document.querySelectorAll("pre.mermaid");t.forEach(e=>{e.getAttribute("data-processed")?(e.removeAttribute("data-processed"),e.innerHTML=e.getAttribute("data-graph")):e.setAttribute("data-graph",e.textContent)}),e?(initMermaidDark(),mermaid.run()):(initMermaidLight(),mermaid.run())}};window.addEventListener("DOMContentLoaded",e=>{const t=document.getElementById("appearance-switcher"),n=document.getElementById("appearance-switcher-mobile");updateMeta(),this.updateLogo?.(getTargetAppearance()),updateMermaidTheme(),t&&(t.addEventListener("click",()=>{document.documentElement.classList.toggle("dark");var e=getTargetAppearance();localStorage.setItem("appearance",e),updateMeta(),updateMermaidTheme(),this.updateLogo?.(e)}),t.addEventListener("contextmenu",e=>{e.preventDefault(),localStorage.removeItem("appearance")})),n&&(n.addEventListener("click",()=>{document.documentElement.classList.toggle("dark");var e=getTargetAppearance();localStorage.setItem("appearance",e),updateMeta(),updateMermaidTheme(),this.updateLogo?.(e)}),n.addEventListener("contextmenu",e=>{e.preventDefault(),localStorage.removeItem("appearance")}))}),updateMeta=()=>{var e=document.querySelector("body"),t=getComputedStyle(e);document.querySelector('meta[name="theme-color"]').setAttribute("content",t.backgroundColor)},getTargetAppearance=()=>document.documentElement.classList.contains("dark")?"dark":"light",window.addEventListener("DOMContentLoaded",e=>{const t=document.getElementById("top-scroller"),n=document.getElementById("site-footer");t&&n&&t.getBoundingClientRect().top>n.getBoundingClientRect().top&&(t.hidden=!0)})
@@ -1 +0,0 @@
function setBackgroundBlur(e,t=300,n=!1,s=!1){if(!e){console.error("data-blur-id is null");return}const o=document.getElementById(e);if(!o)return;n?(o.setAttribute("aria-hidden","true"),s?o.style.display="":(o.style.display="none",o.style.opacity="0")):(o.style.display="",o.removeAttribute("aria-hidden"));const i=()=>{if(!n||s){const e=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;o.style.opacity=e/t}};o.setAttribute("role","presentation"),o.setAttribute("tabindex","-1"),window.addEventListener("scroll",i),i()}document.querySelectorAll("script[data-blur-id]").forEach(e=>{const t=e.getAttribute("data-blur-id"),n=Number(e.getAttribute("data-scroll-divisor")||300),s=t==="menu-blur",o=JSON.parse(localStorage.getItem("a11ySettings")||"{}"),i=o.disableBlur||!1;setBackgroundBlur(t,n,i,s)})
@@ -1 +0,0 @@
const pageScriptElement=document.currentScript,oid=pageScriptElement&&pageScriptElement.getAttribute("data-oid")?pageScriptElement.getAttribute("data-oid"):(console.error("data-oid is null"),null),oid_likes=pageScriptElement&&pageScriptElement.getAttribute("data-oid-likes")?pageScriptElement.getAttribute("data-oid-likes"):(console.error("data-oid-likes is null"),null);let liked_page=!1;const id=oid&&oid.replaceAll("/","-"),id_likes=oid_likes&&oid_likes.replaceAll("/","-");if(typeof auth!="undefined"){const e=localStorage.getItem(id);e||auth.signInAnonymously().then(()=>{const e=db.collection("views").doc(id);localStorage.setItem(id,!0),e.get().then(e=>{e.exists?db.collection("views").doc(id).update({views:firebase.firestore.FieldValue.increment(1)}):db.collection("views").doc(id).set({views:1})}).catch(e=>{console.log("Error getting document:",e)})}).catch(e=>{const t=e.code,n=e.message;console.error(t,n)});const t=localStorage.getItem(id_likes);t&&(liked_page=!0,document.querySelectorAll("span[id='button_likes_heart']")[0].style.display="",document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display="none",document.querySelectorAll("span[id='button_likes_text']")[0].innerText="")}function like_article(e){auth.signInAnonymously().then(()=>{const t=db.collection("likes").doc(e);t.get().then(t=>{liked_page=!0,localStorage.setItem(e,!0),document.querySelectorAll("span[id='button_likes_heart']")[0].style.display="",document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display="none",document.querySelectorAll("span[id='button_likes_text']")[0].innerText="",t.exists?db.collection("likes").doc(e).update({likes:firebase.firestore.FieldValue.increment(1)}):db.collection("likes").doc(e).set({likes:1})}).catch(e=>{console.log("Error getting document:",e)})}).catch(e=>{const t=e.code,n=e.message;console.error(t,n)})}function remove_like_article(e){auth.signInAnonymously().then(()=>{const t=db.collection("likes").doc(e);t.get().then(t=>{liked_page=!1,localStorage.removeItem(e),document.querySelectorAll("span[id='button_likes_heart']")[0].style.display="none",document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display="",document.querySelectorAll("span[id='button_likes_text']")[0].innerText="\xa0Like",t.exists?db.collection("likes").doc(e).update({likes:firebase.firestore.FieldValue.increment(-1)}):db.collection("likes").doc(e).set({likes:0})}).catch(e=>{console.log("Error getting document:",e)})}).catch(e=>{const t=e.code,n=e.message;console.error(t,n)})}function process_article(){liked_page?remove_like_article(id_likes):like_article(id_likes)}
@@ -1 +0,0 @@
if(typeof auth!="undefined"){var update_views,update_likes,viewsCollection=db.collection("views"),likesCollection=db.collection("likes");function numberWithCommas(e){return e.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}function toggleLoaders(e){var t,s,n=e.className;if(n=="")return;t=n.split(" ");for(s in t)e.classList.toggle(t[s])}update_views=function(e,t){viewsCollection.doc(t).onSnapshot(t=>{var n=t.data();n?e.innerText=numberWithCommas(n.views):e.innerText=0,toggleLoaders(e)})},update_likes=function(e,t){likesCollection.doc(t).onSnapshot(t=>{var n=t.data();n?e.innerText=numberWithCommas(n.likes):e.innerText=0,toggleLoaders(e)})},auth.signInAnonymously().then(()=>{var e,t,n,s,o=document.querySelectorAll("span[id^='views_']");for(n in o)e=o[n],t=e.id?e.id.replaceAll("/","-"):e.id,t&&update_views(e,t);s=document.querySelectorAll("span[id^='likes_']");for(n in s)e=s[n],t=e.id?e.id.replaceAll("/","-"):e.id,t&&update_likes(e,t)}).catch(e=>{var t=e.code,n=e.message;console.error(t,n)})}
-1
View File
@@ -1 +0,0 @@
<!doctype html><html lang=en><head><title>https://www.tommytran.io/</title><link rel=canonical href=https://www.tommytran.io/><meta charset=utf-8><meta http-equiv=refresh content="0; url=https://www.tommytran.io/"></head></html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

@@ -1,823 +0,0 @@
<!doctype html>
<html
lang="en"
dir="ltr"
class="scroll-smooth"
data-default-appearance="light"
data-auto-appearance="true"><head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
<meta charset="utf-8">
<meta http-equiv="content-language" content="en">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="theme-color">
<title>Hire Me! &middot; Tommy Tran</title>
<meta name="title" content="Hire Me! &middot; Tommy Tran">
<meta name="description" content="a description">
<meta name="keywords" content="example,tag,">
<link rel="canonical" href="//localhost:1313/posts/1758620989805-hire-me/">
<link
type="text/css"
rel="stylesheet"
href="/css/main.bundle.min.f875dda8a6dc16f33adb8873681506c07444631be7e42b7575718d40698db0db7cd237ac4306f361ed9daaa2f828ff344a9fc7f845cf0217dcbc9360d395f0f9.css"
integrity="sha512-&#43;HXdqKbcFvM624hzaBUGwHREYxvn5Ct1dXGNQGmNsNt80jesQwbzYe2dqqL4KP80Sp/H&#43;EXPAhfcvJNg05Xw&#43;Q==">
<script
type="text/javascript"
src="/js/appearance.min.516a16745bea5a9bd011138d254cc0fd3973cd55ce6e15f3dec763e7c7c2c7448f8fe7b54cca811cb821b0c7e12cd161caace1dd794ac3d34d40937cbcc9ee12.js"
integrity="sha512-UWoWdFvqWpvQERONJUzA/TlzzVXObhXz3sdj58fCx0SPj&#43;e1TMqBHLghsMfhLNFhyqzh3XlKw9NNQJN8vMnuEg=="></script>
<script
defer
type="text/javascript"
id="script-bundle"
src="/js/main.bundle.min.a187118b41a60744310065c567365de85730c8495301d0ebae41810cc6f7a47432b1de7d4f3b11338959f1ac50c266be6b4b73acf6bf770016eb59b602cc1aa0.js"
integrity="sha512-oYcRi0GmB0QxAGXFZzZd6FcwyElTAdDrrkGBDMb3pHQysd59TzsRM4lZ8axQwma&#43;a0tzrPa/dwAW61m2AswaoA=="
data-copy="Copy"
data-copied="Copied"></script>
<script src="/lib/zoom/zoom.min.umd.a527109b68c082a70f3697716dd72a9d5aa8b545cf800cecbbc7399f2ca6f6e0ce3e431f2062b48bbfa47c9ea42822714060bef309be073f49b9c0e30d318d7b.js" integrity="sha512-pScQm2jAgqcPNpdxbdcqnVqotUXPgAzsu8c5nyym9uDOPkMfIGK0i7&#43;kfJ6kKCJxQGC&#43;8wm&#43;Bz9JucDjDTGNew=="></script>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<meta property="og:url" content="//localhost:1313/posts/1758620989805-hire-me/">
<meta property="og:site_name" content="Tommy Tran">
<meta property="og:title" content="Hire Me!">
<meta property="og:description" content="a description">
<meta property="og:locale" content="en">
<meta property="og:type" content="article">
<meta property="article:section" content="posts">
<meta property="article:published_time" content="2025-09-23T00:00:00+00:00">
<meta property="article:modified_time" content="2025-09-23T00:00:00+00:00">
<meta property="article:tag" content="Example">
<meta property="article:tag" content="Tag">
<meta property="og:image" content="//localhost:1313/posts/1758620989805-hire-me/featured.png">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="//localhost:1313/posts/1758620989805-hire-me/featured.png">
<meta name="twitter:title" content="Hire Me!">
<meta name="twitter:description" content="a description">
<meta name="twitter:image" content="//localhost:1313/posts/1758620989805-hire-me/featured.png">
<meta property="og:image" content="//localhost:1313/posts/1758620989805-hire-me/featured.png">
<script type="application/ld+json">
[{
"@context": "https://schema.org",
"@type": "Article",
"articleSection": "Posts",
"name": "Hire Me!",
"headline": "Hire Me!",
"description": "a description",
"inLanguage": "en",
"url" : "\/\/localhost:1313\/posts\/1758620989805-hire-me\/",
"author" : {
"@type": "Person",
"name": "Tommy Tran"
},
"copyrightYear": "2025",
"dateCreated": "2025-09-23T00:00:00\u002b00:00",
"datePublished": "2025-09-23T00:00:00\u002b00:00",
"dateModified": "2025-09-23T00:00:00\u002b00:00",
"keywords": ["example","tag"],
"mainEntityOfPage": "true",
"wordCount": "41"
}]
</script>
<meta name="author" content="Tommy Tran">
<link href="https://github.com/TommyTran732" rel="me">
<link href="https://matrix.to/#/@tommy:metropolis.nexus" rel="me">
<link href="https://t.me/tommytran732" rel="me">
<link href="https://x.com/TommyTran732" rel="me">
<link href="https://www.linkedin.com/in/tommytran732" rel="me">
<link href="/tommy.asc" rel="me">
<script src="/lib/jquery/jquery.slim.min.b0dca576e87d7eaa5850ae4e61759c065786cdb6489d68fcc82240539eebd5da522bdb4fda085ffd245808c8fe2acb2516408eb774ef26b5f6015fc6737c0ea8.js" integrity="sha512-sNylduh9fqpYUK5OYXWcBleGzbZInWj8yCJAU57r1dpSK9tP2ghf/SRYCMj&#43;KsslFkCOt3TvJrX2AV/Gc3wOqA=="></script>
</head>
<body
class="flex flex-col h-screen px-6 m-auto text-lg leading-7 max-w-7xl bg-neutral text-neutral-900 dark:bg-neutral-800 dark:text-neutral sm:px-14 md:px-24 lg:px-32 scrollbar-thin scrollbar-track-neutral-200 scrollbar-thumb-neutral-400 dark:scrollbar-track-neutral-800 dark:scrollbar-thumb-neutral-600">
<div id="the-top" class="absolute flex self-center">
<a
class="px-3 py-1 text-sm -translate-y-8 rounded-b-lg bg-primary-200 focus:translate-y-0 dark:bg-neutral-600"
href="#main-content">
<span class="font-bold text-primary-600 pe-2 dark:text-primary-400">&darr;</span>
Skip to main content
</a>
</div>
<div
class="main-menu flex items-center justify-between px-4 py-6 sm:px-6 md:justify-start gap-x-3 pt-[2px] pr-0 pb-[3px] pl-0">
<div class="flex flex-1 items-center justify-between">
<nav class="flex space-x-3">
<a href="/" class="text-base font-medium">
Tommy Tran
</a>
</nav>
<nav class="hidden md:flex items-center gap-x-5 md:ml-12 h-12">
<button
id="search-button"
aria-label="Search"
class="text-base hover:text-primary-600 dark:hover:text-primary-400"
title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg>
</span>
</button>
<div class=" flex items-center">
<button
id="appearance-switcher"
aria-label="Dark mode switcher"
type="button"
class="text-base hover:text-primary-600 dark:hover:text-primary-400">
<div class="flex items-center justify-center dark:hidden">
<span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M32 256c0-123.8 100.3-224 223.8-224c11.36 0 29.7 1.668 40.9 3.746c9.616 1.777 11.75 14.63 3.279 19.44C245 86.5 211.2 144.6 211.2 207.8c0 109.7 99.71 193 208.3 172.3c9.561-1.805 16.28 9.324 10.11 16.95C387.9 448.6 324.8 480 255.8 480C132.1 480 32 379.6 32 256z"/></svg>
</span>
</div>
<div class="items-center justify-center hidden dark:flex">
<span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 159.1c-53.02 0-95.1 42.98-95.1 95.1S202.1 351.1 256 351.1s95.1-42.98 95.1-95.1S309 159.1 256 159.1zM509.3 347L446.1 255.1l63.15-91.01c6.332-9.125 1.104-21.74-9.826-23.72l-109-19.7l-19.7-109c-1.975-10.93-14.59-16.16-23.72-9.824L256 65.89L164.1 2.736c-9.125-6.332-21.74-1.107-23.72 9.824L121.6 121.6L12.56 141.3C1.633 143.2-3.596 155.9 2.736 164.1L65.89 256l-63.15 91.01c-6.332 9.125-1.105 21.74 9.824 23.72l109 19.7l19.7 109c1.975 10.93 14.59 16.16 23.72 9.824L256 446.1l91.01 63.15c9.127 6.334 21.75 1.107 23.72-9.822l19.7-109l109-19.7C510.4 368.8 515.6 356.1 509.3 347zM256 383.1c-70.69 0-127.1-57.31-127.1-127.1c0-70.69 57.31-127.1 127.1-127.1s127.1 57.3 127.1 127.1C383.1 326.7 326.7 383.1 256 383.1z"/></svg>
</span>
</div>
</button>
</div>
</nav>
<div class="flex md:hidden items-center gap-x-5 md:ml-12 h-12">
<span></span>
<button
id="search-button-mobile"
aria-label="Search"
class="text-base hover:text-primary-600 dark:hover:text-primary-400"
title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg>
</span>
</button>
<button
id="appearance-switcher-mobile"
aria-label="Dark mode switcher"
type="button"
class="text-base hover:text-primary-600 dark:hover:text-primary-400 me-1">
<div class="flex items-center justify-center dark:hidden">
<span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M32 256c0-123.8 100.3-224 223.8-224c11.36 0 29.7 1.668 40.9 3.746c9.616 1.777 11.75 14.63 3.279 19.44C245 86.5 211.2 144.6 211.2 207.8c0 109.7 99.71 193 208.3 172.3c9.561-1.805 16.28 9.324 10.11 16.95C387.9 448.6 324.8 480 255.8 480C132.1 480 32 379.6 32 256z"/></svg>
</span>
</div>
<div class="items-center justify-center hidden dark:flex">
<span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 159.1c-53.02 0-95.1 42.98-95.1 95.1S202.1 351.1 256 351.1s95.1-42.98 95.1-95.1S309 159.1 256 159.1zM509.3 347L446.1 255.1l63.15-91.01c6.332-9.125 1.104-21.74-9.826-23.72l-109-19.7l-19.7-109c-1.975-10.93-14.59-16.16-23.72-9.824L256 65.89L164.1 2.736c-9.125-6.332-21.74-1.107-23.72 9.824L121.6 121.6L12.56 141.3C1.633 143.2-3.596 155.9 2.736 164.1L65.89 256l-63.15 91.01c-6.332 9.125-1.105 21.74 9.824 23.72l109 19.7l19.7 109c1.975 10.93 14.59 16.16 23.72 9.824L256 446.1l91.01 63.15c9.127 6.334 21.75 1.107 23.72-9.822l19.7-109l109-19.7C510.4 368.8 515.6 356.1 509.3 347zM256 383.1c-70.69 0-127.1-57.31-127.1-127.1c0-70.69 57.31-127.1 127.1-127.1s127.1 57.3 127.1 127.1C383.1 326.7 326.7 383.1 256 383.1z"/></svg>
</span>
</div>
</button>
</div>
</div>
<div class="-my-2 md:hidden">
<div id="menu-button" class="block">
</div>
</div>
</div>
<div class="relative flex flex-col grow">
<main id="main-content" class="grow">
<article>
<header id="single_header" class="mt-5 max-w-prose">
<h1 class="mt-0 text-4xl font-extrabold text-neutral-900 dark:text-neutral">
Hire Me!
</h1>
<div class="mt-1 mb-6 text-base text-neutral-500 dark:text-neutral-400 print:hidden">
<div class="flex flex-row flex-wrap items-center">
<time datetime="2025-09-23T00:00:00&#43;00:00">23 September 2025</time><span class="px-2 text-primary-500">&middot;</span><span>41 words</span><span class="px-2 text-primary-500">&middot;</span><span title="Reading time">1 min</span>
</div>
</div>
<div class="flex author">
<img
class="!mt-0 !mb-0 h-24 w-24 rounded-full me-4"
width="96"
height="96"
alt="Tommy Tran"
src="/avatar_hu_222307ea33a3cf7d.png">
<div class="place-self-center">
<div class="text-[0.6rem] uppercase leading-3 text-neutral-500 dark:text-neutral-400">
Author
</div>
<div class="font-semibold leading-6 text-neutral-800 dark:text-neutral-300">
Tommy Tran
</div>
<div class="text-sm text-neutral-700 dark:text-neutral-400">System Administrator and Technical Writer</div>
<div class="text-2xl sm:text-lg">
<div class="flex flex-wrap text-neutral-400 dark:text-neutral-500">
<a
class="px-1 hover:text-primary-700 dark:hover:text-primary-400"
href="https://github.com/TommyTran732"
target="_blank"
aria-label="Github"
title="Github"
rel="me noopener noreferrer"
><span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</span></span></a
>
<a
class="px-1 hover:text-primary-700 dark:hover:text-primary-400"
href="https://matrix.to/#/@tommy:metropolis.nexus"
target="_blank"
aria-label="Matrix"
title="Matrix"
rel="me noopener noreferrer"
><span class="inline-block align-text-bottom"><span class="relative block icon"><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Matrix</title><path fill="currentColor" d="M.632.55v22.9H2.28V24H0V0h2.28v.55zm7.043 7.26v1.157h.033c.309-.443.683-.784 1.117-1.024.433-.245.936-.365 1.5-.365.54 0 1.033.107 1.481.314.448.208.785.582 1.02 1.108.254-.374.6-.706 1.034-.992.434-.287.95-.43 1.546-.43.453 0 .872.056 1.26.167.388.11.716.286.993.53.276.245.489.559.646.951.152.392.23.863.23 1.417v5.728h-2.349V11.52c0-.286-.01-.559-.032-.812a1.755 1.755 0 0 0-.18-.66 1.106 1.106 0 0 0-.438-.448c-.194-.11-.457-.166-.785-.166-.332 0-.6.064-.803.189a1.38 1.38 0 0 0-.48.499 1.946 1.946 0 0 0-.231.696 5.56 5.56 0 0 0-.06.785v4.768h-2.35v-4.8c0-.254-.004-.503-.018-.752a2.074 2.074 0 0 0-.143-.688 1.052 1.052 0 0 0-.415-.503c-.194-.125-.476-.19-.854-.19-.111 0-.259.024-.439.074-.18.051-.36.143-.53.282-.171.138-.319.337-.439.595-.12.259-.18.6-.18 1.02v4.966H5.46V7.81zm15.693 15.64V.55H21.72V0H24v24h-2.28v-.55z"/></svg></span></span></a
>
<a
class="px-1 hover:text-primary-700 dark:hover:text-primary-400"
href="https://t.me/tommytran732"
target="_blank"
aria-label="Telegram"
title="Telegram"
rel="me noopener noreferrer"
><span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M248,8C111.033,8,0,119.033,0,256S111.033,504,248,504,496,392.967,496,256,384.967,8,248,8ZM362.952,176.66c-3.732,39.215-19.881,134.378-28.1,178.3-3.476,18.584-10.322,24.816-16.948,25.425-14.4,1.326-25.338-9.517-39.287-18.661-21.827-14.308-34.158-23.215-55.346-37.177-24.485-16.135-8.612-25,5.342-39.5,3.652-3.793,67.107-61.51,68.335-66.746.153-.655.3-3.1-1.154-4.384s-3.59-.849-5.135-.5q-3.283.746-104.608,69.142-14.845,10.194-26.894,9.934c-8.855-.191-25.888-5.006-38.551-9.123-15.531-5.048-27.875-7.717-26.8-16.291q.84-6.7,18.45-13.7,108.446-47.248,144.628-62.3c68.872-28.647,83.183-33.623,92.511-33.789,2.052-.034,6.639.474,9.61,2.885a10.452,10.452,0,0,1,3.53,6.716A43.765,43.765,0,0,1,362.952,176.66Z"/></svg>
</span></span></a
>
<a
class="px-1 hover:text-primary-700 dark:hover:text-primary-400"
href="https://x.com/TommyTran732"
target="_blank"
aria-label="X-Twitter"
title="X-Twitter"
rel="me noopener noreferrer"
><span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"/></svg></span></span></a
>
<a
class="px-1 hover:text-primary-700 dark:hover:text-primary-400"
href="https://www.linkedin.com/in/tommytran732"
target="_blank"
aria-label="Linkedin"
title="Linkedin"
rel="me noopener noreferrer"
><span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"/></svg>
</span></span></a
>
<a
class="px-1 hover:text-primary-700 dark:hover:text-primary-400"
href="mailto:contact@tommytran.io"
target="_blank"
aria-label="Email"
title="Email"
rel="me noopener noreferrer"
><span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M207.8 20.73c-93.45 18.32-168.7 93.66-187 187.1c-27.64 140.9 68.65 266.2 199.1 285.1c19.01 2.888 36.17-12.26 36.17-31.49l.0001-.6631c0-15.74-11.44-28.88-26.84-31.24c-84.35-12.98-149.2-86.13-149.2-174.2c0-102.9 88.61-185.5 193.4-175.4c91.54 8.869 158.6 91.25 158.6 183.2l0 16.16c0 22.09-17.94 40.05-40 40.05s-40.01-17.96-40.01-40.05v-120.1c0-8.847-7.161-16.02-16.01-16.02l-31.98 .0036c-7.299 0-13.2 4.992-15.12 11.68c-24.85-12.15-54.24-16.38-86.06-5.106c-38.75 13.73-68.12 48.91-73.72 89.64c-9.483 69.01 43.81 128 110.9 128c26.44 0 50.43-9.544 69.59-24.88c24 31.3 65.23 48.69 109.4 37.49C465.2 369.3 496 324.1 495.1 277.2V256.3C495.1 107.1 361.2-9.332 207.8 20.73zM239.1 304.3c-26.47 0-48-21.56-48-48.05s21.53-48.05 48-48.05s48 21.56 48 48.05S266.5 304.3 239.1 304.3z"/></svg>
</span></span></a
>
<a
class="px-1 hover:text-primary-700 dark:hover:text-primary-400"
href="/tommy.asc"
target="_blank"
aria-label="Pgpkey"
title="Pgpkey"
rel="me noopener noreferrer"
><span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M336 352c97.2 0 176-78.8 176-176S433.2 0 336 0S160 78.8 160 176c0 18.7 2.9 36.8 8.3 53.7L7 391c-4.5 4.5-7 10.6-7 17v80c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V448h40c13.3 0 24-10.7 24-24V384h40c6.4 0 12.5-2.5 17-7l33.3-33.3c16.9 5.4 35 8.3 53.7 8.3zm40-176c-22.1 0-40-17.9-40-40s17.9-40 40-40s40 17.9 40 40s-17.9 40-40 40z"/></svg></span></span></a
>
</div>
</div>
</div>
</div>
<div class="mb-5"></div>
</header>
<section class="flex flex-col max-w-full mt-0 prose dark:prose-invert lg:flex-row">
<div class="min-w-0 min-h-0 max-w-fit">
<div class="article-content max-w-prose mb-20">
<p>an example to get you started</p>
<h1 class="relative group">This is a heading
<div id="this-is-a-heading" class="anchor"></div>
<span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
<a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#this-is-a-heading" aria-label="Anchor">#</a>
</span>
</h1>
<h2 class="relative group">This is a subheading
<div id="this-is-a-subheading" class="anchor"></div>
<span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
<a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#this-is-a-subheading" aria-label="Anchor">#</a>
</span>
</h2>
<h3 class="relative group">This is a subsubheading
<div id="this-is-a-subsubheading" class="anchor"></div>
<span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
<a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#this-is-a-subsubheading" aria-label="Anchor">#</a>
</span>
</h3>
<h4 class="relative group">This is a subsubsubheading
<div id="this-is-a-subsubsubheading" class="anchor"></div>
<span
class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
<a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#this-is-a-subsubsubheading" aria-label="Anchor">#</a>
</span>
</h4>
<p>This is a paragraph with <strong>bold</strong> and <em>italic</em> text.
Check more at <a
href="https://blowfish.page/"
target="_blank"
>Blowfish documentation</a>
undefined</p>
</div>
</div>
<script
type="text/javascript"
src="/js/page.min.54b6f4371722649edbe871e431d8670d670878c22be8f36e229fe53cc9b786fe25a834def5e6de621f7a3e37b72bc8cd73839aa5ed907ed6cbd45cd3e1b0fa20.js"
integrity="sha512-VLb0NxciZJ7b6HHkMdhnDWcIeMIr6PNuIp/lPMm3hv4lqDTe9ebeYh96Pje3K8jNc4Oape2QftbL1FzT4bD6IA=="
data-oid="views_posts/1758620989805-Hire-Me!/index.md"
data-oid-likes="likes_posts/1758620989805-Hire-Me!/index.md"></script>
</section>
<footer class="pt-8 max-w-prose print:hidden">
</footer>
</article>
<div id="top-scroller" class="pointer-events-none absolute top-[110vh] bottom-0 w-12 ltr:right-0 rtl:left-0 z-10">
<a
href="#the-top"
class="pointer-events-auto sticky top-[calc(100vh-5.5rem)] flex h-12 w-12 mb-16 items-center justify-center rounded-full bg-neutral/50 text-xl text-neutral-700 hover:text-primary-600 dark:bg-neutral-800/50 dark:text-neutral dark:hover:text-primary-400"
aria-label="Scroll to top"
title="Scroll to top">
&uarr;
</a>
</div>
</main><footer id="site-footer" class="py-10 print:hidden">
<div class="flex items-center justify-between">
<p class="text-sm text-neutral-500 dark:text-neutral-400">
&copy;
2025
Tommy Tran
</p>
<p class="text-xs text-neutral-500 dark:text-neutral-400">
Powered by <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500"
href="https://gohugo.io/" target="_blank" rel="noopener noreferrer">Hugo</a> &amp; <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500"
href="https://blowfish.page/" target="_blank" rel="noopener noreferrer">Blowfish</a>
</p>
</div>
<script>
mediumZoom(document.querySelectorAll("img:not(.nozoom)"), {
margin: 24,
background: "rgba(0,0,0,0.5)",
scrollOffset: 0,
});
</script>
<script
type="text/javascript"
src="/js/process.min.ee03488f19c93c2efb199e2e3014ea5f3cb2ce7d45154adb3399a158cac27ca52831db249ede5bb602700ef87eb02434139de0858af1818ab0fb4182472204a4.js"
integrity="sha512-7gNIjxnJPC77GZ4uMBTqXzyyzn1FFUrbM5mhWMrCfKUoMdsknt5btgJwDvh&#43;sCQ0E53ghYrxgYqw&#43;0GCRyIEpA=="></script>
</footer>
<div
id="search-wrapper"
class="invisible fixed inset-0 flex h-screen w-screen cursor-default flex-col bg-neutral-500/50 p-4 backdrop-blur-sm dark:bg-neutral-900/50 sm:p-6 md:p-[10vh] lg:p-[12vh] z-500"
data-url="//localhost:1313/">
<div
id="search-modal"
class="flex flex-col w-full max-w-3xl min-h-0 mx-auto border rounded-md shadow-lg top-20 border-neutral-200 bg-neutral dark:border-neutral-700 dark:bg-neutral-800">
<header class="relative z-10 flex items-center justify-between flex-none px-2">
<form class="flex items-center flex-auto min-w-0">
<div class="flex items-center justify-center w-8 h-8 text-neutral-400">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg>
</span>
</div>
<input
type="search"
id="search-query"
class="flex flex-auto h-12 mx-1 bg-transparent appearance-none focus:outline-dotted focus:outline-2 focus:outline-transparent"
placeholder="Search"
tabindex="0">
</form>
<button
id="close-search-button"
class="flex items-center justify-center w-8 h-8 text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400"
title="Close (Esc)">
<span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/></svg>
</span>
</button>
</header>
<section class="flex-auto px-2 overflow-auto">
<ul id="search-results">
</ul>
</section>
</div>
</div>
</div>
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Some files were not shown because too many files have changed in this diff Show More