53 Commits

Author SHA1 Message Date
977a09949a README: cd vehicle-counter nach git clone ergaenzt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 12:34:37 +02:00
3b6802cb70 README: venv-Setup (python3-venv, .vehicle) in Installation ergaenzt
- Schritt 2: venv anlegen + aktivieren (apt install python3-venv,
  python3 -m venv .vehicle, source .vehicle/bin/activate)
- supervisord-command auf .vehicle/bin/python angepasst
- Schritte neu nummeriert (2-5)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 12:32:29 +02:00
8e001b432d .env.example: SECRET_KEY-Generierungsbefehl als Kommentar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 12:28:10 +02:00
d570b330c5 Modelle per .env steuerbar (UPLOAD_MODEL), Upload nicht mehr hardcoded
- UPLOAD_MODEL-Env (Default yolo11s.pt) statt fest verdrahtetem YOLO("yolo11s.pt")
- WEBCAM_MODEL bleibt getrennt steuerbar
- .env.example: beide Modelle dokumentiert (n<s<m<l<x)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 16:27:15 +02:00
3fa76e03ae MQTT: laufende Nummer (total) ins Crossing-Event aufnehmen
Jedes crossing-Event enthaelt jetzt "total" = Gesamtzaehler-Stand zum
Zeitpunkt der Ueberquerung (= laufende Nummer des Fahrzeugs).
README-Payload-Beispiel ergaenzt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 11:12:22 +02:00
0b182e23fa Fix: grosse Fahrzeuge (LKW/Bus) wurden nicht gezaehlt
Bezugspunkt fuer die Linienueberquerung von Box-Mitte auf Bodenkontakt
(Unterkante-Mitte) geaendert. Bei hohen Fahrzeugen lag die Box-Mitte
weit ueber der Strasse und kreuzte die Linie nie. Die Unterkante = wo
das Fahrzeug die Strasse beruehrt -> korrekt fuer PKW und LKW/Bus.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 09:51:25 +02:00
8a7323a35f fps_test: Zugangsdaten in URL maskieren (Hilfe/Ausgabe/Fehler)
CAMERA_URL kann Credentials enthalten (z.B. rtsp://user:pass@host).
Diese werden in Hilfetext, Lauf-Ausgabe und Fehlermeldung jetzt zu
***:*** maskiert. Default im Code auf neutralen Platzhalter gesetzt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 09:39:52 +02:00
7f162b2568 gunicorn.conf.py entfernt (ungenutzt)
Betrieb laeuft ueber supervisord + 'python app.py'; gunicorn wird nicht
verwendet. Bei Bedarf aus der Git-Historie wiederherstellbar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 18:13:24 +02:00
144582f866 README: Abschnitt zum Dauerbetrieb mit supervisord (24/7)
Beispiel-Config + reread/update/restart/status/Logs, mit Hinweis auf
directory= (.env/counting_line) und Restart-Bedarf nach Code-Updates.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 18:09:38 +02:00
5d42088502 Hilfs-Scripts nach scripts/ verschoben (test.py -> grab_frame.py)
- fps_test.py -> scripts/fps_test.py
- test.py -> scripts/grab_frame.py (umbenannt + nutzbar gemacht:
  CAMERA_URL aus .env oder URL-Arg, --save, sauberes Error-Handling)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 18:04:57 +02:00
971efcbaab Banner-Bild nach pictures/ verschoben + README-Referenz angepasst
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 18:01:06 +02:00
a3a1b45db8 cam_framesize: val None-sicher zu int (Typ-Warnung weg)
int(str(...)) macht das Argument eindeutig; None/Nicht-Zahl -> ValueError
-> abort 400. Verhalten identisch, kein int(None) mehr fuer den Type-Checker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:51:15 +02:00
6c474da5a0 Template-Auto-Reload aktivieren (Frontend-Aenderungen ohne Neustart)
Bei debug=False cachte Jinja die Templates -> webcam.html-Aenderungen
wurden erst nach App-Neustart sichtbar. Auto-Reload betrifft nur das
Rendern bei Seitenaufrufen, nicht die Video-Pipeline.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:44:14 +02:00
f9ce2e2dc1 Webcam: Zaehler-Box im "LIVE COUNT"-Design (farbige Icons + Total)
Reines Restyling der bestehenden verschiebbaren HTML-Box: dunkles Panel,
LIVE-COUNT-Header, farbige Fahrzeug-Icons (SVG) + farbige Zahlen, TOTAL-
Zeile. Gleiche /api/counts-Daten, gleiche IDs, gleiches Drag/Polling.
Keine Aenderung an der Video-Pipeline -> kein Performance-Einfluss.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:40:57 +02:00
7a522f8927 Webcam: Zaehler-Box als verschiebbares HTML-Overlay (per Maus)
Statt ins Bild gebrannt ist der Zaehler jetzt ein HTML-Overlay, das frei
mit der Maus positioniert werden kann; Position wird in localStorage
gemerkt. Werte kommen ueber /api/counts (Live-Polling).

- draw_overlay/render_static/process_frame: draw_counter-Flag
  (Webcam laesst Box weg, Video-Upload behaelt sie eingebrannt)
- Grabber-State auf self.state -> /api/counts liest live mit
- Drag-Logik + Counts-Polling im Frontend

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:15:54 +02:00
07c0e44cd8 Webcam: Buttons fuer Kamera-Aufloesung (VGA/SVGA)
Schaltet die ESP32-CAM-Aufloesung per Button um (VGA 640x480 = mehr FPS,
SVGA 800x600 = mehr Detail). Server proxyt den /control-Aufruf an die
Kamera (Host automatisch aus CAMERA_URL, Port 80).

- /api/cam_framesize (Whitelist 10=VGA, 11=SVGA)
- zwei Buttons + Status-Feedback im Frontend

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:09:46 +02:00
b50a2d3316 fps_test.py: CLI-Tool zum Messen von FPS/Durchsatz einer MJPEG-Quelle
Misst FPS, Ø/min/max-Framegroesse und Durchsatz (Mbit/s) - zur Diagnose
des ESP32-CAM-WLAN-Engpasses. --app (Pipeline), --cam (Kamera direkt,
CAMERA_URL aus .env) oder beliebige URL, -t fuer Dauer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 14:23:24 +02:00
322afba0cb upload: filename None-sicher an secure_filename (Typ-Warnung weg)
file.filename ist str|None. Guard faengt None jetzt mit ab, und
secure_filename(file.filename or "") macht den Typ eindeutig str.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:40:30 +02:00
57686f6579 reset_count: stream_id eindeutig als str (None-Typ-Warnung weg)
data.get() liefert Any|None; Type-Checker erkannte den abort-Guard nicht
als Einschraenkung. str(... or "") macht den Typ eindeutig str, Verhalten
identisch (None/"" -> abort 400).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:39:18 +02:00
73bcd41b5d model.names statt model.model.names (kein None-Attribut-Warnung)
Type-Checker sah model.model als evtl. None. YOLO bietet die Klassen-
namen direkt ueber model.names an (identischer Inhalt verifiziert).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:37:56 +02:00
8ed9b4662a MQTT-Client-Init via getattr (kein Type-Checker-Fehler bei CallbackAPIVersion)
Direkter Zugriff mqtt.CallbackAPIVersion wurde von Pylance bei paho-1.x-
Stubs als "nicht exportiert" markiert. getattr umgeht das, gleiche
1.x/2.x-Kompatibilitaet zur Laufzeit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:36:06 +02:00
85747d7a42 Webcam: Button zum Freigeben/Uebernehmen der Kamera (ESP32-Slot)
Trotz GRABBER_ALWAYS_ON=1 kann der ESP32-Slot per Button manuell
freigegeben werden (z.B. um die Cam woanders direkt zu oeffnen).
Freigegeben = Slot frei + Zaehlung pausiert; uebernehmen = wieder zaehlen.

- Grabber: paused-Flag, hat Vorrang vor ALWAYS_ON/Karenzzeit
- /api/grabber_toggle + paused-Feld in /api/webcam_status
- Button + eigener Overlay-Text ("Kamera freigegeben") im Frontend

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:59:25 +02:00
264b2b3e3b Fix: Offline-Erkennung loeste Reconnect-Resets aus (Zaehlung gestoert)
Bei GRABBER_ALWAYS_ON=0 kappte kurzes Zuschauer-Aus (<img>-Reload der
Auto-Recovery) die Kameraverbindung -> Reconnect -> Tracker/Zaehlzustand
wurde zurueckgesetzt. Bei ~1 FPS riss das die Zaehlung auseinander.

- Grabber: Karenzzeit (VIEWER_GRACE_SEC, Default 15s) bevor die Kamera
  bei fehlenden Zuschauern freigegeben wird -> kein Reconnect-Churn
- Frontend: Overlay/Reload erst nach ~6s echtem Ausfall (3 Polls),
  nicht bei einzelnen langsamen Frames -> kein Verbindungs-Churn

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:53:46 +02:00
356d0ce977 Diagnose: optionales Zaehl-Debug-Log (COUNT_DEBUG=1)
Pro verarbeitetem Frame mit Fahrzeugen: Anzahl, Abstaende zur Linie,
Band, jetzt gezaehlt, Gesamt. Hilft zu sehen, ob Fahrzeuge erkannt
werden und wie nah sie der Linie kommen (Frame-Rate-/Band-Diagnose).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:42:46 +02:00
eb589210fc Fix: Zaehlen nach Reconnect (stale persistenter Tracker zuruecksetzen)
Nach langer Kamera-Pause (z.B. ueber Nacht aus) trug der persistente
YOLO-Tracker alten Zustand mit: neue Fahrzeuge wurden an verlorene
Alt-Tracks gekoppelt bzw. erst nach 2 Frames aktiviert -> bekamen keine/
verzoegerte ID -> wurden nicht gezaehlt.

- Tracker beim (Re-)Connect via tracker.reset() leeren -> frische IDs
- frame_idx beim Reconnect nullen (Gesamtzaehler bleibt)
- Log-Zeile beim Verbinden (Reconnects in supervisord-Logs sichtbar)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 09:52:03 +02:00
df7f9ce4df README: Banner-Bild (vehicle-counter.png) oben eingebunden
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 20:15:18 +02:00
a8c99503b8 Dateien nach "/" hochladen 2026-06-01 18:14:21 +00:00
d7e1b17a60 Webcam: "Kamera offline"-Overlay + Auto-Recovery des Streams
ESP32-CAM haengt sich gelegentlich auf -> Bild blieb leer ohne Hinweis.

- Grabber merkt sich last_frame_ts; /api/webcam_status liefert online-Flag
  (online = letzter Frame < 5s her)
- webcam.html pollt alle 2s und blendet ein Offline-Overlay ein
- Auto-Recovery: kommt die Kamera zurueck, wird der MJPEG-Stream neu
  angestossen (<img> reconnectet sonst nach Abbruch nicht von selbst)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 19:54:04 +02:00
b8298e584f Dark Mode fuer alle Seiten (Toggle + System-Default)
- CSS-Variablen fuer Hell/Dunkel, Umschalter (🌙/☀️) oben rechts
- Default folgt prefers-color-scheme, Wahl wird in localStorage gemerkt
- Theme wird vor dem Rendern gesetzt -> kein Flackern
- index, webcam und play_video konsistent

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 19:44:49 +02:00
e30aae2781 MQTT: source-Feld der Live-Cam auf "webcam" (statt Kamera-ID)
camera=Kamera-ID (cam1), source=Herkunft (webcam/video) - vorher war
source bei der Live-Cam mit der Kamera-ID belegt und damit redundant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 19:29:48 +02:00
887379a1d6 .flaskenv aus Tracking entfernen (enthielt SECRET_KEY)
.flaskenv (Flask SECRET_KEY) war versehentlich versioniert. Aus Tracking
genommen, in .gitignore aufgenommen, Key lokal rotiert. History-Purge folgt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 19:22:40 +02:00
c6c87be045 Fix: Zaehlen verhungert nach Stunden (unbegrenzte Zustaende)
track_positions/counted_ids wuchsen im 24/7-Betrieb unbegrenzt:
-> Speicherleck/Slowdown -> Bildrate bricht ein -> Linienueberquerungen
werden nicht mehr erfasst (Einzel-Erkennung lief weiter).

- Track-IDs altern jetzt (last-seen-Frame) und werden nach
  COUNT_FORGET_FRAMES aus track_positions UND counted_ids entfernt
- bounded State -> kein Leck; loest auch Unterdrueckung bei spaeterer
  Track-ID-Wiederverwendung
- Langzeit-Simulation (5000 Frames): 100/100 gezaehlt, State-Peak 4

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 19:19:33 +02:00
ff4fe55e05 Zaehl-Band auf 45px erhoehen (schnelle Fahrzeuge nahe Kamera)
Schnelle Fahrzeuge im kamera-nahen (pixel-schnellen) Bereich sprangen
ueber das 24px-Band -> wurden nicht gezaehlt. 45px faengt sie ab; die
Entprellung (60px) verhindert weiterhin Doppelzaehlung.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 16:20:57 +02:00
63c4890c35 README: Outdoor-Setup-Hardwareliste (Box + Powerbank) ergaenzt
ESP32-CAM-Empfehlung zu einer Tabelle erweitert: wetterdichte Box und
Powerbank fuer netzunabhaengigen Aussenbetrieb (Affiliate-Links).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 15:27:40 +02:00
c76a7d2248 README: Affiliate-Link zur ESP32-CAM eingebaut
Hardware-Empfehlung im ESP32-CAM-Abschnitt + Voraussetzungen verlinkt,
mit Affiliate-Hinweis (Transparenz).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 15:24:01 +02:00
6fc40ba4ee Fix: schnelle Fahrzeuge wurden an der Zaehllinie nicht gezaehlt
Bisher musste von DERSELBEN Track-ID ein Punkt vor UND hinter der Linie
erfasst werden. Bei schnellen Fahrzeugen gibt es dafuer oft zu wenige
Samples oder die Track-ID wechselt -> nichts wird gezaehlt.

- Band um die Linie (COUNT_BAND_PX): ein einzelnes Sample nahe der Linie
  reicht jetzt zum Zaehlen
- Entprellung (COUNT_DEDUP_PX/FRAMES): verhindert Doppelzaehlung bei
  Track-ID-Wechseln nahe der Linie
- klassischer Segment-Schnitt bleibt zusaetzlich erhalten
- point_to_segment_dist + Tests fuer langsam/schnell/ID-Wechsel

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 15:03:11 +02:00
5545d7d837 README: auf .env.example verweisen + echte Werte entfernen
- 'cp .env.example .env' als empfohlener Einstieg dokumentiert
- Broker-IP/Topic/Kamera-IP aus README und app.py-Default durch
  Platzhalter ersetzt (versehentlich aus lokalem Setup uebernommen)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:54:35 +02:00
9c325dbff3 .env.example mit dokumentierten Platzhaltern hinzugefuegt
Vorlage fuer die lokale .env (alle 16 Env-Variablen erklaert, nur
generische Platzhalter/Defaults). 'cp .env.example .env' zum Start.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:51:36 +02:00
2b930b3e47 MQTT per MQTT_ENABLED ein-/ausschaltbar (einsteigerfreundlich)
- MQTT_ENABLED=false -> App startet ohne Broker, keine Events/LWT
- publish_crossing wird zum No-Op, kein Reconnect-Rauschen
- README: optional gekennzeichnet, Env-Tabelle + .env-Beispiel ergaenzt

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:49:18 +02:00
b20f4c582c Zaehllinie persistent speichern (ueberlebt Neustart)
- Linie wird beim Setzen atomar in counting_line.json gespeichert
- beim Start geladen -> Default fuer Session UND Webcam-Grabber
- Pfad per LINE_FILE-Env ueberschreibbar, Datei via .gitignore ausgeschlossen
- set_line-Route nutzt jetzt _valid_line (weniger Doppelcode)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:41:29 +02:00
394c72d6d9 MQTT: Birth-Message + Last Will auf {MQTT_TOPIC}/status
- "online" (retained) beim (Re-)Connect via on_connect-Callback
- "offline" automatisch durch Broker bei Verbindungsabbruch (LWT)
- Abnehmer (n8n / Home Assistant) sehen jederzeit den Live-Zustand
- README um Status-/Availability-Topic ergaenzt

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:37:32 +02:00
d593f9e8af Fix: .env wird automatisch geladen (MQTT-Events kamen nicht an)
Ohne 'source .env' liefen Broker/Topic auf Defaults (127.0.0.1 statt
192.168.10.7, vehiclecounter/cam1 statt counter/cam1) -> keine Events.
Jetzt laedt app.py die .env per python-dotenv beim Start.

- load_dotenv() vor dem Auslesen von os.environ
- README: .env-Konfig + supervisord-Hinweis (directory=), python-dotenv

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:35:13 +02:00
bde547368d Modelle nicht mehr versionieren (Ultralytics laedt sie automatisch)
- yolo11s.pt aus Tracking entfernt, .gitignore auf *.pt erweitert
- README: Modelle werden beim ersten Start autom. geladen statt manuell

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:28:00 +02:00
b447d3e7c5 README: Voraussetzungen aktualisiert (CUDA-GPU, ESP32-CAM, MQTT)
- NVIDIA-GPU mit CUDA als Voraussetzung dokumentiert (FP16, CPU-Fallback)
- ESP32-CAM als MJPEG-Live-Quelle inkl. CAMERA_URL/Fan-out/Always-on
- MQTT-Broker fuer Crossing-Events (Topic, Payload, Env-Konfig)
- Installation um CUDA-PyTorch, requests und paho-mqtt ergaenzt

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:16:54 +02:00
c09fd8948b Vehicle-Counter: MQTT-Crossing-Events, Motion-Gating & ESP32-Cam
- Linienueberquerungen werden als MQTT-Event publiziert (fuer n8n -> NocoDB)
- Motion-Gate: YOLO laeuft nur bei Bewegung -> weniger CPU-Last
- Always-on-Grabber (24/7-Zaehlung unabhaengig von Zuschauern)
- Konfigurierbare Inferenz per Env (Modell, imgsz, FP16, Kamera-URL)
- .gitignore ergaenzt (.env, uploads/, Modelle, __pycache__)
- Aufraeumen: alte app2/app3/app4/sudo-Dateien entfernt

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:09:04 +02:00
fd1de272a6 new apps 2026-06-01 10:52:47 +02:00
b28d8965d5 Verbessere Streaming-Sicherheit 2025-12-14 12:02:58 +00:00
c8f49e41f9 YouTube-Demo-Video im README eingebettet
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-09 15:06:03 +00:00
12bc94a28a Fix: Zähllinie wird nicht mehr als Objekt erkannt
Problem: YOLO hat die gelbe Zähllinie als "Zahnbürste" erkannt
Lösung: Zähllinie wird jetzt NACH der YOLO-Erkennung gezeichnet

Änderungen:
- YOLO-Erkennung läuft auf dem Original-Frame
- Zähllinie wird erst danach als Overlay gezeichnet
- Linie ist jetzt etwas dicker (3px statt 2px) für bessere Sichtbarkeit

Resultat: Keine falschen Objekterkennungen mehr durch die Zähllinie

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 18:55:08 +00:00
87a6060a1a Verbesserte Debug-Visualisierung für Linienschnitt
Neue Debug-Features:
- Orange Bewegungslinien zeigen die Trajektorie jedes Fahrzeugs
- Größerer grüner Kreis (25px) beim Zählen für bessere Sichtbarkeit
- crossed_line() Helper-Funktion für bessere Code-Lesbarkeit

Hilft beim Debuggen:
- Bewegungslinien zeigen ob Fahrzeug sich bewegt
- Sichtbar ob Bewegungslinie die Zähllinie kreuzt
- Bestätigt visuell dass Tracking funktioniert

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 16:09:26 +00:00