Compare commits

..

5 Commits

Author SHA1 Message Date
FliegendeWurst
195317fe50 Expand raspi-oled post 2023-11-11 19:23:56 +01:00
FliegendeWurst
9dca5ea21c New project card layout 2023-11-11 19:13:36 +01:00
FliegendeWurst
54197286ef Hide tmp folder from robots 2023-11-09 12:15:07 +01:00
FliegendeWurst
2e7df4c403 Recent activity section 2023-11-09 12:14:56 +01:00
FliegendeWurst
cfe9a124b6 Update kv 2023-11-09 11:38:46 +01:00
24 changed files with 1258 additions and 28 deletions

9
activity.json Normal file
View File

@ -0,0 +1,9 @@
[
{
"date": "2023-10-06",
"title": "amplified_fixed: Noise parameters to reduce flooded caves in Minecraft amplified generation",
"target": "https://github.com/FliegendeWurst/amplified_fixed",
"type": "project"
}
]

View File

@ -1,7 +1,7 @@
+++
title = "Raspberry Pi 0 W + sensors + OLED display = temperature monitoring and calendar"
date = 2022-10-05
updated = 2023-10-02
updated = 2023-11-11
+++
<img id="hero-img" alt="OLED display showing temperature and upcoming appointments, connected to a Raspberry Pi" src="/assets/raspberry-pi-temperature-monitoring.jpg">
@ -22,10 +22,10 @@ When activating another display mode (not active in the picture), this area of t
<li>yellow push switch: TRU Components PBS-18B 701912</li>
</ul>
The components are connected to the Pi as indicated in the wiring diagram below.
The components are connected to the Pi as indicated in the wiring diagram below (made using [Circuit Diagram](https://www.circuit-diagram.org/)).
<embed
style="background: white;"
class="white-svg"
type="image/svg+xml"
src="/assets/circuit.svg"
title="Wiring diagram">
@ -50,7 +50,7 @@ Wiring of the AM2302 to the RPi:
Wiring of the push switch to the Pi: one pin to GPIO 19, the other to 3.3V.
<h3>Software</h3>
### Software
The Raspberry Pi 0 W is running <a href="https://www.raspberrypi.com/software/">Raspberry Pi OS</a> 11 (bullseye).
@ -74,7 +74,7 @@ It is run by another Python script (<a href="https://gist.github.com/FliegendeWu
Below is the crontab of the pi user. status_check is run every five minutes. take_measurement is run every ten minutes. Fifteen minutes into the hour, any new calendar entries are synced using refresh_json. To avoid OLED burn-in, the display is turned off every minute (if it was on previously).
```cron
```
*/5 * * * * /home/pi/status_check /home/pi/sensors.db 2>/dev/null >/dev/null
*/10 * * * * /home/pi/take_measurement /home/pi/sensors.db
15 * * * * /home/pi/refresh_json --no-weekly
@ -91,7 +91,7 @@ The binaries (and the libraries they depend on) may be copied to the Pi like thi
```
mkdir /tmp/nixstore
nix copy --extra-experimental-features nix-command --extra-experimental-features flakes --no-check-sigs --to /tmp/nixstore $(readlink -f result)
nix copy --extra-experimental-features nix-command flakes --no-check-sigs --to /tmp/nixstore $(readlink -f result)
rsync -r --links --info=progress /tmp/nixstore/nix pi@himbeere-null:~/
```
@ -102,4 +102,40 @@ patchelf --set-interpreter /lib/ld-musl-armhf.so.1 nix/store/*-raspi-oled-*/bin/
sudo mv nix /
```
### Enclosure
<img class="content-img-tall" alt="3D model of the case" src="/assets/raspberry-pi-case.png">
To make the whole setup look a bit nicer, I designed a casing using [OpenSCAD](https://openscad.org/).
The image on the right shows the final result as rendered by OpenSCAD ([.scad](/assets/RPi-Zero.scad)).
[Raspberry Pi 0 W - Slim Case](https://www.thingiverse.com/thing:4199739) (by OhSnap) proved to be a great base to build on.
I added some supports around it to ensure it won't topple over as easily.
Since I was too lazy to measure the dimensions of my OLED display, I extracted the relevant part of [Zoid, the Trapezoidal Under Cabinet 1.5" OLED Display](https://www.thingiverse.com/thing:3397089) (by rhattie).
Feeling a little bit fancy, I decided to add some inset icons underneath.
The pin holes will be useful to add some status LEDs later.
Because one button will soon not be enough control, I added three button holders on the top.
A library near me offers a 3D printing service so it was easy to get the case printed.
The new buttons and LEDs will need to be wired up to some unused GPIO pins.
All LEDs are connected using a single resistor since these will only turn on rarely and even more rarely at the same time.
<embed
class="white-svg"
type="image/svg+xml"
src="/assets/circuit_new.svg"
title="Wiring diagram">
To make full use of the three buttons, I came up with a simple one/two-step selection menu to get to the most important functionality.
1. Show time table and large clock
1. (unused)
2. Show temperature chart
3. Show upcoming events
2. Dismiss active action
3. Show TOTP codes
1. Next page
2. (unused)
3. Show RPi screensaver
This post will be updated soon™ to show to the final 3D print (which required some adjustments not yet mentioned).

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="142" height="20" role="img" aria-label="GitHub: FliegendeWurst"><title>GitHub: FliegendeWurst</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="142" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="47" height="20" fill="#555"/><rect x="47" width="95" height="20" fill="white"/><rect width="142" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="245" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">GitHub</text><text x="245" y="140" transform="scale(.1)" fill="#fff" textLength="370">GitHub</text><text aria-hidden="true" x="935" y="150" fill="#ccc" fill-opacity=".3" transform="scale(.1)" textLength="850">FliegendeWurst</text><text x="935" y="140" transform="scale(.1)" fill="#333" textLength="850">FliegendeWurst</text></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="110" height="20" role="img" aria-label="GitLab: arnekeller"><title>GitLab: arnekeller</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="110" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="45" height="20" fill="#555"/><rect x="45" width="65" height="20" fill="white"/><rect width="110" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="235" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="350">GitLab</text><text x="235" y="140" transform="scale(.1)" fill="#fff" textLength="350">GitLab</text><text aria-hidden="true" x="765" y="150" fill="#ccc" fill-opacity=".3" transform="scale(.1)" textLength="550">arnekeller</text><text x="765" y="140" transform="scale(.1)" fill="#333" textLength="550">arnekeller</text></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
static/assets/Gitea.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="39" height="20" role="img" aria-label="Gitea"><title>Gitea</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="39" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="0" height="20" fill="#555"/><rect x="0" width="39" height="20" fill="#555"/><rect width="39" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="290">Gitea</text><text x="195" y="140" transform="scale(.1)" fill="#fff" textLength="290">Gitea</text></g></svg>

After

Width:  |  Height:  |  Size: 901 B

227
static/assets/RPi-Zero.scad Normal file
View File

@ -0,0 +1,227 @@
final = !$preview;
module pizero() {
difference() {
color("green") import("pizero-scase_new.stl");
if (final) {
translate([34.4, -25, 1.05]) cube([1,50,.5]);
translate([34.5, -25, 1.15]) cube([1,50,.5]);
translate([34.6, -25, 1.25]) cube([1,50,.5]);
translate([34.7, -25, 1.35]) cube([1,50,.5]);
translate([34.8, -25, 1.45]) cube([1,50,.5]);
// keep 4.75 - 5.45 = 0.7
h = 10.5;
translate([34.8, -25, 5.45]) cube([1,50,h]);
translate([34.7, -25, 5.55]) cube([1,50,h]);
translate([34.6, -25, 5.65]) cube([1,50,h]);
translate([34.5, -25, 5.75]) cube([1,50,h]);
translate([34.4, -25, 5.85]) cube([1,50,h]);
}
}
}
module oled_hole() {
intersection () {
translate([0,0,0]) import("OLED_Under_Cabinet.stl");
cube([48, 10, 40], center=true);
}
}
module led_hole() {
translate([-1.25, 19, 30]) {
rotate([90, 0, 0]) cylinder(10, .5, .5, center = true, $fn=32);
}
translate([1.25, 19, 30]) {
rotate([90, 0, 0]) cylinder(10, .5, .5, center = true, $fn=32);
}
}
module extender() {
difference() {
s = 90 - 8.5;
//s = 12.5;
h = s;
union() {
/*
translate([0, 19, 60]) {
color("red") rotate([90, 0, 0]) cylinder(10, 1, center = true);
}
*/
translate([0,0,8.5 + s/2]) linear_extrude(s, center=true) projection(cut = true) translate([0,0,-8]) pizero();
translate([33, -15, 8.5]) cube([1,30,s]);
for ( i = [ 1 : 6 ] ) {
w = 19.95;
color("red")
translate([33 + i/10, -w/2 + 0.65, 8.5 - i/10]) cube([0.7 - i/10,w,s]);
}
difference() {
union() {
translate([0,0,8]) cube([34*2,33,2], center=true);
translate([0,0,9]) cube([34*2,33,1], center=true);
}
union () {
scale([0.99, 0.99, 1]) pizero();
translate([-33,17.5,8.5]) cube([3.4,3.4,10], center=true);
translate([-34.9,16,8.5]) cube([3.4,3.4,10], center=true);
translate([33,17.5,8.5]) cube([3.4,3.4,10], center=true);
translate([34.9,16,8.5]) cube([3.4,3.4,10], center=true);
mirror([0,1,0]) {
translate([-33,17.5,8.5]) cube([3.4,3.4,10], center=true);
translate([-34.9,16,8.5]) cube([3.4,3.4,10], center=true);
translate([33,17.5,8.5]) cube([3.4,3.4,10], center=true);
translate([34.9,16,8.5]) cube([3.4,3.4,10], center=true);
}
translate([0,0,8.5]) cube([32*2,14.5*2,10],center=true);
translate([34,0,8.5]) cube([5,14.5*2,10],center=true);
}
}
}
translate([34.4, -25, 8.5]) cube([1,50,h]);
translate([0, 19, 60]) difference() {
cube([48,10,40], center=true);
oled_hole();
}
led_hole();
translate([-10,0,0]) {
led_hole();
}
translate([-20,0,0]) {
led_hole();
}
translate([10,0,0]) {
led_hole();
}
translate([20,0,0]) {
led_hole();
}
// cable hole
translate([35,0,70]) {
minkowski()
{
color("red") cube([5,5,2], center=true);
rotate([0,90,0]) cylinder(r1=2,r2=2,h=1, center=true, $fn=32);
}
}
// icons
translate([0, 17.9 - .5, 41]) {
scale = 0.19;
translate([-14, 0, 0]) scale([scale, 1, scale]) rotate([90,0,0]) linear_extrude(1) import("./rpi_logo.svg", center=true);
translate([-5, 0, 0]) scale([scale, 1, scale]) rotate([90,0,0]) linear_extrude(1) import("./Calendar_font_awesome.svg", center=true);
translate([5, 0, 0]) scale([scale, 1, scale]) rotate([90,0,0]) linear_extrude(1) import("./to cry.svg", center=true);
translate([14, 0, 0]) scale([scale, 1, scale]) mirror([1,0,0]) rotate([90,0,0]) linear_extrude(1) import("./temp.svg", center=true);
}
}
}
module button_hole() {
difference() {
cube([12.4 + 0.05, 12.4 + 0.05,5], center=true);
translate([6.05 + 0.05 / 2, -3.81, 0]) cube([0.3,2.6,5], center=true);
translate([6.05 + 0.05 / 2, 3.81, 0]) cube([0.3,2.6,5], center=true);
translate([-6.05 - 0.05 / 2, -3.81, 0]) cube([0.3,2.6,5], center=true);
translate([-6.05 - 0.05 / 2, 3.81, 0]) cube([0.3,2.6,5], center=true);
}
}
module hat() {
difference() {
translate([0,0,98.5]) mirror([0,0,1]) difference() {
union() {
pizero();
color("red") translate([33, -13.5, 2.65]) cube([1.4,27,5.85]);
color("red") translate([-33-1.4, -13.5, 2.65]) cube([1.4,27,5.85]);
color("red") translate([-30, -18.3+1.4, 2.4]) cube([60,1.4,5.85]);
translate([-30, -15, 0]) cube([60,30,1.4]);
translate([0,0,8.5]) difference() {
cube([66,32,4],center=true);
cube([63,28,4],center=true);
}
}
translate([34.4, -25, 1.05]) cube([1,50,5]);
translate([0, 0, 0]) button_hole();
translate([-20, 0, 0]) button_hole();
translate([20, 0, 0]) button_hole();
}
scale([0.99, 0.99, 1]) extender();
}
}
module sticks1(s=1) {
for ( i = [0 : 8] ){
if (i != 6) {
translate([33.7,0,20+i*8]) cube([s*.75,8,s*.75], center=true);
}
translate([-33.7,0,20+i*8]) cube([s*.75,8,s*.75], center=true);
}
}
module sticks2(s=1) {
translate([0,0,4]) sticks1(s);
}
module print1() {
difference() {
intersection() {
extender();
translate([0,50,0]) cube([1000,100,1000], center=true);
}
sticks2(1.05);
}
sticks1();
}
module print2() {
difference() {
intersection() {
extender();
mirror([0,1,0]) translate([0,50,0]) cube([1000,100,1000], center=true);
}
sticks1(1.05);
}
sticks2();
}
module print3() {
hat();
}
module pyramid() {
difference() {
union() {
for ( i = [0 : 8]) {
s = (8 - i) / 2;
translate([- s, - s, i * 0.5])
cube([4+s,4+s,.5]);
x = 2.5;
}
}
x = 2.6;
translate([4-x,4-x,1])
cube([x,x,4]);
}
}
module fixer() {
translate([0, 30, 1]) linear_extrude(2, center=true) circle(5, $fn=32);
translate([-15, 25, 1]) rotate([0,0,20])scale([1,0.1,1]) linear_extrude(2, center=true) circle(20, $fn=32);
mirror([1,0,0]) translate([-15, 25, 1]) rotate([0,0,20])scale([1,0.1,1]) linear_extrude(2, center=true) circle(20, $fn=32);
translate([0, 50, 1]) linear_extrude(2, center=true) circle(5, $fn=32);
translate([0, 40, 1]) rotate([0,0,90])scale([.7,0.1,1]) linear_extrude(2, center=true) circle(20, $fn=32);
}
module print4() {
difference() {
union() {
pizero();
translate([-34.4 , -16.9, 0]) pyramid();
translate([-34.4 , 16.9, 0]) rotate([0, 0, 270]) pyramid();
translate([34.4 , -16.9, 0]) rotate([0,0,90]) pyramid();
translate([34.4 , 16.9, 0]) rotate([0, 0, 180]) pyramid();
fixer();
mirror([0, 1, 0]) {
fixer();
}
}
translate([21.5, -17, 4.5]) cube([14, 4, 9], center=true);
translate([21.5, -25, 4.5]) cube([14,20, 7], center=true);
}
}
//rotate([-90,0,0]) print1();
//rotate([90,0,0]) print2();
//mirror([0,0,1]) print3();
//print4();
module all() {
print1();
print2();
print3();
print4();
}
all();

File diff suppressed because one or more lines are too long

12
static/assets/gitea.svg Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" id="main_outline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve">
<g>
<path id="teabag" style="fill:#FFFFFF" d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8 c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4 c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z"/>
<g>
<g>
<path style="fill:#609926" d="M622.7,149.8c-4.1-4.1-9.6-4-9.6-4s-117.2,6.6-177.9,8c-13.3,0.3-26.5,0.6-39.6,0.7c0,39.1,0,78.2,0,117.2 c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29,0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5 c-9.8-0.6-22.5-2.1-39,1.5c-8.7,1.8-33.5,7.4-53.8,26.9C-4.9,212.4,6.6,276.2,8,285.8c1.7,11.7,6.9,44.2,31.7,72.5 c45.8,56.1,144.4,54.8,144.4,54.8s12.1,28.9,30.6,55.5c25,33.1,50.7,58.9,75.7,62c63,0,188.9-0.1,188.9-0.1s12,0.1,28.3-10.3 c14-8.5,26.5-23.4,26.5-23.4s12.9-13.8,30.9-45.3c5.5-9.7,10.1-19.1,14.1-28c0,0,55.2-117.1,55.2-231.1 C633.2,157.9,624.7,151.8,622.7,149.8z M125.6,353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6,321.8,60,295.4 c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5,38.5-30c13.8-3.7,31-3.1,31-3.1s7.1,59.4,15.7,94.2c7.2,29.2,24.8,77.7,24.8,77.7 S142.5,359.9,125.6,353.9z M425.9,461.5c0,0-6.1,14.5-19.6,15.4c-5.8,0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55 c0,0-10.9-5.7-12.8-15.6c-2.2-8.1,2.7-18.1,2.7-18.1L322,273c0,0,4.8-9.7,12.2-13c0.6-0.3,2.3-1,4.5-1.5c8.1-2.1,18,2.8,18,2.8 l110.7,53.7c0,0,12.6,5.7,15.3,16.2c1.9,7.4-0.5,14-1.8,17.2C474.6,363.8,425.9,461.5,425.9,461.5z"/>
<path style="fill:#609926" d="M326.8,380.1c-8.2,0.1-15.4,5.8-17.3,13.8c-1.9,8,2,16.3,9.1,20c7.7,4,17.5,1.8,22.7-5.4 c5.1-7.1,4.3-16.9-1.8-23.1l24-49.1c1.5,0.1,3.7,0.2,6.2-0.5c4.1-0.9,7.1-3.6,7.1-3.6c4.2,1.8,8.6,3.8,13.2,6.1 c4.8,2.4,9.3,4.9,13.4,7.3c0.9,0.5,1.8,1.1,2.8,1.9c1.6,1.3,3.4,3.1,4.7,5.5c1.9,5.5-1.9,14.9-1.9,14.9 c-2.3,7.6-18.4,40.6-18.4,40.6c-8.1-0.2-15.3,5-17.7,12.5c-2.6,8.1,1.1,17.3,8.9,21.3c7.8,4,17.4,1.7,22.5-5.3 c5-6.8,4.6-16.3-1.1-22.6c1.9-3.7,3.7-7.4,5.6-11.3c5-10.4,13.5-30.4,13.5-30.4c0.9-1.7,5.7-10.3,2.7-21.3 c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7,9.4-19.3,14.1-29 c-4.1-2-8.1-4-12.2-6.1c-4.8,9.8-9.7,19.7-14.5,29.5c-6.7-0.1-12.9,3.5-16.1,9.4c-3.4,6.3-2.7,14.1,1.9,19.8 C343.2,346.5,335,363.3,326.8,380.1z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

3
static/assets/github.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 0C7.16 0 0 7.16 0 16C0 23.08 4.58 29.06 10.94 31.18C11.74 31.32 12.04 30.84 12.04 30.42C12.04 30.04 12.02 28.78 12.02 27.44C8 28.18 6.96 26.46 6.64 25.56C6.46 25.1 5.68 23.68 5 23.3C4.44 23 3.64 22.26 4.98 22.24C6.24 22.22 7.14 23.4 7.44 23.88C8.88 26.3 11.18 25.62 12.1 25.2C12.24 24.16 12.66 23.46 13.12 23.06C9.56 22.66 5.84 21.28 5.84 15.16C5.84 13.42 6.46 11.98 7.48 10.86C7.32 10.46 6.76 8.82 7.64 6.62C7.64 6.62 8.98 6.2 12.04 8.26C13.32 7.9 14.68 7.72 16.04 7.72C17.4 7.72 18.76 7.9 20.04 8.26C23.1 6.18 24.44 6.62 24.44 6.62C25.32 8.82 24.76 10.46 24.6 10.86C25.62 11.98 26.24 13.4 26.24 15.16C26.24 21.3 22.5 22.66 18.94 23.06C19.52 23.56 20.02 24.52 20.02 26.02C20.02 28.16 20 29.88 20 30.42C20 30.84 20.3 31.34 21.1 31.18C27.42 29.06 32 23.06 32 16C32 7.16 24.84 0 16 0V0Z" fill="#24292E"/>
</svg>

After

Width:  |  Height:  |  Size: 958 B

35
static/assets/gitlab.svg Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 32 32"
version="1.1"
id="svg1608"
width="32"
height="32"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1597">
<style
id="style1595">.cls-1{fill:#e24329;}.cls-2{fill:#fc6d26;}.cls-3{fill:#fca326;}</style>
</defs>
<g
id="LOGO"
transform="matrix(0.16662022,0,0,0.16662022,-15.657843,-15.659503)">
<path
class="cls-1"
d="m 282.83,170.73 -0.27,-0.69 -26.14,-68.22 a 6.81,6.81 0 0 0 -2.69,-3.24 7,7 0 0 0 -8,0.43 7,7 0 0 0 -2.32,3.52 l -17.65,54 h -71.47 l -17.65,-54 a 6.86,6.86 0 0 0 -2.32,-3.53 7,7 0 0 0 -8,-0.43 6.87,6.87 0 0 0 -2.69,3.24 L 97.44,170 l -0.26,0.69 a 48.54,48.54 0 0 0 16.1,56.1 l 0.09,0.07 0.24,0.17 39.82,29.82 19.7,14.91 12,9.06 a 8.07,8.07 0 0 0 9.76,0 l 12,-9.06 19.7,-14.91 40.06,-30 0.1,-0.08 a 48.56,48.56 0 0 0 16.08,-56.04 z"
id="path1599" />
<path
class="cls-2"
d="m 282.83,170.73 -0.27,-0.69 a 88.3,88.3 0 0 0 -35.15,15.8 L 190,229.25 c 19.55,14.79 36.57,27.64 36.57,27.64 l 40.06,-30 0.1,-0.08 a 48.56,48.56 0 0 0 16.1,-56.08 z"
id="path1601" />
<path
class="cls-3"
d="m 153.43,256.89 19.7,14.91 12,9.06 a 8.07,8.07 0 0 0 9.76,0 l 12,-9.06 19.7,-14.91 c 0,0 -17.04,-12.89 -36.59,-27.64 -19.55,14.75 -36.57,27.64 -36.57,27.64 z"
id="path1603" />
<path
class="cls-2"
d="M 132.58,185.84 A 88.19,88.19 0 0 0 97.44,170 l -0.26,0.69 a 48.54,48.54 0 0 0 16.1,56.1 l 0.09,0.07 0.24,0.17 39.82,29.82 c 0,0 17,-12.85 36.57,-27.64 z"
id="path1605" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
static/assets/header_KV.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
static/assets/header_YT.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
static/kv/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -3,7 +3,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>KV diagram calculator</title>
<link rel="shortcut icon" href="favicon.png">
<script type="module">import init from '/kv/svg-wasm-9785c6ab23ac38e3.js';init('/kv/svg-wasm-9785c6ab23ac38e3_bg.wasm');</script>
<script type="module">import init from '/kv/svg-wasm-90f0bdb88ed6bb6e.js';init('/kv/svg-wasm-90f0bdb88ed6bb6e_bg.wasm');</script>
<style>
textarea {
@ -34,8 +34,8 @@
}
</style>
<link rel="preload" href="/kv/svg-wasm-9785c6ab23ac38e3_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
<link rel="modulepreload" href="/kv/svg-wasm-9785c6ab23ac38e3.js"></head>
<link rel="preload" href="/kv/svg-wasm-90f0bdb88ed6bb6e_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
<link rel="modulepreload" href="/kv/svg-wasm-90f0bdb88ed6bb6e.js"></head>
<body>
<div><h1>KV diagram calculator</h1><a href="https://gitlab.kit.edu/uskyk/kv">(source code)</a></div>
<div id="main">

View File

@ -0,0 +1,23 @@
function handleTextChange(event) {
const target = event.target;
const value = target.value;
if (value.length == 0) {
target.value = "-";
} else {
target.value = value.substr(value.length - 1);
}
}
function handleTextScroll(event) {
const target = event.target;
const value = target.value;
if (event.deltaY < 0) {
target.value = "1"; // scroll up
} else {
target.value = "0"; // scroll down
}
event.preventDefault();
}
export function attachTypeListener(element) {
element.addEventListener("input", handleTextChange);
element.addEventListener("wheel", handleTextScroll);
}

View File

@ -0,0 +1,517 @@
import { attachTypeListener } from './snippets/kv-a60e45f081a1ffa1/base.js';
let wasm;
const heap = new Array(128).fill(undefined);
heap.push(undefined, null, true, false);
function getObject(idx) { return heap[idx]; }
let heap_next = heap.length;
function dropObject(idx) {
if (idx < 132) return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
let cachedUint8Memory0 = null;
function getUint8Memory0() {
if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8Memory0;
}
function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
heap_next = heap[idx];
heap[idx] = obj;
return idx;
}
function debugString(val) {
// primitive types
const type = typeof val;
if (type == 'number' || type == 'boolean' || val == null) {
return `${val}`;
}
if (type == 'string') {
return `"${val}"`;
}
if (type == 'symbol') {
const description = val.description;
if (description == null) {
return 'Symbol';
} else {
return `Symbol(${description})`;
}
}
if (type == 'function') {
const name = val.name;
if (typeof name == 'string' && name.length > 0) {
return `Function(${name})`;
} else {
return 'Function';
}
}
// objects
if (Array.isArray(val)) {
const length = val.length;
let debug = '[';
if (length > 0) {
debug += debugString(val[0]);
}
for(let i = 1; i < length; i++) {
debug += ', ' + debugString(val[i]);
}
debug += ']';
return debug;
}
// Test for built-in
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
let className;
if (builtInMatches.length > 1) {
className = builtInMatches[1];
} else {
// Failed to match the standard '[object ClassName]'
return toString.call(val);
}
if (className == 'Object') {
// we're a user defined class or Object
// JSON.stringify avoids problems with cycles, and is generally much
// easier than looping through ownProperties of `val`.
try {
return 'Object(' + JSON.stringify(val) + ')';
} catch (_) {
return 'Object';
}
}
// errors
if (val instanceof Error) {
return `${val.name}: ${val.message}\n${val.stack}`;
}
// TODO we could test for more things here, like `Set`s and `Map`s.
return className;
}
let WASM_VECTOR_LEN = 0;
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
? function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
}
: function (arg, view) {
const buf = cachedTextEncoder.encode(arg);
view.set(buf);
return {
read: arg.length,
written: buf.length
};
});
function passStringToWasm0(arg, malloc, realloc) {
if (realloc === undefined) {
const buf = cachedTextEncoder.encode(arg);
const ptr = malloc(buf.length, 1) >>> 0;
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
WASM_VECTOR_LEN = buf.length;
return ptr;
}
let len = arg.length;
let ptr = malloc(len, 1) >>> 0;
const mem = getUint8Memory0();
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
if (offset !== 0) {
arg = arg.slice(offset);
}
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
const ret = encodeString(arg, view);
offset += ret.written;
}
WASM_VECTOR_LEN = offset;
return ptr;
}
let cachedInt32Memory0 = null;
function getInt32Memory0() {
if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachedInt32Memory0;
}
function makeMutClosure(arg0, arg1, dtor, f) {
const state = { a: arg0, b: arg1, cnt: 1, dtor };
const real = (...args) => {
// First up with a closure we increment the internal reference
// count. This ensures that the Rust closure environment won't
// be deallocated while we're invoking it.
state.cnt++;
const a = state.a;
state.a = 0;
try {
return f(a, state.b, ...args);
} finally {
if (--state.cnt === 0) {
wasm.__wbindgen_export_2.get(state.dtor)(a, state.b);
} else {
state.a = a;
}
}
};
real.original = state;
return real;
}
function __wbg_adapter_14(arg0, arg1) {
wasm.wasm_bindgen__convert__closures__invoke0_mut__he079d9666a9767db(arg0, arg1);
}
function isLikeNone(x) {
return x === undefined || x === null;
}
function handleError(f, args) {
try {
return f.apply(this, args);
} catch (e) {
wasm.__wbindgen_exn_store(addHeapObject(e));
}
}
async function __wbg_load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
} catch (e) {
if (module.headers.get('Content-Type') != 'application/wasm') {
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
} else {
throw e;
}
}
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
}
function __wbg_get_imports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbg_attachTypeListener_065fda4bc7cf970c = function(arg0) {
attachTypeListener(getObject(arg0));
};
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
const ret = new Error();
return addHeapObject(ret);
};
imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) {
const ret = getObject(arg1).stack;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) {
let deferred0_0;
let deferred0_1;
try {
deferred0_0 = arg0;
deferred0_1 = arg1;
console.error(getStringFromWasm0(arg0, arg1));
} finally {
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
}
};
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
const ret = getStringFromWasm0(arg0, arg1);
return addHeapObject(ret);
};
imports.wbg.__wbg_location_7ac41949b772ef21 = function(arg0) {
const ret = getObject(arg0).location;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_createElement_4891554b28d3388b = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).createElement(getStringFromWasm0(arg1, arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_getElementById_cc0e0d931b0d9a28 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2));
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_setclassName_e7c93281fe6d80d6 = function(arg0, arg1, arg2) {
getObject(arg0).className = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_setinnerHTML_b089587252408b67 = function(arg0, arg1, arg2) {
getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_children_27ed308801b57d3f = function(arg0) {
const ret = getObject(arg0).children;
return addHeapObject(ret);
};
imports.wbg.__wbg_setAttribute_e7e80b478b7b8b2f = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_remove_48288e91662163dc = function(arg0) {
getObject(arg0).remove();
};
imports.wbg.__wbg_prepend_95c11a8ae7041c31 = function() { return handleError(function (arg0, arg1) {
getObject(arg0).prepend(getObject(arg1));
}, arguments) };
imports.wbg.__wbg_instanceof_Window_9029196b662bc42a = function(arg0) {
let result;
try {
result = getObject(arg0) instanceof Window;
} catch {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_document_f7ace2b956f30a4f = function(arg0) {
const ret = getObject(arg0).document;
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_location_56243dba507f472d = function(arg0) {
const ret = getObject(arg0).location;
return addHeapObject(ret);
};
imports.wbg.__wbg_setinnerText_1849424c2fdc16ec = function(arg0, arg1, arg2) {
getObject(arg0).innerText = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_style_3801009b2339aa94 = function(arg0) {
const ret = getObject(arg0).style;
return addHeapObject(ret);
};
imports.wbg.__wbg_checked_5ccb3a66eb054121 = function(arg0) {
const ret = getObject(arg0).checked;
return ret;
};
imports.wbg.__wbg_value_9423da9d988ee8cf = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setvalue_1f95e61cbc382f7f = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_debug_9a6b3243fbbebb61 = function(arg0) {
console.debug(getObject(arg0));
};
imports.wbg.__wbg_error_788ae33f81d3b84b = function(arg0) {
console.error(getObject(arg0));
};
imports.wbg.__wbg_info_2e30e8204b29d91d = function(arg0) {
console.info(getObject(arg0));
};
imports.wbg.__wbg_log_1d3ae0273d8f4f8a = function(arg0) {
console.log(getObject(arg0));
};
imports.wbg.__wbg_warn_d60e832f9882c1b2 = function(arg0) {
console.warn(getObject(arg0));
};
imports.wbg.__wbg_hash_a1a795b89dda8e3d = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg1).hash;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
}, arguments) };
imports.wbg.__wbg_sethash_b6135fe95fa0eebe = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).hash = getStringFromWasm0(arg1, arg2);
}, arguments) };
imports.wbg.__wbg_appendChild_51339d4cde00ee22 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).appendChild(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_value_3c5f08ffc2b7d6f9 = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setvalue_0dc100d4b9908028 = function(arg0, arg1, arg2) {
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_addEventListener_5651108fc3ffeb6e = function() { return handleError(function (arg0, arg1, arg2, arg3) {
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3));
}, arguments) };
imports.wbg.__wbg_length_b37ae9be90ea7cf5 = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
imports.wbg.__wbg_item_3364fbfadbf2cf08 = function(arg0, arg1) {
const ret = getObject(arg0).item(arg1 >>> 0);
return isLikeNone(ret) ? 0 : addHeapObject(ret);
};
imports.wbg.__wbg_value_c45528fab757534f = function(arg0, arg1) {
const ret = getObject(arg1).value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_setProperty_b95ef63ab852879e = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
getObject(arg0).setProperty(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_newnoargs_581967eacc0e2604 = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_call_cb65541d95d71282 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).call(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
const ret = getObject(arg0);
return addHeapObject(ret);
};
imports.wbg.__wbg_self_1ff1d729e9aae938 = function() { return handleError(function () {
const ret = self.self;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_window_5f4faef6c12b79ec = function() { return handleError(function () {
const ret = window.window;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_globalThis_1d39714405582d3c = function() { return handleError(function () {
const ret = globalThis.globalThis;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_global_651f05c6a0944d1c = function() { return handleError(function () {
const ret = global.global;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbindgen_is_undefined = function(arg0) {
const ret = getObject(arg0) === undefined;
return ret;
};
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
const ret = debugString(getObject(arg1));
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};
imports.wbg.__wbindgen_closure_wrapper87 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 36, __wbg_adapter_14);
return addHeapObject(ret);
};
return imports;
}
function __wbg_init_memory(imports, maybe_memory) {
}
function __wbg_finalize_init(instance, module) {
wasm = instance.exports;
__wbg_init.__wbindgen_wasm_module = module;
cachedInt32Memory0 = null;
cachedUint8Memory0 = null;
wasm.__wbindgen_start();
return wasm;
}
function initSync(module) {
if (wasm !== undefined) return wasm;
const imports = __wbg_get_imports();
__wbg_init_memory(imports);
if (!(module instanceof WebAssembly.Module)) {
module = new WebAssembly.Module(module);
}
const instance = new WebAssembly.Instance(module, imports);
return __wbg_finalize_init(instance, module);
}
async function __wbg_init(input) {
if (wasm !== undefined) return wasm;
if (typeof input === 'undefined') {
input = new URL('svg-wasm-90f0bdb88ed6bb6e_bg.wasm', import.meta.url);
}
const imports = __wbg_get_imports();
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
input = fetch(input);
}
__wbg_init_memory(imports);
const { instance, module } = await __wbg_load(await input, imports);
return __wbg_finalize_init(instance, module);
}
export { initSync }
export default __wbg_init;

Binary file not shown.

View File

@ -10,10 +10,6 @@
align-items: center;
}
article {
max-width: 45em;
}
main {
max-width: 60em;
margin-left: auto;
@ -28,6 +24,11 @@ main {
width: 30em;
padding: 3em;
}
.content-img-tall {
width: 30%;
padding: 1em;
float: right;
}
.fancy-name, .code {
font-family: monospace;
@ -39,6 +40,58 @@ main {
padding-top: 0.5em;
}
img.activity-favicon, img.activity-favicon-transparent {
width: 1em;
}
ul.hide-decoration, ul.nopad {
padding-left: 0px;
}
ul.nopad {
margin-bottom: 0px;
}
li.hide-decoration {
list-style-type: none;
padding-bottom: .4em;
}
#card-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
row-gap: 1em;
justify-items: center;
}
.card {
background-color: #eeebe4;
border: 2px solid #dcb900;
border-radius: 5px;
width: 300px;
padding: 0.5em;
}
.card-image {
width: 300px;
max-height: 150px;
}
@media screen and (min-width: 1010px) {
.card, .card-image {
width: 450px;
}
.card-image {
max-height: 225px;
}
}
@media screen and (max-width: 710px) {
#card-container {
grid-template-columns: repeat(1, 1fr);
}
}
@media print {
body {
background-color: white;
@ -50,13 +103,22 @@ main {
color: #fff;
background-color: #000;
}
main {
background-color: #222;
--background-color: #222;
}
.card {
background-color: #333;
--background-color: #333;
border: 2px solid rebeccapurple;
}
a {
color: #aaf;
}
a:visited {
color: #faf;
}
main {
background-color: #222;
.white-svg, .activity-favicon {
filter: invert();
}
}

View File

@ -14,13 +14,19 @@
{% block content %} {% endblock %}
<hr>
<center>
<a href="https://github.com/FliegendeWurst/"><img src="/assets/GitHub FliegendeWurst.svg"></a>
<a href="https://gitlab.com/arnekeller"><img src="/assets/GitLab arnekeller.svg"></a>
<a href="https://git.fliegendewurst.eu/explore/repos"><img src="/assets/Gitea.svg"></a>
<br>
<small>
© FliegendeWurst, 2022-2023.
© FliegendeWurst, 2022-2023 (excluding evident exceptions).
Source: <a href="https://github.com/FliegendeWurst/fliegendewurst.eu">github.com/FliegendeWurst/fliegendewurst.eu</a>.
<br>
This work is licensed under a
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
Creative Commons Attribution 4.0 International License</a>.
<br>
<small>Website design inspired by <a href="https://isabelroses.com/">Isabel Roses</a>'s website and <a href="https://utdemir.com/">Utku Demir</a>'s website.</small>
</small>
</center>
</main>

View File

@ -15,14 +15,49 @@
<li><a href="https://gist.github.com/FliegendeWurst/6548c71a0f21a60183dbdd2bb7be16db">Repairing the filesystem on my TV's hard disk</a></li>
</ul>
Projects
<p>Projects</p>
<div id="card-container">
<div class="card">
<img class="card-image" src="/assets/header_qwörtle.png" alt="screenshot of Qwörtle game">
<h2>Qwörtle</h2>
German version of <a href="https://www.quordle.com/">Quordle</a>.
<ul class="nopad">
<li class="hide-decoration"><img alt="" class="activity-favicon-transparent pure-img" src="/assets/gitea.svg"> <small><a href="https://git.fliegendewurst.eu/arnekeller/qw%C3%B6rtle">Repository</a></small></li>
<li class="hide-decoration"><img alt="" class="activity-favicon-transparent pure-img" src="/assets/Exquisite-opera.png"> <small><a href="/qwörtle/">Web</a></small></li>
</ul>
</div>
<div class="card">
<img class="card-image" src="/assets/header_YT.jpg" alt="screenshot of YT with less distractions">
<h2>Youtube Addiction Control</h2>
Firefox extension to hide various UI elements on Youtube.
<ul class="nopad">
<li class="hide-decoration"><img alt="" class="activity-favicon-transparent pure-img" src="/assets/gitlab.svg"> <small><a href="https://gitlab.com/arnekeller/yt-addiction-control">Repository</a></small></li>
<li class="hide-decoration"><img alt="" class="activity-favicon-transparent pure-img" src="/assets/Exquisite-opera.png"> <small><a href="https://addons.mozilla.org/en-US/firefox/addon/youtube-addiction-control/">Mozilla Addons</a></small></li>
</ul>
</div>
<div class="card">
<img class="card-image" src="/assets/header_KV.jpg" alt="example KV diagram">
<h2>kv</h2>
CLI/web tool to generate DMF/KMF based on a <a href="https://en.wikipedia.org/wiki/Karnaugh_map">KV diagram</a>.
<ul class="nopad">
<li class="hide-decoration"><img alt="" class="activity-favicon-transparent pure-img" src="/assets/gitlab.svg"> <small><a href="https://gitlab.kit.edu/uskyk/kv">Repository</a></small></li>
<li class="hide-decoration"><img alt="" class="activity-favicon-transparent pure-img" src="/assets/Exquisite-opera.png"> <small><a href="/kv/">Web</a></small></li>
</ul>
</div>
<div class="card">
<img class="card-image" src="/assets/header_ILIAS.jpg" alt="ILIAS logo next to donkey">
<h2>KIT-ILIAS-downloader</h2>
CLI tool to download files from <a href="https://www.kit.edu/">KIT</a>'s e-learning site.
<p>Definitely not a horse.</p>
<ul class="nopad">
<li class="hide-decoration"><img alt="" class="activity-favicon pure-img" src="/assets/github.svg"> <small><a href="https://github.com/FliegendeWurst/KIT-ILIAS-downloader">Repository</a></small></li>
</ul>
</div>
</div>
<ul>
<li> <a href="https://fliegendewurst.eu/qw%C3%B6rtle/">Qwörtle</a>, a German version of Quordle</li>
<li> <a href="https://github.com/FliegendeWurst/KIT-ILIAS-downloader">KIT-ILIAS-downloader</a>, a tool to download files from the KIT's e-learning site </li>
<li> <a href="https://gitlab.com/arnekeller/yt-addiction-control">YT addiction control</a> (<a href="https://addons.mozilla.org/en-US/firefox/addon/youtube-addiction-control/">download</a>), Firefox extension to reduce Youtube's addiction potential by hiding video suggestions </li>
<li> <a href="{{ get_url(path='@/blog/raspberry-pi-temperature-monitoring.md') }}">raspi-oled</a>, a clock/calendar/temperature display built using a Raspberry Pi </li>
<li> <a href="https://gitlab.kit.edu/uskyk/kv">kv</a>, a small CLI tool / web app to create <a href="https://en.wikipedia.org/wiki/Karnaugh_map">KV diagrams</a> (<a href="https://fliegendewurst.eu/kv/">try it online!</a>) </li>
<li> <a href="https://github.com/FliegendeWurst/telegram_notes_bot">telegram_notes_bot</a>, a Telegram bot to interact with a <a href="https://github.com/zadam/trilium">Trilium Notes</a> database (reminders, todos, etc.) </li>
<li> <a href="https://github.com/FliegendeWurst/ripgrep-all/tree/mail-adapter">mail adapter</a> for ripgrep-all, really convenient to search mails <i>and</i> their attachments </li>
<li> <a href="https://github.com/FliegendeWurst/naviki-gpx-download">Naviki GPX downloader</a>, to download all recorded tracks </li>
<li> <a href="https://github.com/FliegendeWurst/borg-homedir-excludes">borg-homedir-excludes</a>, a list of cache/trash directories that are not worth backing up </li>
@ -33,22 +68,30 @@ Projects
<li> <a href="https://gitlab.com/arnekeller/symlink-dupes">symlink-dupes</a>, creates symbolic links for equal files in a directory </li>
<li> <a href="https://gitlab.com/arnekeller/kwin-toggle-window">kwin-toggle-window</a>, toggle visibility of a specific window with a hotkey </li>
<li> <a href="https://gitlab.com/arnekeller/microsoft-ergonomic-keyboard">microsoft-ergonomic-keyboard</a>, a small kernel module to re-interpret one of the keys on my keyboard </li>
<li> <a href="https://github.com/FliegendeWurst/telegram_notes_bot">telegram_notes_bot</a>, a Telegram bot to interact with a <a href="https://github.com/zadam/trilium">Trilium Notes</a> database (reminders, todos, etc.) </li>
<li> <a href="https://github.com/FliegendeWurst/bwinf.35.1">bwinf.35.1</a>, my solutions to a computer science contest </li>
<li> Minecraft mods: <ul>
<li> <a href="https://github.com/FliegendeWurst/ServerTPS">ServerTPS</a>, displays server TPS estimate and client threads status </li>
<li> <a href="https://github.com/FliegendeWurst/AsyncLighting">AsyncLighting</a>, a hack to queue up re-light events (= more FPS) </li>
</ul>
</ul>
Old projects:
<ul>
<li> <a href="https://github.com/FliegendeWurst/bwinf.35.1">bwinf.35.1</a>, my solutions to a computer science contest </li>
Recent activity
<ul class="hide-decoration">
{% set data = load_data(path="activity.json") %}
{% set printed = 0 %}
{% for x in data %}
{% if printed < 10 %}
<li class="hide-decoration"><img alt="" class="activity-favicon pure-img" src="/assets/github.svg"> <small>{{x.date | date(format="%Y-%m") }}</small> <a href="{{x.target}}">{{ x.title }}</a></li>
{% endif %}
{% set printed = printed + 1 %}
{% endfor %}
</ul>
Links: <a href="https://github.com/FliegendeWurst">GitHub profile</a>, <a href="https://gitlab.com/arnekeller">GitLab profile</a>, <a href="https://git.fliegendewurst.eu/explore/repos" rel="nofollow">Gitea instance</a>, <a href="https://www.boincstats.com/stats/-5/user/detail/86482458946/overview">BOINC contributions</a>.
<br>
<!-- <a href="https://www.boincstats.com/stats/-5/user/detail/86482458946/overview">BOINC contributions</a> -->
<!--
<img src="https://www.boincstats.com/signature/-5/user/86482458946/project/sig.png" alt="BOINC profile">
-->
{% endblock content %}

7
templates/robots.txt Normal file
View File

@ -0,0 +1,7 @@
User-agent: *
Disallow:
Allow: /
Sitemap: {{ get_url(path="sitemap.xml") }}
User-agent: *
Disallow: /tmp/