chore: new license and therefore git history

This commit is contained in:
Muhammad Nauman Raza 2024-01-28 20:03:50 +00:00
commit 11e4e6188f
152 changed files with 6457 additions and 0 deletions

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "themes/serene"]
path = themes/serene
url = https://github.com/isunjn/serene.git
branch = latest

22
LICENSE.md Normal file
View file

@ -0,0 +1,22 @@
The zlib/libpng License
=======================
Copyright (c) 2023-2024 Muhammad Nauman Raza
This software is provided 'as-is', without any express or implied warranty. In
no event will the authors be held liable for any damages arising from the use of
this software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to
the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim
that you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

87
config.toml Normal file
View file

@ -0,0 +1,87 @@
# serene v2.1.2
#
# - docs: https://github.com/isunjn/serene/blob/latest/USAGE.md
# - check for updates: https://github.com/isunjn/serene/releases
#
#=========================================================================================
base_url = "https://devraza.duckdns.org" # Domain name of your website
title = "Devraza"
description = "Someone who does programming, cybersecurity and some other stuff"
default_language = "en"
theme = "serene"
output_dir = "public"
compile_sass = true
minify_html = true
build_search_index = false # Keep this false, search is temporarily unsupported
generate_feed = false # Whether to generate a feed file in root, read docs for more info about rss feed
feed_filename = "feed.xml" # The file name of feed, "feed.xml" / "atom.xml" / "rss.xml", read docs for more info
taxonomies = [{ name = "tags" }, { name = "categories" }]
[markdown]
highlight_code = true
highlight_theme = "boron"
extra_syntaxes_and_themes = ["highlight_themes"]
highlight_themes_css = [
{ theme = "serene-light", filename = "hl-light.css"},
{ theme = "serene-dark", filename = "hl-dark.css"},
]
render_emoji = true
external_links_target_blank = false
external_links_no_follow = true
external_links_no_referrer = true
smart_punctuation = false
[slugify]
paths = "on"
taxonomies = "on"
anchors = "on"
#=========================================================================================
[extra]
name = "Muhammad Nauman Raza"
id = "devraza"
bio = "Programming and cybersecurity"
avatar = "img/avatar.webp" # Your avatar
links = [ # Your links
{ name = "GitHub", icon = "github", url = "https://github.com/devraza" },
{ name = "Email", icon = "email", url = "mailto:devraza@outlook.com" },
]
homepage_layout = "about" # "about" | "list"
sections = [
{ name = "blog", path = "/blog", is_external = false },
{ name = "projects", path = "/projects", is_external = false },
]
blog_section_path = "/blog"
nav_separator = "::"
nav_wrapper_left = "{"
nav_wrapper_right = "} ;"
nav_wrapper_separator = ","
display_id = true # Whether to display your id on homepage
blog_categorized = true # Whether to categorize blog posts
blur_effect = true # Whether to turn on blur effect on navigation bar
back_to_top = true # Whether to show back-to-top button on post pages
toc = true # Whether to show Table-Of-Contents by default
copy = true # Whether to add a copy button on code blocks by default
comment = false # Whether to show giscus comment section by default, see https://giscus.app for more info
display_tags = true # Whether to display tags on post pages by default
truncate_summary = false # Whether to truncate the summary of a post by default
outdate_alert = false # Whether to show outdate alert by default
outdate_alert_days = 120 # How many days will a post be outdated by default
outdate_alert_text_before = "This article was last updated "
outdate_alert_text_after = " days ago and may be out of date."
footer_copyright = "© 2024 Muhammad Nauman Raza"
footer_credits = true # Whether to show "powered by zola and serene" in footer
not_found_title = "404"
not_found_error_text = "Not Found"
not_found_recover_text = "« back to home »"

20
content/_index.md Normal file
View file

@ -0,0 +1,20 @@
+++
template = 'home.html'
[extra]
lang = 'en'
+++
I'm a moderately skilled programmer, beginner in the field of cybersecurity and aspiring graphic designer.
[NixOS](https://nixos.org) is my operating system of choice, and [quark.nvim](https://git.devraza.duckdns.org/devraza/quark.nvim) (my bespoke distribution of [neovim](https://neovim.io)) is my text editor.
I also happen to be a devoted rustacean and a devout follower of the self-hosted way of life.
My skills in programming and scripting languages I've used so far are as follows:
- Advanced: `Python`, `Go`
- Intermediate: `Rust`, `Nix`, `Bash`, `E-Lisp`
- Beginner: `Julia`, `Lua`
However, I consider myself able to work to a reasonable degree with any modern programming language.
Other *tools* that I can work with include `git`, `linux`, `inkscape`, and `GIMP`.

12
content/blog/_index.md Normal file
View file

@ -0,0 +1,12 @@
+++
title = "Blog Posts"
description = "All of the posts for my blog"
sort_by = "date"
template = "blog.html"
page_template = "post.html"
insert_anchor_links = "right"
generate_feed = true
[extra]
lang = 'en'
+++

View file

@ -0,0 +1,41 @@
+++
title = "An overview on hoaxes"
date = 2024-01-04
draft = false
[taxonomies]
categories = ["Cybersecurity"]
tags = ["hoax", "social engineering"]
[extra]
lang = "en"
toc = true
comment = true
copy = true
math = false
mermaid = false
+++
# Introduction
In recent times, hoaxes have become increasingly prevalent as the internet continues to expand and as more people use social media.
Misinformation is on a rise - though this is information which isn't really new, the current state of things is horrible, and things really shouldn't be the way they are.
I aim for this to be a brief blog post detailing the effect of hoaxes on society, focusing on why they're so harmful.
# What exactly is a hoax?
Put simply, a hoax is made-up information, be it a story or something else. Hoaxes are created with the intent of spreading false information - for a immense variety of reasons, from jokes and causing embarrassment to provoking politic or social change<sup>[1](https://en.wikipedia.org/wiki/Hoax)</sup>. I won't discuss the causes of hoaxes further in this blog post.
# The effect of hoaxes
Hoaxes can cause significant damage to their targets if formulated cleverly. For example:
> The stock price of Apple Inc. fell significantly in October 2008 after a hoax story was submitted to CNN's user-generated news site iReport.com claiming that company CEO Steve Jobs had suffered a major heart attack. The source of the story was traced back to 4chan.
> - Excerpt from [the Wikipedia 4chan page](https://en.wikipedia.org/wiki/4chan)
With the incredible presence of social media in our lives, spreading harmful misinformation like that above can be as simple as making a few posts - they don't even need to be very convincing!
What makes matters worse is how gullible the general population is, even those educated in this sort of thing - this shows *just* how much influence the internet and it's contents have on us.
I would like to clarify that I'm not suggesting that people should avoid using the internet to gather information - while its reliability is incredibly questionable, the accessibility and openness it provides far beats traditional methods of gathering information (books and such). My suggestion is that people should be much more careful with how they interpret information on the internet,
and perform their due diligence in their research into whatever they're aiming to learn; **people should make sure that what they're reading is accurate before absorbing any information** (here's your tl;dr).
That's about it for this blog post, as it was meant to be a brief way of expressing my thoughts on the matter. Thanks for reading!

View file

@ -0,0 +1,69 @@
+++
title = "Misconceptions about NFC"
date = 2024-01-19
draft = false
[taxonomies]
categories = ["Cybersecurity"]
tags = ["nfc", "social engineering", "hacking"]
[extra]
lang = "en"
toc = true
comment = true
copy = true
math = false
mermaid = false
+++
{% alert(header="Alert") %}
I made a mistake while writing this blog post - somehow forgetting that security isn't unambiguous. You can actually skim NFC chips from a certain distance
(having a limited distance is still an important factor though!), and though I think some of what I said below still applies you're better off ignoring it all.
There are, of course, a whole range of problems with skimming NFC chips from a distance so my point - don't be so worried - would still stand.
Either way, I recommend you take this with a grain of salt.
{% end %}
# Introduction
NFC (short for Near-Field Communication) is the set of communication protocols which allow for *near-field communication* between two electronic devices.
One of the most prominent uses of this technology are contactless transactions - this includes services like Google and Apple Pay as well as all of your contactless-enabled cards.
It's been a while since my last blog past, but this one will be brief too - I'm writing here for the sake of clearing up some misconceptions people have about NFC.
# The Misconceptions
## Inspiration
While talking with a friend on a WhatsApp group chat a few days ago about a program I found on my jailbroken iOS device - [Aemulo](https://github.com/Aemulo) - I was
informed of 'subway skimmers'; devices that could *supposedly* read data from contactless-enabled devices (via NFC) and would be able to emulate them.
The idea behind the above example was that someone with malicious intent could place such a device in a public location and take their contactless devices for their malicious purposes.
When I heard of this, my first thought was: [hoax](https://devraza.duckdns.org/blog/hoaxes-overview/), and I think that it was rightfully so.
## What exactly is wrong with this?
Several things. I'm no expert in cybersecurity - everyone's a student in some way, but I was sure that NFC was, as it's name implies, for **near-field communication**.
I'm repeating myself here, but that's kind of the point. Various reliable resources, including Wikipedia, show that NFC has a maximum range of only a few centimetres - which makes sense, no?
And yet, whatever source my friend had for 'subway skimmers' gave the impression, or otherwise stated, that it would work within a radius of a few feet, which is just impossible.
Upon voicing my doubts, I was then told that 'with a powerful enough antenna, it's possible'. Hoaxes sure are convincing, aren't they? Unfortunately, I am not able to find the source of my friend's misinformation.
See, NFC only works within a few centimetres anyways. Even if it could *magically* work within a radius of a few feet, you've got to take in the electromagnetic interference
that the clothes and wallets people have would bring to any malicious device. The point of electromagnetic interference is especially true over a *huge* area of a few feet (relatively), where you've got several NFC-enabled devices.
## Where it's actually an issue
Of course, that isn't to say there aren't any issues with NFC and malicious readers - I'm just saying that the word getting around is horribly unrealistic.
For example, a *realistic* example of a malicious NFC reader would be one placed on the card slots in cash machines - you get:
- [X] The short range (< ~20 cm)
- [X] Only one device
- [X] Lots of devices to read!
And so, you've got someone so much more realistic that poses an actual threat!
# Conclusion
The information above, which I deem accurate, is there. What I suggest be taken away from this is pretty much the same as what is was for [my blog post on hoaxes](https://devraza.duckdns.org/blog/hoaxes-overview/) - **do some fact-checking!**

View file

@ -0,0 +1,109 @@
+++
title = "Host your own private search engine with SearXNG"
date = 2023-12-31
draft = false
[taxonomies]
categories = ["Guides"]
tags = ["searxng", "privacy", "selfhosted", "nixos"]
[extra]
lang = "en"
toc = true
comment = true
copy = true
math = false
mermaid = false
+++
# Introduction
[SearXNG](https://docs.searxng.org/), put in its own words, is a 'free internet metasearch engine'.
Note that it describes itself as a *metasearch* engine specifically - unlike your traditional search engine like Google or Bing, SearXNG does things a little bit differently:
It aggregrates the results produced by search services like those aforementioned, and feeds them back to you.
Because of this key detail and a great deal of effort by those who've helped shape it, SearXNG protects your privacy, and does so very well:
- Private data from requests going to the search services it aggregrates results from is removed
- It does **not** forward *anything* to any third parties through search services
- Private data is *also* removed from requests going to the results pages
Furthermore, SearXNG can be configured to use [Tor](https://torproject.org).
However, the aspect of privacy isn't the only great selling feature of the engine; from my use of the engine so far, it's also great at...searching (is that a surprise?). The fact that it's a metasearch engine plays a key role in this,
as it provides SearXNG the ability to pull content more efficiently and gives *you* the ability to further tailor your experience.
# Setting up SearXNG
## Installing the service
As you may have expected if you've used NixOS for a while, searxng is packaged *and* has a service on NixOS. This makes setting it up just that much easier.
To get started, place somewhere in your *system* config the following:
```nix
{
# ...
services.searx = {
enable = true;
settings = {
server = {
port = 8888;
bind_address = "127.0.0.1";
secret_key = "@SEARX_SECRET_KEY@";
base_url = "https://search.devraza.duckdns.org/"; # replace with wherever you want to host yours
};
};
};
# ...
}
```
The snippet above starts the `searx` systemd service for listening on port `8888`, and assumes a `base_url` of `https://search.devraza.duckdns.org`.
Now that we've got the actual `searx` instance running, we can now set up a reverse proxy allowing the service to be accessed remotely (whether this is within your local network or across the internet is up to you).
## Setting up a reverse proxy
### What is a reverse proxy?
Before I get started with the technical details of setting this up, I'd like to briefly clarify what a reverse proxy exactly is (to my understanding).
Let's get the wikipedia definition of reverse proxy out of the way first:
> [...] a reverse proxy is an application that sits in front of back-end applications and forwards client requests to those applications. [...]
However, you might be confused as to what this actually means; I'll give an example of the usage of reverse proxies to better explain this:
- Suppose you've got a few services running on a server (for demonstration purposes, let's name these `x`, `y` and `z`), each running on their own unique port.
- Assuming you had a domain, and wanted to access all of these services from their own unique sub-domains (e.g. `x.yourdomain.com`, `y.yourdomain.com` and `z.yourdomain.com`), you would have to use a reverse proxy.
- This reverse proxy would take in requests from clients going to sub-domains, and forward these requests to the appropriate port on your machine for the service being requested.
The concept should be clear now, if it wasn't already.
### Using NGINX to set up the reverse proxy
NGINX is a popular web server that supports the creation of virtual hosts and the usage of reverse proxies. To accomodate our `searx` instance, we append the following to our NixOS server configuration:
```nix,hl_lines=12,linenos
{
# ...
services.nginx = {
enable = true;
# any extra configuration here
virtualHosts = {
"search" = { # this can be anything, being an arbitrary identifier
forceSSL = true;
serverName = "search.yourdomain.com"; # replace this with whatever you're serving from
# SearX proxy
locations."/" = {
proxyPass = "http://${toString config.services.searx.settings.server.bind_address}:${toString config.services.searx.settings.server.port}";
proxyWebsockets = true;
recommendedProxySettings = true;
};
};
};
};
# ...
}
```
{% note(header="Note") %}
The expression highlighted above is used to dynamically adjust the location NGINX will forward requests to, depending on your `searx` config
{% end %}
After saving your changes and rebuilding your server's system configuration (as usual), you should have a working *private* instance of SearXNG that you can access using the `serverName` you've given it.
Set your browser to use this as your search engine using the relevant documentation (with Firefox this is as easy as right-clicking on the URL after opening up the page and clicking a button). Enjoy!

View file

@ -0,0 +1,98 @@
+++
title = "Take control of tailscale with headscale"
date = 2024-01-10
draft = false
[taxonomies]
categories = ["Guides"]
tags = ["tailscale", "headscale", "selfhosted", "privacy"]
[extra]
lang = "en"
toc = true
comment = true
copy = true
math = false
mermaid = false
+++
# Tailscale
[Tailscale](https://tailscale.com/) is a modern tunnel VPN service based on [WireGuard®](https://www.wireguard.com/) which provides a 'free' and secure means of communication between
devices within a [tailnet](https://tailscale.com/kb/1136/tailnet) - a private network which Tailscale provides its users.
Essentially, it provides a private and secure way of accessing any of your devices, no matter where you are in the world - a personal WAN encompassing the entire world.
And on top of this, Tailscale is completely free and open-source! At least, on the surface...
## Not FOSS? What do you mean?
There's a quite popular saying within the free and open-source software community, which goes along the lines of:
> If you aren't paying for the product, then you are the product.
Which makes perfect sense. It's the *modern* era so anything significant is powered by some form of *modern* technology, data is the new oil, and so on.
In exchange for offering you 'free' services, companies collect and use your data;
while there supposedly are laws in place preventing the inconcensual collection of data in most countries around the world, *your* personal data may *still* be traded unethically and inconsensually.
I personally am of the opinion that these laws are worth absolutely nothing if people aren't educated in how their data is being used, and what specifically is being collected.
But I digress, and that's a blog post for another time.
I also think it's quite unfortunate that users of paid services *still* have their personal data collected in the unethical manner outlined above, despite the fact that they are *paying* for the service...
In the context of Tailscale: while their clients are all open-source, their control server - the thing that's managing and rerouting *everything* going through what they advertise as *your* 'secure' VPN, isn't.
You've got no idea what this thing is doing with the traffic it recieves.
# Headscale
For every problem, there's probably a solution somewhere. And luckily for this one (which may or may not actually be a problem for you), we've got [Headscale](https://headscale.net/) as our solution.
Headscale's a self-hostable, open-source alternative to the Tailscale control server, and aims to 'provide self-hosters and hobbyists with an open-source server they can use for their projects and labs'.
## Installing on NixOS
Moving on to installing and setting up Headscale on NixOS.
```nix
# ...
{
# ...
services.headscale = {
enable = true;
address = "0.0.0.0";
port = 7070;
settings = {
logtail.enabled = false;
server_url = "https://headscale.devraza.duckdns.org";
dns_config.base_domain = "devraza.duckdns.org";
};
};
# ...
}
```
This starts up the `headscale` systemd service on our host machine at port `7070`. After that, we make Headscale available over the clearnet with an NGINX reverse proxy, per the usual:
```nix
{
services.nginx = {
enable = true;
virtualHosts = {
"headscale" = {
addSSL = true;
serverName = "headscale.devraza.duckdns.org";
sslCertificate = ./services/nginx/certs/subdomains/fullchain.pem;
sslCertificateKey = ./services/nginx/certs/subdomains/privkey.pem;
# Headscale proxy
locations."/" = {
proxyPass = "http://127.0.0.1:${toString config.services.headscale.port}";
proxyWebsockets = true;
};
};
};
};
}
```
And that's it. A self-hosted, *truly* open-source Wireguard®-based VPN is now at your fingertips. Enjoy! Oh, but please read the conclusion before doing that:
# Conclusion
For those of you who wish to have access to something like Tailscale but value your privacy above all, you would genuinely be greatful for Headscale.
However, I've found that some are fine with what Tailscale *does* provide in regards to FOSS, and are satisfied by the raw convenience and simplicity of a non-selfhosted Tailscale control server - exactly what it hopes to provide, as shown by their self-description on their website: 'a zero-config, no-fuss VPN [provider]'.
Or you could just settle with bare Wireguard®.

View file

@ -0,0 +1,95 @@
+++
title = "Setting up Zola on NixOS"
date = 2023-12-29
draft = false
[taxonomies]
categories = ["Guides"]
tags = ["zola", "nixos"]
[extra]
lang = "en"
toc = true
comment = true
copy = true
math = false
mermaid = false
+++
# Introduction
[Zola](https://getzola.org) is a static site generator (similarly to the infamous [Hugo](https://gohugo.io), which you may have already heard of) and is written in Rust.
It also happens to be the framework that this site is built on!
This blog post is a guide on setting up the site engine on NixOS specifically.
# Installation
## Installing the package
`zola` is packaged in the nix package repository, so you just declaratively add the package to your configuration as usual:
For the purposes of this guide, zola can be installed either as a system or user package.
- As a system package:
```nix
{ pkgs, ... }: {
# ...
environment.systemPackages = with pkgs; [
zola # Append the package name to the list
];
# ...
}
```
- As a user package (with home-manager):
```nix
{ pkgs, ... }: {
# ...
home.packages = with pkgs; [
zola # Append the package name to the list
];
# ...
}
```
Now that `zola` itself is installed, we can move on setting up the pages it serves - continue reading...
## Setting up a theme
Zola actually has a section of its website showcasing several community-made themes which you can choose from to be the theme for your static site [here](https://getzola.org/themes/).
Simply choose a theme that you like (demos are usually available for each theme listed) and follow its appropriate documentation to set it up - this site uses a version of the [serene theme](https://www.getzola.org/themes/serene/) with my custom colours.
{% note(header="Custom themes") %}
You can also make your own theme if that better suits you (I recommend giving the [documentation](https://getzola.org/documentation) a read if so).
{% end %}
## Setting up NGINX
After selecting a theme (or making your own) you should now have a directory somewhere on your server containing your static site.
For the following snippet, we'll assume this is at `/var/lib/blog`.
[NGINX](https://nginx.com) is a popular webserver which we're going to use for the purposes of hosting and serving our site. To do so, append the following somewhere in your configuration:
```nix
# ...
{
# ...
services.nginx = {
enable = true;
virtualHosts = {
"blog" = {
forceSSL = true;
serverName = "blog.devraza.duckdns.org"; # replace this with wherever your site will be
root = "/var/lib/blog/public"; # the path to the `public` folder in our site directory
};
};
};
# ...
}
```
# Finishing up
You should now have your own static site built with Zola! You can use this for a bunch of things, like:
- Your personal blog (as I've done)
- A way to showcase your projects ([as I've also done](https://blog.devraza.duckdns.org/projects))
- Hosting documentation (check out [this Zola theme](https://www.getzola.org/themes/adidoks/), for example)
{% question(header="Help, my changes aren't sticking!") %}
When you make new markdown files (or any other changes to the structure of your site), remember to run `zola build` in your site directory (`/var/lib/blog`) for the changes to *build* into the actual site.
{% end %}

View file

@ -0,0 +1,8 @@
+++
title = "Projects"
description = "All of my (public) projects."
template = "projects.html"
[extra]
lang = 'en'
+++

View file

@ -0,0 +1,39 @@
[[project]]
name = "DianciEmacs"
desc = "A minimal and elegant Emacs configuration framework."
tags = ["emacs", "config", "diancie"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/dianciemacs" },
]
[[project]]
name = "Kagayaki for Emacs"
desc = "A gorgeously soft colorscheme for Emacs."
tags = ["emacs", "colorscheme", "theme", "dark"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/kagayaki-emacs" },
]
[[project]]
name = "Ambition"
desc = "A textual fast-paced 2D MMORPG written in Rust."
tags = ["rust", "bevy", "mmorpg"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/ambition" },
]
[[project]]
name = "quark.nvim"
desc = "A fast and minimal Neovim configuration framework. `[Deprecated]`"
tags = ["neovim"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/quark.nvim" },
]
[[project]]
name = "particle.nvim"
desc = "A gorgeously soft colorscheme for Neovim. `[Deprecated]`"
tags = ["neovim", "colorscheme"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/particle.nvim" },
]

View file

@ -0,0 +1,287 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Generated by: TmTheme-Editor -->
<!-- ============================================ -->
<!-- app: http://tmtheme-editor.herokuapp.com -->
<!-- code: https://github.com/aziz/tmTheme-Editor -->
<plist version="1.0">
<dict>
<key>comment</key>
<string>http:&#x2f;&#x2f;chriskempson.com</string>
<key>name</key>
<string>Tomorrow Night</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>caret</key>
<string>#AEAFAD</string>
<key>foreground</key>
<string>#fefefa</string>
<key>invisibles</key>
<string>#4B4E55</string>
<key>lineHighlight</key>
<string>#282A2E</string>
<key>selection</key>
<string>#373B41</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comment</string>
<key>scope</key>
<string>comment, string.quoted.double.block.python</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#999999</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Foreground</string>
<key>scope</key>
<string>keyword.operator.class, constant.other, source.php.embedded.line</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#CED1CF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variable, String Link, Regular Expression, Tag Name</string>
<key>scope</key>
<string>variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#A67878</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>
<key>scope</key>
<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#E08355</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Class, Support</string>
<key>scope</key>
<string>type,
entity.name.class, entity.name.type.class, support.type, support.class</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#6A8F8A</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>String, Symbols, Inherited Class, Markup Heading</string>
<key>scope</key>
<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#85AD74</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Operator, Misc</string>
<key>scope</key>
<string>keyword.operator, constant.other.color</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#6A8F8A</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function, Special Method, Block Level</string>
<key>scope</key>
<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#81A2BE</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keyword, Storage</string>
<key>scope</key>
<string>keyword, storage, storage.type, entity.name.tag.css</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#B294BB</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Invalid</string>
<key>scope</key>
<string>invalid</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#DF5F5F</string>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#CED2CF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Separator</string>
<key>scope</key>
<string>meta.separator</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#82A3BF</string>
<key>foreground</key>
<string>#CED2CF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Deprecated</string>
<key>scope</key>
<string>invalid.deprecated</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#B798BF</string>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#CED2CF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff foreground</string>
<key>scope</key>
<string>markup.inserted.diff, markup.deleted.diff, meta.diff.header.to-file, meta.diff.header.from-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff insertion</string>
<key>scope</key>
<string>markup.inserted.diff, meta.diff.header.to-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5FE375</string>
<key>background</key>
<string>#00000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff deletion</string>
<key>scope</key>
<string>markup.deleted.diff, meta.diff.header.from-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#D46565</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff header</string>
<key>scope</key>
<string>meta.diff.header.from-file, meta.diff.header.to-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#FFFFFF</string>
<key>background</key>
<string>#4271ae</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff range</string>
<key>scope</key>
<string>meta.diff.range</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>italic</string>
<key>foreground</key>
<string>#3e999f</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>diff.deleted</string>
<key>scope</key>
<string>markup.deleted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#F92672</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>diff.inserted</string>
<key>scope</key>
<string>markup.inserted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#A6E22E</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>diff.changed</string>
<key>scope</key>
<string>markup.changed</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#967EFB</string>
</dict>
</dict>
</array>
<key>uuid</key>
<string>F96223EB-1A60-4617-92F3-D24D4F13DB09</string>
<key>colorSpaceName</key>
<string>sRGB</string>
<key>semanticClass</key>
<string>theme.dark.tomorrow_night</string>
</dict>
</plist>

View file

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Generated by: TmTheme-Editor -->
<!-- ============================================ -->
<!-- app: http://tmtheme-editor.herokuapp.com -->
<!-- code: https://github.com/aziz/tmTheme-Editor -->
<plist version="1.0">
<dict>
<key>comment</key>
<string>http:&#x2f;&#x2f;chriskempson.com</string>
<key>name</key>
<string>Tomorrow</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>caret</key>
<string>#AEAFAD</string>
<key>foreground</key>
<string>#4D4D4C</string>
<key>invisibles</key>
<string>#D1D1D1</string>
<key>lineHighlight</key>
<string>#EFEFEF</string>
<key>selection</key>
<string>#D6D6D6</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comment</string>
<key>scope</key>
<string>comment, string.quoted.double.block.python</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#999999</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Foreground</string>
<key>scope</key>
<string>keyword.operator.class, constant.other, source.php.embedded.line</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#666969</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variable, String Link, Regular Expression, Tag Name</string>
<key>scope</key>
<string>variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#A67878</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>
<key>scope</key>
<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#E08355</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Type, Class, Support</string>
<key>scope</key>
<string>type,
entity.name.class, entity.name.type.class, support.type, support.class</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#568A8F</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>String, Symbols, Inherited Class, Markup Heading</string>
<key>scope</key>
<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#85AD74</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Operator, Misc</string>
<key>scope</key>
<string>keyword.operator, constant.other.color</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#568A8F</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function, Special Method, Block Level</string>
<key>scope</key>
<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#4271AE</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keyword, Storage</string>
<key>scope</key>
<string>keyword, storage, storage.type</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#8959A8</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Invalid</string>
<key>scope</key>
<string>invalid</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#DF5F5F</string>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Separator</string>
<key>scope</key>
<string>meta.separator</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#4271AE</string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Deprecated</string>
<key>scope</key>
<string>invalid.deprecated</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#8959A8</string>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff foreground</string>
<key>scope</key>
<string>markup.inserted.diff, markup.deleted.diff, meta.diff.header.to-file, meta.diff.header.from-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff insertion</string>
<key>scope</key>
<string>markup.inserted.diff, meta.diff.header.to-file</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#65C23A66</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff deletion</string>
<key>scope</key>
<string>markup.deleted.diff, meta.diff.header.from-file</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#C8282966</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff header</string>
<key>scope</key>
<string>meta.diff.header.from-file, meta.diff.header.to-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#FFFFFF</string>
<key>background</key>
<string>#4271ae</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff range</string>
<key>scope</key>
<string>meta.diff.range</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>italic</string>
<key>foreground</key>
<string>#3e999f</string>
</dict>
</dict>
</array>
<key>uuid</key>
<string>82CCD69C-F1B1-4529-B39E-780F91F07604</string>
<key>colorSpaceName</key>
<string>sRGB</string>
<key>semanticClass</key>
<string>theme.light.tomorrow</string>
</dict>
</plist>

1
public/404.html Normal file
View file

@ -0,0 +1 @@
<!doctype html><html lang=en><head><meta charset=utf-8><meta content="width=device-width,initial-scale=1.0" name=viewport><meta content="light dark" name=color-scheme><title>404</title><link href=/img/favicon-32x32.png rel=icon sizes=32x32 type=image/png><link href=/img/favicon-16x16.png rel=icon sizes=16x16 type=image/png><link href=/img/apple-touch-icon.png rel=apple-touch-icon sizes=180x180><link href=https://fonts.googleapis.com rel=preconnect><link crossorigin href=https://fonts.gstatic.com rel=preconnect><link href="https://fonts.googleapis.com/css2?family=Signika&display=swap" rel=stylesheet><style>body{--primary-color:#8070c6;--primary-pale-color:#8070c61c;--text-color:#151517;--text-pale-color:#454449;--bg-color:#ece5ea;--highlight-mark-color:#5f75b045;--callout-note-color:#e887bb;--callout-important-color:#a292e8;--callout-warning-color:#d9d564;--callout-alert-color:#f06969;--callout-question-color:#78b9c4;--callout-tip-color:#91d65c;--main-font:'Signika',ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--code-font:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--homepage-max-width:750px;--main-max-width:750px;--avatar-size:70px;--paragraph-font-size:18px;--paragraph-line-height:1.75;--aside-font-size:16px;--img-border-radius:0;--inline-code-border-radius:2px}body.dark{--primary-color:#a292e8;--primary-pale-color:#a292e81c;--text-color:#ece5ea;--text-pale-color:#5c5c61;--bg-color:#151517;--highlight-mark-color:#5f75b045;--callout-note-color:#e887bb;--callout-important-color:#a292e8;--callout-warning-color:#d9d564;--callout-alert-color:#f06969;--callout-question-color:#78b9c4;--callout-tip-color:#91d65c}</style><link href=/main.css rel=stylesheet><body class=not-found><script>if(localStorage.getItem('theme')=='dark'){document.body.classList.add('dark');const a=document.querySelector('link#hl');if(a)a.href='/hl-dark.css'}</script><div class=wrapper><div class=error><div class=code>404</div><div class=spacer></div><div class=text>Not Found</div></div><a href=/>« back to home »</a></div><script src=/js/main.js></script>

350
public/blog/feed.xml Normal file
View file

@ -0,0 +1,350 @@
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<title>Blog Posts</title>
<subtitle>All of the posts for my blog</subtitle>
<link href="https://devraza.duckdns.org/blog/feed.xml" rel="self" type="application/atom+xml"/>
<link href="https://devraza.duckdns.org/blog/"/>
<updated>2024-01-19T00:00:00+00:00</updated>
<id>https://devraza.duckdns.org/blog/feed.xml</id>
<entry xml:lang="en">
<title>Misconceptions about NFC</title>
<published>2024-01-19T00:00:00+00:00</published>
<updated>2024-01-19T00:00:00+00:00</updated>
<link href="https://devraza.duckdns.org/blog/nfc-misconceptions/" type="text/html"/>
<id>https://devraza.duckdns.org/blog/nfc-misconceptions/</id>
<content type="html">&lt;blockquote class=&quot;callout alert&quot;&gt;
&lt;div class=&quot;icon&quot;&gt;
&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; viewBox=&quot;0 0 24 24&quot; width=&quot;20&quot; height=&quot;20&quot;&gt;&lt;path d=&quot;M4.00098 20V14C4.00098 9.58172 7.5827 6 12.001 6C16.4193 6 20.001 9.58172 20.001 14V20H21.001V22H3.00098V20H4.00098ZM6.00098 20H18.001V14C18.001 10.6863 15.3147 8 12.001 8C8.68727 8 6.00098 10.6863 6.00098 14V20ZM11.001 2H13.001V5H11.001V2ZM19.7792 4.80761L21.1934 6.22183L19.0721 8.34315L17.6578 6.92893L19.7792 4.80761ZM2.80859 6.22183L4.22281 4.80761L6.34413 6.92893L4.92991 8.34315L2.80859 6.22183ZM7.00098 14C7.00098 11.2386 9.23956 9 12.001 9V11C10.3441 11 9.00098 12.3431 9.00098 14H7.00098Z&quot; fill=&quot;currentColor&quot;&gt;&lt;&#x2F;path&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;p&gt;&lt;strong&gt;Alert&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I made a mistake while writing this blog post - somehow forgetting that security isn&#x27;t unambiguous. You can actually skim NFC chips from a certain distance
(having a limited distance is still an important factor though!), and though I think some of what I said below still applies you&#x27;re better off ignoring it all.&lt;&#x2F;p&gt;
&lt;p&gt;There are, of course, a whole range of problems with skimming NFC chips from a distance so my point - don&#x27;t be so worried - would still stand.&lt;&#x2F;p&gt;
&lt;p&gt;Either way, I recommend you take this with a grain of salt.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;blockquote&gt;&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;a class=&quot;zola-anchor&quot; href=&quot;#introduction&quot; aria-label=&quot;Anchor link for: introduction&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;NFC (short for Near-Field Communication) is the set of communication protocols which allow for &lt;em&gt;near-field communication&lt;&#x2F;em&gt; between two electronic devices.
One of the most prominent uses of this technology are contactless transactions - this includes services like Google and Apple Pay as well as all of your contactless-enabled cards.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s been a while since my last blog past, but this one will be brief too - I&#x27;m writing here for the sake of clearing up some misconceptions people have about NFC.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-misconceptions&quot;&gt;The Misconceptions&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-misconceptions&quot; aria-label=&quot;Anchor link for: the-misconceptions&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;inspiration&quot;&gt;Inspiration&lt;a class=&quot;zola-anchor&quot; href=&quot;#inspiration&quot; aria-label=&quot;Anchor link for: inspiration&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;While talking with a friend on a WhatsApp group chat a few days ago about a program I found on my jailbroken iOS device - &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Aemulo&quot;&gt;Aemulo&lt;&#x2F;a&gt; - I was
informed of &#x27;subway skimmers&#x27;; devices that could &lt;em&gt;supposedly&lt;&#x2F;em&gt; read data from contactless-enabled devices (via NFC) and would be able to emulate them.&lt;&#x2F;p&gt;
&lt;p&gt;The idea behind the above example was that someone with malicious intent could place such a device in a public location and take their contactless devices for their malicious purposes.
When I heard of this, my first thought was: &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;devraza.duckdns.org&#x2F;blog&#x2F;hoaxes-overview&#x2F;&quot;&gt;hoax&lt;&#x2F;a&gt;, and I think that it was rightfully so.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-exactly-is-wrong-with-this&quot;&gt;What exactly is wrong with this?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-exactly-is-wrong-with-this&quot; aria-label=&quot;Anchor link for: what-exactly-is-wrong-with-this&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Several things. I&#x27;m no expert in cybersecurity - everyone&#x27;s a student in some way, but I was sure that NFC was, as it&#x27;s name implies, for &lt;strong&gt;near-field communication&lt;&#x2F;strong&gt;.
I&#x27;m repeating myself here, but that&#x27;s kind of the point. Various reliable resources, including Wikipedia, show that NFC has a maximum range of only a few centimetres - which makes sense, no?&lt;&#x2F;p&gt;
&lt;p&gt;And yet, whatever source my friend had for &#x27;subway skimmers&#x27; gave the impression, or otherwise stated, that it would work within a radius of a few feet, which is just impossible.
Upon voicing my doubts, I was then told that &#x27;with a powerful enough antenna, it&#x27;s possible&#x27;. Hoaxes sure are convincing, aren&#x27;t they? Unfortunately, I am not able to find the source of my friend&#x27;s misinformation.&lt;&#x2F;p&gt;
&lt;p&gt;See, NFC only works within a few centimetres anyways. Even if it could &lt;em&gt;magically&lt;&#x2F;em&gt; work within a radius of a few feet, you&#x27;ve got to take in the electromagnetic interference
that the clothes and wallets people have would bring to any malicious device. The point of electromagnetic interference is especially true over a &lt;em&gt;huge&lt;&#x2F;em&gt; area of a few feet (relatively), where you&#x27;ve got several NFC-enabled devices.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;where-it-s-actually-an-issue&quot;&gt;Where it&#x27;s actually an issue&lt;a class=&quot;zola-anchor&quot; href=&quot;#where-it-s-actually-an-issue&quot; aria-label=&quot;Anchor link for: where-it-s-actually-an-issue&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Of course, that isn&#x27;t to say there aren&#x27;t any issues with NFC and malicious readers - I&#x27;m just saying that the word getting around is horribly unrealistic.
For example, a &lt;em&gt;realistic&lt;&#x2F;em&gt; example of a malicious NFC reader would be one placed on the card slots in cash machines - you get:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot; checked=&quot;&quot;&#x2F;&gt;
The short range (&amp;lt; ~20 cm)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot; checked=&quot;&quot;&#x2F;&gt;
Only one device&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot; checked=&quot;&quot;&#x2F;&gt;
Lots of devices to read!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And so, you&#x27;ve got someone so much more realistic that poses an actual threat!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;The information above, which I deem accurate, is there. What I suggest be taken away from this is pretty much the same as what is was for &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;devraza.duckdns.org&#x2F;blog&#x2F;hoaxes-overview&#x2F;&quot;&gt;my blog post on hoaxes&lt;&#x2F;a&gt; - &lt;strong&gt;do some fact-checking!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
</content>
</entry>
<entry xml:lang="en">
<title>Take control of tailscale with headscale</title>
<published>2024-01-10T00:00:00+00:00</published>
<updated>2024-01-10T00:00:00+00:00</updated>
<link href="https://devraza.duckdns.org/blog/selfhost-tailscale/" type="text/html"/>
<id>https://devraza.duckdns.org/blog/selfhost-tailscale/</id>
<content type="html">&lt;h1 id=&quot;tailscale&quot;&gt;Tailscale&lt;a class=&quot;zola-anchor&quot; href=&quot;#tailscale&quot; aria-label=&quot;Anchor link for: tailscale&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;tailscale.com&#x2F;&quot;&gt;Tailscale&lt;&#x2F;a&gt; is a modern tunnel VPN service based on &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.wireguard.com&#x2F;&quot;&gt;WireGuard®&lt;&#x2F;a&gt; which provides a &#x27;free&#x27; and secure means of communication between
devices within a &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;tailscale.com&#x2F;kb&#x2F;1136&#x2F;tailnet&quot;&gt;tailnet&lt;&#x2F;a&gt; - a private network which Tailscale provides its users.&lt;&#x2F;p&gt;
&lt;p&gt;Essentially, it provides a private and secure way of accessing any of your devices, no matter where you are in the world - a personal WAN encompassing the entire world.&lt;&#x2F;p&gt;
&lt;p&gt;And on top of this, Tailscale is completely free and open-source! At least, on the surface...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;not-foss-what-do-you-mean&quot;&gt;Not FOSS? What do you mean?&lt;a class=&quot;zola-anchor&quot; href=&quot;#not-foss-what-do-you-mean&quot; aria-label=&quot;Anchor link for: not-foss-what-do-you-mean&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;There&#x27;s a quite popular saying within the free and open-source software community, which goes along the lines of:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you aren&#x27;t paying for the product, then you are the product.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Which makes perfect sense. It&#x27;s the &lt;em&gt;modern&lt;&#x2F;em&gt; era so anything significant is powered by some form of &lt;em&gt;modern&lt;&#x2F;em&gt; technology, data is the new oil, and so on.
In exchange for offering you &#x27;free&#x27; services, companies collect and use your data;
while there supposedly are laws in place preventing the inconcensual collection of data in most countries around the world, &lt;em&gt;your&lt;&#x2F;em&gt; personal data may &lt;em&gt;still&lt;&#x2F;em&gt; be traded unethically and inconsensually.&lt;&#x2F;p&gt;
&lt;p&gt;I personally am of the opinion that these laws are worth absolutely nothing if people aren&#x27;t educated in how their data is being used, and what specifically is being collected.
But I digress, and that&#x27;s a blog post for another time.&lt;&#x2F;p&gt;
&lt;p&gt;I also think it&#x27;s quite unfortunate that users of paid services &lt;em&gt;still&lt;&#x2F;em&gt; have their personal data collected in the unethical manner outlined above, despite the fact that they are &lt;em&gt;paying&lt;&#x2F;em&gt; for the service...&lt;&#x2F;p&gt;
&lt;p&gt;In the context of Tailscale: while their clients are all open-source, their control server - the thing that&#x27;s managing and rerouting &lt;em&gt;everything&lt;&#x2F;em&gt; going through what they advertise as &lt;em&gt;your&lt;&#x2F;em&gt; &#x27;secure&#x27; VPN, isn&#x27;t.
You&#x27;ve got no idea what this thing is doing with the traffic it recieves.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;headscale&quot;&gt;Headscale&lt;a class=&quot;zola-anchor&quot; href=&quot;#headscale&quot; aria-label=&quot;Anchor link for: headscale&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;For every problem, there&#x27;s probably a solution somewhere. And luckily for this one (which may or may not actually be a problem for you), we&#x27;ve got &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;headscale.net&#x2F;&quot;&gt;Headscale&lt;&#x2F;a&gt; as our solution.
Headscale&#x27;s a self-hostable, open-source alternative to the Tailscale control server, and aims to &#x27;provide self-hosters and hobbyists with an open-source server they can use for their projects and labs&#x27;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-on-nixos&quot;&gt;Installing on NixOS&lt;a class=&quot;zola-anchor&quot; href=&quot;#installing-on-nixos&quot; aria-label=&quot;Anchor link for: installing-on-nixos&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Moving on to installing and setting up Headscale on NixOS.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;headscale &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;enable &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;address &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;0.0.0.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;port &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;7070&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;settings &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;logtail&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;enabled &lt;&#x2F;span&gt;&lt;span&gt;= false;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;server_url &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;headscale.devraza.duckdns.org&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;dns_config&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;base_domain &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;devraza.duckdns.org&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This starts up the &lt;code&gt;headscale&lt;&#x2F;code&gt; systemd service on our host machine at port &lt;code&gt;7070&lt;&#x2F;code&gt;. After that, we make Headscale available over the clearnet with an NGINX reverse proxy, per the usual:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;nginx &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;enable &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;virtualHosts &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;headscale&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;addSSL &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;serverName &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;headscale.devraza.duckdns.org&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;sslCertificate &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&#x2F;services&#x2F;nginx&#x2F;certs&#x2F;subdomains&#x2F;fullchain.pem&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;sslCertificateKey &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&#x2F;services&#x2F;nginx&#x2F;certs&#x2F;subdomains&#x2F;privkey.pem&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# Headscale proxy
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;locations&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;&#x2F;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;proxyPass &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;http:&#x2F;&#x2F;127.0.0.1:${toString &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;headscale&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;port&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;proxyWebsockets &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that&#x27;s it. A self-hosted, &lt;em&gt;truly&lt;&#x2F;em&gt; open-source Wireguard®-based VPN is now at your fingertips. Enjoy! Oh, but please read the conclusion before doing that:&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;For those of you who wish to have access to something like Tailscale but value your privacy above all, you would genuinely be greatful for Headscale.
However, I&#x27;ve found that some are fine with what Tailscale &lt;em&gt;does&lt;&#x2F;em&gt; provide in regards to FOSS, and are satisfied by the raw convenience and simplicity of a non-selfhosted Tailscale control server - exactly what it hopes to provide, as shown by their self-description on their website: &#x27;a zero-config, no-fuss VPN [provider]&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;Or you could just settle with bare Wireguard®.&lt;&#x2F;p&gt;
</content>
</entry>
<entry xml:lang="en">
<title>An overview on hoaxes</title>
<published>2024-01-04T00:00:00+00:00</published>
<updated>2024-01-04T00:00:00+00:00</updated>
<link href="https://devraza.duckdns.org/blog/hoaxes-overview/" type="text/html"/>
<id>https://devraza.duckdns.org/blog/hoaxes-overview/</id>
<content type="html">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;a class=&quot;zola-anchor&quot; href=&quot;#introduction&quot; aria-label=&quot;Anchor link for: introduction&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;In recent times, hoaxes have become increasingly prevalent as the internet continues to expand and as more people use social media.
Misinformation is on a rise - though this is information which isn&#x27;t really new, the current state of things is horrible, and things really shouldn&#x27;t be the way they are.&lt;&#x2F;p&gt;
&lt;p&gt;I aim for this to be a brief blog post detailing the effect of hoaxes on society, focusing on why they&#x27;re so harmful.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-exactly-is-a-hoax&quot;&gt;What exactly is a hoax?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-exactly-is-a-hoax&quot; aria-label=&quot;Anchor link for: what-exactly-is-a-hoax&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Put simply, a hoax is made-up information, be it a story or something else. Hoaxes are created with the intent of spreading false information - for a immense variety of reasons, from jokes and causing embarrassment to provoking politic or social change&lt;sup&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hoax&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. I won&#x27;t discuss the causes of hoaxes further in this blog post.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-effect-of-hoaxes&quot;&gt;The effect of hoaxes&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-effect-of-hoaxes&quot; aria-label=&quot;Anchor link for: the-effect-of-hoaxes&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Hoaxes can cause significant damage to their targets if formulated cleverly. For example:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The stock price of Apple Inc. fell significantly in October 2008 after a hoax story was submitted to CNN&#x27;s user-generated news site iReport.com claiming that company CEO Steve Jobs had suffered a major heart attack. The source of the story was traced back to 4chan.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Excerpt from &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;4chan&quot;&gt;the Wikipedia 4chan page&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;With the incredible presence of social media in our lives, spreading harmful misinformation like that above can be as simple as making a few posts - they don&#x27;t even need to be very convincing!
What makes matters worse is how gullible the general population is, even those educated in this sort of thing - this shows &lt;em&gt;just&lt;&#x2F;em&gt; how much influence the internet and it&#x27;s contents have on us.&lt;&#x2F;p&gt;
&lt;p&gt;I would like to clarify that I&#x27;m not suggesting that people should avoid using the internet to gather information - while its reliability is incredibly questionable, the accessibility and openness it provides far beats traditional methods of gathering information (books and such). My suggestion is that people should be much more careful with how they interpret information on the internet,
and perform their due diligence in their research into whatever they&#x27;re aiming to learn; &lt;strong&gt;people should make sure that what they&#x27;re reading is accurate before absorbing any information&lt;&#x2F;strong&gt; (here&#x27;s your tl;dr).&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s about it for this blog post, as it was meant to be a brief way of expressing my thoughts on the matter. Thanks for reading!&lt;&#x2F;p&gt;
</content>
</entry>
<entry xml:lang="en">
<title>Host your own private search engine with SearXNG</title>
<published>2023-12-31T00:00:00+00:00</published>
<updated>2023-12-31T00:00:00+00:00</updated>
<link href="https://devraza.duckdns.org/blog/selfhost-search-engine/" type="text/html"/>
<id>https://devraza.duckdns.org/blog/selfhost-search-engine/</id>
<content type="html">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;a class=&quot;zola-anchor&quot; href=&quot;#introduction&quot; aria-label=&quot;Anchor link for: introduction&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;docs.searxng.org&#x2F;&quot;&gt;SearXNG&lt;&#x2F;a&gt;, put in its own words, is a &#x27;free internet metasearch engine&#x27;.
Note that it describes itself as a &lt;em&gt;metasearch&lt;&#x2F;em&gt; engine specifically - unlike your traditional search engine like Google or Bing, SearXNG does things a little bit differently:
It aggregrates the results produced by search services like those aforementioned, and feeds them back to you.&lt;&#x2F;p&gt;
&lt;p&gt;Because of this key detail and a great deal of effort by those who&#x27;ve helped shape it, SearXNG protects your privacy, and does so very well:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Private data from requests going to the search services it aggregrates results from is removed&lt;&#x2F;li&gt;
&lt;li&gt;It does &lt;strong&gt;not&lt;&#x2F;strong&gt; forward &lt;em&gt;anything&lt;&#x2F;em&gt; to any third parties through search services&lt;&#x2F;li&gt;
&lt;li&gt;Private data is &lt;em&gt;also&lt;&#x2F;em&gt; removed from requests going to the results pages&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Furthermore, SearXNG can be configured to use &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;torproject.org&quot;&gt;Tor&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;However, the aspect of privacy isn&#x27;t the only great selling feature of the engine; from my use of the engine so far, it&#x27;s also great at...searching (is that a surprise?). The fact that it&#x27;s a metasearch engine plays a key role in this,
as it provides SearXNG the ability to pull content more efficiently and gives &lt;em&gt;you&lt;&#x2F;em&gt; the ability to further tailor your experience.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;setting-up-searxng&quot;&gt;Setting up SearXNG&lt;a class=&quot;zola-anchor&quot; href=&quot;#setting-up-searxng&quot; aria-label=&quot;Anchor link for: setting-up-searxng&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;installing-the-service&quot;&gt;Installing the service&lt;a class=&quot;zola-anchor&quot; href=&quot;#installing-the-service&quot; aria-label=&quot;Anchor link for: installing-the-service&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;As you may have expected if you&#x27;ve used NixOS for a while, searxng is packaged &lt;em&gt;and&lt;&#x2F;em&gt; has a service on NixOS. This makes setting it up just that much easier.&lt;&#x2F;p&gt;
&lt;p&gt;To get started, place somewhere in your &lt;em&gt;system&lt;&#x2F;em&gt; config the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;searx &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;enable &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;settings &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;server &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;port &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cf6a4c;&quot;&gt;8888&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;bind_address &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;127.0.0.1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;secret_key &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;@SEARX_SECRET_KEY@&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;base_url &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;search.devraza.duckdns.org&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# replace with wherever you want to host yours
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The snippet above starts the &lt;code&gt;searx&lt;&#x2F;code&gt; systemd service for listening on port &lt;code&gt;8888&lt;&#x2F;code&gt;, and assumes a &lt;code&gt;base_url&lt;&#x2F;code&gt; of &lt;code&gt;https:&#x2F;&#x2F;search.devraza.duckdns.org&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we&#x27;ve got the actual &lt;code&gt;searx&lt;&#x2F;code&gt; instance running, we can now set up a reverse proxy allowing the service to be accessed remotely (whether this is within your local network or across the internet is up to you).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-a-reverse-proxy&quot;&gt;Setting up a reverse proxy&lt;a class=&quot;zola-anchor&quot; href=&quot;#setting-up-a-reverse-proxy&quot; aria-label=&quot;Anchor link for: setting-up-a-reverse-proxy&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;what-is-a-reverse-proxy&quot;&gt;What is a reverse proxy?&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-is-a-reverse-proxy&quot; aria-label=&quot;Anchor link for: what-is-a-reverse-proxy&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Before I get started with the technical details of setting this up, I&#x27;d like to briefly clarify what a reverse proxy exactly is (to my understanding).&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s get the wikipedia definition of reverse proxy out of the way first:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] a reverse proxy is an application that sits in front of back-end applications and forwards client requests to those applications. [...]&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;However, you might be confused as to what this actually means; I&#x27;ll give an example of the usage of reverse proxies to better explain this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Suppose you&#x27;ve got a few services running on a server (for demonstration purposes, let&#x27;s name these &lt;code&gt;x&lt;&#x2F;code&gt;, &lt;code&gt;y&lt;&#x2F;code&gt; and &lt;code&gt;z&lt;&#x2F;code&gt;), each running on their own unique port.&lt;&#x2F;li&gt;
&lt;li&gt;Assuming you had a domain, and wanted to access all of these services from their own unique sub-domains (e.g. &lt;code&gt;x.yourdomain.com&lt;&#x2F;code&gt;, &lt;code&gt;y.yourdomain.com&lt;&#x2F;code&gt; and &lt;code&gt;z.yourdomain.com&lt;&#x2F;code&gt;), you would have to use a reverse proxy.&lt;&#x2F;li&gt;
&lt;li&gt;This reverse proxy would take in requests from clients going to sub-domains, and forward these requests to the appropriate port on your machine for the service being requested.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The concept should be clear now, if it wasn&#x27;t already.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-nginx-to-set-up-the-reverse-proxy&quot;&gt;Using NGINX to set up the reverse proxy&lt;a class=&quot;zola-anchor&quot; href=&quot;#using-nginx-to-set-up-the-reverse-proxy&quot; aria-label=&quot;Anchor link for: using-nginx-to-set-up-the-reverse-proxy&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;NGINX is a popular web server that supports the creation of virtual hosts and the usage of reverse proxies. To accomodate our &lt;code&gt;searx&lt;&#x2F;code&gt; instance, we append the following to our NixOS server configuration:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;nix&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;nginx &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;enable &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# any extra configuration here
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;virtualHosts &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;search&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;= { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# this can be anything, being an arbitrary identifier
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;forceSSL &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;serverName &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;search.yourdomain.com&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# replace this with whatever you&amp;#39;re serving from
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# SearX proxy
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;locations&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;&#x2F;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;&lt;mark style=&quot;background-color:#010101;&quot;&gt;12&lt;&#x2F;mark&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;mark style=&quot;background-color:#010101;&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;proxyPass &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;http:&#x2F;&#x2F;${toString &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;searx&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;settings&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;server&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;bind_address&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;}:${toString &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;searx&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;settings&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;server&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;port&lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;mark&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;proxyWebsockets &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;recommendedProxySettings &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote class=&quot;callout note&quot;&gt;
&lt;div class=&quot;icon&quot;&gt;
&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; viewBox=&quot;0 0 24 24&quot; width=&quot;20&quot; height=&quot;20&quot;&gt;&lt;path d=&quot;M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 7H13V9H11V7ZM11 11H13V17H11V11Z&quot; fill=&quot;currentColor&quot;&gt;&lt;&#x2F;path&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The expression highlighted above is used to dynamically adjust the location NGINX will forward requests to, depending on your &lt;code&gt;searx&lt;&#x2F;code&gt; config&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;After saving your changes and rebuilding your server&#x27;s system configuration (as usual), you should have a working &lt;em&gt;private&lt;&#x2F;em&gt; instance of SearXNG that you can access using the &lt;code&gt;serverName&lt;&#x2F;code&gt; you&#x27;ve given it.&lt;&#x2F;p&gt;
&lt;p&gt;Set your browser to use this as your search engine using the relevant documentation (with Firefox this is as easy as right-clicking on the URL after opening up the page and clicking a button). Enjoy!&lt;&#x2F;p&gt;
</content>
</entry>
<entry xml:lang="en">
<title>Setting up Zola on NixOS</title>
<published>2023-12-29T00:00:00+00:00</published>
<updated>2023-12-29T00:00:00+00:00</updated>
<link href="https://devraza.duckdns.org/blog/setting-up-zola-nixos/" type="text/html"/>
<id>https://devraza.duckdns.org/blog/setting-up-zola-nixos/</id>
<content type="html">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;a class=&quot;zola-anchor&quot; href=&quot;#introduction&quot; aria-label=&quot;Anchor link for: introduction&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;getzola.org&quot;&gt;Zola&lt;&#x2F;a&gt; is a static site generator (similarly to the infamous &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;gohugo.io&quot;&gt;Hugo&lt;&#x2F;a&gt;, which you may have already heard of) and is written in Rust.
It also happens to be the framework that this site is built on!&lt;&#x2F;p&gt;
&lt;p&gt;This blog post is a guide on setting up the site engine on NixOS specifically.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;a class=&quot;zola-anchor&quot; href=&quot;#installation&quot; aria-label=&quot;Anchor link for: installation&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;installing-the-package&quot;&gt;Installing the package&lt;a class=&quot;zola-anchor&quot; href=&quot;#installing-the-package&quot; aria-label=&quot;Anchor link for: installing-the-package&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;zola&lt;&#x2F;code&gt; is packaged in the nix package repository, so you just declaratively add the package to your configuration as usual:
For the purposes of this guide, zola can be installed either as a system or user package.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;As a system package:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;pkgs&lt;&#x2F;span&gt;&lt;span&gt;, ... }: {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;environment&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;systemPackages &lt;&#x2F;span&gt;&lt;span&gt;= with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;pkgs&lt;&#x2F;span&gt;&lt;span&gt;; [
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;zola &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# Append the package name to the list
&lt;&#x2F;span&gt;&lt;span&gt; ];
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;As a user package (with home-manager):&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;pkgs&lt;&#x2F;span&gt;&lt;span&gt;, ... }: {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;home&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;packages &lt;&#x2F;span&gt;&lt;span&gt;= with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;pkgs&lt;&#x2F;span&gt;&lt;span&gt;; [
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;zola &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# Append the package name to the list
&lt;&#x2F;span&gt;&lt;span&gt; ];
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that &lt;code&gt;zola&lt;&#x2F;code&gt; itself is installed, we can move on setting up the pages it serves - continue reading...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-a-theme&quot;&gt;Setting up a theme&lt;a class=&quot;zola-anchor&quot; href=&quot;#setting-up-a-theme&quot; aria-label=&quot;Anchor link for: setting-up-a-theme&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Zola actually has a section of its website showcasing several community-made themes which you can choose from to be the theme for your static site &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;getzola.org&#x2F;themes&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Simply choose a theme that you like (demos are usually available for each theme listed) and follow its appropriate documentation to set it up - this site uses a version of the &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.getzola.org&#x2F;themes&#x2F;serene&#x2F;&quot;&gt;serene theme&lt;&#x2F;a&gt; with my custom colours.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;callout note&quot;&gt;
&lt;div class=&quot;icon&quot;&gt;
&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; viewBox=&quot;0 0 24 24&quot; width=&quot;20&quot; height=&quot;20&quot;&gt;&lt;path d=&quot;M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 7H13V9H11V7ZM11 11H13V17H11V11Z&quot; fill=&quot;currentColor&quot;&gt;&lt;&#x2F;path&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;p&gt;&lt;strong&gt;Custom themes&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can also make your own theme if that better suits you (I recommend giving the &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;getzola.org&#x2F;documentation&quot;&gt;documentation&lt;&#x2F;a&gt; a read if so).&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;blockquote&gt;&lt;h2 id=&quot;setting-up-nginx&quot;&gt;Setting up NGINX&lt;a class=&quot;zola-anchor&quot; href=&quot;#setting-up-nginx&quot; aria-label=&quot;Anchor link for: setting-up-nginx&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;After selecting a theme (or making your own) you should now have a directory somewhere on your server containing your static site.
For the following snippet, we&#x27;ll assume this is at &lt;code&gt;&#x2F;var&#x2F;lib&#x2F;blog&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;nginx.com&quot;&gt;NGINX&lt;&#x2F;a&gt; is a popular webserver which we&#x27;re going to use for the purposes of hosting and serving our site. To do so, append the following somewhere in your configuration:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#151515;color:#e8e8d3;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;nginx &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;enable &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;virtualHosts &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;blog&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;= {
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;forceSSL &lt;&#x2F;span&gt;&lt;span&gt;= true;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;serverName &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;blog.devraza.duckdns.org&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# replace this with wherever your site will be
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffb964;&quot;&gt;root &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#99ad6a;&quot;&gt;&amp;quot;&#x2F;var&#x2F;lib&#x2F;blog&#x2F;public&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# the path to the `public` folder in our site directory
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; };
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#888888;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;finishing-up&quot;&gt;Finishing up&lt;a class=&quot;zola-anchor&quot; href=&quot;#finishing-up&quot; aria-label=&quot;Anchor link for: finishing-up&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;You should now have your own static site built with Zola! You can use this for a bunch of things, like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Your personal blog (as I&#x27;ve done)&lt;&#x2F;li&gt;
&lt;li&gt;A way to showcase your projects (&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;blog.devraza.duckdns.org&#x2F;projects&quot;&gt;as I&#x27;ve also done&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Hosting documentation (check out &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.getzola.org&#x2F;themes&#x2F;adidoks&#x2F;&quot;&gt;this Zola theme&lt;&#x2F;a&gt;, for example)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote class=&quot;callout question&quot;&gt;
&lt;div class=&quot;icon&quot;&gt;
&lt;svg xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; viewBox=&quot;0 0 24 24&quot; width=&quot;20&quot; height=&quot;20&quot;&gt;&lt;path d=&quot;M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM13 13.3551V14H11V12.5C11 11.9477 11.4477 11.5 12 11.5C12.8284 11.5 13.5 10.8284 13.5 10C13.5 9.17157 12.8284 8.5 12 8.5C11.2723 8.5 10.6656 9.01823 10.5288 9.70577L8.56731 9.31346C8.88637 7.70919 10.302 6.5 12 6.5C13.933 6.5 15.5 8.067 15.5 10C15.5 11.5855 14.4457 12.9248 13 13.3551Z&quot; fill=&quot;currentColor&quot;&gt;&lt;&#x2F;path&gt;&lt;&#x2F;svg&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;p&gt;&lt;strong&gt;Help, my changes aren&amp;#x27;t sticking!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When you make new markdown files (or any other changes to the structure of your site), remember to run &lt;code&gt;zola build&lt;&#x2F;code&gt; in your site directory (&lt;code&gt;&#x2F;var&#x2F;lib&#x2F;blog&lt;&#x2F;code&gt;) for the changes to &lt;em&gt;build&lt;&#x2F;em&gt; into the actual site.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;blockquote&gt;</content>
</entry>
</feed>

File diff suppressed because one or more lines are too long

1
public/blog/index.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

View file

1
public/giscus_dark.css Normal file
View file

@ -0,0 +1 @@
main{--primary-default: 109, 155, 255;--bg-default: 22, 22, 24;--color-prettylights-syntax-comment: #8b949e;--color-prettylights-syntax-constant: #79c0ff;--color-prettylights-syntax-entity: #d2a8ff;--color-prettylights-syntax-storage-modifier-import: #c9d1d9;--color-prettylights-syntax-entity-tag: #7ee787;--color-prettylights-syntax-keyword: #ff7b72;--color-prettylights-syntax-string: #a5d6ff;--color-prettylights-syntax-variable: #ffa657;--color-prettylights-syntax-brackethighlighter-unmatched: #f85149;--color-prettylights-syntax-invalid-illegal-text: #f0f6fc;--color-prettylights-syntax-invalid-illegal-bg: #8e1519;--color-prettylights-syntax-carriage-return-text: #f0f6fc;--color-prettylights-syntax-carriage-return-bg: #b62324;--color-prettylights-syntax-string-regexp: #7ee787;--color-prettylights-syntax-markup-list: #f2cc60;--color-prettylights-syntax-markup-heading: #1f6feb;--color-prettylights-syntax-markup-italic: #c9d1d9;--color-prettylights-syntax-markup-bold: #c9d1d9;--color-prettylights-syntax-markup-deleted-text: #ffdcd7;--color-prettylights-syntax-markup-deleted-bg: #67060c;--color-prettylights-syntax-markup-inserted-text: #aff5b4;--color-prettylights-syntax-markup-inserted-bg: #033a16;--color-prettylights-syntax-markup-changed-text: #ffdfb6;--color-prettylights-syntax-markup-changed-bg: #5a1e02;--color-prettylights-syntax-markup-ignored-text: #c9d1d9;--color-prettylights-syntax-markup-ignored-bg: #1158c7;--color-prettylights-syntax-meta-diff-range: #d2a8ff;--color-prettylights-syntax-brackethighlighter-angle: #8b949e;--color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;--color-prettylights-syntax-constant-other-reference-link: #a5d6ff;--color-btn-text: rgb(235 235 245 / 86%);--color-btn-bg: rgba(var(--bg-default), 1);--color-btn-border: rgba(var(--bg-default), 1);--color-btn-shadow: 0 1px 0 rgba(var(--bg-default), 1);--color-btn-inset-shadow: inset 0 1px 0 rgba(var(--bg-default), 1);--color-btn-hover-bg: rgba(var(--bg-default), 0.5);--color-btn-hover-border: rgba(var(--bg-default), 0.5);--color-btn-active-bg: rgba(var(--primary-default), 0.2);--color-btn-active-border: rgba(var(--primary-default), 1);--color-btn-selected-bg: rgba(var(--primary-default), 0.15);--color-btn-primary-text: rgb(255 255 255 / 100%);--color-btn-primary-bg: rgba(var(--primary-default), 0.45);--color-btn-primary-border: rgba(var(--primary-default), 0.5);--color-btn-primary-shadow: 0 1px 0 rgb(27 31 36 / 10%);--color-btn-primary-inset-shadow: inset 0 1px 0 hsl(0deg 0% 100% / 3%);--color-btn-primary-hover-bg: rgba(var(--primary-default), 0.53);--color-btn-primary-hover-border: rgba(var(--primary-default), 0.75);--color-btn-primary-selected-bg: rgba(var(--primary-default), 0.45);--color-btn-primary-selected-shadow: inset 0 1px 0 rgb(0 45 17 / 20%);--color-btn-primary-disabled-text: rgb(255 255 255 / 80%);--color-btn-primary-disabled-bg: rgba(var(--primary-default), 0.5);--color-btn-primary-disabled-border: rgba(var(--primary-default), 0.5);--color-action-list-item-default-hover-bg: rgb(177 186 196 / 12%);--color-segmented-control-bg: rgb(110 118 129 / 10%);--color-segmented-control-button-bg: #0d1117;--color-segmented-control-button-selected-border: rgba(var(--bg-default), 0.85);--color-fg-default: rgb(235 235 245 / 86%);--color-fg-muted: rgb(235 235 245 / 60%);--color-fg-subtle: rgb(235 235 245 / 50%);--color-canvas-default: rgb(30 30 32 / 100%);--color-canvas-overlay: rgb(30 30 32 / 100%);--color-canvas-inset: rgba(var(--bg-default), 0.85);--color-canvas-subtle: rgba(var(--bg-default), 1);--color-border-default: rgba(var(--bg-default), 0.85);--color-border-muted: rgb(175 184 193 / 20%);--color-neutral-muted: rgb(175 184 193 / 20%);--color-accent-fg: rgba(var(--primary-default), 0.85);--color-accent-emphasis: rgba(var(--primary-default), 0.95);--color-accent-muted: rgba(var(--primary-default), 0.4);--color-accent-subtle: rgba(var(--primary-default), 0.1);--color-success-fg: #3fb950;--color-attention-fg: #d29922;--color-attention-muted: rgb(187 128 9 / 40%);--color-attention-subtle: rgb(187 128 9 / 15%);--color-danger-fg: #f85149;--color-danger-muted: rgb(248 81 73 / 40%);--color-danger-subtle: rgb(248 81 73 / 10%);--color-primer-shadow-inset: 0 1px 0 rgba(var(--bg-default), 1), inset 0 1px 0 rgba(var(--bg-default), 1);--color-scale-gray-7: rgb(22 22 24 / 100%);--color-scale-blue-8: rgb(16 185 129 / 15%);/*! Extensions from @primer/css/alerts/flash.scss */--color-social-reaction-bg-hover: var(--color-scale-gray-7);--color-social-reaction-bg-reacted-hover: var(--color-scale-blue-8)}main .pagination-loader-container{background-image:url("https://github.com/images/modules/pulls/progressive-disclosure-line-dark.svg")}main .gsc-loading-image{background-image:url("https://github.githubassets.com/images/mona-loading-dark.gif")}.gsc-comment-box-buttons a{border-radius:.25rem !important}

1
public/giscus_light.css Normal file
View file

@ -0,0 +1 @@
main{--primary-default: 109, 155, 255;--bg-default: 246, 246, 247;--color-prettylights-syntax-comment: #6e7781;--color-prettylights-syntax-constant: #0550ae;--color-prettylights-syntax-entity: #8250df;--color-prettylights-syntax-storage-modifier-import: #24292f;--color-prettylights-syntax-entity-tag: #116329;--color-prettylights-syntax-keyword: #cf222e;--color-prettylights-syntax-string: #0a3069;--color-prettylights-syntax-variable: #953800;--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;--color-prettylights-syntax-invalid-illegal-bg: #82071e;--color-prettylights-syntax-carriage-return-text: #f6f8fa;--color-prettylights-syntax-carriage-return-bg: #cf222e;--color-prettylights-syntax-string-regexp: #116329;--color-prettylights-syntax-markup-list: #3b2300;--color-prettylights-syntax-markup-heading: #0550ae;--color-prettylights-syntax-markup-italic: #24292f;--color-prettylights-syntax-markup-bold: #24292f;--color-prettylights-syntax-markup-deleted-text: #82071e;--color-prettylights-syntax-markup-deleted-bg: #ffebe9;--color-prettylights-syntax-markup-inserted-text: #116329;--color-prettylights-syntax-markup-inserted-bg: #dafbe1;--color-prettylights-syntax-markup-changed-text: #953800;--color-prettylights-syntax-markup-changed-bg: #ffd8b5;--color-prettylights-syntax-markup-ignored-text: #eaeef2;--color-prettylights-syntax-markup-ignored-bg: #0550ae;--color-prettylights-syntax-meta-diff-range: #8250df;--color-prettylights-syntax-brackethighlighter-angle: #57606a;--color-prettylights-syntax-sublimelinter-gutter-mark: #8c959f;--color-prettylights-syntax-constant-other-reference-link: #0a3069;--color-btn-text: #24292f;--color-btn-bg: rgba(var(--bg-default), 1);--color-btn-border: rgba(var(--bg-default), 1);--color-btn-shadow: 0 1px 0 rgba(var(--bg-default), 1);--color-btn-inset-shadow: inset 0 1px 0 rgba(var(--bg-default), 1);--color-btn-hover-bg: rgba(var(--bg-default), 0.5);--color-btn-hover-border: rgba(var(--bg-default), 0.5);--color-btn-active-bg: rgba(var(--primary-default), 0.2);--color-btn-active-border: rgba(var(--primary-default), 1);--color-btn-selected-bg: rgba(var(--primary-default), 0.15);--color-btn-primary-text: rgb(255 255 255 / 100%);--color-btn-primary-bg: rgba(var(--primary-default), 1);--color-btn-primary-border: rgba(var(--primary-default), 1);--color-btn-primary-shadow: 0 1px 0 rgb(31 35 40 / 10%);--color-btn-primary-inset-shadow: inset 0 1px 0 rgb(255 255 255 / 3%);--color-btn-primary-hover-bg: rgba(var(--primary-default), 0.9);--color-btn-primary-hover-border: rgba(var(--primary-default), 0.75);--color-btn-primary-selected-bg: rgba(var(--primary-default), 1);--color-btn-primary-selected-shadow: inset 0 1px 0 rgb(0 45 17 / 20%);--color-btn-primary-disabled-text: rgb(255 255 255 / 80%);--color-btn-primary-disabled-bg: rgba(var(--primary-default), 0.5);--color-btn-primary-disabled-border: rgba(var(--primary-default), 0.5);--color-action-list-item-default-hover-bg: rgb(208 215 222 / 32%);--color-segmented-control-bg: #eaeef2;--color-segmented-control-button-bg: #fff;--color-segmented-control-button-selected-border: rgba(var(--bg-default), 0.85);--color-fg-default: rgb(60 60 67);--color-fg-muted: rgb(60 60 67 / 75%);--color-fg-subtle: rgb(60 60 67 / 33%);--color-canvas-default: rgb(255 255 255);--color-canvas-overlay: rgb(255 255 255);--color-canvas-inset: rgba(var(--bg-default), 0.85);--color-canvas-subtle: rgba(var(--bg-default), 1);--color-border-default: rgba(var(--bg-default), 0.85);--color-border-muted: rgb(175 184 193 / 20%);--color-neutral-muted: rgb(175 184 193 / 20%);--color-accent-fg: rgba(var(--primary-default), 0.85);--color-accent-emphasis: rgba(var(--primary-default), 0.95);--color-accent-muted: rgba(var(--primary-default), 0.4);--color-accent-subtle: rgba(var(--primary-default), 0.1);--color-success-fg: #1a7f37;--color-attention-fg: #9a6700;--color-attention-muted: rgb(212 167 44 / 40%);--color-attention-subtle: #fff8c5;--color-danger-fg: #d1242f;--color-danger-muted: rgb(255 129 130 / 40%);--color-danger-subtle: #ffebe9;--color-primer-shadow-inset: 0 1px 0 rgba(var(--bg-default), 1), inset 0 1px 0 rgba(var(--bg-default), 1);--color-scale-gray-1: rgb(234 238 242 / 100%);--color-scale-blue-1: rgb(16 185 129 / 15%);/*! Extensions from @primer/css/alerts/flash.scss */--color-social-reaction-bg-hover: var(--color-scale-gray-1);--color-social-reaction-bg-reacted-hover: var(--color-scale-blue-1)}main .pagination-loader-container{background-image:url("https://github.com/images/modules/pulls/progressive-disclosure-line.svg")}main .gsc-loading-image{background-image:url("https://github.githubassets.com/images/mona-loading-default.gif")}.gsc-comment:not(.gsc-reply-box) .gsc-replies{border-radius:unset}.gsc-comment-box-buttons a{border-radius:.25rem !important}

74
public/hl-dark.css Normal file
View file

@ -0,0 +1,74 @@
/*
* theme "Tomorrow Night" generated by syntect
*/
.z-code {
color: #c5c8c6;
}
.z-comment, .z-string.z-quoted.z-double.z-block.z-python {
color: #999999;
}
.z-keyword.z-operator.z-class, .z-constant.z-other, .z-source.z-php.z-embedded.z-line {
color: #ced1cf;
}
.z-variable, .z-support.z-other.z-variable, .z-string.z-other.z-link, .z-string.z-regexp, .z-entity.z-name.z-tag, .z-entity.z-other.z-attribute-name, .z-meta.z-tag, .z-declaration.z-tag {
color: #a67878;
}
.z-constant.z-numeric, .z-constant.z-language, .z-support.z-constant, .z-constant.z-character, .z-variable.z-parameter, .z-punctuation.z-section.z-embedded, .z-keyword.z-other.z-unit {
color: #e08355;
}
.z-type, .z-entity.z-name.z-class, .z-entity.z-name.z-type.z-class, .z-support.z-type, .z-support.z-class {
color: #6a8f8a;
}
.z-string, .z-constant.z-other.z-symbol, .z-entity.z-other.z-inherited-class, .z-markup.z-heading {
color: #85ad74;
}
.z-keyword.z-operator, .z-constant.z-other.z-color {
color: #6a8f8a;
}
.z-entity.z-name.z-function, .z-meta.z-function-call, .z-support.z-function, .z-keyword.z-other.z-special-method, .z-meta.z-block-level {
color: #81a2be;
}
.z-keyword, .z-storage, .z-storage.z-type, .z-entity.z-name.z-tag.z-css {
color: #b294bb;
}
.z-invalid {
color: #ced2cf;
background-color: #df5f5f;
}
.z-meta.z-separator {
color: #ced2cf;
background-color: #82a3bf;
}
.z-invalid.z-deprecated {
color: #ced2cf;
background-color: #b798bf;
}
.z-markup.z-inserted.z-diff, .z-markup.z-deleted.z-diff, .z-meta.z-diff.z-header.z-to-file, .z-meta.z-diff.z-header.z-from-file {
color: #ffffff;
}
.z-markup.z-inserted.z-diff, .z-meta.z-diff.z-header.z-to-file {
color: #5fe375;
background-color: #000000;
}
.z-markup.z-deleted.z-diff, .z-meta.z-diff.z-header.z-from-file {
color: #d46565;
}
.z-meta.z-diff.z-header.z-from-file, .z-meta.z-diff.z-header.z-to-file {
color: #ffffff;
background-color: #4271ae;
}
.z-meta.z-diff.z-range {
color: #3e999f;
font-style: italic;
}
.z-markup.z-deleted {
color: #f92672;
}
.z-markup.z-inserted {
color: #a6e22e;
}
.z-markup.z-changed {
color: #967efb;
}

64
public/hl-light.css Normal file
View file

@ -0,0 +1,64 @@
/*
* theme "Tomorrow" generated by syntect
*/
.z-code {
color: #4d4d4c;
}
.z-comment, .z-string.z-quoted.z-double.z-block.z-python {
color: #999999;
}
.z-keyword.z-operator.z-class, .z-constant.z-other, .z-source.z-php.z-embedded.z-line {
color: #666969;
}
.z-variable, .z-support.z-other.z-variable, .z-string.z-other.z-link, .z-string.z-regexp, .z-entity.z-name.z-tag, .z-entity.z-other.z-attribute-name, .z-meta.z-tag, .z-declaration.z-tag {
color: #a67878;
}
.z-constant.z-numeric, .z-constant.z-language, .z-support.z-constant, .z-constant.z-character, .z-variable.z-parameter, .z-punctuation.z-section.z-embedded, .z-keyword.z-other.z-unit {
color: #e08355;
}
.z-type, .z-entity.z-name.z-class, .z-entity.z-name.z-type.z-class, .z-support.z-type, .z-support.z-class {
color: #568a8f;
}
.z-string, .z-constant.z-other.z-symbol, .z-entity.z-other.z-inherited-class, .z-markup.z-heading {
color: #85ad74;
}
.z-keyword.z-operator, .z-constant.z-other.z-color {
color: #568a8f;
}
.z-entity.z-name.z-function, .z-meta.z-function-call, .z-support.z-function, .z-keyword.z-other.z-special-method, .z-meta.z-block-level {
color: #4271ae;
}
.z-keyword, .z-storage, .z-storage.z-type {
color: #8959a8;
}
.z-invalid {
color: #ffffff;
background-color: #df5f5f;
}
.z-meta.z-separator {
color: #ffffff;
background-color: #4271ae;
}
.z-invalid.z-deprecated {
color: #ffffff;
background-color: #8959a8;
}
.z-markup.z-inserted.z-diff, .z-markup.z-deleted.z-diff, .z-meta.z-diff.z-header.z-to-file, .z-meta.z-diff.z-header.z-from-file {
color: #ffffff;
}
.z-markup.z-inserted.z-diff, .z-meta.z-diff.z-header.z-to-file {
background-color: #65c23a;
}
.z-markup.z-deleted.z-diff, .z-meta.z-diff.z-header.z-from-file {
background-color: #c82829;
}
.z-meta.z-diff.z-header.z-from-file, .z-meta.z-diff.z-header.z-to-file {
color: #ffffff;
background-color: #4271ae;
}
.z-meta.z-diff.z-range {
color: #3e999f;
font-style: italic;
}

1
public/icon/alert.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M4.00098 20V14C4.00098 9.58172 7.5827 6 12.001 6C16.4193 6 20.001 9.58172 20.001 14V20H21.001V22H3.00098V20H4.00098ZM6.00098 20H18.001V14C18.001 10.6863 15.3147 8 12.001 8C8.68727 8 6.00098 10.6863 6.00098 14V20ZM11.001 2H13.001V5H11.001V2ZM19.7792 4.80761L21.1934 6.22183L19.0721 8.34315L17.6578 6.92893L19.7792 4.80761ZM2.80859 6.22183L4.22281 4.80761L6.34413 6.92893L4.92991 8.34315L2.80859 6.22183ZM7.00098 14C7.00098 11.2386 9.23956 9 12.001 9V11C10.3441 11 9.00098 12.3431 9.00098 14H7.00098Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 625 B

1
public/icon/arrow-up.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M11.9997 10.8284L7.04996 15.7782L5.63574 14.364L11.9997 8L18.3637 14.364L16.9495 15.7782L11.9997 10.8284Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 232 B

1
public/icon/backlink.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M9.41421 8L18.0208 16.6066L16.6066 18.0208L8 9.41421V17H6V6H17V8H9.41421Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 200 B

1
public/icon/check.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M10.0007 15.1709L19.1931 5.97852L20.6073 7.39273L10.0007 17.9993L3.63672 11.6354L5.05093 10.2212L10.0007 15.1709Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 240 B

1
public/icon/copy.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M6.9998 6V3C6.9998 2.44772 7.44752 2 7.9998 2H19.9998C20.5521 2 20.9998 2.44772 20.9998 3V17C20.9998 17.5523 20.5521 18 19.9998 18H16.9998V20.9991C16.9998 21.5519 16.5499 22 15.993 22H4.00666C3.45059 22 3 21.5554 3 20.9991L3.0026 7.00087C3.0027 6.44811 3.45264 6 4.00942 6H6.9998ZM5.00242 8L5.00019 20H14.9998V8H5.00242ZM8.9998 6H16.9998V16H18.9998V4H8.9998V6Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 487 B

1
public/icon/email.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3ZM20 7.23792L12.0718 14.338L4 7.21594V19H20V7.23792ZM4.51146 5L12.0619 11.662L19.501 5H4.51146Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 340 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M17.0003 13V14C17.0003 16.7696 16.3364 19.445 15.0853 21.8455L14.8585 22.2663L13.1116 21.2924C14.2716 19.2115 14.9211 16.8817 14.9935 14.4559L15.0003 14V13H17.0003ZM11.0003 10H13.0003V14L12.9948 14.3787C12.9153 17.1495 11.9645 19.7731 10.3038 21.928L10.073 22.2189L8.52406 20.9536C10.0408 19.0969 10.9145 16.8017 10.9943 14.3663L11.0003 14V10ZM12.0003 6C14.7617 6 17.0003 8.23858 17.0003 11H15.0003C15.0003 9.34315 13.6571 8 12.0003 8C10.3434 8 9.00025 9.34315 9.00025 11V14C9.00025 16.2354 8.1806 18.3444 6.72928 19.9768L6.51767 20.2067L5.06955 18.8273C6.23328 17.6056 6.92099 16.0118 6.99381 14.3027L7.00025 14V11C7.00025 8.23858 9.23883 6 12.0003 6ZM12.0003 2C16.9708 2 21.0003 6.02944 21.0003 11V14C21.0003 15.6979 20.7985 17.3699 20.4035 18.9903L20.2647 19.5285L18.3349 19.0032C18.726 17.5662 18.9475 16.0808 18.9919 14.5684L19.0003 14V11C19.0003 7.13401 15.8662 4 12.0003 4C10.4279 4 8.97663 4.51841 7.80805 5.39364L6.38308 3.96769C7.92267 2.73631 9.87547 2 12.0003 2ZM4.96794 5.38282L6.39389 6.8078C5.5635 7.91652 5.0543 9.27971 5.00431 10.7593L4.99961 10.999L5.00378 13C5.00378 14.1195 4.73991 15.2026 4.24263 16.1772L4.08648 16.4663L2.34961 15.4747C2.72889 14.8103 2.95077 14.0681 2.99539 13.2924L3.00378 13L3.00361 11C3.00025 8.87522 3.73656 6.92242 4.96794 5.38282Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

1
public/icon/github.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M5.88401 18.6531C5.58404 18.4523 5.32587 18.1972 5.0239 17.8366C4.91473 17.7062 4.47283 17.1521 4.55811 17.258C4.09533 16.6831 3.80296 16.4168 3.50156 16.3087C2.9817 16.1223 2.7114 15.5497 2.89784 15.0298C3.08428 14.51 3.65685 14.2397 4.17672 14.4261C4.92936 14.696 5.43847 15.1609 6.12425 16.0141C6.03025 15.8972 6.46364 16.4408 6.55731 16.5526C6.74784 16.7802 6.88732 16.918 6.99629 16.9909C7.20118 17.128 7.58451 17.1871 8.14709 17.1308C8.17065 16.7487 8.24136 16.378 8.34919 16.0355C5.38097 15.3101 3.70116 13.3949 3.70116 9.63947C3.70116 8.4006 4.0704 7.28368 4.75917 6.34756C4.5415 5.45368 4.57433 4.37259 5.06092 3.15611C5.1725 2.87715 5.40361 2.66314 5.69031 2.57328C5.77242 2.54949 5.81791 2.5389 5.89878 2.52648C6.70167 2.40319 7.83573 2.69681 9.31449 3.62311C10.181 3.41855 11.0885 3.31476 12.0012 3.31476C12.9129 3.31476 13.8196 3.41835 14.6854 3.62253C16.1619 2.68976 17.2986 2.39625 18.1072 2.52627C18.1919 2.53988 18.2645 2.55758 18.3249 2.57741C18.6059 2.66967 18.8316 2.88155 18.9414 3.15611C19.4279 4.37232 19.4608 5.45319 19.2433 6.34695C19.9342 7.28313 20.3012 8.39184 20.3012 9.63947C20.3012 13.3966 18.627 15.3046 15.6588 16.0318C15.7837 16.4467 15.8496 16.9103 15.8496 17.4118C15.8496 18.0763 15.8471 18.7108 15.8424 19.4223C15.8412 19.6124 15.8397 19.8156 15.8375 20.1279C16.2129 20.2107 16.5229 20.5074 16.6031 20.9086C16.7114 21.4502 16.3602 21.977 15.8186 22.0853C14.6794 22.3132 13.8353 21.5535 13.8353 20.5608C13.8353 20.4705 13.836 20.3414 13.8375 20.1142C13.8398 19.8012 13.8412 19.5987 13.8425 19.4092C13.8471 18.7017 13.8496 18.0714 13.8496 17.4118C13.8496 16.7145 13.6664 16.26 13.4237 16.0508C12.7627 15.481 13.0977 14.3971 13.965 14.2996C16.9314 13.9663 18.3012 12.8174 18.3012 9.63947C18.3012 8.68484 17.9893 7.89547 17.3881 7.23534C17.1301 6.95209 17.0567 6.54634 17.199 6.19062C17.3647 5.77639 17.4354 5.2336 17.2941 4.57678L17.2847 4.57944C16.7928 4.71861 16.1744 5.01956 15.4261 5.52826C15.182 5.69413 14.8772 5.74377 14.5932 5.66388C13.7729 5.43319 12.8913 5.31476 12.0012 5.31476C11.111 5.31476 10.2294 5.43319 9.40916 5.66388C9.12662 5.74335 8.82344 5.69468 8.57997 5.53077C7.8274 5.02414 7.2056 4.72355 6.71079 4.58352C6.56735 5.23672 6.63814 5.77758 6.80336 6.19062C6.94565 6.54634 6.87219 6.95209 6.61423 7.23534C6.01715 7.89096 5.70116 8.69352 5.70116 9.63947C5.70116 12.8114 7.07225 13.9681 10.023 14.2996C10.8883 14.3969 11.2246 15.4767 10.5675 16.048C10.3751 16.2153 10.1384 16.7799 10.1384 17.4118V20.5608C10.1384 21.5472 9.30356 22.2866 8.17878 22.0898C7.63476 21.9946 7.27093 21.4764 7.36613 20.9324C7.43827 20.5201 7.75331 20.2114 8.13841 20.1274V19.1379C7.22829 19.1991 6.47656 19.0496 5.88401 18.6531Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 389 B

1
public/icon/moon.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M10 7C10 10.866 13.134 14 17 14C18.9584 14 20.729 13.1957 21.9995 11.8995C22 11.933 22 11.9665 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C12.0335 2 12.067 2 12.1005 2.00049C10.8043 3.27098 10 5.04157 10 7ZM4 12C4 16.4183 7.58172 20 12 20C15.0583 20 17.7158 18.2839 19.062 15.7621C18.3945 15.9187 17.7035 16 17 16C12.0294 16 8 11.9706 8 7C8 6.29648 8.08133 5.60547 8.2379 4.938C5.71611 6.28423 4 8.9417 4 12Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 576 B

1
public/icon/note.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 7H13V9H11V7ZM11 11H13V17H11V11Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 388 B

1
public/icon/question.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM13 13.3551V14H11V12.5C11 11.9477 11.4477 11.5 12 11.5C12.8284 11.5 13.5 10.8284 13.5 10C13.5 9.17157 12.8284 8.5 12 8.5C11.2723 8.5 10.6656 9.01823 10.5288 9.70577L8.56731 9.31346C8.88637 7.70919 10.302 6.5 12 6.5C13.933 6.5 15.5 8.067 15.5 10C15.5 11.5855 14.4457 12.9248 13 13.3551Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 657 B

1
public/icon/rss.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 17C5.20914 17 7 18.7909 7 21H3V17ZM3 10C9.07513 10 14 14.9249 14 21H12C12 16.0294 7.97056 12 3 12V10ZM3 3C12.9411 3 21 11.0589 21 21H19C19 12.1634 11.8366 5 3 5V3Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 293 B

1
public/icon/sun.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 18C8.68629 18 6 15.3137 6 12C6 8.68629 8.68629 6 12 6C15.3137 6 18 8.68629 18 12C18 15.3137 15.3137 18 12 18ZM12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16ZM11 1H13V4H11V1ZM11 20H13V23H11V20ZM3.51472 4.92893L4.92893 3.51472L7.05025 5.63604L5.63604 7.05025L3.51472 4.92893ZM16.9497 18.364L18.364 16.9497L20.4853 19.0711L19.0711 20.4853L16.9497 18.364ZM19.0711 3.51472L20.4853 4.92893L18.364 7.05025L16.9497 5.63604L19.0711 3.51472ZM5.63604 16.9497L7.05025 18.364L4.92893 20.4853L3.51472 19.0711L5.63604 16.9497ZM23 11V13H20V11H23ZM4 11V13H1V11H4Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 742 B

1
public/icon/tip.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M9.97308 18H11V13H13V18H14.0269C14.1589 16.7984 14.7721 15.8065 15.7676 14.7226C15.8797 14.6006 16.5988 13.8564 16.6841 13.7501C17.5318 12.6931 18 11.385 18 10C18 6.68629 15.3137 4 12 4C8.68629 4 6 6.68629 6 10C6 11.3843 6.46774 12.6917 7.31462 13.7484C7.40004 13.855 8.12081 14.6012 8.23154 14.7218C9.22766 15.8064 9.84103 16.7984 9.97308 18ZM10 20V21H14V20H10ZM5.75395 14.9992C4.65645 13.6297 4 11.8915 4 10C4 5.58172 7.58172 2 12 2C16.4183 2 20 5.58172 20 10C20 11.8925 19.3428 13.6315 18.2443 15.0014C17.624 15.7748 16 17 16 18.5V21C16 22.1046 15.1046 23 14 23H10C8.89543 23 8 22.1046 8 21V18.5C8 17 6.37458 15.7736 5.75395 14.9992Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 763 B

1
public/icon/toc.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 4H21V6H3V4ZM3 11H15V13H3V11ZM3 18H21V20H3V18Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 175 B

1
public/icon/twitter.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M15.3499 5.5498C13.7681 5.5498 12.4786 6.81785 12.4504 8.39633L12.4223 9.97138C12.4164 10.3027 12.143 10.5665 11.8117 10.5606C11.7881 10.5602 11.7646 10.5584 11.7413 10.5552L10.1805 10.3423C8.12699 10.0623 6.15883 9.11711 4.27072 7.54387C3.67275 10.8535 4.84 13.147 7.65342 14.9157L9.40041 16.014C9.68095 16.1904 9.7654 16.5608 9.58903 16.8413C9.54861 16.9056 9.49636 16.9616 9.43504 17.0064L7.84338 18.1693C8.78973 18.2288 9.68938 18.1873 10.435 18.0385C15.1526 17.097 18.2897 13.5468 18.2897 7.69084C18.2897 7.21275 17.2774 5.5498 15.3499 5.5498ZM10.4507 8.36066C10.4983 5.69559 12.6735 3.5498 15.3499 3.5498C16.7132 3.5498 17.9465 4.10658 18.8348 5.00515C19.5462 4.9998 20.1514 5.17966 21.5035 4.35943C21.1693 5.9998 21.0034 6.71177 20.2897 7.69084C20.2897 15.3324 15.5926 19.0487 10.8264 19.9998C7.5587 20.6519 2.80646 19.5812 1.44531 18.1584C2.13874 18.1051 4.95928 17.8018 6.58895 16.6089C5.20994 15.6984 -0.278631 12.4679 3.32772 3.78617C5.02119 5.76283 6.73797 7.10831 8.47807 7.82262C9.63548 8.29774 9.91978 8.28825 10.4507 8.36066Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
public/icon/warning.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.4091 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72191 12.7772 2.84815 12.865 3.00017ZM4.20471 19.0002H19.7932L11.9989 5.50017L4.20471 19.0002ZM10.9989 16.0002H12.9989V18.0002H10.9989V16.0002ZM10.9989 9.00017H12.9989V14.0002H10.9989V9.00017Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 621 B

BIN
public/img/avatar.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

1
public/index.html Normal file

File diff suppressed because one or more lines are too long

2
public/js/lightense.min.js vendored Normal file

File diff suppressed because one or more lines are too long

166
public/js/main.js Normal file
View file

@ -0,0 +1,166 @@
function enableThemeToggle() {
const themeToggle = document.querySelector('#theme-toggle');
const hlLink = document.querySelector('link#hl');
const preferDark = window.matchMedia("(prefers-color-scheme: dark)");
function toggleTheme(theme) {
if (theme == "dark") document.body.classList.add('dark'); else document.body.classList.remove('dark');
if (hlLink) hlLink.href = `/hl-${theme}.css`;
themeToggle.innerHTML = theme == "dark" ? themeToggle.dataset.sunIcon : themeToggle.dataset.moonIcon;
localStorage.setItem("theme", theme);
toggleGiscusTheme(theme);
}
function toggleGiscusTheme(theme) {
const iframe = document.querySelector('iframe.giscus-frame');
if (iframe) iframe.contentWindow.postMessage({ giscus: { setConfig: { theme: `${location.origin}/giscus_${theme}.css` } } }, 'https://giscus.app');
}
function initGiscusTheme() {
toggleGiscusTheme(localStorage.getItem("theme") || (preferDark.matches ? "dark" : "light"));
window.removeEventListener('message', initGiscusTheme);
}
window.addEventListener('message', initGiscusTheme);
themeToggle.addEventListener('click', () => toggleTheme(localStorage.getItem("theme") == "dark" ? "light" : "dark"));
preferDark.addEventListener("change", e => toggleTheme(e.matches ? "dark" : "light"));
if (!localStorage.getItem("theme") && preferDark.matches) toggleTheme("dark");
if (localStorage.getItem("theme") == "dark") toggleTheme("dark");
}
function enableNavFold() {
const nav = document.querySelector('header nav');
if (!nav) return;
const toggler = nav.querySelector('#toggler');
if (!toggler) return;
const foldItems = nav.querySelectorAll('.fold');
toggler.addEventListener('click', () => {
if (window.innerWidth < 768 && [...foldItems].every(item => !item.classList.contains('shown'))) return;
foldItems.forEach(item => item.classList.toggle('shown'));
});
}
function enableOutdateAlert() {
const alert = document.querySelector('#outdate_alert');
if (!alert) return;
const publish = document.querySelector('#publish');
const updated = document.querySelector('#updated');
const updateDate = new Date(updated ? updated.textContent : publish.textContent);
const intervalDays = Math.floor((Date.now() - updateDate.getTime()) / (24 * 60 * 60 * 1000));
const alertDays = parseInt(alert.dataset.days);
if (intervalDays >= alertDays) {
const msg = alert.dataset.alertTextBefore + intervalDays + alert.dataset.alertTextAfter;
alert.querySelector('.content').textContent = msg;
alert.classList.remove('hidden');
}
}
function enableTocToggle() {
const tocToggle = document.querySelector('#toc-toggle');
if (!tocToggle) return;
const aside = document.querySelector('aside');
tocToggle.addEventListener('click', () => {
tocToggle.classList.toggle('active');
aside.classList.toggle('shown');
});
}
function enableTocIndicate() {
const toc = document.querySelector('aside nav');
if (!toc) return;
const headers = document.querySelectorAll('h2, h3');
const tocMap = new Map();
headers.forEach(header => tocMap.set(header, toc.querySelector(`a[href="#${header.id}"]`)));
let actived = null;
const observer = new IntersectionObserver((entries) => entries.forEach(entry => {
if (entry.isIntersecting) {
const target = tocMap.get(entry.target);
if (target == actived) return;
if (actived) actived.classList.remove('active');
target.classList.add('active');
actived = target;
}
}), { rootMargin: '-9% 0px -90% 0px' });
headers.forEach(header => observer.observe(header));
}
function addCopyBtns() {
const cfg = document.querySelector('#copy-cfg');
if (!cfg) return;
const copyIcon = cfg.dataset.copyIcon;
const checkIcon = cfg.dataset.checkIcon;
document.querySelectorAll('pre').forEach(block => {
if (block.classList.contains('mermaid')) return;
const wrapper = document.createElement('div');
wrapper.className = 'codeblock';
const btn = document.createElement('button');
btn.className = 'copy';
btn.ariaLabel = 'copy';
btn.innerHTML = copyIcon;
const copy = () => {
navigator.clipboard.writeText(block.textContent).then(() => {
btn.innerHTML = checkIcon;
btn.classList.add('copied');
btn.removeEventListener('click', copy);
setTimeout(() => {
btn.innerHTML = copyIcon;
btn.classList.remove('copied');
btn.addEventListener('click', copy);
}, 2000);
});
};
btn.addEventListener('click', copy);
wrapper.appendChild(block.cloneNode(true));
wrapper.appendChild(btn);
block.replaceWith(wrapper);
});
}
function addBackToTopBtn() {
const backBtn = document.querySelector('#back-to-top');
if (!backBtn) return;
const toTop = () => window.scrollTo({ top: 0, behavior: 'smooth' });
const toggle = () => {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop > 200 && !backBtn.classList.contains('shown')) {
backBtn.classList.add('shown');
backBtn.addEventListener('click', toTop);
} else if (scrollTop <= 200 && backBtn.classList.contains('shown')) {
backBtn.classList.remove('shown');
backBtn.removeEventListener('click', toTop);
}
};
window.addEventListener('scroll', toggle);
toggle();
}
function addFootnoteBacklink() {
const backlinkIcon = document.querySelector('.prose').dataset.backlinkIcon;
const footnotes = document.querySelectorAll('.footnote-definition');
footnotes.forEach(footnote => {
const backlink = document.createElement('button');
backlink.className = 'backlink';
backlink.ariaLabel = 'backlink';
backlink.innerHTML = backlinkIcon;
backlink.addEventListener('click', () => window.scrollTo({
top: document.querySelector(`.footnote-reference a[href="#${footnote.id}"]`).getBoundingClientRect().top + window.scrollY - 50,
}));
footnote.appendChild(backlink);
});
}
function enableImgLightense() {
window.addEventListener("load", () => Lightense(".prose img", { background: 'rgba(43, 43, 43, 0.19)' }));
}
//--------------------------------------------
enableThemeToggle();
enableNavFold();
if (document.body.classList.contains('post')) {
enableOutdateAlert();
enableTocToggle();
enableTocIndicate();
addBackToTopBtn();
}
if (document.querySelector('.prose')) {
addCopyBtns();
addFootnoteBacklink();
enableImgLightense();
}

1
public/main.css Normal file

File diff suppressed because one or more lines are too long

39
public/projects/data.toml Normal file
View file

@ -0,0 +1,39 @@
[[project]]
name = "DianciEmacs"
desc = "A minimal and elegant Emacs configuration framework."
tags = ["emacs", "config", "diancie"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/dianciemacs" },
]
[[project]]
name = "Kagayaki for Emacs"
desc = "A gorgeously soft colorscheme for Emacs."
tags = ["emacs", "colorscheme", "theme", "dark"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/kagayaki-emacs" },
]
[[project]]
name = "Ambition"
desc = "A textual fast-paced 2D MMORPG written in Rust."
tags = ["rust", "bevy", "mmorpg"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/ambition" },
]
[[project]]
name = "quark.nvim"
desc = "A fast and minimal Neovim configuration framework. `[Deprecated]`"
tags = ["neovim"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/quark.nvim" },
]
[[project]]
name = "particle.nvim"
desc = "A gorgeously soft colorscheme for Neovim. `[Deprecated]`"
tags = ["neovim", "colorscheme"]
links = [
{ name = "git", url = "https://git.devraza.duckdns.org/devraza/particle.nvim" },
]

File diff suppressed because one or more lines are too long

4
public/robots.txt Normal file
View file

@ -0,0 +1,4 @@
User-agent: *
Disallow:
Allow: /
Sitemap: https://devraza.duckdns.org/sitemap.xml

77
public/sitemap.xml Normal file
View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://devraza.duckdns.org/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/blog/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/blog/hoaxes-overview/</loc>
<lastmod>2024-01-04</lastmod>
</url>
<url>
<loc>https://devraza.duckdns.org/blog/nfc-misconceptions/</loc>
<lastmod>2024-01-19</lastmod>
</url>
<url>
<loc>https://devraza.duckdns.org/blog/selfhost-search-engine/</loc>
<lastmod>2023-12-31</lastmod>
</url>
<url>
<loc>https://devraza.duckdns.org/blog/selfhost-tailscale/</loc>
<lastmod>2024-01-10</lastmod>
</url>
<url>
<loc>https://devraza.duckdns.org/blog/setting-up-zola-nixos/</loc>
<lastmod>2023-12-29</lastmod>
</url>
<url>
<loc>https://devraza.duckdns.org/categories/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/categories/cybersecurity/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/categories/guides/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/projects/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/hacking/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/headscale/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/hoax/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/nfc/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/nixos/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/privacy/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/searxng/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/selfhosted/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/social-engineering/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/tailscale/</loc>
</url>
<url>
<loc>https://devraza.duckdns.org/tags/zola/</loc>
</url>
</urlset>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

3
public/tags/index.html Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

74
static/hl-dark.css Normal file
View file

@ -0,0 +1,74 @@
/*
* theme "Tomorrow Night" generated by syntect
*/
.z-code {
color: #c5c8c6;
}
.z-comment, .z-string.z-quoted.z-double.z-block.z-python {
color: #999999;
}
.z-keyword.z-operator.z-class, .z-constant.z-other, .z-source.z-php.z-embedded.z-line {
color: #ced1cf;
}
.z-variable, .z-support.z-other.z-variable, .z-string.z-other.z-link, .z-string.z-regexp, .z-entity.z-name.z-tag, .z-entity.z-other.z-attribute-name, .z-meta.z-tag, .z-declaration.z-tag {
color: #a67878;
}
.z-constant.z-numeric, .z-constant.z-language, .z-support.z-constant, .z-constant.z-character, .z-variable.z-parameter, .z-punctuation.z-section.z-embedded, .z-keyword.z-other.z-unit {
color: #e08355;
}
.z-type, .z-entity.z-name.z-class, .z-entity.z-name.z-type.z-class, .z-support.z-type, .z-support.z-class {
color: #6a8f8a;
}
.z-string, .z-constant.z-other.z-symbol, .z-entity.z-other.z-inherited-class, .z-markup.z-heading {
color: #85ad74;
}
.z-keyword.z-operator, .z-constant.z-other.z-color {
color: #6a8f8a;
}
.z-entity.z-name.z-function, .z-meta.z-function-call, .z-support.z-function, .z-keyword.z-other.z-special-method, .z-meta.z-block-level {
color: #81a2be;
}
.z-keyword, .z-storage, .z-storage.z-type, .z-entity.z-name.z-tag.z-css {
color: #b294bb;
}
.z-invalid {
color: #ced2cf;
background-color: #df5f5f;
}
.z-meta.z-separator {
color: #ced2cf;
background-color: #82a3bf;
}
.z-invalid.z-deprecated {
color: #ced2cf;
background-color: #b798bf;
}
.z-markup.z-inserted.z-diff, .z-markup.z-deleted.z-diff, .z-meta.z-diff.z-header.z-to-file, .z-meta.z-diff.z-header.z-from-file {
color: #ffffff;
}
.z-markup.z-inserted.z-diff, .z-meta.z-diff.z-header.z-to-file {
color: #5fe375;
background-color: #000000;
}
.z-markup.z-deleted.z-diff, .z-meta.z-diff.z-header.z-from-file {
color: #d46565;
}
.z-meta.z-diff.z-header.z-from-file, .z-meta.z-diff.z-header.z-to-file {
color: #ffffff;
background-color: #4271ae;
}
.z-meta.z-diff.z-range {
color: #3e999f;
font-style: italic;
}
.z-markup.z-deleted {
color: #f92672;
}
.z-markup.z-inserted {
color: #a6e22e;
}
.z-markup.z-changed {
color: #967efb;
}

64
static/hl-light.css Normal file
View file

@ -0,0 +1,64 @@
/*
* theme "Tomorrow" generated by syntect
*/
.z-code {
color: #4d4d4c;
}
.z-comment, .z-string.z-quoted.z-double.z-block.z-python {
color: #999999;
}
.z-keyword.z-operator.z-class, .z-constant.z-other, .z-source.z-php.z-embedded.z-line {
color: #666969;
}
.z-variable, .z-support.z-other.z-variable, .z-string.z-other.z-link, .z-string.z-regexp, .z-entity.z-name.z-tag, .z-entity.z-other.z-attribute-name, .z-meta.z-tag, .z-declaration.z-tag {
color: #a67878;
}
.z-constant.z-numeric, .z-constant.z-language, .z-support.z-constant, .z-constant.z-character, .z-variable.z-parameter, .z-punctuation.z-section.z-embedded, .z-keyword.z-other.z-unit {
color: #e08355;
}
.z-type, .z-entity.z-name.z-class, .z-entity.z-name.z-type.z-class, .z-support.z-type, .z-support.z-class {
color: #568a8f;
}
.z-string, .z-constant.z-other.z-symbol, .z-entity.z-other.z-inherited-class, .z-markup.z-heading {
color: #85ad74;
}
.z-keyword.z-operator, .z-constant.z-other.z-color {
color: #568a8f;
}
.z-entity.z-name.z-function, .z-meta.z-function-call, .z-support.z-function, .z-keyword.z-other.z-special-method, .z-meta.z-block-level {
color: #4271ae;
}
.z-keyword, .z-storage, .z-storage.z-type {
color: #8959a8;
}
.z-invalid {
color: #ffffff;
background-color: #df5f5f;
}
.z-meta.z-separator {
color: #ffffff;
background-color: #4271ae;
}
.z-invalid.z-deprecated {
color: #ffffff;
background-color: #8959a8;
}
.z-markup.z-inserted.z-diff, .z-markup.z-deleted.z-diff, .z-meta.z-diff.z-header.z-to-file, .z-meta.z-diff.z-header.z-from-file {
color: #ffffff;
}
.z-markup.z-inserted.z-diff, .z-meta.z-diff.z-header.z-to-file {
background-color: #65c23a;
}
.z-markup.z-deleted.z-diff, .z-meta.z-diff.z-header.z-from-file {
background-color: #c82829;
}
.z-meta.z-diff.z-header.z-from-file, .z-meta.z-diff.z-header.z-to-file {
color: #ffffff;
background-color: #4271ae;
}
.z-meta.z-diff.z-range {
color: #3e999f;
font-style: italic;
}

1
static/icon/alert.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M4.00098 20V14C4.00098 9.58172 7.5827 6 12.001 6C16.4193 6 20.001 9.58172 20.001 14V20H21.001V22H3.00098V20H4.00098ZM6.00098 20H18.001V14C18.001 10.6863 15.3147 8 12.001 8C8.68727 8 6.00098 10.6863 6.00098 14V20ZM11.001 2H13.001V5H11.001V2ZM19.7792 4.80761L21.1934 6.22183L19.0721 8.34315L17.6578 6.92893L19.7792 4.80761ZM2.80859 6.22183L4.22281 4.80761L6.34413 6.92893L4.92991 8.34315L2.80859 6.22183ZM7.00098 14C7.00098 11.2386 9.23956 9 12.001 9V11C10.3441 11 9.00098 12.3431 9.00098 14H7.00098Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 625 B

1
static/icon/arrow-up.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M11.9997 10.8284L7.04996 15.7782L5.63574 14.364L11.9997 8L18.3637 14.364L16.9495 15.7782L11.9997 10.8284Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 232 B

1
static/icon/backlink.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M9.41421 8L18.0208 16.6066L16.6066 18.0208L8 9.41421V17H6V6H17V8H9.41421Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 200 B

1
static/icon/check.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M10.0007 15.1709L19.1931 5.97852L20.6073 7.39273L10.0007 17.9993L3.63672 11.6354L5.05093 10.2212L10.0007 15.1709Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 240 B

1
static/icon/copy.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M6.9998 6V3C6.9998 2.44772 7.44752 2 7.9998 2H19.9998C20.5521 2 20.9998 2.44772 20.9998 3V17C20.9998 17.5523 20.5521 18 19.9998 18H16.9998V20.9991C16.9998 21.5519 16.5499 22 15.993 22H4.00666C3.45059 22 3 21.5554 3 20.9991L3.0026 7.00087C3.0027 6.44811 3.45264 6 4.00942 6H6.9998ZM5.00242 8L5.00019 20H14.9998V8H5.00242ZM8.9998 6H16.9998V16H18.9998V4H8.9998V6Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 487 B

1
static/icon/email.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3ZM20 7.23792L12.0718 14.338L4 7.21594V19H20V7.23792ZM4.51146 5L12.0619 11.662L19.501 5H4.51146Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 340 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M17.0003 13V14C17.0003 16.7696 16.3364 19.445 15.0853 21.8455L14.8585 22.2663L13.1116 21.2924C14.2716 19.2115 14.9211 16.8817 14.9935 14.4559L15.0003 14V13H17.0003ZM11.0003 10H13.0003V14L12.9948 14.3787C12.9153 17.1495 11.9645 19.7731 10.3038 21.928L10.073 22.2189L8.52406 20.9536C10.0408 19.0969 10.9145 16.8017 10.9943 14.3663L11.0003 14V10ZM12.0003 6C14.7617 6 17.0003 8.23858 17.0003 11H15.0003C15.0003 9.34315 13.6571 8 12.0003 8C10.3434 8 9.00025 9.34315 9.00025 11V14C9.00025 16.2354 8.1806 18.3444 6.72928 19.9768L6.51767 20.2067L5.06955 18.8273C6.23328 17.6056 6.92099 16.0118 6.99381 14.3027L7.00025 14V11C7.00025 8.23858 9.23883 6 12.0003 6ZM12.0003 2C16.9708 2 21.0003 6.02944 21.0003 11V14C21.0003 15.6979 20.7985 17.3699 20.4035 18.9903L20.2647 19.5285L18.3349 19.0032C18.726 17.5662 18.9475 16.0808 18.9919 14.5684L19.0003 14V11C19.0003 7.13401 15.8662 4 12.0003 4C10.4279 4 8.97663 4.51841 7.80805 5.39364L6.38308 3.96769C7.92267 2.73631 9.87547 2 12.0003 2ZM4.96794 5.38282L6.39389 6.8078C5.5635 7.91652 5.0543 9.27971 5.00431 10.7593L4.99961 10.999L5.00378 13C5.00378 14.1195 4.73991 15.2026 4.24263 16.1772L4.08648 16.4663L2.34961 15.4747C2.72889 14.8103 2.95077 14.0681 2.99539 13.2924L3.00378 13L3.00361 11C3.00025 8.87522 3.73656 6.92242 4.96794 5.38282Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

1
static/icon/github.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M5.88401 18.6531C5.58404 18.4523 5.32587 18.1972 5.0239 17.8366C4.91473 17.7062 4.47283 17.1521 4.55811 17.258C4.09533 16.6831 3.80296 16.4168 3.50156 16.3087C2.9817 16.1223 2.7114 15.5497 2.89784 15.0298C3.08428 14.51 3.65685 14.2397 4.17672 14.4261C4.92936 14.696 5.43847 15.1609 6.12425 16.0141C6.03025 15.8972 6.46364 16.4408 6.55731 16.5526C6.74784 16.7802 6.88732 16.918 6.99629 16.9909C7.20118 17.128 7.58451 17.1871 8.14709 17.1308C8.17065 16.7487 8.24136 16.378 8.34919 16.0355C5.38097 15.3101 3.70116 13.3949 3.70116 9.63947C3.70116 8.4006 4.0704 7.28368 4.75917 6.34756C4.5415 5.45368 4.57433 4.37259 5.06092 3.15611C5.1725 2.87715 5.40361 2.66314 5.69031 2.57328C5.77242 2.54949 5.81791 2.5389 5.89878 2.52648C6.70167 2.40319 7.83573 2.69681 9.31449 3.62311C10.181 3.41855 11.0885 3.31476 12.0012 3.31476C12.9129 3.31476 13.8196 3.41835 14.6854 3.62253C16.1619 2.68976 17.2986 2.39625 18.1072 2.52627C18.1919 2.53988 18.2645 2.55758 18.3249 2.57741C18.6059 2.66967 18.8316 2.88155 18.9414 3.15611C19.4279 4.37232 19.4608 5.45319 19.2433 6.34695C19.9342 7.28313 20.3012 8.39184 20.3012 9.63947C20.3012 13.3966 18.627 15.3046 15.6588 16.0318C15.7837 16.4467 15.8496 16.9103 15.8496 17.4118C15.8496 18.0763 15.8471 18.7108 15.8424 19.4223C15.8412 19.6124 15.8397 19.8156 15.8375 20.1279C16.2129 20.2107 16.5229 20.5074 16.6031 20.9086C16.7114 21.4502 16.3602 21.977 15.8186 22.0853C14.6794 22.3132 13.8353 21.5535 13.8353 20.5608C13.8353 20.4705 13.836 20.3414 13.8375 20.1142C13.8398 19.8012 13.8412 19.5987 13.8425 19.4092C13.8471 18.7017 13.8496 18.0714 13.8496 17.4118C13.8496 16.7145 13.6664 16.26 13.4237 16.0508C12.7627 15.481 13.0977 14.3971 13.965 14.2996C16.9314 13.9663 18.3012 12.8174 18.3012 9.63947C18.3012 8.68484 17.9893 7.89547 17.3881 7.23534C17.1301 6.95209 17.0567 6.54634 17.199 6.19062C17.3647 5.77639 17.4354 5.2336 17.2941 4.57678L17.2847 4.57944C16.7928 4.71861 16.1744 5.01956 15.4261 5.52826C15.182 5.69413 14.8772 5.74377 14.5932 5.66388C13.7729 5.43319 12.8913 5.31476 12.0012 5.31476C11.111 5.31476 10.2294 5.43319 9.40916 5.66388C9.12662 5.74335 8.82344 5.69468 8.57997 5.53077C7.8274 5.02414 7.2056 4.72355 6.71079 4.58352C6.56735 5.23672 6.63814 5.77758 6.80336 6.19062C6.94565 6.54634 6.87219 6.95209 6.61423 7.23534C6.01715 7.89096 5.70116 8.69352 5.70116 9.63947C5.70116 12.8114 7.07225 13.9681 10.023 14.2996C10.8883 14.3969 11.2246 15.4767 10.5675 16.048C10.3751 16.2153 10.1384 16.7799 10.1384 17.4118V20.5608C10.1384 21.5472 9.30356 22.2866 8.17878 22.0898C7.63476 21.9946 7.27093 21.4764 7.36613 20.9324C7.43827 20.5201 7.75331 20.2114 8.13841 20.1274V19.1379C7.22829 19.1991 6.47656 19.0496 5.88401 18.6531Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 389 B

1
static/icon/moon.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M10 7C10 10.866 13.134 14 17 14C18.9584 14 20.729 13.1957 21.9995 11.8995C22 11.933 22 11.9665 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C12.0335 2 12.067 2 12.1005 2.00049C10.8043 3.27098 10 5.04157 10 7ZM4 12C4 16.4183 7.58172 20 12 20C15.0583 20 17.7158 18.2839 19.062 15.7621C18.3945 15.9187 17.7035 16 17 16C12.0294 16 8 11.9706 8 7C8 6.29648 8.08133 5.60547 8.2379 4.938C5.71611 6.28423 4 8.9417 4 12Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 576 B

1
static/icon/note.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 7H13V9H11V7ZM11 11H13V17H11V11Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 388 B

1
static/icon/question.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM13 13.3551V14H11V12.5C11 11.9477 11.4477 11.5 12 11.5C12.8284 11.5 13.5 10.8284 13.5 10C13.5 9.17157 12.8284 8.5 12 8.5C11.2723 8.5 10.6656 9.01823 10.5288 9.70577L8.56731 9.31346C8.88637 7.70919 10.302 6.5 12 6.5C13.933 6.5 15.5 8.067 15.5 10C15.5 11.5855 14.4457 12.9248 13 13.3551Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 657 B

1
static/icon/rss.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 17C5.20914 17 7 18.7909 7 21H3V17ZM3 10C9.07513 10 14 14.9249 14 21H12C12 16.0294 7.97056 12 3 12V10ZM3 3C12.9411 3 21 11.0589 21 21H19C19 12.1634 11.8366 5 3 5V3Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 293 B

1
static/icon/sun.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 18C8.68629 18 6 15.3137 6 12C6 8.68629 8.68629 6 12 6C15.3137 6 18 8.68629 18 12C18 15.3137 15.3137 18 12 18ZM12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16ZM11 1H13V4H11V1ZM11 20H13V23H11V20ZM3.51472 4.92893L4.92893 3.51472L7.05025 5.63604L5.63604 7.05025L3.51472 4.92893ZM16.9497 18.364L18.364 16.9497L20.4853 19.0711L19.0711 20.4853L16.9497 18.364ZM19.0711 3.51472L20.4853 4.92893L18.364 7.05025L16.9497 5.63604L19.0711 3.51472ZM5.63604 16.9497L7.05025 18.364L4.92893 20.4853L3.51472 19.0711L5.63604 16.9497ZM23 11V13H20V11H23ZM4 11V13H1V11H4Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 742 B

1
static/icon/tip.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M9.97308 18H11V13H13V18H14.0269C14.1589 16.7984 14.7721 15.8065 15.7676 14.7226C15.8797 14.6006 16.5988 13.8564 16.6841 13.7501C17.5318 12.6931 18 11.385 18 10C18 6.68629 15.3137 4 12 4C8.68629 4 6 6.68629 6 10C6 11.3843 6.46774 12.6917 7.31462 13.7484C7.40004 13.855 8.12081 14.6012 8.23154 14.7218C9.22766 15.8064 9.84103 16.7984 9.97308 18ZM10 20V21H14V20H10ZM5.75395 14.9992C4.65645 13.6297 4 11.8915 4 10C4 5.58172 7.58172 2 12 2C16.4183 2 20 5.58172 20 10C20 11.8925 19.3428 13.6315 18.2443 15.0014C17.624 15.7748 16 17 16 18.5V21C16 22.1046 15.1046 23 14 23H10C8.89543 23 8 22.1046 8 21V18.5C8 17 6.37458 15.7736 5.75395 14.9992Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 763 B

1
static/icon/toc.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 4H21V6H3V4ZM3 11H15V13H3V11ZM3 18H21V20H3V18Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 175 B

1
static/icon/twitter.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M15.3499 5.5498C13.7681 5.5498 12.4786 6.81785 12.4504 8.39633L12.4223 9.97138C12.4164 10.3027 12.143 10.5665 11.8117 10.5606C11.7881 10.5602 11.7646 10.5584 11.7413 10.5552L10.1805 10.3423C8.12699 10.0623 6.15883 9.11711 4.27072 7.54387C3.67275 10.8535 4.84 13.147 7.65342 14.9157L9.40041 16.014C9.68095 16.1904 9.7654 16.5608 9.58903 16.8413C9.54861 16.9056 9.49636 16.9616 9.43504 17.0064L7.84338 18.1693C8.78973 18.2288 9.68938 18.1873 10.435 18.0385C15.1526 17.097 18.2897 13.5468 18.2897 7.69084C18.2897 7.21275 17.2774 5.5498 15.3499 5.5498ZM10.4507 8.36066C10.4983 5.69559 12.6735 3.5498 15.3499 3.5498C16.7132 3.5498 17.9465 4.10658 18.8348 5.00515C19.5462 4.9998 20.1514 5.17966 21.5035 4.35943C21.1693 5.9998 21.0034 6.71177 20.2897 7.69084C20.2897 15.3324 15.5926 19.0487 10.8264 19.9998C7.5587 20.6519 2.80646 19.5812 1.44531 18.1584C2.13874 18.1051 4.95928 17.8018 6.58895 16.6089C5.20994 15.6984 -0.278631 12.4679 3.32772 3.78617C5.02119 5.76283 6.73797 7.10831 8.47807 7.82262C9.63548 8.29774 9.91978 8.28825 10.4507 8.36066Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
static/icon/warning.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path d="M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.4091 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72191 12.7772 2.84815 12.865 3.00017ZM4.20471 19.0002H19.7932L11.9989 5.50017L4.20471 19.0002ZM10.9989 16.0002H12.9989V18.0002H10.9989V16.0002ZM10.9989 9.00017H12.9989V14.0002H10.9989V9.00017Z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 621 B

BIN
static/img/avatar.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -0,0 +1,51 @@
<style>
/* light mode colors */
body {
--primary-color: #8070c6;
--primary-pale-color: #8070c61c;
--text-color: #151517;
--text-pale-color: #454449;
--bg-color: #ece5ea;
--highlight-mark-color: #5f75b045;
--callout-note-color: #e887bb;
--callout-important-color: #a292e8;
--callout-warning-color: #d9d564;
--callout-alert-color: #f06969;
--callout-question-color: #78b9c4;
--callout-tip-color: #91d65c;
}
/* dark mode colors */
body.dark {
--primary-color: #a292e8;
--primary-pale-color: #a292e81c;
--text-color: #ece5ea;
--text-pale-color: #5c5c61;
--bg-color: #151517;
--highlight-mark-color: #5f75b045;
--callout-note-color: #e887bb;
--callout-important-color: #a292e8;
--callout-warning-color: #d9d564;
--callout-alert-color: #f06969;
--callout-question-color: #78b9c4;
--callout-tip-color: #91d65c;
}
/* typography */
body {
--main-font: 'Signika', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--code-font: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--homepage-max-width: 750px;
--main-max-width: 750px;
--avatar-size: 70px;
--paragraph-font-size: 18px;
--paragraph-line-height: 1.75;
--aside-font-size: 16px;
--img-border-radius: 0px;
--inline-code-border-radius: 2px;
}
</style>

14
themes/serene/.gitignore vendored Normal file
View file

@ -0,0 +1,14 @@
public/
content/
!content/_index.md
static/img/
config.toml
.DS_Store
static/hl-light.css
static/hl-dark.css

133
themes/serene/CHANGELOG.md Normal file
View file

@ -0,0 +1,133 @@
# Changelog
All notable changes to this project will be documented in this file.
## [2.1.2] - 2023-09-19
### Fix:
- Outdate alert not 'hidden' ([#49](https://github.com/isunjn/serene/issues/49))
## [2.1.1] - 2023-09-16
### Add:
- Custom 404 page
## [2.0.1] - 2023-09-13
### Fix:
- Min height of prose page & post page
## [2.0.0] - 2023-09-01
> **Warning**
> This version contains several breaking changes.
> If you came from a previous version and want to upgrade, I suggest you start all over again.
### UI:
- Text selction now is styled
- Other minor tweaks
- Change defalut bg color of codeblock to transparent
### Add:
- Option `dispaly_tags` and `truncate_summary` [@woojiq](https://github.com/woojiq) ([#40](https://github.com/isunjn/serene/issues/40))
- Support for footnote and backlink
- Active TOC indicator
- Generay `prose` section/page
- Config option `sections`, now you can rename `blog` to somthing else, e.g. `posts`
- Support for header nav fold/unfold
- Option for homepage layout, can be `about` or `list`
- A separate `_custom_css.html` for css customization
### Fix:
- Codeblock distance calculation
- Codeblock highlight style
- Add description tag only when it's available
- Post 3 column layout issue
- Inline code style in list item
- Link text-decoration style on mobile
## [1.2.0] - 2023-08-19
### UI:
- Use noborder theme of giscus by default
- Post list item and callout styles changed
- Code block styles improved
- Default colors changed
### Add:
- Outline styles [@mrtnvgr](https://github.com/mrtnvgr) ([#26](https://github.com/isunjn/serene/pull/26))
- Support self-host font ([#29](https://github.com/isunjn/serene/pull/29))
- Copy button for code blocks ([#30](https://github.com/isunjn/serene/pull/30))
- Support light/dark switch for code blocks ([#33](https://github.com/isunjn/serene/pull/33))
- Support tags for project page
- Back-to-top button
- A shortcode for code block with file name: `codeblock` ([#39](https://github.com/isunjn/serene/pull/39))
### Fix:
- Update theme toggle icon on page load [@mrtnvgr](https://github.com/mrtnvgr) ([#25](https://github.com/isunjn/serene/pull/25))
- Layout shift problem on post page ([#27](https://github.com/isunjn/serene/pull/27))
## [1.1.1] - 2023-08-09
- Allow no tags in front matter [@mrtnvgr](https://github.com/mrtnvgr)
- Fix figcaption width issue
## [1.1.0] - 2023-05-27
- Fix theme auto-toggle logic
- A few ui tweaks
## [1.0.0] - 2023-05-24
> **Warning**
> The 1.0.0 version contains many breaking changes.
> If you came from a previous version and want to upgrade, I suggest you start all over again.
### Breaking
- `config.toml` restructured, config items are renamed
- All analytics configs removed, use `_head_extend.html` instead
- All comment-support configs removed, replace with [giscus](https://giscus.app)
- Icons now using svg files
- Callout renamed: `info -> note`, `caution -> warning`, `warning -> alert`
- Callout removed: `good`, `bad`, `happy`, `unhappy`, `check`, `wrong`, `flag`, `star`
- `cc_license` removed
- Reading-progress-bar removed
- Back-to-top button removed
- Many other tweaks
## [0.2.0] - 2022-02-16
### Add:
- KaTeX support
- Mermaid support
### Fix:
- Style issue of table-of-contents
- A few non-critical bugs
## [0.1.0] - 2022-01-14
First release 🎉
[2.1.2]: https://github.com/isunjn/serene/compare/v2.1.1...v2.1.2
[2.1.1]: https://github.com/isunjn/serene/compare/v2.0.1...v2.1.1
[2.0.1]: https://github.com/isunjn/serene/compare/v2.0.0...v2.0.1
[2.0.0]: https://github.com/isunjn/serene/compare/v1.2.0...v2.0.0
[1.2.0]: https://github.com/isunjn/serene/compare/v1.1.1...v1.2.0
[1.1.1]: https://github.com/isunjn/serene/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/isunjn/serene/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/isunjn/serene/compare/v0.2.0...v1.0.0
[0.2.0]: https://github.com/isunjn/serene/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/isunjn/serene/releases/tag/v0.1.0

21
themes/serene/LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-2023 isunjn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

31
themes/serene/README.md Normal file
View file

@ -0,0 +1,31 @@
<img width="1501" alt="screenshot" src="https://github.com/isunjn/serene/assets/60461730/33516366-3670-497f-bd72-41ebe8f06f1a">
<br /><br />
A blog theme for [zola](https://www.getzola.org), simple and clean
## Demo
- <https://serene-demo-site.vercel.app>
## Features
- A spiffy design, well crafted
- Projects page
- Dark mode
- Image zooming
- Out-of-date alert
- Sticky table-of-contents
- Callouts (note, warning, alert, etc.)
- Comments using [Giscus](https://giscus.app)
- Mathematical notations using [KaTeX](https://katex.org)
- Diagrams and visualizations using [Mermaid](https://github.com/mermaid-js/mermaid)
## Usage
- Check the [USAGE.md](https://github.com/isunjn/serene/blob/latest/USAGE.md) of `latest` branch
- Also available in Simplified Chinese: [USAGE-zh_CN.md](https://github.com/isunjn/serene/blob/latest/USAGE-zh_CN.md) (简体中文)
## Contributing
- Before you make any non-trivial changes, you may want to open an issue so we can discuss

View file

@ -0,0 +1,379 @@
如果你还没有创建 Zola 站点,使用以下命令创建新的 Zola 站点(假设你的网站名为 myblog:
```sh
zola init myblog
```
进入 myblog 目录:
```sh
cd myblog
```
添加 serene 主题:
```sh
git submodule add -b latest https://github.com/isunjn/serene.git themes/serene
```
`myblog/themes/serene/config.example.toml` 的内容复制到 `myblog/config.toml`,参考文件中的注释和 Zola 的[文档](https://www.getzola.org/documentation/getting-started/overview/)进行相应的修改
## 区块和页面
`config.toml` 中有一个 `sections` 配置项,它列举了网站都有哪几部分, 你应该至少有一个“博客”部分。名称和路径可以更改,注意如果你更改了博客 section 的路径(例如从 `/blog``/posts`),那么你还应该同步更改 `blog_section_path` 配置项
myblog 目录此时像这样:
```
├── config.toml
├── content/
├── sass/
├── static/
├── templates/
└── themes/
└── serene/
```
创建 `myblog/content/_index.md``myblog/content/blog/_index.md`, 文件内容如下:
`myblog/content/_index.md`
```
+++
template = 'home.html'
[extra]
lang = 'en'
+++
Words about you
```
`myblog/content/blog/_index.md`:
```
+++
title = "My Blog"
description = "My blog site."
sort_by = "date"
template = "blog.html"
page_template = "post.html"
insert_anchor_links = "right"
generate_feed = true
[extra]
lang = 'en'
+++
```
路径和目录应该匹配。如果你将博客 section 的 path 更改为 `/posts`,那么你创建的是 `myblog/content/posts/_index.md`,而不是 `myblog/content/blog/_index.md` 别的 section 也一样
如果你还想要 Projects 页面,创建 `myblog/content/projects/_index.md`
`myblog/content/projects/_index.md`:
```
+++
title = "My Projects"
description = "My projects page."
template = "projects.html"
[extra]
lang = 'en'
+++
```
`blog``projects` 是 serene 默认支持的两个 section它们具有特定的结构和样式在模板 `blog.html``projects.html` 中定义
Serene 还支持一个名为 `prose.html` 的特殊模板,它应用了与博客文章页面相同的样式,你可以将其用作自定义 section 页面的模板,例如,如果你想要一个单独的 `about` 页面,可以在 `sections` 配置项中添加一个 `{ name = "about", path = "/about", is_external = false }` 并创建一个 `myblog/content/about/_index.md` ,内容如下:
```
+++
title = "About me"
description = "A about page of ..."
template = "prose.html"
[extra]
lang = 'en'
math = false
mermaid = false
copy = false
comment = false
+++
Hi, My name is ....
(more markdown content goes here)
```
你还可以创建一个 `friends` 页面来列出你在互联网上的朋友,一个 `collections/bookmarks` 页面来列出你认为有价值的书签,一个 `cat` 页面来放几张你家可爱猫咪的照片...... 未来 serene 可能会添加更多特定的模板
现在目录可能长这样:
```
├── config.toml
├── content/
│ ├── blog/
│ │ └── _index.md
│ ├── projects/
│ │ └── _index.md
│ ├── about/
│ │ └── _index.md
│ └── _index.md
├── sass/
├── static/
├── templates/
└── themes/
└── serene/
```
## 配置
### Favicons
`myblog/static` 下新建目录 `img` ,放置 favicon 相关图片,你可以使用类似 [favicon.io](https://favicon.io/favicon-converter/) 这样的工具在线生成
另外放入你的头像图片文件 `avatar.webp`, 推荐 webp 格式
```
...
├── static/
│ └── img/
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── apple-touch-icon.png
│ └── avatar.webp
...
```
### 图标
- 将 `myblog/themes/serene/static/icon` 复制到 `myblog/static/icon`links 中的 icon 值为其中的 svg 文件的文件名,不包含 `.svg` 后缀
- 找到你想要的 icon 的 svg 文件,修改其宽高为 24颜色为 currentColor: `... width="24" height="24" ... fill="currentColor" ...`
- 默认图标来自 [Remix Icon](https://remixicon.com/)
### 代码高亮
- 将 `myblog/themes/serene/highlight_themes` 目录复制到 `myblog/highlight_themes`
- 如果你将 `config.toml` 中的 `highlight_theme` 设置为 zola 的 [内置高亮主题](https://www.getzola.org/documentation/getting-started/configuration/#syntax-highlighting) 之一,浅色和深色模式都将使用该主题
- 默认情况下serene 对亮/暗模式使用不同的主题,由 `highlight_theme`、`extra_syntaxes_and_themes` 和 `highlight_themes_css` 配置。 默认高亮主题 `serene-light` `serene-dark` 是 [Tomorrow](https://github.com/ChrisKempson/Tomorrow-Theme) 主题的一个修改版本
- 如果你想要不同的主题,找到你的主题的 `.tmTheme` TextMate文件将其放在 `myblog/static/highlight_themes` 中,然后将 `highlight_themes_css``theme` 值修改为该文件的名称,不带` .tmTheme` 扩展名。 这将在 `myblog/static/` 中生成 `hl-light.css``hl-dark.css` 文件,你需要在修改 `theme` 值之前先删除它们,以便 zola 可以重新生成
- 你可以在[这个网站](https://tmtheme-editor.glitch.me/)上找到一些 TextMate 主题
### RSS
- 你可以为你的站点添加 RSSZola 默认的 feed 文件位于站点的根目录,在 `config.toml` 设置 `generate_feed = ture` `feed_filename` 可以设置为 `atom.xml``rss.xml` ,对应两种不同的 rss 文件标准, `myblog/content/blog/_index.md` 中设置 `generate_feed = false`
- Serene 主题风格更像个人网站,文章在 `/blog` 目录下,你可能希望 feed 文件在 `/blog` 目录下而不是根目录下,这需要你在 `config.toml` 中设置 `generate_feed = false``feed_filename = "feed.xml"` 并在 `myblog/content/blog/_index.md` 中设置 `generate_feed = true`
- `feed.xml` 使用 `myblog/content/blog/_index.md` 中的 `title``description`,其他两个则是使用 `config.toml` 中的
### Projects 页面
- Serene 有一个 projects 页面,可以在其上展示你的项目、产品等信息
- 在 `config.toml` 中设置 `projects_page = ture` ,在 `myblog/content/projects/` 下新建一个 `data.toml` ,在其中添加项目信息,格式如下:
```toml
[[project]]
name = ""
desc = ""
tags = ["", ""]
links = [
{ name = "", url = "" },
{ name = "", url = "" },
]
[[project]]
name = ""
desc = ""
tags = ["", ""]
links = [
{ name = "", url = "" },
{ name = "", url = "" },
]
```
### 文章过时提示
- 如果你的某篇文章具有较强的时效性,可以设置若干天后在页面上显示一个过时提示
- `config.toml` 中的 `outdate_alert``outdate_alert_days` 设置默认的是否过时和多少天过时。是否显示过时提示以及过时天数可以在单独的一篇文章上配置,你可以将`config.toml`中的 `outdate_alert` 设置为 `false`,然后在有时效性的文章的 front matter 中单独开启
- `outdate_alert_text_before``outdate_alert_text_after` 是提示的具体内容,分别是在天数之前和之后
### 文章评论
- Serene 支持使用 [Giscus](https://giscus.app) 作为文章评论系统
- 开启此功能需要新建 `myblog/templates/_giscus_script.html` 并将在 Giscus 网站上配置好的 script 放入其中,然后将其中 `data-theme` 的值改为 `https://<your-domain-name>/giscus_light.css`, 将 `<your-domain-name>` 改为你自己的域名,和 `config.toml` 中的 `base_url` 一致
- `config.toml` 中的 `comment = true` 设置所有文章开启评论,可以在文章的 front matter 中 `[extra]` 下设置 `comment = false` 控制单篇文章是否显示评论
### Analytics
- 如需放置 Analytics 工具(如 Google Anayltics、Umami 等)的脚本,可以新建 `myblog/templates/_head_extend.html` 并将相应内容放入其中,该文件的内容将被添加到每个页面的 html head 中
### 字体
- Serene 默认使用 [Google Fonts](https://fonts.google.com/) 的 Signika 字体,如需自定义字体,新建 `myblog/templates/_custom_font.html` 并将从 Google Fonts 复制的字体样式表 link 标签放入其中,然后修改 `myblog/sass/main.scss` 中的 `--main-font` 或者 `--code-font`.
- 为了进一步提高网站速度, 你也可以选择自己托管字体文件(可选):
1. 打开 [google-webfonts-helper](https://gwfh.mranftl.com) 并选择一个字体
2. 将步骤 3 中的 `Customize folder prefix` 改为 `/font/`, 然后复制该 css
3. 将 `myblog/tempaltes/_custom_font.html` 替换为一个 `<style> </style>` 标签, 把你刚复制的 css 放在里面
4. 下载步骤 4 的字体文件, 放在 `myblog/static/font/` 目录
### 自定义 CSS
- 将 `myblog/themes/serene/templates/_custom_css.html` 复制到 `myblog/templates/_custom_css.html`, 该文件里的若干变量值用于控制样式,例如主题色 `--primary-color`,可以自行修改
- 如果你想修改更多的内容,你只需要将相应的 `themes/serene``templates`、`static`、`sass` 目录下的文件复制到 myblog 同名目录下,并进行修改。注意不要直接修改 serene 目录下的文件,因为如果更新主题,这些修改可能导致冲突
### 首页布局
- 主页默认显示 `myblog/content/_index.md` 的 markdown 内容
- 可以将 `config.toml` 中的 `homepage_layout``about` 更改为 `list`,这样博客文章列表将直接显示在首页中
## 写作
### front matter
- 文章 Markdown 文件顶部两个 `+++` 内部的内容称为 front matter支持的配置项如下
```md
+++
title = ""
date = 2022-01-01
draft = true
[taxonomies]
categories = ["one"]
tags = ["one", "two", "three"]
[extra]
lang = "en"
toc = true
comment = true
copy = true
math = false
mermaid = false
outdate_alert = true
outdate_alert_days = 120
display_tags = true
truncate_summary = false
+++
new post about somthing...
<!-- more -->
more post content...
```
- 你可以添加一行`<!-- more -->`, 在其前面的内容会成为文章的总结/描述, 可以设置 `truncate_summary = ture` 来让其在最终的文章网页上不显示
- 文章文件在 `myblog/content/blog` 下创建,写完后将 draft 改为 false 即可
### Shortcodes
- Zola 支持 Shortcodes可以在标准 Markdown 格式之外增加一些额外的样式或方便进行输入的模板
- Zola 支持一些[代码块注解](https://www.getzola.org/documentation/content/syntax-highlighting/#annotations), Serene 通过一个 `codeblock` shortcode 额外支持了显示代码块文件名, 用法如下:
```md
{% codeblock(name="path/to/file") %}
// a markdown code block ...
{% end %}
```
- 除了标准 Markdown 的 `![img](/path/to/img)` , Serene 还支持 figure shortcode以便为图片添加一些说明性的文字格式如下
```md
{{ figure(src="/path/to/img", alt="alt text", caption="caption text") }}
```
这将在网页上显示为 HTML 中的 `<figure></figure>` ,而非 `<img>`caption 的内容将居中显示在图像下方。alt 属性是可选的,但推荐加上,有助于增强可访问性
为图片添加出处信息是很常见的情况,你可以直接使用 `via` 属性,这将在图片下方显示一个名为 via 的链接:
```md
{{ figure(src="/path/to/img", alt="some alt text", via="https://example.com") }}
```
### Callout
- Serene 还使用 Shortcodes 实现了 Callout, 效果如示例站点的 [这个页面](https://serene-demo-site.vercel.app/blog/callouts) 所示,目前共有 6 种:`note` `important` `warning` `alert` `question` `tip`格式如下header 属性是可选的:
```md
{% note(header="Note") %}
note text
{% end %}
```
- 如果读者通过 RSS 阅读你的文章,这些 Callouts 将会显示为普通的 `<blockquote>`
### KaTeX
- 在文章 front matter 中设置 `math = true` 开启 [KaTeX](https://katex.org/) 支持
- 行内公式 `$...$`,块级公式 `$$...$$`
### Mermaid
- 在文章 front matter 中设置 `mermaid = true` 开启 [Mermaid](https://github.com/mermaid-js/mermaid) 支持,然后用如下格式插入图表:
```md
{% mermaid() %}
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
{% end %}
```
## 构建部署
本地预览:
```sh
zola serve
```
构建站点:
```sh
zola build
```
部署静态站点请参考 Zola [关于部署的文档](https://www.getzola.org/documentation/deployment/overview/)
## 更新
- 更新主题前请在 GitHub 上查看 [CHANGELOG.md](https://github.com/isunjn/serene/blob/main/CHANGELOG.md) 以确认是否有 breaking changes
- 如果你从 `myblog/themes/serene` 复制了一些文件到 `myblog/` 进行自定义,例如 `_custom_css.html``main.scss`,那么你应该在更新之前记录下你修改的内容,在更新后重新复制这些文件, 然后重新修改这些文件. `config.toml` 也要重新复制
- 你可以在 GitHub 上 watch`watch > custom >releases > apply`)此项目,在有新版本时会收到提醒
```sh
git submodule update --remote themes/serene
```
<br />
*Happy blogging :)*
<br />

378
themes/serene/USAGE.md Normal file
View file

@ -0,0 +1,378 @@
If you haven't created a zola site yet, create a new zola site with the following command (assuming your site is called `myblog`):
```sh
zola init myblog
```
Enter the directory:
```sh
cd myblog
```
Add the serene theme:
```sh
git submodule add -b latest https://github.com/isunjn/serene.git themes/serene
```
Copy the content of `myblog/themes/serene/config.example.toml` to `myblog/config.toml`, refer to the comments in the file and Zola's [documentation](https://www.getzola.org/documentation/getting-started/overview/) to modify accordingly
## Sections and pages
There is a `sections` config item in your `config.toml`, which enumerates the sections your website has. You should have at least one `blog` section. The name and path can be changed, be noticed that if you changed the blog section path (e.g. from `/blog` to `/posts`), then you should also change `blog_section_path` config item.
The myblog directory now looks like this:
```
├── config.toml
├── content/
├── sass/
├── static/
├── templates/
└── themes/
└── serene/
```
Create `myblog/content/_index.md` and `myblog/content/blog/_index.md` with the following content:
`myblog/content/_index.md`:
```
+++
template = 'home.html'
[extra]
lang = 'en'
+++
Words about you
```
`myblog/content/blog/_index.md`:
```
+++
title = "My Blog"
description = "My blog site."
sort_by = "date"
template = "blog.html"
page_template = "post.html"
insert_anchor_links = "right"
generate_feed = true
[extra]
lang = 'en'
+++
```
The path and the directory should match. If you changed the blog section path to `/posts`, then you create `myblog/content/posts/_index.md`, rather than `myblog/content/blog/_index.md`. The same goes for the others.
If you want to display a projects page (as you see in the demo site), also create `myblog/content/projects/_index.md`:
```
+++
title = "My Projects"
description = "My projects page."
template = "projects.html"
[extra]
lang = 'en'
+++
```
The `blog` and `projects` are two sections that serene supports by default, they have specific structures and styles, defined in template `blog.html` and `projects.html`.
Serene also support a special template called `prose.html`, it applies the same styles of blog post page and you can use it as a section template for a custom section page, for example if you want a separate `about` page, you can add a `{ name = "about", path = "/about", is_external = false }` to the `sections` config item and create a `myblog/content/about/_index.md` with the following content:
```
+++
title = "About me"
description = "A about page of ..."
template = "prose.html"
[extra]
lang = 'en'
math = false
mermaid = false
copy = false
comment = false
+++
Hi, My name is ....
(more markdown content goes here)
```
You may also create a `friends` page to list all your friends on the internet, a `collections/bookmarks` page to list your considered valuable bookmarks, a `cat` page to post a few pics of your lovely cat... In the future, serene may add more specific templates.
Now the myblog directory may looks like this:
```
├── config.toml
├── content/
│ ├── blog/
│ │ └── _index.md
│ ├── projects/
│ │ └── _index.md
│ ├── about/
│ │ └── _index.md
│ └── _index.md
├── sass/
├── static/
├── templates/
└── themes/
└── serene/
```
## Configuration
### Favicons
- Create a new directory `img` under `myblog/static`, put favicon related files here, you can use tools like [favicon.io](https://favicon.io/favicon-converter/) to generate those files
- Also put your avatar picture file `avatar.webp` here, webp format is recommended
```
...
├── static/
│ └── img/
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── apple-touch-icon.png
│ └── avatar. webp
...
```
### Icon
- Copy `myblog/themes/serene/static/icon` directory to `myblog/static/icon`, the icon value in `links` is the file name of the svg file in it, without the `.svg` suffix
- Find the svg file of the icon you want, modify its width and height to 24, and the color to currentColor:
`... width="24" height="24" ... fill="currentColor" ...`
- The default icons came from [Remix Icon](https://remixicon.com/)
### Code highlight
- Copy `myblog/themes/serene/highlight_themes` directory to `myblog/highlight_themes`.
- If you set `highlight_theme` in `config.toml` to one of zola's [built-in highlight themes](https://www.getzola.org/documentation/getting-started/configuration/#syntax-highlighting), you will get that theme used in both light and dark mode.
- By default serene use different themes for light/dark modes, configured by `highlight_theme`, `extra_syntaxes_and_themes` and `highlight_themes_css`. The default highlight theme `serene-light` `serene-dark` is a modified version of [Tomorrow](https://github.com/ChrisKempson/Tomorrow-Theme) theme.
- If you want a different theme, find the `.tmTheme` TextMate file of your theme, put it in `myblog/static/highlight_themes`, and then modify the `theme` value of `highlight_themes_css` to that file's name, without `.tmTheme` extension. This will generate a `hl-light.css` and a `hl-dark.css` file in `myblog/static/`, you may have to delete them first before you change the `theme` value, so zola can re-generate.
- You can find some TextMate themes on [this website](https://tmtheme-editor.glitch.me/).
### RSS
- You can add rss to your site, Zola's default feed file is located in the root directory of the site, set `generate_feed = true` in `config.toml`, `feed_filename` can be set to `atom.xml` or `rss.xml ` , corresponding to two different rss file standards, you should also set `generate_feed = false` in `myblog/content/blog/_index.md`
- The serene theme looks more like a personal website, the posts are in the `/blog` directory, you may want the feed file to be in the `/blog` directory instead of the root directory, this requires you to set `generate_feed = false ` `feed_filename = "feed.xml"` in `config.toml`, and set `generate_feed = true` in `myblog/content/blog/_index.md`
- `feed.xml` uses `title` and `description` from `myblog/content/blog/_index.md`, the other two use `config.toml`'s
### Projects page
- Serene has a projects page where you can showcase your projects, products, etc.
- Create a new `data.toml` under `myblog/content/projects/`, add projects information in it, the format is as follows:
```toml
[[project]]
name = ""
desc = ""
tags = ["", ""]
links = [
{ name = "", url = "" },
{ name = "", url = "" },
]
[[project]]
name = ""
desc = ""
tags = ["", ""]
links = [
{ name = "", url = "" },
{ name = "", url = "" },
]
```
### Outdated alert
- If one of your posts has strong timeliness, you can set an outdated alert to be displayed on the page after certain days
- `outdate_alert` and `outdate_alert_days` in `config.toml` set the default whether to be outdated and how many days to be outdated. These two can also be configured on a separate post, you can set `outdate_alert` in `config.toml` to `false`, and then enable it separately in the front matter of time-sensitive posts
- `outdate_alert_text_before` and `outdate_alert_text_after` are the specific content of the alert, before and after the number of days respectively
### Comments
- Serene supports using [giscus](https://giscus.app) as the comment system
- To enable it, you need to create `myblog/templates/_giscus_script.html` and put the script configured on the giscus website into it, then change the value of `data-theme` to `https://<your-domain-name>/giscus_light.css`, replace `<your-domain-name>` with you domain name, same as `base_url` in `config.toml`
- `comment = true` in `config.toml` sets all posts to enable comments, you can set `comment = false` under `[extra]` in the front matter of the post to control whether a specific post displays comments
### Analytics
- To place scripts for analytics tools (such as Google Anayltics, Umami, etc.), you can create a new `myblog/templates/_head_extend.html` and put the corresponding content in it. The content of this file will be added to the html head of each page
### Fonts
- Serene uses the Signika font of [Google Fonts](https://fonts.google.com/) by default. If you want a different font, create a new `myblog/templates/_custom_font.html` and put the font link tags you copied from google fonts website into it, and then modify `--main-font` or `--code-font` in `myblog/sass/main.scss`.
- For performance reason, you may want to self-host font files (optional):
1. Open [google-webfonts-helper](https://gwfh.mranftl.com) and choose your font
2. Modify `Customize folder prefix` of step 3 to `/font/` and then copy the css
3. Replace the content of `myblog/templates/_custom_font.html` with a `<style> </style>` tag, with the css you just copied in it.
4. Download step 4 font files and put them in `myblog/static/font/` folder
### Custom CSS
- Copy `myblog/themes/serene/templates/_custom_css.html` to `myblog/templates/_custom_css.html`, variables in this file are used to control styles, such as the theme color `--primary-color`, you can modify them as you want
- If you want to customize more, you only need to copy that file under the `templates`, `static`, `sass` directory in the corresponding `themes/serene` to the same name directory of `myblog`, and modify it. Be careful not to directly modify the files under the serene directory, because these modifications may cause conflicts if the theme is updated
### Homepage layout
- By default, homepage displays markdown content of your `myblog/content/_index.md`
- You can change `homepage_layout` in `config.toml` from `about` to `list`, then the blog post list will be displayed directly in the homepage
## Writing
### front matter
- The content inside the two `+++` at the top of the post markdown file is called front matter, and the supported configuration items are as follows:
```md
+++
title = ""
date = 2022-01-01
draft = true
[taxonomies]
categories = ["one"]
tags = ["one", "two", "three"]
[extra]
lang = "en"
toc = true
comment = true
copy = true
math = false
mermaid = false
outdate_alert = true
outdate_alert_days = 120
display_tags = true
truncate_summary = false
+++
new post about somthing...
<!-- more -->
more post content...
```
- You can add a `<!-- more -->` line, the content before it will become the summary/description of the post. You can set `truncate_summary = true` to remove the summary from the post webpage.
- Post files are created under `myblog/content/blog`, after done writing, change `draft` to false
### Shortcodes
- Zola supports 'shortcodes', which can be used to add some extra styles or templates in addition to the standard markdown format
- Zola support some [annotations for code blocks](https://www.getzola.org/documentation/content/syntax-highlighting/#annotations). Serene add another one to display the file name: `codeblock`, use it like this:
```md
{% codeblock(name="path/to/file") %}
// a markdown code block ...
{% end %}
```
- In addition to `![img](/path/to/img)` of standard markdown, serene also supports a `figure` shortcode to add some explanatory text to the image:
```md
{{ figure(src="/path/to/img", alt="alt text", caption="caption text") }}
```
This will be displayed as `<figure></figure>` in HTML on the web page instead of `<img>`, and the content of the caption will be centered below the image. The alt attribute is optional but recommended to help enhance accessibility
Adding attribution information to a image is very common, you can directly use the `via` attribute, which will display a link named via below the image:
```md
{{ figure(src="/path/to/img", alt="some alt text", via="https://example.com") }}
```
### Callout
- Serene also uses shortcodes to implement callouts, the effect is shown in [this page](https://serene-demo-site.vercel.app/blog/callouts) of the demo site, there are currently 6 types: `note` `important ` `warning` `alert` `question` `tip`, the format is as follows, the header attribute is optional:
```md
{% note(header="Note") %}
note text
{% end %}
```
- If people read your posts via rss reader, these callouts will appear as normal `<blockquote>`
### KaTeX
- Set `math = true` in the front matter to enable [KaTeX](https://katex.org/) support
- Inline formula `$...$`, block-level formula `$$...$$`
### Mermaid
- Set `mermaid = true` in the front matter to enable [Mermaid](https://github.com/mermaid-js/mermaid) support, and then insert a chart in the following format:
```md
{% mermaid() %}
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
{% end %}
```
## Build & Deploy
Local preview:
```sh
zola serve
```
Build the site:
```sh
zola build
```
To deploy a static site, please refer to zola's [documentation about deployment](https://www.getzola.org/documentation/deployment/overview/)
## Update
- Please check the [CHANGELOG.md](https://github.com/isunjn/serene/blob/main/CHANGELOG.md) on github for breaking changes before updating the theme
- If you copied some files from `myblog/themes/serene` to `myblog/` for customization, such as `_custom_css.html` or `main.scss`, then you should record what you have modified before you update, re-copy those files and re-apply your modification after updating. The `config.toml` should be re-copied too.
- You can watch (`watch > custom > releases > apply`) this project on github to be reminded of a new release
```sh
git submodule update --remote themes/serene
```
<br />
*Happy blogging :)*
<br />

View file

@ -0,0 +1,90 @@
# serene v2.1.2
#
# - docs: https://github.com/isunjn/serene/blob/latest/USAGE.md
# - check for updates: https://github.com/isunjn/serene/releases
#
#=========================================================================================
base_url = "https://example.com" # Domain name of your website
title = "xxxx"
description = "xxxx xxxx xxxx"
default_language = "en"
theme = "serene"
output_dir = "public"
compile_sass = true
minify_html = true
build_search_index = false # Keep this false, search is temporarily unsupported
generate_feed = false # Whether to generate a feed file in root, read docs for more info about rss feed
feed_filename = "feed.xml" # The file name of feed, "feed.xml" / "atom.xml" / "rss.xml", read docs for more info
taxonomies = [{ name = "tags" }, { name = "categories" }]
[markdown]
highlight_code = true
highlight_theme = "css"
extra_syntaxes_and_themes = ["highlight_themes"]
highlight_themes_css = [
{ theme = "serene-light", filename = "hl-light.css"},
{ theme = "serene-dark", filename = "hl-dark.css"},
]
render_emoji = false
external_links_target_blank = false
external_links_no_follow = true
external_links_no_referrer = true
smart_punctuation = false
[slugify]
paths = "on"
taxonomies = "on"
anchors = "on"
#=========================================================================================
[extra]
name = "xxxx" # Your name
id = "xxxx" # Your id / username / handle
bio = "xxxx" # Your bio
avatar = "img/avatar.webp" # Your avatar
links = [ # Your links
{ name = "GitHub", icon = "github", url = "https://github.com/<your-username>" },
{ name = "Twitter", icon = "twitter", url = "https://twitter.com/<your-username>" },
{ name = "Email", icon = "email", url = "mailto:<your-email-address>" },
]
homepage_layout = "about" # "about" | "list"
sections = [
{ name = "blog", path = "/blog", is_external = false },
{ name = "projects", path = "/projects", is_external = false },
# { name = "about", path = "/about", is_external = false },
# { name = "github", path = "https://github.com/<your-username>", is_external = true },
]
blog_section_path = "/blog"
nav_separator = "::"
nav_wrapper_left = "{"
nav_wrapper_right = "} ;"
nav_wrapper_separator = ","
display_id = true # Whether to display your id on homepage
blog_categorized = true # Whether to categorize blog posts
blur_effect = true # Whether to turn on blur effect on navigation bar
back_to_top = true # Whether to show back-to-top button on post pages
toc = true # Whether to show Table-Of-Contents by default
copy = true # Whether to add a copy button on code blocks by default
comment = false # Whether to show giscus comment section by default, see https://giscus.app for more info
display_tags = true # Whether to display tags on post pages by default
truncate_summary = false # Whether to truncate the summary of a post by default
outdate_alert = false # Whether to show outdate alert by default
outdate_alert_days = 120 # How many days will a post be outdated by default
outdate_alert_text_before = "This article was last updated "
outdate_alert_text_after = " days ago and may be out of date."
footer_copyright = "© 2023 <your-name>"
footer_credits = true # Whether to show "powered by zola and serene" in footer
not_found_title = "404"
not_found_error_text = "Not Found"
not_found_recover_text = "« back to home »"

View file

@ -0,0 +1,287 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Generated by: TmTheme-Editor -->
<!-- ============================================ -->
<!-- app: http://tmtheme-editor.herokuapp.com -->
<!-- code: https://github.com/aziz/tmTheme-Editor -->
<plist version="1.0">
<dict>
<key>comment</key>
<string>http:&#x2f;&#x2f;chriskempson.com</string>
<key>name</key>
<string>Tomorrow Night</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>caret</key>
<string>#AEAFAD</string>
<key>foreground</key>
<string>#C5C8C6</string>
<key>invisibles</key>
<string>#4B4E55</string>
<key>lineHighlight</key>
<string>#282A2E</string>
<key>selection</key>
<string>#373B41</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comment</string>
<key>scope</key>
<string>comment, string.quoted.double.block.python</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#999999</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Foreground</string>
<key>scope</key>
<string>keyword.operator.class, constant.other, source.php.embedded.line</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#CED1CF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variable, String Link, Regular Expression, Tag Name</string>
<key>scope</key>
<string>variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#A67878</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>
<key>scope</key>
<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#E08355</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Class, Support</string>
<key>scope</key>
<string>type,
entity.name.class, entity.name.type.class, support.type, support.class</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#6A8F8A</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>String, Symbols, Inherited Class, Markup Heading</string>
<key>scope</key>
<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#85AD74</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Operator, Misc</string>
<key>scope</key>
<string>keyword.operator, constant.other.color</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#6A8F8A</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function, Special Method, Block Level</string>
<key>scope</key>
<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#81A2BE</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keyword, Storage</string>
<key>scope</key>
<string>keyword, storage, storage.type, entity.name.tag.css</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#B294BB</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Invalid</string>
<key>scope</key>
<string>invalid</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#DF5F5F</string>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#CED2CF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Separator</string>
<key>scope</key>
<string>meta.separator</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#82A3BF</string>
<key>foreground</key>
<string>#CED2CF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Deprecated</string>
<key>scope</key>
<string>invalid.deprecated</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#B798BF</string>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#CED2CF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff foreground</string>
<key>scope</key>
<string>markup.inserted.diff, markup.deleted.diff, meta.diff.header.to-file, meta.diff.header.from-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff insertion</string>
<key>scope</key>
<string>markup.inserted.diff, meta.diff.header.to-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#5FE375</string>
<key>background</key>
<string>#00000000</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff deletion</string>
<key>scope</key>
<string>markup.deleted.diff, meta.diff.header.from-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#D46565</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff header</string>
<key>scope</key>
<string>meta.diff.header.from-file, meta.diff.header.to-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#FFFFFF</string>
<key>background</key>
<string>#4271ae</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff range</string>
<key>scope</key>
<string>meta.diff.range</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>italic</string>
<key>foreground</key>
<string>#3e999f</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>diff.deleted</string>
<key>scope</key>
<string>markup.deleted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#F92672</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>diff.inserted</string>
<key>scope</key>
<string>markup.inserted</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#A6E22E</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>diff.changed</string>
<key>scope</key>
<string>markup.changed</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#967EFB</string>
</dict>
</dict>
</array>
<key>uuid</key>
<string>F96223EB-1A60-4617-92F3-D24D4F13DB09</string>
<key>colorSpaceName</key>
<string>sRGB</string>
<key>semanticClass</key>
<string>theme.dark.tomorrow_night</string>
</dict>
</plist>

View file

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Generated by: TmTheme-Editor -->
<!-- ============================================ -->
<!-- app: http://tmtheme-editor.herokuapp.com -->
<!-- code: https://github.com/aziz/tmTheme-Editor -->
<plist version="1.0">
<dict>
<key>comment</key>
<string>http:&#x2f;&#x2f;chriskempson.com</string>
<key>name</key>
<string>Tomorrow</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>caret</key>
<string>#AEAFAD</string>
<key>foreground</key>
<string>#4D4D4C</string>
<key>invisibles</key>
<string>#D1D1D1</string>
<key>lineHighlight</key>
<string>#EFEFEF</string>
<key>selection</key>
<string>#D6D6D6</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comment</string>
<key>scope</key>
<string>comment, string.quoted.double.block.python</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#999999</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Foreground</string>
<key>scope</key>
<string>keyword.operator.class, constant.other, source.php.embedded.line</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#666969</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variable, String Link, Regular Expression, Tag Name</string>
<key>scope</key>
<string>variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#A67878</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Number, Constant, Function Argument, Tag Attribute, Embedded</string>
<key>scope</key>
<string>constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#E08355</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Type, Class, Support</string>
<key>scope</key>
<string>type,
entity.name.class, entity.name.type.class, support.type, support.class</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#568A8F</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>String, Symbols, Inherited Class, Markup Heading</string>
<key>scope</key>
<string>string, constant.other.symbol, entity.other.inherited-class, markup.heading</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#85AD74</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Operator, Misc</string>
<key>scope</key>
<string>keyword.operator, constant.other.color</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#568A8F</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function, Special Method, Block Level</string>
<key>scope</key>
<string>entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#4271AE</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keyword, Storage</string>
<key>scope</key>
<string>keyword, storage, storage.type</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#8959A8</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Invalid</string>
<key>scope</key>
<string>invalid</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#DF5F5F</string>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Separator</string>
<key>scope</key>
<string>meta.separator</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#4271AE</string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Deprecated</string>
<key>scope</key>
<string>invalid.deprecated</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#8959A8</string>
<key>fontStyle</key>
<string></string>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff foreground</string>
<key>scope</key>
<string>markup.inserted.diff, markup.deleted.diff, meta.diff.header.to-file, meta.diff.header.from-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#FFFFFF</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff insertion</string>
<key>scope</key>
<string>markup.inserted.diff, meta.diff.header.to-file</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#65C23A66</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff deletion</string>
<key>scope</key>
<string>markup.deleted.diff, meta.diff.header.from-file</string>
<key>settings</key>
<dict>
<key>background</key>
<string>#C8282966</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff header</string>
<key>scope</key>
<string>meta.diff.header.from-file, meta.diff.header.to-file</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#FFFFFF</string>
<key>background</key>
<string>#4271ae</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Diff range</string>
<key>scope</key>
<string>meta.diff.range</string>
<key>settings</key>
<dict>
<key>fontStyle</key>
<string>italic</string>
<key>foreground</key>
<string>#3e999f</string>
</dict>
</dict>
</array>
<key>uuid</key>
<string>82CCD69C-F1B1-4529-B39E-780F91F07604</string>
<key>colorSpaceName</key>
<string>sRGB</string>
<key>semanticClass</key>
<string>theme.light.tomorrow</string>
</dict>
</plist>

View file

@ -0,0 +1,100 @@
main {
--primary-default: 109, 155, 255;
--bg-default: 22, 22, 24;
--color-prettylights-syntax-comment: #8b949e;
--color-prettylights-syntax-constant: #79c0ff;
--color-prettylights-syntax-entity: #d2a8ff;
--color-prettylights-syntax-storage-modifier-import: #c9d1d9;
--color-prettylights-syntax-entity-tag: #7ee787;
--color-prettylights-syntax-keyword: #ff7b72;
--color-prettylights-syntax-string: #a5d6ff;
--color-prettylights-syntax-variable: #ffa657;
--color-prettylights-syntax-brackethighlighter-unmatched: #f85149;
--color-prettylights-syntax-invalid-illegal-text: #f0f6fc;
--color-prettylights-syntax-invalid-illegal-bg: #8e1519;
--color-prettylights-syntax-carriage-return-text: #f0f6fc;
--color-prettylights-syntax-carriage-return-bg: #b62324;
--color-prettylights-syntax-string-regexp: #7ee787;
--color-prettylights-syntax-markup-list: #f2cc60;
--color-prettylights-syntax-markup-heading: #1f6feb;
--color-prettylights-syntax-markup-italic: #c9d1d9;
--color-prettylights-syntax-markup-bold: #c9d1d9;
--color-prettylights-syntax-markup-deleted-text: #ffdcd7;
--color-prettylights-syntax-markup-deleted-bg: #67060c;
--color-prettylights-syntax-markup-inserted-text: #aff5b4;
--color-prettylights-syntax-markup-inserted-bg: #033a16;
--color-prettylights-syntax-markup-changed-text: #ffdfb6;
--color-prettylights-syntax-markup-changed-bg: #5a1e02;
--color-prettylights-syntax-markup-ignored-text: #c9d1d9;
--color-prettylights-syntax-markup-ignored-bg: #1158c7;
--color-prettylights-syntax-meta-diff-range: #d2a8ff;
--color-prettylights-syntax-brackethighlighter-angle: #8b949e;
--color-prettylights-syntax-sublimelinter-gutter-mark: #484f58;
--color-prettylights-syntax-constant-other-reference-link: #a5d6ff;
--color-btn-text: rgb(235 235 245 / 86%);
--color-btn-bg: rgba(var(--bg-default), 1);
--color-btn-border: rgba(var(--bg-default), 1);
--color-btn-shadow: 0 1px 0 rgba(var(--bg-default), 1);
--color-btn-inset-shadow: inset 0 1px 0 rgba(var(--bg-default), 1);
--color-btn-hover-bg: rgba(var(--bg-default), 0.5);
--color-btn-hover-border: rgba(var(--bg-default), 0.5);
--color-btn-active-bg: rgba(var(--primary-default), 0.2);
--color-btn-active-border: rgba(var(--primary-default), 1);
--color-btn-selected-bg: rgba(var(--primary-default), 0.15);
--color-btn-primary-text: rgb(255 255 255 / 100%);
--color-btn-primary-bg: rgba(var(--primary-default), 0.45);
--color-btn-primary-border: rgba(var(--primary-default), 0.5);
--color-btn-primary-shadow: 0 1px 0 rgb(27 31 36 / 10%);
--color-btn-primary-inset-shadow: inset 0 1px 0 hsl(0deg 0% 100% / 3%);
--color-btn-primary-hover-bg: rgba(var(--primary-default), 0.53);
--color-btn-primary-hover-border: rgba(var(--primary-default), 0.75);
--color-btn-primary-selected-bg: rgba(var(--primary-default), 0.45);
--color-btn-primary-selected-shadow: inset 0 1px 0 rgb(0 45 17 / 20%);
--color-btn-primary-disabled-text: rgb(255 255 255 / 80%);
--color-btn-primary-disabled-bg: rgba(var(--primary-default), 0.5);
--color-btn-primary-disabled-border: rgba(var(--primary-default), 0.5);
--color-action-list-item-default-hover-bg: rgb(177 186 196 / 12%);
--color-segmented-control-bg: rgb(110 118 129 / 10%);
--color-segmented-control-button-bg: #0d1117;
--color-segmented-control-button-selected-border: rgba(var(--bg-default), 0.85);
--color-fg-default: rgb(235 235 245 / 86%);
--color-fg-muted: rgb(235 235 245 / 60%);
--color-fg-subtle: rgb(235 235 245 / 50%);
--color-canvas-default: rgb(30 30 32 / 100%);
--color-canvas-overlay: rgb(30 30 32 / 100%);
--color-canvas-inset: rgba(var(--bg-default), 0.85);
--color-canvas-subtle: rgba(var(--bg-default), 1);
--color-border-default: rgba(var(--bg-default), 0.85);
--color-border-muted: rgb(175 184 193 / 20%);
--color-neutral-muted: rgb(175 184 193 / 20%);
--color-accent-fg: rgba(var(--primary-default), 0.85);
--color-accent-emphasis: rgba(var(--primary-default), 0.95);
--color-accent-muted: rgba(var(--primary-default), 0.4);
--color-accent-subtle: rgba(var(--primary-default), 0.1);
--color-success-fg: #3fb950;
--color-attention-fg: #d29922;
--color-attention-muted: rgb(187 128 9 / 40%);
--color-attention-subtle: rgb(187 128 9 / 15%);
--color-danger-fg: #f85149;
--color-danger-muted: rgb(248 81 73 / 40%);
--color-danger-subtle: rgb(248 81 73 / 10%);
--color-primer-shadow-inset: 0 1px 0 rgba(var(--bg-default), 1), inset 0 1px 0 rgba(var(--bg-default), 1);
--color-scale-gray-7: rgb(22 22 24 / 100%);
--color-scale-blue-8: rgb(16 185 129 / 15%);
/*! Extensions from @primer/css/alerts/flash.scss */
--color-social-reaction-bg-hover: var(--color-scale-gray-7);
--color-social-reaction-bg-reacted-hover: var(--color-scale-blue-8);
}
main .pagination-loader-container {
background-image: url("https://github.com/images/modules/pulls/progressive-disclosure-line-dark.svg");
}
main .gsc-loading-image {
background-image: url("https://github.githubassets.com/images/mona-loading-dark.gif");
}
.gsc-comment-box-buttons a {
border-radius: 0.25rem !important;
}

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