first commit

This commit is contained in:
2026-04-13 08:32:28 +02:00
commit 1074a91487
72 changed files with 4078 additions and 0 deletions

103
scripts/generate_assets.py Normal file
View File

@@ -0,0 +1,103 @@
from __future__ import annotations
import struct
import zlib
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1] / "app" / "static" / "images"
def png_chunk(tag: bytes, data: bytes) -> bytes:
return struct.pack("!I", len(data)) + tag + data + struct.pack("!I", zlib.crc32(tag + data) & 0xFFFFFFFF)
def save_png(path: Path, width: int, height: int, rgba_rows: list[bytes]) -> None:
raw = b"".join(b"\x00" + row for row in rgba_rows)
header = struct.pack("!IIBBBBB", width, height, 8, 6, 0, 0, 0)
content = b"".join(
[
b"\x89PNG\r\n\x1a\n",
png_chunk(b"IHDR", header),
png_chunk(b"IDAT", zlib.compress(raw, 9)),
png_chunk(b"IEND", b""),
]
)
path.write_bytes(content)
def lerp(a: int, b: int, t: float) -> int:
return int(a + (b - a) * t)
def rounded_square_icon(size: int) -> list[bytes]:
rows = []
radius = size * 0.22
for y in range(size):
row = bytearray()
for x in range(size):
dx = min(x, size - 1 - x)
dy = min(y, size - 1 - y)
in_corner = (dx < radius and dy < radius)
if in_corner:
cx = radius - dx
cy = radius - dy
inside = cx * cx + cy * cy <= radius * radius
else:
inside = True
if not inside:
row.extend((0, 0, 0, 0))
continue
t = (x + y) / (2 * size)
r = lerp(37, 52, t)
g = lerp(99, 211, t)
b = lerp(235, 153, t)
if (x - size * 0.5) ** 2 + (y - size * 0.48) ** 2 < (size * 0.33) ** 2:
r, g, b = 250, 252, 255
roof = abs(x - size * 0.5) + (y - size * 0.40)
if roof < size * 0.19 and y < size * 0.55:
r, g, b = 37, 99, 235
if size * 0.33 < x < size * 0.67 and size * 0.52 < y < size * 0.80:
r, g, b = 159, 208, 255
star_x = x - size * 0.68
star_y = y - size * 0.28
if abs(star_x) + abs(star_y) < size * 0.06 or (abs(star_x) < size * 0.018 or abs(star_y) < size * 0.018):
r, g, b = 245, 158, 11
row.extend((r, g, b, 255))
rows.append(bytes(row))
return rows
def badge_icon(size: int) -> list[bytes]:
rows = []
radius = size * 0.48
cx = cy = size / 2
for y in range(size):
row = bytearray()
for x in range(size):
if (x - cx) ** 2 + (y - cy) ** 2 > radius ** 2:
row.extend((0, 0, 0, 0))
continue
row.extend((37, 99, 235, 255))
rows.append(bytes(row))
return rows
def main() -> None:
ROOT.mkdir(parents=True, exist_ok=True)
save_png(ROOT / "pwa-icon-192.png", 192, 192, rounded_square_icon(192))
save_png(Path(__file__).resolve().parents[1] / "icon.png", 256, 256, rounded_square_icon(256))
save_png(ROOT / "pwa-icon-512.png", 512, 512, rounded_square_icon(512))
save_png(ROOT / "apple-touch-icon.png", 180, 180, rounded_square_icon(180))
save_png(ROOT / "pwa-badge.png", 96, 96, badge_icon(96))
if __name__ == "__main__":
main()