Compare commits

..
26 Commits
Author SHA1 Message Date
libretech 7ae2a9964a 223015c 02: layer 1 (bit) ergänzt, tabellen-refactor, http/2.0, dimmed/klausur-klassen 2026-05-22 09:47:58 +02:00
libretech abc8dece9c 223015b 01: edit-müll raus (style-tag-injection + eof-tippfehler) 2026-05-15 22:06:58 +02:00
libretech a5f890ae24 hdm fixes 2026-05-15 09:44:50 +02:00
libretech 56901d6068 update logos 2026-05-14 22:58:35 +02:00
libretech 2184870e0b dhbw 01-intro: über-mich collage refresh + wording-fixes + index-script polish
- collage.png neu: 11 marken (3 spalten brick-staggered + breite kombi-row für klett+pons+langenscheidt), normalisiert mit padding rechts, dhbw-dark + uni-stuttgart-dark variants (light-svgs unsichtbar auf weiß)
- neue logos: pons.svg (wikimedia, ersetzt gecropptes pons.jpg), bosch.svg, leibniz-fh.svg (alle wikimedia), hdm.jpg, libretech.png (gitea avatar), nextlevelshit.png (github avatar), pons-langenscheidt-klett.png (kombi)
- 01-intro slide: "Web App" -> "Web Applikation" (PWA-fachbegriff bleibt), "Betriebssystem (GNU/Linux, Windows, macOS, iOS, Android)" als erste kategorie ergänzt + OSs aus desktop/mobile rausgezogen, "ODER" -> "XOR"
- scripts/generate-index: dhbw spezifisch — KONTAKT_URL/LABEL pro course, QR_IMG-pfad pro course, footer 'Kursübersicht'-link conditional auf BREADCRUMB_URL, dhbw-subtitle ohne hdm-modul-name
2026-05-09 20:47:03 +02:00
libretech 755aadbc6a scripts/generate-index: per-course BREADCRUMB_URL + EXAM_URL/EXAM_LABEL — dhbw ohne 'kursübersicht'-link (ging fälschlich auf homepage), dhbw mit prüfungsleistung-link (git.librete.ch/DHBW/pruefungsleistung) 2026-05-08 21:49:55 +02:00
libretech 3554908246 scripts/generate-index: dhbw-case ergänzt (web engineering, dhbw stuttgart, himbeer-akzent, sitzung statt kapitel), HEADLINE+INSTITUTION+KAPITEL_TERM pro course, dhbw-topics in TOPIC_MAP (html-css, js-frameworks, nodejs-basics, express, testing, typescript, docker, best-practices) 2026-05-08 21:39:55 +02:00
libretech 2ac3303167 dhbw: file-namen auf dash-convention vereinheitlicht (consistent mit hdm), Makefile dhbw_KAPITEL aktualisiert 2026-05-08 21:36:59 +02:00
libretech 7970ba84d1 dhbw 09_best_practices: qr-code-folie nach cover + url unter cover, mirror hdm-pattern 2026-05-08 13:57:44 +02:00
libretech bb7c2730ca dhbw 08_docker: qr-code-folie nach cover + url unter cover, mirror hdm-pattern 2026-05-08 13:57:14 +02:00
libretech 4f4e989721 dhbw 07_typescript: qr-code-folie nach cover + url unter cover, mirror hdm-pattern 2026-05-08 13:56:42 +02:00
libretech 32a633188a dhbw 06_testing: qr-code-folie nach cover + url unter cover, mirror hdm-pattern 2026-05-08 13:56:09 +02:00
libretech 8ae050baad dhbw 05_express: qr-code-folie nach cover + url unter cover, mirror hdm-pattern 2026-05-08 13:55:33 +02:00
libretech 19d05252ef dhbw 04_nodejs_basics: qr-code-folie nach cover + url unter cover, mirror hdm-pattern 2026-05-08 13:54:53 +02:00
libretech e1c75a1ba3 dhbw 03_js_frameworks: qr-code-folie nach cover + url unter cover, mirror hdm-pattern 2026-05-08 13:54:17 +02:00
libretech c21a073984 dhbw 02_html_css: qr-code-folie nach cover + url unter cover, mirror hdm-pattern 2026-05-08 13:53:36 +02:00
libretech bd473fc890 dhbw 01_intro: qr-code-folie nach cover (zeigt auf librete.ch/dhbw/) + url unter cover, mirror hdm-pattern 2026-05-08 13:52:40 +02:00
libretech 95ff4a08d7 dhbw assets: qr-code zu librete.ch/dhbw/ (slides-dhbw.png) für post-cover-folien 2026-05-08 13:51:54 +02:00
libretech 29403e0f78 dhbw 01_intro: was-keine-webapp-folie auf * statt - bullets für marp-fragmented-list 2026-05-08 13:35:44 +02:00
libretech 0a7730ad9a dhbw 01_intro: vorstellungsrunde-folie zwischen über-mich und vorlesungsplan (gap aus original-PDF slide 4 — wer bist du, was machst du) 2026-05-08 13:32:43 +02:00
libretech c4c6119b8a dhbw 01_intro: was-ist-keine-webapp-block (cover + content) zwischen prüfungsleistung-abgabe und internet-timeline (gap aus original-PDF slides 8/9) 2026-05-08 13:30:43 +02:00
libretech a830480100 dhbw 01_intro: erwartungen-und-wünsche-folie zwischen vorlesungsplan und prüfungsleistung (gap aus original-PDF slide 6) 2026-05-08 13:27:46 +02:00
libretech a56b487bd4 dhbw 01_intro: editor-folie titel präzisiert (Editor → Editor (IDE)) 2026-05-08 13:24:27 +02:00
libretech 81f233b61a dhbw slides: 1 file pro sitzung (issue #2)
01_web_eng.md (103 slides) aufgesplittet:
- 01_intro.md: cover, ueber-mich, vorlesungsplan, pruefungsleistung, internet 101, onboarding
- 02_html_css.md: html, a11y/wcag, css basics + css extended (aus 02_css_extended.md gemergt)
- 03_js_frameworks.md: ecmascript, js, dom, fetch, async, frameworks, build tools, microfrontends

renames (03-08 -> 04-09):
- 03_nodejs_basics -> 04_nodejs_basics
- 04_nodejs_advanced -> 05_express
- 05_testing -> 06_testing
- 06_typescript -> 07_typescript
- 07_docker -> 08_docker
- 08_best_practices -> 09_best_practices

02_css_extended.md geloescht (inhalte in 02_html_css.md)
makefile: dhbw_KAPITEL + dhbw_NAME aktualisiert
2026-05-08 09:06:19 +02:00
libretech 0774b8652d dhbw 01: pruefungsleistung aktualisiert (100 basis + 15 bonus statt 75+10)
punkteverteilung nach source-of-truth (git.librete.ch/DHBW/pruefungsleistung):
- grundanforderungen 30p (projektgrundlagen 15 + praesentation 15)
- clean code 25p (struktur 10 + qualitaet 10 + doku 5)
- accessibility & ux 25p (a11y 15 + responsive 10) — neu
- technische umsetzung 20p — neu
- bonus max 15p (6 bereiche statt 8, je 5p)
2026-05-08 08:54:40 +02:00
libretech dde33f108f dhbw 01: fix pruefungsleistung link (git.librete.ch) 2026-05-08 08:46:23 +02:00
37 changed files with 1573 additions and 1274 deletions

No files matched your search

+2 -2
View File
@@ -22,8 +22,8 @@ DEPLOY_HOST = tengo@tuttle.uberspace.de
223015c_DEPLOY = /home/tengo/html/hdm/223015c
223015c_KLAUSUR = 1
dhbw_NAME = Technik I – Grundlagen IT
dhbw_KAPITEL = 01_web_eng 02_css_extended 03_nodejs_basics 04_nodejs_advanced 05_testing 06_typescript 07_docker 08_best_practices
dhbw_NAME = Web Engineering
dhbw_KAPITEL = 01-intro 02-html-css 03-js-frameworks 04-nodejs-basics 05-express 06-testing 07-typescript 08-docker 09-best-practices
dhbw_DEPLOY = /home/tengo/html/dhbw
dhbw_KLAUSUR =
+92 -9
View File
@@ -13,6 +13,15 @@ case "$COURSE" in
SLIDES_URL="https://librete.ch/hdm/223015b"
ACCENT_COLOR="#1e5f8a"
ACCENT_LIGHT="#e8f4fc"
INSTITUTION="HdM Stuttgart"
HEADLINE="HdM Vorlesungen"
KAPITEL_TERM="Kapitel"
BREADCRUMB_URL="../"
EXAM_URL=""
EXAM_LABEL=""
KONTAKT_URL="mailto:mail@librete.ch"
KONTAKT_LABEL="Kontakt"
QR_IMG="qr-index.svg"
;;
223015c)
TITLE="Grundlagen IT- und Internettechnik"
@@ -20,16 +29,72 @@ case "$COURSE" in
SLIDES_URL="https://librete.ch/hdm/223015c"
ACCENT_COLOR="#d63384"
ACCENT_LIGHT="#fce4ec"
INSTITUTION="HdM Stuttgart"
HEADLINE="HdM Vorlesungen"
KAPITEL_TERM="Kapitel"
BREADCRUMB_URL="../"
EXAM_URL=""
EXAM_LABEL=""
KONTAKT_URL="mailto:mail@librete.ch"
KONTAKT_LABEL="Kontakt"
QR_IMG="qr-index.svg"
;;
dhbw)
TITLE="Web Engineering"
SUBTITLE="Informatik / Wirtschaftsinformatik"
SLIDES_URL="https://librete.ch/dhbw"
ACCENT_COLOR="#a02060"
ACCENT_LIGHT="#fce4ec"
INSTITUTION="DHBW Stuttgart"
HEADLINE="DHBW Vorlesungen"
KAPITEL_TERM="Sitzung"
BREADCRUMB_URL=""
EXAM_URL="https://git.librete.ch/DHBW/pruefungsleistung"
EXAM_LABEL="Prüfungsleistung"
KONTAKT_URL="mailto:michael.czechowski@lehre.dhbw-stuttgart.de"
KONTAKT_LABEL="Kontakt"
QR_IMG="assets/slides-dhbw.png"
;;
*)
TITLE="$COURSE - HdM Slides"
TITLE="$COURSE - Slides"
SUBTITLE="Lecture Slides"
SLIDES_URL="https://librete.ch/hdm/$COURSE"
SLIDES_URL="https://librete.ch/$COURSE"
ACCENT_COLOR="#0066cc"
ACCENT_LIGHT="#e8f4fc"
INSTITUTION="Stuttgart"
HEADLINE="Vorlesungen"
KAPITEL_TERM="Kapitel"
BREADCRUMB_URL=""
EXAM_URL=""
EXAM_LABEL=""
KONTAKT_URL="mailto:mail@librete.ch"
KONTAKT_LABEL="Kontakt"
QR_IMG="qr-index.svg"
;;
esac
# Optional breadcrumb HTML (empty if no parent overview)
if [[ -n "$BREADCRUMB_URL" ]]; then
BREADCRUMB_HTML="<p class=\"breadcrumb\"><a href=\"$BREADCRUMB_URL\">← Kursübersicht</a></p>"
else
BREADCRUMB_HTML=""
fi
# Optional exam-link HTML
if [[ -n "$EXAM_URL" ]]; then
EXAM_HTML="<p class=\"exam-link\"><a href=\"$EXAM_URL\">$EXAM_LABEL →</a></p>"
else
EXAM_HTML=""
fi
# Footer kursübersicht link only when breadcrumb parent exists
if [[ -n "$BREADCRUMB_URL" ]]; then
FOOTER_KURS_HTML=" ·
<a href=\"$BREADCRUMB_URL\">Kursübersicht</a>"
else
FOOTER_KURS_HTML=""
fi
# Topic mappings for nice German titles
declare -A TOPIC_MAP
TOPIC_MAP["intro"]="Einführung"
@@ -41,6 +106,14 @@ TOPIC_MAP["vertiefung-offene-fragen"]="Vertiefung & Offene Fragen"
TOPIC_MAP["geschichte-grundlagen-html"]="Geschichte, Grundlagen & HTML"
TOPIC_MAP["netzwerke-protokolle-css"]="Netzwerke, Protokolle & CSS"
TOPIC_MAP["interaktivitaet-javascript"]="Interaktivität & JavaScript"
TOPIC_MAP["html-css"]="HTML & CSS"
TOPIC_MAP["js-frameworks"]="JS, Frameworks & Build Tools"
TOPIC_MAP["nodejs-basics"]="Node.js: Scripting, Running & Building"
TOPIC_MAP["express"]="Express API, CRUD & Middlewares"
TOPIC_MAP["testing"]="Testing"
TOPIC_MAP["typescript"]="TypeScript"
TOPIC_MAP["docker"]="Docker, Proxies & DBs"
TOPIC_MAP["best-practices"]="Wrap-up & Best Practices"
# Configure which topics should appear disabled per course
# Two modes: fully disabled (non-clickable card) and buttons-disabled (link remains clickable, buttons are disabled)
@@ -101,6 +174,16 @@ cat > "$BUILD_DIR/index.html" << HEADER
font-size: 0.875rem;
margin-top: 0.25rem;
}
.exam-link {
margin-top: 1rem;
font-size: 0.95rem;
}
.exam-link a {
color: $ACCENT_COLOR;
text-decoration: none;
font-weight: 500;
}
.exam-link a:hover { text-decoration: underline; }
/* Use the .termine wrapper and add a gap between cards */
.termine {
margin-top: 1.5rem;
@@ -226,11 +309,12 @@ cat > "$BUILD_DIR/index.html" << HEADER
</head>
<body>
<header>
<p class="breadcrumb"><a href="../">← Kursübersicht</a></p>
<h1>HdM Vorlesungen</h1>
$BREADCRUMB_HTML
<h1>$HEADLINE</h1>
<h2 class="course-heading">$TITLE</h2>
<p class="subtitle">$SUBTITLE</p>
<p class="meta">HdM Stuttgart · Sommersemester 2026 · Michael Czechowski</p>
<p class="meta">$INSTITUTION · Sommersemester 2026 · Michael Czechowski</p>
$EXAM_HTML
</header>
<div class="termine">
HEADER
@@ -253,7 +337,7 @@ for html in $(ls "$BUILD_DIR"/[0-9][0-9]-*.html 2>/dev/null | sort); do
if [[ "$kapitel_num" == "0" ]] || [[ -z "$kapitel_num" ]]; then
kapitel_label="Einführung"
else
kapitel_label="Kapitel $kapitel_num"
kapitel_label="$KAPITEL_TERM $kapitel_num"
fi
pdf_filename="${filename%.html}.pdf"
@@ -363,12 +447,11 @@ fi
cat >> "$BUILD_DIR/index.html" << FOOTER
</div>
<div class="qr-section">
<img src="qr-index.svg" alt="QR Code" class="qr-code">
<img src="$QR_IMG" alt="QR Code" class="qr-code">
<p class="qr-url">$SLIDES_URL</p>
</div>
<footer>
<a href="mailto:mail@librete.ch">Kontakt</a> ·
<a href="../">Kursübersicht</a>
<a href="$KONTAKT_URL">$KONTAKT_LABEL</a>$FOOTER_KURS_HTML
</footer>
</body>
</html>
+2 -72
View File
@@ -9,6 +9,7 @@ title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
---
<style>
:root {
--color-foreground: #1a1a2e;
--color-highlight: #1e5f8a;
@@ -1191,33 +1192,6 @@ Sog. RGB Tuple (geordnete endliche Liste)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/byte-nibble-hex.png)
<!--
Kernidee: jedes Byte lässt sich sauber in zwei 4-Bit-Hälften (Nibbles) zerlegen. Jede Hälfte hat 2⁴ = 16 Zustände – und genau 16 Symbole hat Hex (0-F). Deshalb passt Hex perfekt: 1 Nibble = 1 Hex-Ziffer, 1 Byte = 2 Hex-Ziffern. Keine krumme Umrechnung.
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/why-8-bit.png)
<!--
Warum gerade 8 Bit?
- CPU adressiert byteweise — kleinste adressierbare Einheit
- Halbe Byte (z.B. 0x0000.5) existieren nicht
- Speichercontroller, Bus, CPU-Register alle auf 8-Bit-Häppchen ausgelegt
- Einzelne Bit lesen: erst Byte holen, dann mit Bitmaske isolieren (byte & 0b1000_0000)
- Hardware-Geschichte: IBM System/360 (1964) setzte 8-Bit-Standard, 7-Bit-ASCII + 1 Paritätsbit
-->
---
<!-- _class: lead -->
# Hexadezimal
@@ -1249,50 +1223,6 @@ Warum gerade 8 Bit?
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/hex-dec-table.png)
<!--
Hex ↔ Dezimal Lookup-Tabelle: 0–F = 0–15
A=10, B=11, C=12, D=13, E=14, F=15
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/byte-flow.png)
<!--
1 Byte = 8 Bit = 2 Hex-Ziffern = 1 ASCII-Zeichen
- Dieselbe Datei, drei Schreibweisen
- Jeder Rahmen = ein Byte
- Byte ändern sich nicht, nur unsere Anzeige
- ↵ (0x0A) = nicht druckbar → Hex-Editoren zeigen . als Platzhalter
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/three-views.png)
<!--
Dieselben 8 Byte (PNG-Dateianfang: 89 50 4E 47 0D 0A 1A 0A) — drei Perspektiven:
1. Bitstream — was wirklich gespeichert wird (unleserlich)
2. Hex — gruppiert in 8-Bit-Häppchen (kompakt)
3. Bedeutung — was die Byte signalisieren:
- 89: Magic Byte (>127 → "ich bin Binärdatei")
- 50 4E 47: P N G (ASCII-Format-Kürzel)
- 0D 0A 1A 0A: CR LF EOF LF (erkennt kaputte Übertragung)
-->
---
# Wo begegnet Ihnen Hex-Code?
| Kontext | Beispiel |
@@ -2143,4 +2073,4 @@ Vollständige Lizenz: https://creativecommons.org/licenses/by-sa/4.0/
- hex5: ZIP (50 4B 03 04)
- Gruppenarbeit: 3-4 Personen
- Ziel: Hex-Dump lesen lernen, Dateiformate verstehen
-->
-->
-41
View File
@@ -713,11 +713,6 @@ KLAUSURRELEVANT:
---
<!-- _class: klausur -->
<!-- _header: '' -->
<!-- _footer: '' -->
<!-- _backgroundColor: #e3f2fd -->
# JPEG Schritt 6: Huffman-Coding
**Verlustfreie Kompression der Restwerte**
@@ -770,40 +765,6 @@ JPEG verwendet zwei Huffman-Tabellen: eine für DC-Koeffizienten (Durchschnittsw
---
<!-- _class: klausur -->
<!-- _header: '' -->
<!-- _footer: '' -->
<!-- _backgroundColor: #e3f2fd -->
<!--
# Huffman-Coding: Beispiel
**Originaltext:** `ABRACADABRA` (11 Zeichen × 8 Bit = 88 Bit)
**Häufigkeitsanalyse:**
A=5, B=2, R=2, C=1, D=1
**Huffman-Baum → Codes:**
| Zeichen | Häufigkeit | Code |
|---------|------------|------|
| A | 5 | `0` |
| B | 2 | `10` |
| R | 2 | `110` |
| C | 1 | `1110` |
| D | 1 | `1111` |
**Codiert:** `0 10 110 0 1110 0 1111 0 10 110 0` = **23 Bit**
**Kompression:** 88 → 23 Bit = **74% gespart**
- Beispiel Schritt für Schritt durchrechnen
- Warum funktioniert's? A kommt 5× vor, bekommt kürzesten Code
- Präfix-Eigenschaft: Kein Code ist Anfang eines anderen → eindeutig dekodierbar
- Frage: "Was passiert, wenn alle Zeichen gleich häufig sind?" → Keine Ersparnis
- In JPEG: Nicht Buchstaben, sondern DCT-Koeffizienten werden so codiert
-->
---
<!-- _header: '' -->
<!-- _footer: '' -->
@@ -824,8 +785,6 @@ A=5, B=2, R=2, C=1, D=1
# Andere Bildformate
## PNG, GIF, WebP, AVIF
15:33 Uhr weiter
<!--
- JPEG ist nicht für alles geeignet
- Jetzt: Alternativen und ihre Stärken
@@ -119,7 +119,7 @@ Hochschule der Medien Stuttgart
<!-- _class: lead -->
# Kapitel 3 – 23.01.2026
# Kapitel 3
## Speichermedien & Schnittstellen
---
@@ -369,8 +369,7 @@ Seitdem native Linux-Unterstützung.
**Features:**
- Journaling (Crash-Sicherheit)
- Dateirechte (ACLs)
- Kompression, Verschlüsselung
- Große Dateien und Volumes
- Kompression, Verschlüsselung, große Dateien und Volumes
**Nachteile:**
- Nur Windows schreibt nativ
@@ -629,11 +628,6 @@ Millionen von Websites und Spielen verloren.
- 30 Jahre Haltbarkeit
- Für Cold Storage ideal
**M-DISC:**
- Spezielle DVD/Blu-ray
- 1.000+ Jahre Haltbarkeit (Herstellerangabe)
- Für kleine, wichtige Daten
**Cloud:**
- Glacier, Backblaze B2
- Günstig für Langzeit
+76 -67
View File
@@ -91,6 +91,9 @@ section.erklaerung p {
section.erklaerung table {
font-size: 0.9rem;
}
section.dimmed {
opacity: 0.2;
}
</style>
<!-- _class: invert -->
@@ -197,26 +200,14 @@ SPEAKER NOTES:
Das Web folgt dem **Client-Server-Modell**: Ein Client (Browser) sendet einen **Request**, ein Server liefert eine **Response** – nach den Regeln eines **Protokolls**.
| Begriff | Was ist das? | Analogie |
|---------|--------------|----------|
| **Host** | Ein Rechner im Netz | Ein Haus mit Adresse |
| **Client** | Der, der fragt (Browser) | Gast im Restaurant |
| **Server** | Der, der antwortet | Küche im Restaurant |
| **Request** | Die Anfrage | Bestellung |
| **Response** | Die Antwort | Das Essen |
| **Protokoll** | Regeln für Kommunikation (z. B. TCP, HTTP) | Speisekarte + Bestellablauf |
<!--
SPEAKER NOTES:
- 6 Grundbegriffe – tauchen überall auf
- Client/Server = Grundstruktur des Webs
- Browser = Client
- Google/HdM/Netflix = Server
- Request/Response = Kommunikationsmuster
- Protokoll = Regelwerk
- Analogie: Restaurant in Japan ohne Regeln zu kennen
- Host = Rechner mit Adresse im Netz
-->
| Begriff | Was ist das? |
|---------------|--------------------------------------------------------------------------|
| **Host** | Ein netzwerkfähiger Rechner (Laptop, Smartphone, Display in S-Bahn etc.) |
| **Client** | Host bzw. Anwendung mit einer Anfrage (bspw. Browser) |
| **Server** | Host bzw. Anwendung mit der Antwort (bspw. Webserver) |
| **Request** | Die Anfrage des Clients |
| **Response** | Die Antwort des Servers |
| **Protokoll** | Regeln für Kommunikation (z. B. TCP, HTTP) |
---
@@ -253,13 +244,15 @@ SPEAKER NOTES:
Daten werden Schicht für Schicht verpackt — jede Schicht fügt einen eigenen **Header** hinzu und erzeugt so eine neue Dateneinheit.
| Begriff | Was ist das? | Schicht |
|---------|--------------|---------|
| **Paket** | Daten + IP-Header | Internet (Layer 3) |
| **Segment** | Daten + TCP-Header | Transport (Layer 4) |
| **Frame** | Daten + MAC-Header | Netzzugang (Layer 2) |
| **Header** | Metadaten am Anfang | Jede Schicht |
| **Payload** | Die eigentlichen Nutzdaten | Der Inhalt |
| Begriff | Was ist das? | Schicht |
|-------------|-------------------------------------------------------|--------------------------|
| **Payload** | Die eigentlichen Nutzdaten (bspw. Request, Response) | Anwendung |
| **Header** | Metadaten vor und nach dem Payload | Jedes Layer |
| **Segment** | Payload + TCP-Header (Anwendungsport) | Transport (Layer 4) |
| **Paket** | Payload + IP-Header (WLAN-Router) | Internet (Layer 3) |
| **Frame** | Payload + MAC-Header (Netzwerkkarte) | Netzzugang (Layer 2) |
| **Bit** | Abfolge von Signalen (Licht, Strom, Kabel, Mobilfunk) | Bitübertragung (Layer 1) |
<!--
SPEAKER NOTES:
@@ -268,7 +261,6 @@ SPEAKER NOTES:
- Header = Metadaten (wer, wohin, wie groß)
- Paket/Segment/Frame = gleiche Daten, verschiedene Verpackung
- Wie Matroschka: Schicht packt Schicht ein
- Wird klarer beim Schichtenmodell gleich
-->
---
@@ -279,13 +271,13 @@ SPEAKER NOTES:
**Latenz** und **Bandbreite** bestimmen, wie schnell Daten ankommen — Latenz misst die Verzögerung, Bandbreite die Kapazität.
| Begriff | Was ist das? | Einheit |
|---------|--------------|---------|
| **Latenz** | Verzögerung (hin + zurück) | Millisekunden |
| **Bandbreite** | Datenmenge pro Zeiteinheit | Mbit/s |
| **Hop** | Ein Sprung zum nächsten Router | – |
| **Round-Trip** | Hin- und Rückweg | – |
| **Ping** | "Bist du da?" + Antwort | ms |
| Begriff | Was ist das? | Einheit |
|----------------|-------------------------------------------------|--------------------|
| **Latenz** | Verzögerung (hin + zurück) | Millisekunden (ms) |
| **Bandbreite** | Datenmenge pro Zeiteinheit | Mbit/s |
| **Hop** | Ein Sprung zum nächsten Router (im Internet) | – |
| **Round-Trip** | Hin- und Rückweg | – |
| **Ping** | Client sendet "ping", bekommt von Server "pong" | ms |
<!--
SPEAKER NOTES:
@@ -309,14 +301,17 @@ SPEAKER NOTES:
Protokolle regeln die Kommunikation auf jeder Schicht — von der Anwendung (HTTP) über den Transport (TCP/UDP) bis zum Routing (IP).
| Protokoll | Wofür? | Port | Schicht |
|-----------|--------|------|---------|
| **HTTP** | Webseiten übertragen | 80 | Anwendung |
| **HTTPS** | HTTP + Verschlüsselung | 443 | Anwendung |
| **TCP** | Zuverlässige Übertragung | – | Transport |
| **UDP** | Schnelle Übertragung | – | Transport |
| **IP** | Routing durchs Internet | – | Internet |
| **DNS** | Namen → IP-Adressen | 53 | Anwendung |
| Protokoll | Wofür? | Port | Schicht |
|-----------|--------------------------------|------|---------------------|
| **HTTP** | Webseiten + Inhalte übertragen | 80 | Anwendung (Layer 4) |
| **HTTPS** | HTTP + Verschlüsselung | 443 | Anwendung (Layer 4) |
| **DNS** | Namen → IP-Adressen | 53 | Anwendung (Layer 4) |
| **TCP** | Zuverlässige Übertragung | – | Transport (Layer 4) |
| **UDP** | Schnelle Übertragung | – | Transport (Layer 4) |
| **IP** | Routing durchs Internet | – | Internet (Layer 3) |
<i><small>HTTP(S) = Hypertext Transfer Protocol (Secure)</small> · <small>DNS = Domain Name System</small> · <small>TCP = Transmission Control Protocol</small> · <small>UDP = User Datagram Protocol</small> · <small>IP = Internet Protocol</small>
</i>
<!--
SPEAKER NOTES:
@@ -402,12 +397,12 @@ SPEAKER NOTES:
# Das TCP/IP-Modell
| Schicht | Name | Aufgabe | Protokolle |
|---------|------|---------|------------|
| **4** | Anwendung | Was? Welcher Dienst? | HTTP, DNS, SMTP |
| **3** | Transport | Zuverlässigkeit, Ports | TCP, UDP |
| **2** | Internet | Routing, globale Adressen | IP |
| **1** | Netzzugang | Lokale Übertragung | Ethernet, WLAN |
| Schicht | Name | Aufgabe | Protokolle |
|---------|------|------------------------------------------|-------------------|
| **4** | Anwendung | Dienste steuern, Daten austauschen etc. | HTTP, DNS, SMTP |
| **3** | Transport | Zuverlässige Verbindung aufbauen (Ports) | TCP, UDP |
| **2** | Internet | Routing, global eindeutige Adressen | IP |
| **1** | Netzzugang | Lokale Übertragung | Ethernet, WLAN |
Jede Schicht hat genau eine Aufgabe und nutzt nur die Schicht direkt darunter.
@@ -419,12 +414,11 @@ SPEAKER NOTES:
- Transport: Kommt an? Welches Programm? (TCP, UDP)
- Internet: Wie zum Zielrechner? (IP)
- Netzzugang: Wie zum nächsten Gerät? (Ethernet, WLAN)
- KLAUSUR: Welches Protokoll → welche Schicht
-->
---
<!-- _class: erklaerung -->
<!-- _class: "erklaerung dimmed" -->
<!-- _header: '' -->
<!-- _footer: '' -->
@@ -1009,7 +1003,7 @@ SPEAKER NOTES:
# Was Ihr Browser sendet
```http
GET / HTTP/1.1
GET / HTTP/2.0
Host: www.hdm-stuttgart.de
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html
@@ -1109,6 +1103,9 @@ SPEAKER NOTES:
---
<!-- _class: dimmed -->
# Woher kennt Ihr Laptop die Router-MAC?
**ARP** – Address Resolution Protocol
@@ -1441,6 +1438,8 @@ SPEAKER NOTES:
---
<!-- _class: dimmed -->
# MTU & Fragmentierung
**MTU** = Maximum Transmission Unit
@@ -1465,21 +1464,24 @@ SPEAKER NOTES:
---
<!-- _class: klausur -->
<!-- _header: '' -->
<!-- _footer: '' -->
# HTTP-Methoden
HTTP-Methoden beschreiben, **was** der Client mit einer Ressource tun will.
| Methode | Bedeutung | Beispiel |
|---------|-----------|----------|
| **GET** | Daten abrufen | Seite laden |
| **POST** | Daten senden | Formular absenden |
| **PUT** | Daten ersetzen | Profil aktualisieren |
| **DELETE** | Daten löschen | Account löschen |
| Methode | Bedeutung | Beispiel |
|---------|-----------|-----------------------------------------------|
| **GET** | Daten abrufen | Seite laden `GET /index.html HTTP/2.0` |
| **POST** | Daten senden | Formular absenden `POST /login HTTP/2.0` |
| **PUT** | Daten ersetzen | Profil aktualisieren `PUT /users/42 HTTP/2.0` |
| **DELETE** | Daten löschen | Account löschen `DELETE /users/42 HTTP/2.0` |
<small>CRUD = Create, Read, Update, Delete</small>
```http
GET /index.html HTTP/1.1
POST /login HTTP/1.1
```
<!--
SPEAKER NOTES:
@@ -1528,14 +1530,18 @@ POST /users → Neuen Benutzer erstellen
---
<!-- _class: klausur -->
<!-- _header: '' -->
<!-- _footer: '' -->
# HTTP Status-Codes
Jede HTTP-Response enthält einen dreistelligen Status-Code — die erste Ziffer verrät die Kategorie.
```http
HTTP/1.1 200 OK
HTTP/1.1 404 Not Found
HTTP/1.1 500 Internal Server Error
HTTP/2.0 200 OK
HTTP/2.0 404 Not Found
HTTP/2.0 500 Internal Server Error
```
| Code-Bereich | Bedeutung |
@@ -1586,6 +1592,9 @@ Die erste Ziffer kategorisiert die Antwort:
---
<!-- _class: dimmed -->
# Zusammenfassung Teil 1
**Der Ablauf:**
@@ -1632,11 +1641,11 @@ Die vier Kernkonzepte für Web-Entwickelnde:
- Caching auf jeder Ebene (TTL = Time To Live)
**2. TCP-Verbindungsaufbau:**
- 3-Way-Handshake vor jeder HTTP-Anfrage (HTTP/1.1)
- 3-Way-Handshake vor jeder HTTP(S)-Anfrage (HTTP/2.0)
- Keep-Alive: Verbindung bleibt offen für mehrere Requests
- HTTP/2: Multiplexing – viele Requests über eine Verbindung
**3. HTTP Request/Response:**
**3. HTTP(S) Request/Response:**
```
Request: Methode + URL + Header + (Body)
Response: Status + Header + Body
+666
View File
@@ -0,0 +1,666 @@
---
marp: true
theme: gaia
paginate: true
backgroundColor: #fff
header: "Web Engineering – DHBW Stuttgart"
footer: "Michael Czechowski – SoSe 2026"
title: Intro
---
<style>
:root {
--color-foreground: #1a1a2e;
--color-highlight: #d63384;
--color-dimmed: #4a4a6a;
}
section.invert {
--color-foreground: #fff;
}
section {
font-size: 1.4rem;
}
h1 {
color: #a02060;
}
section.invert h1 {
color: #fff;
}
h2 {
color: #1f2937;
}
section.invert h2 {
color: #f48fb1;
}
pre {
background: #0f0f23;
color: #f48fb1;
border-radius: 8px;
border-left: 3px solid #d63384;
}
pre code {
background: transparent;
color: inherit;
}
code {
background: #1a1a2e;
color: #f48fb1;
padding: 0.15em 0.4em;
border-radius: 4px;
}
a {
color: var(--color-highlight);
}
</style>
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
![bg cover opacity:0.2](./assets/background.png)
# Web Engineering
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
**Sommersemester 2026**
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
# Ressourcen zum Selbstlernen
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
- **MDN** (Mozilla Developer Network) — [developer.mozilla.org/de/](https://developer.mozilla.org/de/)
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
---
<!-- _class: lead -->
# Herzlich Willkommen!
## 1. Sitzung: 08.05.2026
---
# Über mich
![bg right:33% fit](./assets/logos/collage.png)
**Michael Werner Czechowski**
- Systems and Platform Engineer
- Schwerpunkte:
- Web-Technologien, Barriere-Armut, Open Source
- Hintergrund:
- Philosophie (Uni Stuttgart)
- Wirtschaftsinformatik (Leibniz-FH Hannover)
- Honorardozent (DHBW Stuttgart, HdM Stuttgart, Leibniz-FH)
- Kontakt: michael.czechowski@lehre.dhbw-stuttgart.de
---
# Vorstellungsrunde
## Wer bist du, was machst du?
> Ich bin \_\_\_, mache bei \_\_\_ \_\_\_ und ein Fun Fact über mich ist, dass ich ...
- ... sämtliche One Piece Bände gelesen habe.
- ... alle XKCD Comics mit Titel kenne.
- ... irgendwann bei \_\_\_ arbeiten möchte.
- ... Paulaner Spezi im Blindtest herausschmecken kann.
---
# Vorlesungsplan
<style scoped>
.lp-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
margin-top: 0.5rem;
}
.lp-card {
border: 1px solid #d63384;
border-radius: 8px;
padding: 10px 12px;
background: #fff;
font-size: 0.95em;
display: flex;
flex-direction: column;
gap: 4px;
}
.lp-card .head {
font-weight: bold;
color: #a02060;
display: flex;
justify-content: space-between;
align-items: baseline;
font-size: 0.85em;
}
.lp-card .head .num {
font-size: 1.1em;
}
.lp-card .topic {
color: #1a1a2e;
line-height: 1.25;
}
.lp-card.milestone {
background: #fce4ec;
border-color: #a02060;
border-width: 2px;
}
.lp-card.milestone .topic {
font-weight: bold;
}
</style>
<div class="lp-grid">
<div class="lp-card"><div class="head"><span class="num">1</span><span>08.05.</span></div><div class="topic">Intro · Projektgruppen · Internet 101</div></div>
<div class="lp-card"><div class="head"><span class="num">2</span><span>15.05.</span></div><div class="topic">HTML und CSS (Frameworks)</div></div>
<div class="lp-card"><div class="head"><span class="num">3</span><span>22.05.</span></div><div class="topic">JS (Frameworks) und npm</div></div>
<div class="lp-card"><div class="head"><span class="num">4</span><span>29.05.</span></div><div class="topic">nodeJS: Scripting, Running, Building</div></div>
<div class="lp-card"><div class="head"><span class="num">5</span><span>05.06.</span></div><div class="topic">Express API, CRUD, Middlewares</div></div>
<div class="lp-card milestone"><div class="head"><span class="num">6</span><span>12.06.</span></div><div class="topic">Projektwerkstattbericht</div></div>
<div class="lp-card"><div class="head"><span class="num">7</span><span>19.06.</span></div><div class="topic">Testing (Unit · Integration · E2E)</div></div>
<div class="lp-card"><div class="head"><span class="num">8</span><span>26.06.</span></div><div class="topic">TypeScript</div></div>
<div class="lp-card"><div class="head"><span class="num">9</span><span>03.07.</span></div><div class="topic">Docker · Proxies · DBs</div></div>
<div class="lp-card"><div class="head"><span class="num">10</span><span>10.07.</span></div><div class="topic">Wrap-up & Projektsupport</div></div>
<div class="lp-card milestone"><div class="head"><span class="num">11</span><span>17.07.</span></div><div class="topic">Präsentation</div></div>
</div>
---
# Erwartungen und Wünsche
- Was haben wir bisher gelernt?
- Was kennen wir bereits aus dem Arbeitskontext?
- Welche Technologien nutzen wir bereits?
- Was möchte ich hier lernen: Frontend, Backend, DevOps?
- Eigene FOSS entwickeln?
- CLI-Skills verbessern?
- Cloud, Cloud, Cloud?
---
# Prüfungsleistung – Übersicht
Eigenes Projekt: **Web-Applikation** XOR **Backend** (API/CLI).
| Punkte | Bereich |
|--------|---------|
| 30 | Grundanforderungen (Projektgrundlagen + Präsentation) |
| 25 | Clean Code Prinzipien |
| 25 | Accessibility & UX |
| 20 | Technische Umsetzung |
| **100** | **Basispunkte** |
| +15 | Bonuspunkte (max. 3 Features a 5 P.) |
---
# Prüfungsleistung – Grundanforderungen (30 P.)
**Projektgrundlagen (15 P.)**
- Funktionsfähige Anwendung (8 P.)
- Repository mit Versionskontrolle (4 P.)
- Projektdokumentation / README (3 P.)
**Präsentation (15 P.)**
- Elevator Pitch (5 P.)
- Technische Präsentation (5 P.)
- Projektevolution: wie hat sich das Projekt vs. Ursprungsidee verändert? (5 P.)
---
# Prüfungsleistung – Clean Code (25 P.)
**Projektstruktur (10 P.)**
- Ordnerstruktur (5 P.)
- Datei-Organisation (5 P.)
**Code-Qualität (10 P.)**
- KISS – Keep It Simple, Stupid (3 P.)
- Beschreibende Namen (3 P.)
- Funktionsverantwortlichkeiten (4 P.)
**Kommentierung & Dokumentation (5 P.)**
---
# Prüfungsleistung – Accessibility & UX (25 P.)
**Web Accessibility (15 P.)**
- Semantisches HTML (5 P.)
- ARIA Labels & Alt-Texte (5 P.)
- Tastaturnavigation (5 P.)
**Responsive Design (10 P.)**
- Mobile First Approach (5 P.)
- Flexbox/Grid Layout (5 P.)
---
# Prüfungsleistung – Technische Umsetzung (20 P.)
- Plattformunabhängigkeit (5 P.)
- Package Management (5 P.)
- Build Tools & Optimierung (5 P.)
- Live-Demo (5 P.)
---
# Prüfungsleistung – Bonuspunkte (max. 15 P.)
Mindestens 2 Bereiche wählen, je 5 Punkte:
- API Integration
- Local Storage / State Management
- Progressive Web App Features
- Testing
- Erweiterte Responsive Features (3+ Breakpoints)
- Security Features
---
# Prüfungsleistung – Abgabe & Termine
- **Code-Upload:** bis 27.07.
- **Präsentation:** 17.07. (Gruppen, ~10 Min.)
Details: https://git.librete.ch/DHBW/pruefungsleistung
---
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# Was ist (k)eine Web Applikation?
## Exkurs
---
# Was ist (k)eine Web Applikation?
**Keine Web Applikation ist:**
* Betriebssystem (GNU/Linux, Windows, macOS, iOS, Android)
* Desktop-Applikation
* Mobile-Applikation
* Embedded System (Microcontroller, IoT)
**Eine Web Applikation ist:**
* plattformunabhängig (läuft im Browser)
* nutzt in der Regel HTTP-Requests
* keine Installation nötig — serverseitig aktualisiert
* gebaut in Web-Technologien (HTML, CSS, JS/TS)
* skalierbar durch verteilte Architektur
---
# Internet-Timeline
| Jahr | Meilenstein |
|------|-------------|
| **1966** | ARPANET-Projekt startet (DARPA) |
| **1969** | Erste Verbindung zwischen UCLA und Stanford |
| **1974** | TCP/IP-Protokoll entwickelt |
| **1989** | Tim Berners-Lee erfindet das WWW (CERN) |
| **1993** | Mosaic — erster grafischer Browser |
| **1994** | W3C gegründet (HTML, CSS, SVG, WCAG) |
| **1995** | ECMAScript / JavaScript wird Standard |
| **2008** | V8 JavaScript Engine (Chrome / Node.js) |
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/arpanet.jpg)
---
# Das WWW (1989)
**Tim Berners-Lee** am **CERN** (Genf)
**Problem:** Wissenschaftler:innen können Forschungsdokumente nicht verlinken — Inkompatible Systeme, kein gemeinsames Format.
**Lösung — drei Bausteine:**
- **HTML** — Auszeichnungssprache für Dokumente
- **HTTP** — Protokoll zur Übertragung
- **URL** — eindeutige Adressen
**1991:** erste Webseite geht online · 1993 vom CERN gemeinfrei freigegeben.
→ WWW ≠ Internet. Das WWW ist eine **Anwendung auf** dem Internet.
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/mosaic.jpg)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg cover](./assets/img_633d7b91366e0-1025x538-768x403.jpg)
---
# Heute: Physische Infrastruktur
- **5,5 Milliarden** Menschen online
- **> 400 Unterseekabel**, ca. **1,3 Mio. km** Glasfaser
- Daten reisen mit **Lichtgeschwindigkeit**
- Latenz Frankfurt — New York: ~80 ms
→ Keine "Cloud" ohne Kabel. Das Internet ist **physische** Infrastruktur — und damit angreifbar.
**Geopolitik:** Five-Eyes-Allianz (USA, UK, CA, AU, NZ) zapft Unterseekabel ab (Programm "Tempora", aufgedeckt 2013 durch Snowden). DE ist Teil der Fourteen Eyes.
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/browser-server-sequence.png)
---
# HTTP – Hypertext Transfer Protocol
**Request:**
```
GET /products HTTP/1.1
Host: localhost:8080
```
**Response:**
```
HTTP/1.1 200 OK
Content-Type: application/json
[{"id": 1, "name": "Produkt A"}, ...]
```
---
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# Onboarding
## Tools, Runtimes, Workflows
---
# Werkzeuge & Betriebssystem
**Erforderliche Werkzeuge:**
- **Terminal** (zsh / bash / fish / pwsh) — Kommandozeile
- **Editor** (siehe folgende Folie)
- **JavaScript-Runtime** (Node.js / Bun / Deno)
- **Browser mit DevTools** (Chromium / Firefox / Safari)
- **Git** — verteiltes Versionskontrollsystem (Stand der Industrie)
**OS-Empfehlung:**
| OS | Status |
|----|--------|
| **macOS** | First-class, viele Tools "just work" |
| **Linux** | First-class, beste Server-Parität |
| **Windows + WSL2** | Empfohlen — Windows-CLI hat Edge Cases |
| **Windows nativ** (PowerShell) | Funktioniert, aber holpriger Pfad |
---
# Node.js installieren – macOS
Empfohlen: **LTS** (aktuell **Node.js 24** — Stand 2026).
Paketmanager: **[Homebrew](https://brew.sh)**
```bash
# Homebrew installieren (falls nicht vorhanden)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Node.js LTS installieren
brew install node@24
# Version prüfen
node --version
npm --version
```
Alternative: Installer von [nodejs.org](https://nodejs.org)
---
# Node.js installieren – Linux
Empfohlen: **LTS** (aktuell **Node.js 24**).
**Debian / Ubuntu** ([NodeSource](https://github.com/nodesource/distributions)):
```bash
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
```
**Arch / Manjaro:**
```bash
sudo pacman -S nodejs npm
```
**Fedora / RHEL:**
```bash
sudo dnf module install nodejs:24/common
```
→ Distro-Pakete sind oft **veraltet**. Versionsmanager (folgende Folie) bevorzugen.
---
# Node.js installieren – Windows
Empfohlen: **LTS** (aktuell **Node.js 24**).
**Option 1: winget** (empfohlen, Win 10/11):
```powershell
winget install OpenJS.NodeJS.LTS
```
**Option 2: Chocolatey** ([chocolatey.org](https://chocolatey.org)):
```powershell
choco install nodejs-lts
```
**Option 3: Scoop** ([scoop.sh](https://scoop.sh)):
```powershell
scoop install nodejs-lts
```
**Option 4:** Installer von [nodejs.org](https://nodejs.org)
→ **Empfehlung:** WSL2 + Linux-Workflow nutzen.
---
# Direkt-Install: Wenn es eng wird
**Typisches Szenario** — drei parallele Projekte mit unterschiedlichen Anforderungen:
| Projekt | Stack | Node-Version |
|---------|-------|--------------|
| Praktikums-API | Express (Legacy) | 18.x (LTS Hydrogen) |
| Studienarbeit | Next.js 15 | 22.x (LTS Jod) |
| Aktuelles Lab-Projekt | neueste Features | 24.x (Iron, current LTS) |
System-Install kennt nur **eine** Node-Version global → Konflikt.
---
# Symptome im Alltag
- `npm install` bricht mit `engines`-Warning ab
- native Module (z. B. `node-sass`) bauen nicht
- CI-Pipeline ist grün, lokal rot — oder umgekehrt
- erheblicher Zeitverlust beim Debuggen von Versions-Konflikten
→ Lösung: **Versionsmanager** und Node-Version pro Projekt pinnen.
---
# Node-Versionsmanager
Verschiedene Projekte brauchen oft verschiedene Node-Versionen. **Lösung:** Versionsmanager.
| Tool | Sprache | Geschwindigkeit | Plattform |
|------|---------|-----------------|-----------|
| **nvm** | Bash | langsam (Shell-Funktion) | macOS, Linux |
| **fnm** | Rust | sehr schnell | macOS, Linux, Windows |
| **asdf** | Bash | mittel, multi-language | macOS, Linux |
| **volta** | Rust | schnell, pinning per `package.json` | alle |
```bash
# fnm
curl -fsSL https://fnm.vercel.app/install | bash
fnm install --lts # aktuell Node 24
fnm use lts-latest
# .nvmrc / .node-version automatisch
echo "lts/*" > .nvmrc
fnm use # liest .nvmrc
```
---
# Alternative Runtimes
| Runtime | Erschienen | Engine | USP |
|---------|------------|--------|-----|
| **Node.js** | 2009 | V8 (C++) | Standard, größtes Ökosystem |
| **Deno** | 2020 | V8 (Rust) | Sicherheit, TypeScript nativ, Std-Lib |
| **Bun** | 2022 | JavaScriptCore (Zig) | Geschwindigkeit, all-in-one |
```bash
# Deno
curl -fsSL https://deno.land/install.sh | sh
deno run main.ts
# Bun
curl -fsSL https://bun.sh/install | bash
bun install
bun run dev
```
→ Im Kurs primär **Node.js**. Bun und Deno sind ebenfalls zulässig.
---
# Editor (IDE)
- **VS Code** (empfohlen) — kostenlos, große Plugin-Auswahl
- **JetBrains WebStorm** — sehr mächtig, kostenpflichtig
- kostenlos für Studierende via [JetBrains Education](https://www.jetbrains.com/community/education/#students)
- **Vim / Neovim / Emacs** — für CLI-Profis
- **Zed** — modern, schnell
---
# Browser DevTools
Chromium / Firefox / Safari — `F12` oder `Cmd+Opt+I`
<small>Chromium = Open-Source-Basis von Chrome, Edge, Brave, Opera, Vivaldi etc.</small>
**Wichtigste Panels:**
- **Network** — HTTP-Requests, Responses, Timing
- **Console** — `console.log`, JS-Errors, REPL
- **Elements** — DOM-Inspektor, Live-CSS-Editor
- **Sources** — Debugger, Breakpoints, Source-Maps
- **Performance** — Profiling, Frame-Rate, FPS
- **Application** — LocalStorage, Cookies, Service Workers
---
# HTTP-Clients
- **Bruno** ([usebruno.com](https://usebruno.com)) — open source, git-friendly
- **Hoppscotch** ([hoppscotch.io](https://hoppscotch.io)) — open source, browser-basiert (vormals Postwoman)
- **Insomnia** / **Postman** — etabliert, freemium
- **curl** / **httpie** — CLI (Command-Line Interface, scriptbar)
---
# Git Setup & Workflow
**Einmalige Konfiguration:**
```bash
git config --global user.name "Vorname Nachname"
git config --global user.email "vorname.nachname@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase true
```
**SSH-Key für GitHub/GitLab:**
```bash
ssh-keygen -t ed25519 -C "vorname.nachname@example.com"
cat ~/.ssh/id_ed25519.pub # → in GitHub-Settings einfügen
```
**Tägliche Befehle:**
```bash
git status # was hat sich geändert?
git add <file> # für Commit vormerken
git commit -m "feat: ..." # Conventional Commits
git push # hochladen
git pull --rebase # neueste Änderungen holen
```
---
# Projekt-Skeleton
```bash
mkdir mein-projekt && cd mein-projekt
git init
npm init -y # erzeugt package.json
echo "node_modules" > .gitignore
echo ".env" >> .gitignore
npm install express
```
**`package.json` minimal:**
```json
{
"name": "mein-projekt",
"version": "0.1.0",
"type": "module",
"scripts": {
"start": "node index.js",
"dev": "node --watch index.js"
}
}
```
`.env` für Secrets (nie committen!), `.env.example` mit Dummy-Werten committen.
---
File diff suppressed because it is too large. Load diff
-292
View File
@@ -1,292 +0,0 @@
---
marp: true
theme: gaia
paginate: true
backgroundColor: #fff
header: "Web Engineering – DHBW Stuttgart"
footer: "Michael Czechowski – SoSe 2026"
---
<style>
:root {
--color-foreground: #1a1a2e;
--color-highlight: #d63384;
--color-dimmed: #4a4a6a;
}
section.invert {
--color-foreground: #fff;
}
section {
font-size: 1.4rem;
}
h1 {
color: #a02060;
}
section.invert h1 {
color: #fff;
}
h2 {
color: #1f2937;
}
section.invert h2 {
color: #f48fb1;
}
pre {
background: #0f0f23;
color: #f48fb1;
border-radius: 8px;
border-left: 3px solid #d63384;
}
pre code {
background: transparent;
color: inherit;
}
code {
background: #1a1a2e;
color: #f48fb1;
padding: 0.15em 0.4em;
border-radius: 4px;
}
a {
color: var(--color-highlight);
}
</style>
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# Web Engineering
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
**Sommersemester 2026** · Sitzung 2 — HTML & CSS (Frameworks)
---
# Ressourcen zum Selbstlernen
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
- **MDN** (Mozilla Developer Network) — [developer.mozilla.org/de/](https://developer.mozilla.org/de/)
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
---
# Inhalt
Aufbauend auf den Grundlagen aus Sitzung 1.
1. Attribut-Selektoren
2. Combinators (vertieft)
3. Pseudo-Klassen — erweitert
4. Shorthand Properties
5. Flexbox-Shorthands
6. Custom Properties (Variables)
7. CSS Functions (`calc`, `clamp`, ...)
8. Transition & Animation
9. CSS Frameworks (Tailwind & Co.)
---
<!-- _class: invert -->
<!-- _backgroundColor: #000 -->
# CSS: Extended
---
# CSS Selectors – Attribut-Selektoren
```css
/* presence */
[disabled] { opacity: 0.5; }
/* exact value */
[type="email"] { border-color: blue; }
/* contains word */
[class~="btn"] { cursor: pointer; }
/* starts with */
[href^="https"] { color: green; }
/* ends with */
[src$=".png"] { border: 1px solid #ccc; }
/* contains substring */
[class*="icon"] { padding-left: 20px; }
```
---
# CSS Combinators
```css
/* Child (direkt) */
div > p { margin: 0; }
/* Descendant (Nachkomme) */
div p { margin: 0; }
/* Next Sibling */
h1 + p { font-size: 1.2em; }
/* Subsequent Sibling */
h1 ~ p { color: #666; }
/* Selector List */
h1, h2, h3 { font-weight: bold; }
```
---
# Pseudo Classes – Erweitert
```css
/* Form States */
:valid { border-color: green; }
:invalid { border-color: red; }
:placeholder-shown { color: #999; }
/* Content */
:before { content: "→ "; }
:after { content: " [Wichtig]"; }
:first-letter { font-size: 2em; }
:first-line { font-weight: bold; }
/* NOT */
:not(.disabled) { pointer-events: auto; }
:not(:last-child) { border-bottom: 1px solid #ccc; }
```
---
# Shorthand Properties
```css
/* margin: top right bottom left */
margin: 10px 20px 10px 20px;
/* centering */
margin: 0 auto;
/* padding same */
padding: 20px;
/* border: width style color */
border: 1px solid #333;
/* background: color image position/size repeat */
background: #fff url(logo.png) 0 0 no-repeat;
/* font: style variant weight size/line-height family */
font: italic normal bold 16px/1.5 Arial, sans-serif;
```
---
# Flexbox Shorthands
```css
/* flex: grow shrink basis */
flex: 1 0 auto;
/* place-items: align-items justify-items */
place-items: center stretch;
/* place-content: align-content justify-content */
place-content: space-between center;
/* gap: row-gap column-gap */
gap: 20px 40px;
```
---
# CSS Custom Properties (Variables)
```css
:root {
--primary-color: #d63384;
--spacing: 20px;
--radius: 8px;
}
.button {
background: var(--primary-color);
padding: var(--spacing);
border-radius: var(--radius);
}
```
---
# CSS Functions
```css
/* calc */
width: calc(100% - 40px);
/* min/max/clamp */
width: min(100%, 600px);
font-size: clamp(14px, 2vw, 20px);
/* var with fallback */
color: var(--text-color, #333);
/* rgb/rgba/hsl/hsla */
color: hsl(200, 100%, 50%);
background: rgba(0, 0, 0, 0.5);
```
---
# Transition & Animation
```css
/* transition: property duration timing-function */
transition: all 0.3s ease-in-out;
transition: background 0.2s, transform 0.1s;
/* animation */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 0.5s ease-out;
}
```
---
# CSS Frameworks
| Framework | Stil |
|-----------|------|
| **Bootstrap** | Komponenten + Grid, opinionated |
| **Tailwind CSS** | Utility-First, atomar |
| **Bulma** | klassisch, ohne JS |
| **shadcn/ui** | kopierbare Komponenten (Tailwind-basiert) |
| **Flowbite** | Tailwind-Komponentenbib. |
---
# Tailwind CSS – Beispiel
```html
<button class="bg-blue-600 hover:bg-blue-700
text-white font-semibold
px-4 py-2 rounded-lg
transition shadow-sm">
Klick mich
</button>
```
- Keine eigenen CSS-Klassen mehr
- JIT-Compiler erzeugt nur genutzte Klassen
- Design-System via `tailwind.config.js`
+412
View File
@@ -0,0 +1,412 @@
---
marp: true
theme: gaia
paginate: true
backgroundColor: #fff
header: "Web Engineering – DHBW Stuttgart"
footer: "Michael Czechowski – SoSe 2026"
title: JavaScript & Frameworks
---
<style>
:root {
--color-foreground: #1a1a2e;
--color-highlight: #d63384;
--color-dimmed: #4a4a6a;
}
section.invert {
--color-foreground: #fff;
}
section {
font-size: 1.4rem;
}
h1 {
color: #a02060;
}
section.invert h1 {
color: #fff;
}
h2 {
color: #1f2937;
}
section.invert h2 {
color: #f48fb1;
}
pre {
background: #0f0f23;
color: #f48fb1;
border-radius: 8px;
border-left: 3px solid #d63384;
}
pre code {
background: transparent;
color: inherit;
}
code {
background: #1a1a2e;
color: #f48fb1;
padding: 0.15em 0.4em;
border-radius: 4px;
}
a {
color: var(--color-highlight);
}
</style>
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
![bg cover opacity:0.2](./assets/background.png)
# Web Engineering
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
**Sommersemester 2026** · Sitzung 3 — JS, Frameworks & Build Tools
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
# Ressourcen zum Selbstlernen
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
- **MDN** (Mozilla Developer Network) — [developer.mozilla.org/de/](https://developer.mozilla.org/de/)
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# JavaScript
---
# ECMAScript
- **Ecma International** — European Computer Manufacturers Association
- Seit **1997** standardisiert als **ECMA-262**
- Implementierungen: **JavaScript** (Netscape, später Mozilla), **JScript** (Microsoft), **ActionScript** (Adobe Flash) etc.
- Aktuelle Version: **ECMAScript 2024 (ES15)**, jährliche Releases
**Browser-Kompatibilität:**
- Faustregel: **ES2017+** läuft in allen modernen Browsern
- Ältere Targets via Transpiler (Babel, esbuild, swc, tsc)
- Kompatibilitätstabelle: [kangax.github.io/compat-table](https://kangax.github.io/compat-table/)
---
# JavaScript Grundlagen
```javascript
// Variablen
let name = "Welt";
const alter = 25;
// Funktionen
function gruss(name) {
return `Hallo, ${name}!`;
}
// Arrow Functions
const add = (a, b) => a + b;
// Arrays
const arr = [1, 2, 3];
arr.map(x => x * 2); // [2, 4, 6]
```
---
# DOM Manipulation
```javascript
// Element auswählen
const title = document.querySelector('h1');
// Inhalt ändern
title.textContent = 'Neue Überschrift';
// Event Listener
button.addEventListener('click', () => {
alert('Geklickt!');
});
```
---
# Fetch API
```javascript
fetch('/api/products')
.then(res => res.json())
.then(data => {
console.log(data);
})
.catch(err => console.error(err));
```
---
# Async/Await
```javascript
async function loadProducts() {
try {
const res = await fetch('/api/products');
const data = await res.json();
return data;
} catch (err) {
console.error('Fehler:', err);
}
}
```
---
<!-- _header: '' -->
<!-- _footer: '' -->
<!-- _backgroundColor: #050517 -->
![bg fit](./assets/demos/web-engineering-mandala.png)
---
<!-- _backgroundColor: #050517 -->
<!-- _color: #e2e8f0 -->
# Web Engineering Mandala
Interaktive version: [nextlevelshit.github.io/web-engineering-mandala](https://nextlevelshit.github.io/web-engineering-mandala/)
3 Schichten:
- **Core Layer** — JS, HTML, CSS (vanilla)
- **Build Layer** — bundlers, runtimes, template engines, pre/post processors
- **Application Layer** — frontend, backend, frameworks, SSR, CSS-utilities
3 Segmente: HTML (blau) · JavaScript (rot) · CSS (grün) · Mittelpunkt: `package.json`
---
# JavaScript Frameworks – Kategorien
| Kategorie | Beispiele |
|-----------|-----------|
| **CSS Frameworks** | Tailwind, Bootstrap, shadcn/ui |
| **Frontend Frameworks** | React, Vue, Svelte, Astro |
| **Rendering / Meta** | Next.js, Nuxt, Gatsby |
| **Build Tools / Bundler** | Webpack, Vite, Parcel, esbuild |
| **Backend Frameworks** | Express, Fastify, NestJS |
---
# Vanilla JS – Counter
```html
<button id="myButton">Clicked 0 times</button>
<script>
let count = 0;
const btn = document.getElementById('myButton');
btn.addEventListener('click', () => {
count++;
btn.textContent = `Clicked ${count} times`;
});
</script>
```
**Pro:** hohe Kompatibilität, simpel
**Contra:** State-Management und Re-Rendering werden schnell komplex
---
# React – Counter (JSX)
![bg right:25% fit](./assets/logos/frameworks/react.svg)
```jsx
import { useState } from "react";
function MyButton() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
);
}
```
- **Component-Based** Architecture
- **Virtual DOM**, JSX, Hooks
- großes Ökosystem (React Router, Redux, …)
---
# Vue 3 – Composition API
![bg right:25% fit](./assets/logos/frameworks/vue.svg)
```vue
<script setup>
import { ref } from "vue";
const count = ref(0);
</script>
<template>
<button @click="count++">
Clicked {{ count }} times
</button>
</template>
```
- **Reactive Data Binding**
- Single-File Components (`.vue`)
- Vue Router, Pinia (State)
---
# Svelte – Counter
![bg right:25% fit](./assets/logos/frameworks/svelte.svg)
```svelte
<script>
let count = 0;
</script>
<button on:click={() => count += 1}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
```
- **Compiler-Based** – kein Runtime-Framework
- Reactive Assignments (`let`)
- Built-in Animationen
---
# Astro – Content-First
![bg right:25% fit](./assets/logos/frameworks/astro.svg)
```astro
---
const greeting = "Hallo DHBW";
---
<html>
<body>
<h1>{greeting}</h1>
<MyReactButton client:load />
</body>
</html>
```
- **Islands Architecture** – Komponenten mehrerer Frameworks mischen
- Default: kein JS im Output (nur statisches HTML)
- Hydration on demand (`client:load`, `client:visible`)
---
# Rendering Frameworks
| | Frontend | SSR | SSG | File Routing |
|---|---|---|---|---|
| **Next.js** | React | ja | ja | `/app/page.js` |
| **Nuxt** | Vue | ja | ja | `/pages/*.vue` |
| **Gatsby** | React | nein | ja | GraphQL Data |
---
# Build Tools – Webpack
![bg right:25% fit](./assets/logos/frameworks/webpack.svg)
- Module Bundling (JS, CSS, Images)
- Module Loaders + großes Plugin-Ökosystem
- Code Splitting, HMR
- Konfigurations-lastig (`webpack.config.js`)
→ Standard für viele Legacy-Setups.
---
# Build Tools – Vite
![bg right:25% fit](./assets/logos/frameworks/vite.svg)
```javascript
// vite.config.js
import { defineConfig } from "vite";
export default defineConfig({
server: {
proxy: {
"/api": {
target: "http://localhost:4567",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, "")
}
}
}
});
```
- Rollup unter der Haube, **HMR mit ES Modules**
- Tree-Shaking, Code Splitting, React + Vue out-of-the-box
---
# Build Tools – Parcel
![bg right:25% fit](./assets/logos/frameworks/parcel.png)
```json
{
"name": "my-project",
"source": "src/index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": {
"start": "parcel",
"build": "parcel build"
},
"devDependencies": {
"parcel": "latest"
}
}
```
- **Zero-Config**
- Auto-Resolution, HMR
- TS / CSS-Preprocessors out-of-the-box
---
# Microfrontends
- Mehrere unabhängige Frontend-Apps in einer Page
- Module Federation (Webpack 5)
- **single-spa**: https://single-spa.js.org/
- Anwendungsfall: große Teams, unterschiedliche Tech-Stacks pro Domain
→ Komplexitätskosten: nur bei echtem Skalierungsbedarf.
---
# Demo-Repos
- https://github.com/nextlevelshit/dhbw-client-js (Counter, multi-framework)
- https://github.com/nextlevelshit/node-cache-api (API + Tests)
- https://github.com/nextlevelshit/dhbw-docker (Compose-Stack)
@@ -62,6 +62,15 @@ a {
**Sommersemester 2026** · Sitzung 4 — Node.js: Scripting, Running and Building
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
# Ressourcen zum Selbstlernen
@@ -62,6 +62,15 @@ a {
**Sommersemester 2026** · Sitzung 5 — Express API, CRUD und Middlewares
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
# Ressourcen zum Selbstlernen
@@ -63,6 +63,15 @@ a {
**Sommersemester 2026** · Sitzung 7 — Testing
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
# Ressourcen zum Selbstlernen
@@ -63,6 +63,15 @@ a {
**Sommersemester 2026** · Sitzung 8 — TypeScript
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
<!-- _class: invert -->
@@ -63,6 +63,15 @@ a {
**Sommersemester 2026** · Sitzung 9 — Docker, Proxies and DBs
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
<!-- _class: invert -->
@@ -63,6 +63,15 @@ a {
**Sommersemester 2026** · Sitzung 10 — Wrap-up & Projektsupport
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
<!-- _class: invert -->
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+15
View File
@@ -0,0 +1,15 @@
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" width="433" height="97" viewBox="0 0 433 97">
<g>
<g id="logotype">
<path id="logotype-b-47" d="M185.2,46.88a13.77,13.77,0,0,0,8.8-13c0-11.7-8.3-17.5-19.7-17.5H144.4V80h32.5c10,0,19.8-7,19.8-17.7C196.7,49.58,185.2,47,185.2,46.88ZM160,29.58h11.6a5.66,5.66,0,0,1,6,5.31q0,.34,0,.69a5.93,5.93,0,0,1-6,5.81H159.9Zm11.7,37.1H160.1V54.18h11.3c5.7,0,8.4,2.5,8.4,6.2C179.8,65,176.4,66.68,171.7,66.68Z" style="fill: #ed0007;fill-rule: evenodd"/>
<path id="logotype-o-47" d="M231.1,14.78c-18.4,0-29.2,14.7-29.2,33.3s10.8,33.3,29.2,33.3,29.2-14.6,29.2-33.3S249.6,14.78,231.1,14.78Zm0,51.4c-9,0-13.5-8.1-13.5-18.1s4.5-18,13.5-18,13.6,8.1,13.6,18C244.7,58.18,240.1,66.18,231.1,66.18Z" style="fill: #ed0007;fill-rule: evenodd"/>
<path id="logotype-s-47" d="M294.2,41.38l-2.2-.5c-5.4-1.1-9.7-2.5-9.7-6.4,0-4.2,4.1-5.9,7.7-5.9a17.86,17.86,0,0,1,13,5.9l9.9-9.8c-4.5-5.1-11.8-10-23.2-10-13.4,0-23.6,7.5-23.6,20,0,11.4,8.2,17,18.2,19.1l2.2.5c8.3,1.7,11.4,3,11.4,7,0,3.8-3.4,6.3-8.6,6.3-6.2,0-11.8-2.7-16.1-8.2l-10.1,10c5.6,6.7,12.7,11.9,26.4,11.9,11.9,0,24.6-6.8,24.6-20.7C314.3,46.08,303.3,43.28,294.2,41.38Z" style="fill: #ed0007;fill-rule: evenodd"/>
<path id="logotype-c-47" d="M349.7,66.18c-7,0-14.3-5.8-14.3-18.5,0-11.3,6.8-17.6,13.9-17.6,5.6,0,8.9,2.6,11.5,7.1l12.8-8.5c-6.4-9.7-14-13.8-24.5-13.8-19.2,0-29.6,14.9-29.6,32.9,0,18.9,11.5,33.7,29.4,33.7,12.6,0,18.6-4.4,25.1-13.8L361.1,59C358.5,63.18,355.7,66.18,349.7,66.18Z" style="fill: #ed0007;fill-rule: evenodd"/>
<polygon id="logotype-h-47" points="416.3 16.38 416.3 39.78 397 39.78 397 16.38 380.3 16.38 380.3 79.98 397 79.98 397 54.88 416.3 54.88 416.3 79.98 433 79.98 433 16.38 416.3 16.38" style="fill: #ed0007;fill-rule: evenodd"/>
</g>
<g id="symbol">
<path d="M48.2.18a48.2,48.2,0,1,0,48.2,48.2A48.2,48.2,0,0,0,48.2.18Zm0,91.9a43.7,43.7,0,1,1,43.7-43.7,43.71,43.71,0,0,1-43.7,43.7Z"/>
<path d="M68.1,18.28H64.8v16.5H31.7V18.28H28.3a36.06,36.06,0,0,0,0,60.2h3.4V62H64.8v16.5h3.3a36.05,36.05,0,0,0,0-60.2ZM27.1,72A31.59,31.59,0,0,1,24.47,27.4a32.51,32.51,0,0,1,2.63-2.62Zm37.7-14.6H31.7V39.28H64.8Zm4.5,14.5v-10h0V34.78h0v-10a31.65,31.65,0,0,1,2.39,44.71A33.68,33.68,0,0,1,69.3,71.88Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 KiB

+1
View File
@@ -0,0 +1 @@
<svg width="189" height="45" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M-46-32h1440V68H-46z"/><g fill-rule="nonzero"><g fill="#0E1111"><path d="M133.298 34.907v-1.509L142.48 20.1h-8.71v-1.982h11.44v1.513l-9.183 13.296h9.494v1.981h-12.222M129.365 35.163c-2.235 0-2.145-.927-2.145-3.611V18.117h2.132V31.82l.013 3.343M120.61 34.907v-12.19c0-2.181-1.192-2.854-3.135-2.854-2.037 0-3.071.371-4.23 1.075v13.97h-2.194v-16.79h1.223l.471 1.41c1.472-1.175 3.07-1.746 4.73-1.746 3.728 0 5.327 1.812 5.327 5.039v12.086h-2.193M100.87 33.163c-2.038 0-3.168-.37-4.389-1.075v-11.15c1.221-.704 2.351-1.075 4.388-1.075 3.76 0 4.229 3.325 4.229 6.65s-.47 6.65-4.229 6.65zm0-15.381a7.795 7.795 0 00-4.389 1.376V9.723h-2.193v25.184h1.221l.47-1.377c1.63 1.109 3.196 1.714 4.89 1.714 5.045 0 6.422-3.896 6.422-8.731s-1.377-8.731-6.422-8.731zM89.417 35.24c-2.256 0-2.148-1.004-2.148-3.688V18.117h2.13V31.82l.018 3.42M72.667 25.674c.092-3.023.751-5.811 4.387-5.811 3.603 0 3.76 2.822 3.76 5.81h-8.147zm10.34.839c0-4.835-.627-8.731-5.953-8.731-5.297 0-6.581 3.896-6.581 8.73 0 4.836 1.284 8.732 6.581 8.732 1.534 0 3.413-.168 5.17-1.008v-2.013c-1.535.704-2.914.94-5.17.94-3.542 0-4.263-2.653-4.387-5.574h10.34v-1.076zM54.492 34.907V9.723h2.131v23.07h10.874v2.114H54.492M188.975 34.9V9.723h-2.12v11.011h-11.658V9.724h-2.119V34.9h2.12V22.848h11.657V34.9h2.12M158.053 11.837h11.128V9.723h-13.248V34.9h2.12V22.848h10.037v-2.114h-10.037v-8.897M87.261 15.025h2.142v-2.24h-2.142zM127.222 15.025h2.142v-2.24h-2.142z"/></g><path d="M.195 1.476l9.617-.42v43.75L.2 42.284C.2 23.158.197 8.006.195 1.476M39.777 43.49l-9.655.422V.162l9.65 2.953c0 19.392.002 34.192.005 40.375" fill="#0288d1"/><path fill="#74BEE6" d="M9.812 34.613v10.193l15.285-.67V33.888l-15.285.725M15.11.837v10.285l15.012-.724V.161L15.11.837"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

+78
View File
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="123.1184" height="38" id="svg2">
<defs id="defs4"/>
<g transform="translate(-4.113659e-8,-8.1875909)" id="g2881">
<g transform="matrix(0.8227318,0,0,0.8227318,0,8.1875911)" id="g3725">
<path d="m 5.9058686,3.5864545 c 0,1.6289778 -1.3205475,2.9495254 -2.9495254,2.9495254 -1.628978,0 -2.9495254,-1.3205476 -2.9495254,-2.9495254 0,-1.6289779 1.3205474,-2.94952547 2.9495254,-2.94952547 1.6289779,0 2.9495254,1.32054757 2.9495254,2.94952547 l 0,0 z" id="path2492" style="fill:#022d6f;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"/>
<use transform="translate(123.33173,0.52756266)" id="use2494" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(12.995121,0.24968358)" id="use3266" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(-0.0021669,6.4942292)" id="use3268" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(-0.00100324,13.007016)" id="use3270" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(1.6068057e-4,19.515151)" id="use3272" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(5.6386012,22.744639)" id="use3274" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(-0.00681775,26.008952)" id="use3276" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(12.102606,22.633932)" id="use3278" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(19.117759,2.4186714)" id="use3280" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(22.403372,8.0486075)" id="use3282" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(18.008113,19.840656)" id="use3284" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(21.756631,14.51843)" id="use3286" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(-0.00100325,32.490405)" id="use3290" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(0.00132398,38.988066)" id="use3292" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(37.905739,3.6984537)" id="use3294" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(65.078186,33.204228)" id="use3296" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(33.398214,8.5473695)" id="use3298" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(30.724945,14.638897)" id="use3300" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(30.159334,21.213576)" id="use3302" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(31.812768,27.679762)" id="use3304" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(35.421974,33.202782)" id="use3306" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(40.652784,37.299478)" id="use3308" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(43.733988,0.5434759)" id="use3310" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(50.271054,-0.58340514)" id="use3312" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(56.815356,0.50441766)" id="use3314" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(46.959848,39.447642)" id="use3316" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(62.637816,3.6608425)" id="use3318" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(53.579391,39.44039)" id="use3320" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(67.139555,8.5531567)" id="use3322" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(69.779551,14.64179)" id="use3324" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(70.340823,21.210681)" id="use3326" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(79.933056,19.51385)" id="use3328" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(59.8575,37.257529)" id="use3330" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(68.722105,27.673974)" id="use3332" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(6.4702426,5.7452075e-4)" id="use3334" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(79.938844,13.014391)" id="use3336" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(79.933047,0.00245617)" id="use3338" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(79.934503,6.494682)" id="use3340" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(85.563127,3.2586948)" id="use3342" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(89.846429,8.1177379)" id="use3344" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(94.152881,13.004267)" id="use3346" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(79.938841,26.013309)" id="use3348" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(98.462222,17.886454)" id="use3350" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(102.76578,22.745497)" id="use3352" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(79.930164,32.496854)" id="use3354" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(108.40887,26.016202)" id="use3356" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(108.40597,0.00390394)" id="use3358" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(108.40887,6.4888947)" id="use3360" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(108.40742,13.012946)" id="use3362" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(108.41031,19.509501)" id="use3364" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(79.933058,38.984738)" id="use3366" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(108.40308,32.498301)" id="use3368" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(108.40308,38.98329)" id="use3370" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(118.86037,5.2694337)" id="use3372" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(118.33815,11.771784)" id="use3374" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(122.73574,16.555607)" id="use3376" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(129.72991,-0.63692924)" id="use3378" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(136.11652,0.46102075)" id="use3380" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(128.89236,18.606849)" id="use3382" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(135.21099,20.106946)" id="use3384" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(142.06329,3.0879996)" id="use3386" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(141.06815,22.998648)" id="use3388" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(118.41627,34.426578)" id="use3390" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(143.73998,28.915145)" id="use3392" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(123.96821,37.788408)" id="use3394" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(130.21596,39.651611)" id="use3396" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(136.68652,38.987622)" id="use3398" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
<use transform="translate(141.93608,35.149863)" id="use3400" style="fill:#022d6f;fill-opacity:1" x="0" y="0" width="117" height="36" xlink:href="#path2492"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B