diff --git a/server/pruef-anruf.mjs b/server/pruef-anruf.mjs index cf802d49..027a2300 100644 --- a/server/pruef-anruf.mjs +++ b/server/pruef-anruf.mjs @@ -229,6 +229,119 @@ melde("=== 5. Auflegen ==="); Sie enthalten Zugangsdaten (TURN braucht Benutzer und Passwort). Deshalb darf nur DogFather sie setzen. ======================================================================= */ +/* ======================================================================= + 5c. WER ERST DURCH DIE BENACHRICHTIGUNG KOMMT + + Filipe, 18.09.2026: „wenn ich vanvan anrufe kriegt sie nur eine + benarichtigung aber keinen anruf was soll das." + + Das war kein Missverstaendnis, sondern ein Loch. Das Klingeln lief + ausschliesslich ueber den offenen Ereignisstrom: Wer zusieht, hoert + es. Wer die Seite NICHT offen hat, bekommt die Push-Nachricht, + tippt darauf, die Seite laedt -- und bleibt still. Das Ereignis war + vorbei, bevor sie da war. + + Der Anruf funktionierte damit ausgerechnet fuer die nicht, fuer die + die Benachrichtigung gebaut wurde. + + DIESE PRUEFUNG BILDET GENAU DAS AB: Erst anrufen, DANN die Seite + oeffnen. Ohne sie beweist der Dreier-Test unten nur, dass es + funktioniert, wenn alle schon zusehen. + ======================================================================= */ +/* ======================================================================= + 5d. WAS IN DER BENACHRICHTIGUNG STEHT + + Filipe: „wenn ich vanvan anrufe kriegt sie nur eine benarichtigung + aber keinen anruf was soll das." + + Gemessen kam bei ihr an: „Nachricht von [object Object]", ohne Text. + + Zwei Fehler in einer Zeile. `von` ist beim Klingeln ein OBJEKT und + keine Zeichenkette; und einen `text` gibt es bei einem Anruf gar + nicht. Moeglich wurde beides, weil die ART des Ereignisses die + Benachrichtigung nie erreichte -- jedes Ereignis galt dort als + Chatnachricht. + + DIESE PRUEFUNG WAR VORHER NICHT MOEGLICH. Der Text entstand tief in + einer Funktion, die nur der Push-Weg aufruft. Er steht deshalb + jetzt in `pushTextFuer()` -- eine Zeile weniger Verschachtelung und + eine Frage, die sich beantworten laesst. + ======================================================================= */ +melde(""); +melde("=== 5d. Was in der Benachrichtigung steht ==="); +{ + const { pushTextFuer } = await import("./workspace-chat.js"); + + const a = pushTextFuer("anruf", { von: { id: 7, name: "Filipe" }, video: false }, 3); + ok(a.titel === "Filipe ruft an", `beim Anruf steht der Name und „ruft an" (${a.titel})`); + ok(!/\[object/i.test(a.titel + a.text), + "und nirgends [object Object] -- genau das kam vorher an"); + ok(a.text.includes("Rangehen"), `der Text sagt, was zu tun ist (${a.text})`); + ok(a.ziel === "/workspace/chat.html?raum=3", + `und es fuehrt in das richtige Gespraech (${a.ziel})`); + + const v = pushTextFuer("anruf", { von: { id: 7, name: "Filipe" }, video: true }, 3); + ok(v.text.toLowerCase().includes("video"), + `ein Videoanruf sagt das auch (${v.text})`); + + /* UND EINE NORMALE NACHRICHT BLEIBT EINE NORMALE NACHRICHT. */ + const n = pushTextFuer("neu", { von: "Rieke", text: "Hallo!" }, 3); + ok(n.titel === "Nachricht von Rieke" && n.text === "Hallo!", + `eine Nachricht meldet sich weiter als Nachricht (${n.titel})`); + + /* Und wenn dort doch einmal ein Objekt steht -- dieselbe Falle, + nur an der anderen Stelle -- kommt trotzdem ein Name heraus. */ + const o = pushTextFuer("neu", { von: { name: "Rieke" }, text: "Hallo!" }, 3); + ok(!/\[object/i.test(o.titel), `auch mit einem Objekt als Absender (${o.titel})`); +} + +melde(""); +melde("=== 5c. Wer erst durch die Benachrichtigung kommt ==="); +{ + const raum = json(await roh("/workspace/api/chat/raeume", HAUS, + { cookie: kDogi })).raeume?.[0]; + if (!raum) { + unklar("kein Gespraech vorhanden -- nicht nachgesehen"); + } else { + /* Erst pruefen, dass nichts offen ist -- sonst misst der Rest + einen Rest von vorher. */ + const vorher = json(await roh("/workspace/api/anruf/offen", CREW, { cookie: kHand })); + ok(Array.isArray(vorher.anrufe) && vorher.anrufe.length === 0, + `vorher klingelt nichts (${vorher.anrufe?.length})`); + + const start = await roh(`/workspace/api/anruf/${raum.id}/start`, HAUS, + { cookie: kDogi }, { video: false }); + ok(start.code === 200 || start.code === 201, `DogFather ruft an (${start.code})`); + + /* JETZT fragt die rechte Hand -- so, wie ihre Seite es beim Laden + tut, nachdem sie auf die Benachrichtigung getippt hat. */ + const offen = json(await roh("/workspace/api/anruf/offen", CREW, { cookie: kHand })); + ok(offen.anrufe?.length === 1, + `sie erfaehrt beim Laden, dass es klingelt (${offen.anrufe?.length})`); + ok(offen.anrufe?.[0]?.von?.name && offen.anrufe[0].von.id !== undefined, + `und von wem (${offen.anrufe?.[0]?.von?.name})`); + ok(offen.anrufe?.[0]?.raum_id === raum.id, + "und in welchem Gespraech"); + + /* DER ANRUFER SELBST DARF NICHT KLINGELN. Er hat den Anruf + gestartet; ein zweites Fenster von ihm wuerde sonst mitlaeuten. */ + const beimAnrufer = json(await roh("/workspace/api/anruf/offen", HAUS, { cookie: kDogi })); + ok(beimAnrufer.anrufe?.length === 0, + `beim Anrufer selbst klingelt nichts (${beimAnrufer.anrufe?.length})`); + + /* UND WER NICHT IN DEN RAUM GEHOERT, ERFAEHRT NICHTS. Dieselbe + Frage wie ueberall sonst -- eine neue Route ist eine neue Tuer. */ + const fremd = json(await roh("/workspace/api/anruf/offen", HAUS, { cookie: kFremd })); + ok(fremd.anrufe?.length === 0, + `ein Fremder erfaehrt nichts davon (${fremd.anrufe?.length})`); + + await roh(`/workspace/api/anruf/${raum.id}/ende`, HAUS, { cookie: kDogi }, {}); + const danach = json(await roh("/workspace/api/anruf/offen", CREW, { cookie: kHand })); + ok(danach.anrufe?.length === 0, + `nach dem Auflegen klingelt es nicht mehr (${danach.anrufe?.length})`); + } +} + melde(""); melde("=== 6. Die Verbindungsadressen ==="); { diff --git a/server/workspace-anruf.js b/server/workspace-anruf.js index 92362392..b48d5e9a 100644 --- a/server/workspace-anruf.js +++ b/server/workspace-anruf.js @@ -398,6 +398,65 @@ anrufRouter.post("/workspace/api/anruf/:raum/signal", gleicheHerkunft, }); /** Läuft hier gerade ein Anruf? Für den, der die Seite frisch öffnet. */ +/* ===================================================================== + KLINGELT GERADE ETWAS FUER MICH? (18.09.2026) + + Filipe: „wenn ich vanvan anrufe kriegt sie nur eine benarichtigung + aber keinen anruf was soll das." + + DAS WAR DER FEHLER, UND ER WAR GRUNDSAETZLICH. Das Klingeln lief + ausschliesslich ueber `chatEreignis` -- also ueber den offenen + Ereignisstrom. Wer die Seite gerade ansieht, hoert es. Wer sie + NICHT offen hat, bekommt die Push-Benachrichtigung, tippt darauf, + die Seite laedt -- und dann passiert nichts mehr. Das Ereignis war + in dem Moment vorbei, in dem es geschickt wurde. + + Damit funktionierte der Anruf ausgerechnet fuer die nicht, fuer die + die Benachrichtigung gebaut wurde. Und es sah aus wie ein Fehler + beim Angerufenen („sie kriegt nur eine Benachrichtigung"), obwohl + nichts kaputt war -- es fehlte schlicht der Weg zurueck. + + Diese Route ist dieser Weg: Beim Laden fragt die Seite einmal nach, + ob in einem ihrer Raeume gerade jemand wartet. Ein laufender Anruf + steht im Speicher (`laufend`), die Frage kostet also nichts. + + NUR WAS NOCH KLINGELT: Anrufe, die laenger als KLINGELT_SEKUNDEN + her sind, gelten als verpasst -- sonst klingelte es beim Oeffnen + noch, obwohl der andere laengst aufgelegt hat. Und nur Raeume, in + denen die Person auch wirklich drin ist; `istDrinFuerAnruf` ist + dieselbe Pruefung wie ueberall sonst. + ===================================================================== */ +anrufRouter.get("/workspace/api/anruf/offen", (req, res) => { + try { + aufraeumen(); + const jetzt = Date.now(); + const offen = []; + for (const [raumId, a] of laufend) { + /* Schon dabei? Dann klingelt es nicht mehr, dann telefoniert + man. */ + if (a.wer.has(req.person.id)) continue; + if (jetzt - a.seit > KLINGELT_SEKUNDEN * 1000) continue; + /* DIE PERSON, NICHT IHRE NUMMER -- istDrin() wirft sonst einen + TypeError, und zwar ausdruecklich: Die Sicherung steht dort + genau fuer diesen Fall. Hier stand zuerst `.id`. */ + if (!istDrinFuerAnruf(raumId, req.person)) continue; + const ersterAndere = [...a.wer.entries()][0]; + offen.push({ + raum_id: raumId, + video: !!a.video, + von: ersterAndere + ? { id: ersterAndere[0], name: ersterAndere[1].name } + : null, + laeuft_bis: a.seit + KLINGELT_SEKUNDEN * 1000, + }); + } + res.json({ anrufe: offen }); + } catch (f) { + console.error("[anruf] Offene:", f?.message); + res.status(503).json({ fehler: "nicht_verfuegbar" }); + } +}); + anrufRouter.get("/workspace/api/anruf/:raum", (req, res) => { try { aufraeumen(); diff --git a/server/workspace-chat.js b/server/workspace-chat.js index c428c0a6..3a6bda50 100644 --- a/server/workspace-chat.js +++ b/server/workspace-chat.js @@ -1791,25 +1791,100 @@ function chatEreignis(raumId, nachricht, benachrichtigen, art = "neu") { Benachrichtigungen abschaltet. */ for (const personId of benachrichtigen) { if ((zuschauer.get(personId) || []).length) continue; - void meldeNeueNachricht(personId, raumId, nachricht); + /* DIE ART GEHT MIT (18.09.2026). Sie stand als Parameter oben und + endete im Ereignisstrom -- die Benachrichtigung bekam sie nie zu + sehen und behandelte deshalb JEDES Ereignis als Chatnachricht. + Bei einem Anruf kam dabei woertlich „Nachricht von [object + Object]" heraus. */ + void meldeNeueNachricht(personId, raumId, nachricht, art); } } /** Die Push-Benachrichtigung. Absichtlich träge geladen: Der Chat soll * auch dann laufen, wenn am Push-Teil etwas klemmt. */ -async function meldeNeueNachricht(personId, raumId, nachricht) { +/** Was in der Benachrichtigung steht. + * + * ALS EIGENE FUNKTION UND EXPORTIERT, damit eine Pruefung sie lesen + * kann, ohne einen Push-Dienst nachzubauen. Genau hier stand der + * Fehler, den Filipe am 18.09.2026 gemeldet hat -- und er war von + * aussen nicht messbar, weil der Text tief in einer Funktion entstand, + * die nur der Push-Weg aufruft. + * + * @param art "anruf" oder alles andere + * @returns {{titel: string, text: string, ziel: string}} + */ +export function pushTextFuer(art, nachricht, raumId) { + const ziel = `/workspace/chat.html?raum=${raumId}`; + + /* ---- EIN ANRUF IST KEINE NACHRICHT ---------------------------- + + Filipe: „wenn ich vanvan anrufe kriegt sie nur eine benarichtigung + aber keinen anruf was soll das." + + Gemessen kam bei ihr an: + + Nachricht von [object Object] + (kein Text) + + Zwei Fehler auf einmal. `nachricht.von` ist beim Klingeln ein + OBJEKT (`{id, name}`) und keine Zeichenkette -- aus der Vorlage + wurde deshalb „[object Object]". Und einen `text` gibt es bei + einem Anruf gar nicht, also blieb die Zeile leer. + + Dass es so weit kam, lag daran, dass die ART des Ereignisses hier + nie ankam: Jedes Ereignis wurde als Chatnachricht behandelt, auch + das Klingeln. */ + if (art === "anruf") { + const wer = nachricht.von?.name || "Jemand"; + return { + titel: `${wer} ruft an`, + text: nachricht.video ? "Videoanruf – tippen zum Rangehen" + : "Tippen zum Rangehen", + ziel, + }; + } + + return { + titel: `Nachricht von ${typeof nachricht.von === "string" + ? nachricht.von : (nachricht.von?.name || "jemandem")}`, + /* Der Anfang der Nachricht steht in der Meldung -- eine + Benachrichtigung, die nur "Neue Nachricht" sagt, zwingt zum + Öffnen, um zu erfahren, ob es wichtig war. */ + text: String(nachricht.text || "").slice(0, 120) + || (nachricht.anhang?.art === "bild" ? "Foto" + : nachricht.anhang?.art === "pdf" ? "PDF" : ""), + ziel, + }; +} + +async function meldeNeueNachricht(personId, raumId, nachricht, art = "neu") { try { const { benachrichtige } = await import("./workspace-push.js"); - await benachrichtige(personId, "chat_nachricht", { - titel: `Nachricht von ${nachricht.von}`, - /* Der Anfang der Nachricht steht in der Meldung -- eine - Benachrichtigung, die nur "Neue Nachricht" sagt, zwingt zum - Öffnen, um zu erfahren, ob es wichtig war. */ - text: String(nachricht.text || "").slice(0, 120) - || (nachricht.anhang?.art === "bild" ? "Foto" - : nachricht.anhang?.art === "pdf" ? "PDF" : ""), - ziel: `/workspace/chat.html?raum=${raumId}`, - }); + + /* ---- EIN ANRUF IST KEINE NACHRICHT (18.09.2026) -------------- + + Filipe: „wenn ich vanvan anrufe kriegt sie nur eine + benarichtigung aber keinen anruf was soll das." + + Gemessen kam bei ihr an: + + Nachricht von [object Object] + (kein Text) + + Zwei Fehler auf einmal. `nachricht.von` ist beim Klingeln ein + OBJEKT (`{id, name}`) und keine Zeichenkette -- aus der Vorlage + wurde deshalb „[object Object]". Und einen `text` gibt es bei + einem Anruf gar nicht, also blieb die Zeile leer. + + Dass es ueberhaupt so weit kam, lag daran, dass die ART des + Ereignisses hier nie ankam: Jedes Ereignis wurde als + Chatnachricht behandelt, auch das Klingeln. + + Jetzt steht dort, was los ist -- und beim Tippen landet man im + richtigen Gespraech, wo es dank der Route `/anruf/offen` auch + wirklich klingelt. */ + await benachrichtige(personId, "chat_nachricht", + pushTextFuer(art, nachricht, raumId)); } catch (fehler) { console.error("[chat] Benachrichtigung:", fehler?.message); } diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index 5fb5eef7..51957fe9 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609182214", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609182254", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609182214", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609182254", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609182214", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609182254", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609182214", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609182254", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/assets/js/anruf.js b/workspace/assets/js/anruf.js index ed5a6e77..5230f1ed 100644 --- a/workspace/assets/js/anruf.js +++ b/workspace/assets/js/anruf.js @@ -678,6 +678,34 @@ const i = await fetch('/workspace/api/ich', { credentials: 'same-origin' }); if (i.ok) ichId = (await i.json())?.id ?? null; } catch { /* der Chat holt es ohnehin auch */ } + + /* ---- KLINGELT GERADE ETWAS? (18.09.2026) ---------------------- + + Filipe: „wenn ich vanvan anrufe kriegt sie nur eine + benarichtigung aber keinen anruf." + + Genau so war es: Das Klingeln kam ausschliesslich ueber den + offenen Ereignisstrom. Wer die Seite nicht offen hatte, bekam + die Benachrichtigung, tippte darauf -- und landete auf einer + stillen Seite. Das Ereignis war vorbei, bevor sie geladen war. + + Der Anruf funktionierte damit fuer alle ausser denen, fuer die + die Benachrichtigung ueberhaupt gedacht ist. + + ERST NACH `ichId`: Die Klingel prueft, ob der Anruf vom eigenen + Konto kommt. Ohne die Nummer wuerde sie beim eigenen Anruf in + einem zweiten Fenster mitlaeuten. */ + try { + const a = await fetch('/workspace/api/anruf/offen', { credentials: 'same-origin' }); + if (a.ok) { + for (const r of ((await a.json())?.anrufe || [])) { + if (!r.von || r.von.id === ichId) continue; + if (anruf) break; /* telefoniert schon */ + klingelnZeigen(r.raum_id, r.von, r.video); + break; /* einer reicht */ + } + } + } catch { /* dann eben nur ueber den Ereignisstrom */ } void gruppeMax; })(); diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index e86c2bda..a51e7dae 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -12,19 +12,19 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - + @@ -291,10 +291,10 @@ - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index abc7b75a..cdf25624 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -168,10 +168,10 @@ - - - - - + + + + + diff --git a/workspace/befinden.html b/workspace/befinden.html index 4c67e032..9123c954 100644 --- a/workspace/befinden.html +++ b/workspace/befinden.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -105,9 +105,9 @@ - - - - + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index 8348aa4e..218e8570 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -12,24 +12,24 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - - + + - + @@ -251,14 +251,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/workspace/bewerben.html b/workspace/bewerben.html index 039f13bd..9115d3b0 100644 --- a/workspace/bewerben.html +++ b/workspace/bewerben.html @@ -7,17 +7,17 @@ - - - - - - - - - + + + + + + + + + - + @@ -108,10 +108,10 @@ - - - - - + + + + + diff --git a/workspace/bewerbungen.html b/workspace/bewerbungen.html index f8d9e647..c4aa1fc8 100644 --- a/workspace/bewerbungen.html +++ b/workspace/bewerbungen.html @@ -7,16 +7,16 @@ - - - - - - - - + + + + + + + + - + @@ -80,10 +80,10 @@ - - - - - + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index ceaf4b96..d4075271 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -89,11 +89,11 @@ - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index 18671e02..ba895fad 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -12,26 +12,26 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -341,15 +341,15 @@ - - - - + + + + - - + + diff --git a/workspace/content.html b/workspace/content.html index 526c9120..7a79122b 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -179,12 +179,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/crew-index.html b/workspace/crew-index.html index ef717748..83595de2 100644 --- a/workspace/crew-index.html +++ b/workspace/crew-index.html @@ -36,15 +36,15 @@ - - - + + + - + @@ -339,6 +339,6 @@ - + diff --git a/workspace/crew.webmanifest b/workspace/crew.webmanifest index 5a9fa25f..8ec7fea3 100644 --- a/workspace/crew.webmanifest +++ b/workspace/crew.webmanifest @@ -22,25 +22,25 @@ }, "icons": [ { - "src": "/assets/img/app-symbole/crew-192.png?v=202609182214", + "src": "/assets/img/app-symbole/crew-192.png?v=202609182254", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-512.png?v=202609182214", + "src": "/assets/img/app-symbole/crew-512.png?v=202609182254", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609182214", + "src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609182254", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609182214", + "src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609182254", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/dateien.html b/workspace/dateien.html index 4e992b42..e62f3d4c 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -108,10 +108,10 @@ - - - - - + + + + + diff --git a/workspace/entwicklung.html b/workspace/entwicklung.html index ad205734..9618a15a 100644 --- a/workspace/entwicklung.html +++ b/workspace/entwicklung.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -102,9 +102,9 @@ - - - - + + + + diff --git a/workspace/index.html b/workspace/index.html index e671f6a4..bb23cb96 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -30,9 +30,9 @@ - - - + + + @@ -401,6 +401,6 @@ - + diff --git a/workspace/kalender.html b/workspace/kalender.html index 4c490828..353cda8e 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -377,11 +377,11 @@ - - - - - - + + + + + + diff --git a/workspace/leistung.html b/workspace/leistung.html index a2df55df..0b0672dd 100644 --- a/workspace/leistung.html +++ b/workspace/leistung.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -444,10 +444,10 @@ - - - - - + + + + + diff --git a/workspace/personen.html b/workspace/personen.html index 70376eb9..84da6289 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -423,10 +423,10 @@ - - - - - + + + + + diff --git a/workspace/profil.html b/workspace/profil.html index 1eb95b37..f4572a33 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -214,11 +214,11 @@ - - - - - - + + + + + + diff --git a/workspace/rechte.html b/workspace/rechte.html index be14db3d..7fe147e8 100644 --- a/workspace/rechte.html +++ b/workspace/rechte.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -134,9 +134,9 @@ Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen, die seit dem 07.09. jede Seite danach absucht. --> - - - - + + + + diff --git a/workspace/report.html b/workspace/report.html index d4390657..cae79a6f 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -106,11 +106,11 @@ - - - - - - + + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index 7f530e1e..4e8ca00d 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -173,10 +173,10 @@ - - - - - + + + + + diff --git a/workspace/start.html b/workspace/start.html index e68b6e9d..3b792967 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -12,21 +12,21 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - + + - + @@ -678,10 +678,10 @@

- - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index 25a4754d..f58898d2 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -85,11 +85,11 @@ - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index 464d73e9..cea5b780 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -146,11 +146,11 @@ - - - - - - + + + + + + diff --git a/workspace/talente.html b/workspace/talente.html index 57a5aee1..28817fca 100644 --- a/workspace/talente.html +++ b/workspace/talente.html @@ -7,18 +7,18 @@ - - - - - - + + + + + + - - - + + + @@ -111,9 +111,9 @@ - - - - + + + + diff --git a/workspace/team.html b/workspace/team.html index 467e91e5..e7fd3751 100644 --- a/workspace/team.html +++ b/workspace/team.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + @@ -110,10 +110,10 @@ - - - - - + + + + + diff --git a/workspace/teamlage.html b/workspace/teamlage.html index 1e332597..4f80ec51 100644 --- a/workspace/teamlage.html +++ b/workspace/teamlage.html @@ -7,20 +7,20 @@ - - - - - - - + + + + + + + - + - - - - + + + + diff --git a/workspace/teilen.html b/workspace/teilen.html index 2a4feeae..2f22e31e 100644 --- a/workspace/teilen.html +++ b/workspace/teilen.html @@ -7,13 +7,13 @@ - - - - - - - + + + + + + + @@ -112,9 +112,9 @@ - - - - + + + + diff --git a/workspace/treff-moderation.html b/workspace/treff-moderation.html index db09ddde..fc0e1644 100644 --- a/workspace/treff-moderation.html +++ b/workspace/treff-moderation.html @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + @@ -126,9 +126,9 @@ - - - - + + + + diff --git a/workspace/treff-regeln.html b/workspace/treff-regeln.html index d97f5161..5c9798af 100644 --- a/workspace/treff-regeln.html +++ b/workspace/treff-regeln.html @@ -7,18 +7,18 @@ - - - - - - - + + + + + + + - + @@ -221,10 +221,10 @@ Beim ersten Anlauf fehlte die Zeile auf genau diesen beiden neuen Seiten. Gefunden hat das nicht das Auge, sondern pruef-css-klassen, die seit dem 07.09. jede Seite danach absucht. --> - - - - - + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index b5c51d34..24e67bc0 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -12,22 +12,22 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - + + + + - - - + + + - + @@ -149,11 +149,11 @@ - + - - - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 7f052dfc..b1f60d3c 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -12,20 +12,20 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - - + + + + + + + - + @@ -190,10 +190,10 @@ - - - - - + + + + +