Die TikTok-Datei des Creators -- ohne Entwicklerkonto
Filipe: "tiktok entwicklerkonto hab ich nicht und werd ich nicht
bekommen."
Damit sind zwei der drei Wege aus dem Plan vom 10.09. erledigt: Login
Kit und die Datenportabilitaets-API haengen beide an einer App auf
developers.tiktok.com. Sie sind nicht verschoben, sie sind weg.
DER DRITTE BRAUCHT KEINES. Jeder TikTok-Nutzer kann seine eigenen Daten
selbst herunterladen (Profil -> Einstellungen -> Konto -> Deine Daten
herunterladen, Format JSON). Die Datei enthaelt laut TikToks eigener
Datentypen-Liste einen Abschnitt "TikTok LIVE" mit dem Go-LIVE-Verlauf.
Der Creator gibt sie her, mit eigenen Haenden -- legitimer wird es
nicht, und es ist jetzt der einzige verbliebene Weg an TikTok-Daten.
ICH KENNE DAS FORMAT NICHT -- UND BAUE TROTZDEM.
TikTok dokumentiert, DASS es den Verlauf gibt, nicht wie die Schluessel
heissen. Der naheliegende Weg waere, Namen zu raten. Das waere die
schlechteste Loesung: Er fiele bei der ersten echten Datei auseinander,
und zwar STILL -- "0 Eintraege gefunden" sieht aus wie "war nicht live".
Deshalb wird gesucht statt geraten. Der Leser geht die Datei durch,
sammelt ALLE Listen, deren Eintraege ein Datum tragen (gemessen am
INHALT, nicht am Feldnamen), schlaegt eine Zuordnung vor und legt sie
zur Auswahl vor -- mit Anzahl, Zeitraum, Beispielzeile und dem, was
dabei herauskaeme. Bestaetigt wird von Hand. Damit ist der Leser
unabhaengig davon, wie die Felder heissen.
DIE EINHEIT IST DIE FALLE. "83" kann Sekunden, Minuten oder Stunden
sein. Geraten wird NICHT aus der Zahl, sondern aus dem Schluesselnamen
-- und wo der schweigt, aus der Form ("01:23:45" ist eindeutig).
Schweigen beide, kommt null zurueck. Eine Dauer, die um Faktor 60
danebenliegt, sieht richtig aus und ist es nicht.
MEHRERE LIVES AN EINEM TAG SIND EIN TAG: Dauer und Diamanten addiert,
bei den Zuschauern gewinnt die hoehere Spitze -- ein Durchschnitt aus
zwei Streams waere eine Zahl, die es nie gegeben hat.
DIE DATEI UEBERSCHREIBT NICHTS. Anders als der Backstage-Import, der
die Wahrheit der Agentur bringt, ist diese Datei die ZWEITE Quelle. Wo
schon eine Zahl steht -- von Hand oder aus Backstage --, bleibt sie
stehen (COALESCE statt REPLACE). Sonst wuerde ein Dateiupload
stillschweigend die offiziellen Zahlen ersetzen, und niemand wuesste
hinterher, welche gilt.
UND SIE WIRD NICHT GESPEICHERT. Gelesen, ausgewertet, verworfen. In
derselben Datei stehen Direktnachrichten, Such- und Ansehverlauf; die
haben auf diesem Server nichts zu suchen. "Income and Wallet" bleibt
ebenfalls liegen: Diamanten sind Leistung, Auszahlungen sind Gehalt.
GEPRUEFT OHNE ECHTE DATEI -- MIT DREI ERFUNDENEN (47 Pruefungen):
A englisch, flach, Dauer in Sekunden
B deutsch, verschachtelt, Dauer als "01:23:45"
C Sekundenstempel, Dauer in Minuten, andere Namen
+ eine Datei ganz ohne Verlauf -> muss abgelehnt werden
Eine Pruefung gegen EINE ausgedachte Form wuerde nur beweisen, dass
mein Leser meine eigene Erfindung liest. Drei verschiedene zeigen, dass
er das Prinzip kann und nicht eine Form.
EIN EIGENER FEHLER, von der Pruefung gefunden: Der Nachrichtenverlauf
in Form A hatte nur EINEN Eintrag und fiel damit unter die
Mindestgroesse von zwei. Die Pruefung "der LIVE-Verlauf steht oben"
hatte danach nur einen Kandidaten und bewies gar nichts -- eine
Rangfolge laesst sich nur an mindestens zwei Dingen zeigen. Jetzt sind
es drei Nachrichten, und die Rangfolge ist wirklich gemessen.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,295 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
DIE TIKTOK-DATEI EINES CREATORS — und warum sie ohne Beispieldatei
|
||||||
|
trotzdem prüfbar ist.
|
||||||
|
|
||||||
|
Filipe, 11.09.2026: "tiktok entwicklerkonto hab ich nicht und werd
|
||||||
|
ich nicht bekommen." Damit sind Login Kit und Datenportabilitäts-API
|
||||||
|
erledigt. Übrig bleibt der Weg, der keines braucht: Der Creator lädt
|
||||||
|
seine eigenen Daten herunter und gibt die Datei her.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
DAS PRÜFPROBLEM
|
||||||
|
|
||||||
|
Ich habe keine echte Datei. TikTok dokumentiert, DASS es einen
|
||||||
|
Go-LIVE-Verlauf gibt, nicht wie die Schlüssel heissen. Eine Prüfung
|
||||||
|
gegen EINE ausgedachte Form würde nur beweisen, dass mein Leser meine
|
||||||
|
eigene Erfindung liest.
|
||||||
|
|
||||||
|
DESHALB DREI FORMEN, absichtlich verschieden:
|
||||||
|
|
||||||
|
A englisch, flach, Dauer in Sekunden
|
||||||
|
B deutsch, verschachtelt, Dauer als "01:23:45"
|
||||||
|
C Zeitstempel als Sekundenzahl, Dauer in Minuten, andere Namen
|
||||||
|
|
||||||
|
Besteht der Leser alle drei, hat er nicht eine Form gelernt, sondern
|
||||||
|
das Prinzip: Listen mit Datum finden, Felder vorschlagen, den
|
||||||
|
Menschen bestätigen lassen. Und dazu eine vierte Datei, die KEINEN
|
||||||
|
Verlauf enthält -- sie muss abgelehnt werden, sonst hiesse "es
|
||||||
|
funktioniert" nur "es sagt immer ja".
|
||||||
|
|
||||||
|
Aufruf: node server/pruef-tiktok-datei.mjs
|
||||||
|
===================================================================== */
|
||||||
|
import { mkdtempSync, rmSync } from "node:fs";
|
||||||
|
import { tmpdir } from "node:os";
|
||||||
|
import { join, dirname } from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { spawn } from "node:child_process";
|
||||||
|
import { DatabaseSync } from "node:sqlite";
|
||||||
|
import { scryptSync, randomBytes } from "node:crypto";
|
||||||
|
import { notbremse } from "./helfer-notbremse.mjs";
|
||||||
|
import { tagAus, minutenAus, kandidatenFinden, listeAmPfad, zuTagen } from "./workspace-tiktok-datei.js";
|
||||||
|
|
||||||
|
notbremse(240_000, "pruef-tiktok-datei");
|
||||||
|
|
||||||
|
const HIER = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const PORT = 4391;
|
||||||
|
const BASIS = `http://127.0.0.1:${PORT}`;
|
||||||
|
const ordner = mkdtempSync(join(tmpdir(), "ws-ttdatei-"));
|
||||||
|
const DB = join(ordner, "workspace.db");
|
||||||
|
const jetzt = new Date().toISOString();
|
||||||
|
|
||||||
|
let gemacht = 0, fehler = 0;
|
||||||
|
const ok = (b, text) => {
|
||||||
|
gemacht++;
|
||||||
|
if (b) console.log(` ok ${text}`);
|
||||||
|
else { fehler++; console.log(` FEHL ${text}`); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
TEIL 1: Die Bausteine allein -- ohne Server, ohne Browser
|
||||||
|
======================================================================= */
|
||||||
|
console.log("=== Datum lesen ===");
|
||||||
|
ok(tagAus("2026-09-10 21:14:03") === "2026-09-10", "Text mit Uhrzeit");
|
||||||
|
ok(tagAus("2026-09-10T19:14:03.000Z") === "2026-09-10", "ISO");
|
||||||
|
ok(tagAus("10.09.2026") === "2026-09-10", "deutsches Datum");
|
||||||
|
ok(tagAus(1757538843) === new Date(1757538843000).toISOString().slice(0, 10),
|
||||||
|
"Sekundenstempel");
|
||||||
|
ok(tagAus(1757538843000) === new Date(1757538843000).toISOString().slice(0, 10),
|
||||||
|
"Millisekundenstempel");
|
||||||
|
/* GEGENPROBEN: Was KEIN Datum ist, darf auch keines werden. */
|
||||||
|
ok(tagAus("Just Chatting") === null, "ein Text ist kein Datum");
|
||||||
|
ok(tagAus(42) === null, "eine kleine Zahl ist kein Datum (Jahr 1970)");
|
||||||
|
ok(tagAus("1999-01-01") === null, "vor 2016 gab es TikTok nicht");
|
||||||
|
ok(tagAus(null) === null, "und nichts ist nichts");
|
||||||
|
|
||||||
|
console.log("\n=== Dauer lesen -- die Einheit ist die Falle ===");
|
||||||
|
ok(minutenAus("01:23:45") === 83.75, `"01:23:45" sind 83,75 Minuten (${minutenAus("01:23:45")})`);
|
||||||
|
ok(minutenAus("23:45") === 23.75, `"23:45" sind 23,75 Minuten (${minutenAus("23:45")})`);
|
||||||
|
ok(minutenAus(5025, "duration_seconds") === 83.75, "5025 Sekunden sind 83,75 Minuten");
|
||||||
|
ok(minutenAus(84, "dauer_minuten") === 84, "84 Minuten bleiben 84");
|
||||||
|
ok(minutenAus(2, "hours_live") === 120, "2 Stunden sind 120 Minuten");
|
||||||
|
ok(minutenAus("2h 15m") === 135, `"2h 15m" sind 135 Minuten (${minutenAus("2h 15m")})`);
|
||||||
|
/* DIE WICHTIGSTE GEGENPROBE: Sagt der Name nichts und die Form nichts,
|
||||||
|
wird NICHTS geraten. Eine Dauer, die um Faktor 60 danebenliegt, sieht
|
||||||
|
richtig aus und ist es nicht. */
|
||||||
|
ok(minutenAus(83, "wert") === null, "eine nackte Zahl ohne Einheit ergibt null, nicht 83");
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
TEIL 2: Drei Dateiformen
|
||||||
|
======================================================================= */
|
||||||
|
const FORM_A = { // englisch, flach, Sekunden
|
||||||
|
Profile: { username: "nova" },
|
||||||
|
"TikTok Live": {
|
||||||
|
"Go Live History": [
|
||||||
|
{ start_time: "2026-09-08 20:00:00", duration_seconds: 5400, total_diamonds: "1200", peak_viewers: 310 },
|
||||||
|
{ start_time: "2026-09-08 23:30:00", duration_seconds: 1800, total_diamonds: "300", peak_viewers: 120 },
|
||||||
|
{ start_time: "2026-09-09 21:00:00", duration_seconds: 7200, total_diamonds: "2450", peak_viewers: 512 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
/* DREI Nachrichten, nicht eine. Beim ersten Anlauf stand hier EINE,
|
||||||
|
und damit fiel der Verlauf unter die Mindestgrösse von zwei
|
||||||
|
Einträgen -- die Prüfung "der LIVE-Verlauf steht oben" hatte danach
|
||||||
|
nur einen Kandidaten und bewies gar nichts. Eine Rangfolge lässt
|
||||||
|
sich nur an mindestens zwei Dingen zeigen. */
|
||||||
|
"Direct Messages": {
|
||||||
|
ChatHistory: [
|
||||||
|
{ Date: "2026-09-01 10:00:00", Content: "hi" },
|
||||||
|
{ Date: "2026-09-02 11:00:00", Content: "und?" },
|
||||||
|
{ Date: "2026-09-03 12:00:00", Content: "bis dann" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const FORM_B = { // deutsch, verschachtelt, hh:mm:ss
|
||||||
|
Konto: { Nutzername: "kiro" },
|
||||||
|
Aktivität: {
|
||||||
|
LIVE: {
|
||||||
|
Verlauf: [
|
||||||
|
{ Datum: "08.09.2026", Dauer: "01:30:00", Diamanten: "1.200", "Höchste Zuschauer": "310" },
|
||||||
|
{ Datum: "09.09.2026", Dauer: "02:00:00", Diamanten: "2.450", "Höchste Zuschauer": "512" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const FORM_C = { // Stempel + Minuten, andere Namen
|
||||||
|
live_sessions: [
|
||||||
|
{ started_at: 1757361600, live_minutes: 90, gift_count: 1200, audience_peak: 310 },
|
||||||
|
{ started_at: 1757448000, live_minutes: 120, gift_count: 2450, audience_peak: 512 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const FORM_LEER = { // kein Verlauf
|
||||||
|
Profile: { username: "lumi" },
|
||||||
|
Settings: { language: "de", theme: "dark" },
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("\n=== Drei verschiedene Dateiformen -- und eine ohne Verlauf ===");
|
||||||
|
for (const [name, datei, erwarteteTage] of [["A englisch/Sekunden", FORM_A, 2],
|
||||||
|
["B deutsch/hh:mm:ss", FORM_B, 2], ["C Stempel/Minuten", FORM_C, 2]]) {
|
||||||
|
const k = kandidatenFinden(datei);
|
||||||
|
ok(k.length >= 1, `${name}: eine Liste gefunden (${k.length})`);
|
||||||
|
const beste = k[0];
|
||||||
|
const liste = listeAmPfad(datei, beste.pfad);
|
||||||
|
ok(Array.isArray(liste) && liste.length >= 2,
|
||||||
|
`${name}: die Liste ist wieder auffindbar (${liste?.length} Einträge)`);
|
||||||
|
const { tage } = zuTagen(liste, beste.vorschlag);
|
||||||
|
ok(tage.length === erwarteteTage,
|
||||||
|
`${name}: ${tage.length} Tage (erwartet ${erwarteteTage})`);
|
||||||
|
/* Form A hat ZWEI Lives am 8. September -- sie müssen zu EINEM Tag
|
||||||
|
mit 120 Minuten zusammenfallen. Das ist der Fall, an dem sich
|
||||||
|
zeigt, ob addiert statt überschrieben wird. */
|
||||||
|
if (name.startsWith("A")) {
|
||||||
|
const achter = tage.find((t) => t.tag === "2026-09-08");
|
||||||
|
ok(achter?.lives === 2, `A: der 8. hat zwei Lives (${achter?.lives})`);
|
||||||
|
ok(achter?.dauer_min === 120, `A: und zusammen 120 Minuten (${achter?.dauer_min})`);
|
||||||
|
ok(achter?.diamanten === 1500, `A: und 1500 Diamanten (${achter?.diamanten})`);
|
||||||
|
ok(achter?.zuschauer_max === 310, `A: Spitze ist die höhere der beiden (${achter?.zuschauer_max})`);
|
||||||
|
}
|
||||||
|
if (name.startsWith("B")) {
|
||||||
|
const t = tage.find((x) => x.tag === "2026-09-09");
|
||||||
|
ok(t?.dauer_min === 120, `B: "02:00:00" wurde zu 120 Minuten (${t?.dauer_min})`);
|
||||||
|
ok(t?.diamanten === 2450, `B: "2.450" wurde zu 2450 (${t?.diamanten})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const k = kandidatenFinden(FORM_LEER);
|
||||||
|
ok(k.length === 0, `eine Datei ohne Verlauf ergibt keine Kandidaten (${k.length})`);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
/* UND DER VERLAUF MUSS OBEN STEHEN. Form A enthält auch einen
|
||||||
|
Nachrichtenverlauf mit Datum -- der ist ebenfalls ein gültiger
|
||||||
|
Kandidat, darf aber nicht der erste Vorschlag sein. */
|
||||||
|
const k = kandidatenFinden(FORM_A);
|
||||||
|
ok(k.length >= 2, `A: auch die Nachrichten werden als Liste erkannt (${k.length} Kandidaten)`);
|
||||||
|
ok(/live/i.test(k[0].pfad), `A: vorgeschlagen wird aber der LIVE-Verlauf ("${k[0].pfad}")`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =======================================================================
|
||||||
|
TEIL 3: Der ganze Weg über den Server
|
||||||
|
======================================================================= */
|
||||||
|
let kind = null;
|
||||||
|
async function starten() {
|
||||||
|
kind = spawn(process.execPath, [join(HIER, "index.js")], {
|
||||||
|
env: { ...process.env, WORKSPACE_DB: DB, PORT: String(PORT),
|
||||||
|
SITE_ACCESS_SECRET: "lokaler-test",
|
||||||
|
SITE_PUBLIC_LAUNCH_AT: "2020-01-01T00:00:00+01:00" },
|
||||||
|
stdio: ["ignore", "pipe", "pipe"] });
|
||||||
|
let aus = "";
|
||||||
|
kind.stdout.on("data", (d) => { aus += d; });
|
||||||
|
kind.stderr.on("data", (d) => { aus += d; });
|
||||||
|
for (let i = 0; i < 80; i++) {
|
||||||
|
await new Promise((r) => setTimeout(r, 250));
|
||||||
|
if (kind.exitCode !== null) break;
|
||||||
|
try { const a = await fetch(BASIS + "/workspace/", { redirect: "manual" });
|
||||||
|
if (a.status < 500) return; } catch { /* noch nicht oben */ }
|
||||||
|
}
|
||||||
|
throw new Error("Server startete nicht:\n" + aus.slice(-1500));
|
||||||
|
}
|
||||||
|
await starten();
|
||||||
|
kind.kill();
|
||||||
|
await new Promise((r) => setTimeout(r, 600));
|
||||||
|
|
||||||
|
let idNova;
|
||||||
|
{
|
||||||
|
const d = new DatabaseSync(DB);
|
||||||
|
const anlegen = (name, rolle, code) => {
|
||||||
|
const salz = randomBytes(16).toString("hex");
|
||||||
|
const hash = scryptSync(code, salz, 64,
|
||||||
|
{ N: 32768, r: 8, p: 1, maxmem: 96 * 1024 * 1024 }).toString("hex");
|
||||||
|
d.prepare("INSERT INTO personen (name, rolle, code_hash, code_salt, code_n, aktiv, erstellt) VALUES (?,?,?,?,?,1,?)")
|
||||||
|
.run(name, rolle, hash, salz, 32768, jetzt);
|
||||||
|
return d.prepare("SELECT last_insert_rowid() AS id").get().id;
|
||||||
|
};
|
||||||
|
anlegen("Filipe", "admin", "CODE-DOGI-0001");
|
||||||
|
idNova = anlegen("Nova", "creator", "CODE-NOVA-0001");
|
||||||
|
d.close();
|
||||||
|
}
|
||||||
|
await starten();
|
||||||
|
|
||||||
|
const anmelden = async (rolle, code) => {
|
||||||
|
const a = await fetch(BASIS + "/workspace/api/anmelden", {
|
||||||
|
method: "POST", headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ rolle, code }) });
|
||||||
|
const keks = (a.headers.getSetCookie?.() || []).map((k) => k.split(";")[0]).join("; ");
|
||||||
|
if (!keks) throw new Error(`Anmeldung ${rolle} fehlgeschlagen (${a.status})`);
|
||||||
|
return keks;
|
||||||
|
};
|
||||||
|
const keksDogi = await anmelden("admin", "CODE-DOGI-0001");
|
||||||
|
const keksNova = await anmelden("creator", "CODE-NOVA-0001");
|
||||||
|
|
||||||
|
const ruf = async (weg, keks, koerper) => {
|
||||||
|
const a = await fetch(BASIS + weg, { method: "POST",
|
||||||
|
headers: { Cookie: keks, "Content-Type": "application/json", Origin: BASIS },
|
||||||
|
body: JSON.stringify(koerper) });
|
||||||
|
let daten = null; try { daten = await a.json(); } catch { /* leer erlaubt */ }
|
||||||
|
return { status: a.status, daten };
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("\n=== Über den Server ===");
|
||||||
|
let vorschlag = null;
|
||||||
|
{
|
||||||
|
const { status, daten } = await ruf(`/workspace/api/leistung/${idNova}/tiktok-datei/vorschau`,
|
||||||
|
keksDogi, { inhalt: FORM_A });
|
||||||
|
ok(status === 200, `die Vorschau liest die Datei (HTTP ${status})`);
|
||||||
|
ok(daten?.kandidaten?.length >= 1, `${daten?.kandidaten?.length} Kandidaten`);
|
||||||
|
vorschlag = daten?.kandidaten?.[0];
|
||||||
|
ok(vorschlag?.tage_gesamt === 2, `der beste ergäbe 2 Tage (${vorschlag?.tage_gesamt})`);
|
||||||
|
ok(!!vorschlag?.vorschlag?.dauer, `mit erkannter Dauerspalte (${vorschlag?.vorschlag?.dauer})`);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const { status, daten } = await ruf(`/workspace/api/leistung/${idNova}/tiktok-datei`,
|
||||||
|
keksDogi, { inhalt: FORM_A, pfad: vorschlag.pfad, zuordnung: vorschlag.vorschlag });
|
||||||
|
ok(status === 200, `die Übernahme läuft (HTTP ${status})`);
|
||||||
|
ok(daten?.geschrieben === 2, `zwei Tage geschrieben (${daten?.geschrieben})`);
|
||||||
|
|
||||||
|
const d = new DatabaseSync(DB);
|
||||||
|
const z = d.prepare("SELECT tag, dauer_min, diamanten, gueltiger_tag, quelle FROM leistung WHERE creator_id = ? ORDER BY tag").all(idNova);
|
||||||
|
ok(z.length === 2, `zwei Zeilen in der Datenbank (${z.length})`);
|
||||||
|
ok(z[0].dauer_min === 120 && z[0].diamanten === 1500,
|
||||||
|
`der 8. trägt beide Lives zusammen (${z[0].dauer_min} Min, ${z[0].diamanten} Dia)`);
|
||||||
|
ok(z.every((x) => x.gueltiger_tag === 1), "beide als gültiger Tag gezählt");
|
||||||
|
ok(z.every((x) => x.quelle === "import"), "Quelle 'import'");
|
||||||
|
d.close();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
/* DIE ENTSCHEIDENDE REGEL: Eine vorhandene Zahl wird NICHT
|
||||||
|
überschrieben. Die Datei kommt vom Creator und ist die zweite
|
||||||
|
Quelle -- Backstage und die Hand gelten mehr. */
|
||||||
|
const d = new DatabaseSync(DB);
|
||||||
|
d.prepare("UPDATE leistung SET diamanten = 9999 WHERE creator_id = ? AND tag = '2026-09-08'").run(idNova);
|
||||||
|
d.close();
|
||||||
|
await ruf(`/workspace/api/leistung/${idNova}/tiktok-datei`, keksDogi,
|
||||||
|
{ inhalt: FORM_A, pfad: vorschlag.pfad, zuordnung: vorschlag.vorschlag });
|
||||||
|
const d2 = new DatabaseSync(DB);
|
||||||
|
const z = d2.prepare("SELECT diamanten FROM leistung WHERE creator_id = ? AND tag = '2026-09-08'").get(idNova);
|
||||||
|
ok(z?.diamanten === 9999, `eine vorhandene Zahl bleibt stehen (${z?.diamanten})`);
|
||||||
|
d2.close();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const { status, daten } = await ruf(`/workspace/api/leistung/${idNova}/tiktok-datei/vorschau`,
|
||||||
|
keksDogi, { inhalt: FORM_LEER });
|
||||||
|
ok(status === 400 && /JSON|Liste/i.test(daten?.fehler || ""),
|
||||||
|
`eine Datei ohne Verlauf wird abgelehnt ("${(daten?.fehler || "").slice(0, 50)}…")`);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const { status } = await ruf(`/workspace/api/leistung/${idNova}/tiktok-datei`,
|
||||||
|
keksNova, { inhalt: FORM_A, pfad: vorschlag.pfad, zuordnung: vorschlag.vorschlag });
|
||||||
|
ok(status === 403,
|
||||||
|
`ein Creator kann sich seine Zahlen nicht selbst eintragen (HTTP ${status})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
kind.kill();
|
||||||
|
await new Promise((r) => setTimeout(r, 400));
|
||||||
|
try { rmSync(ordner, { recursive: true, force: true }); } catch { /* Zugabe */ }
|
||||||
|
|
||||||
|
console.log(`\n${gemacht} Pruefungen`);
|
||||||
|
console.log(fehler === 0 ? "ALLES IN ORDNUNG" : `${fehler} FEHLER`);
|
||||||
|
process.exit(fehler ? 1 : 0);
|
||||||
@@ -47,6 +47,7 @@ import {
|
|||||||
db, protokolliere, echteIp, sitzungLesen, istLeitung, istSpicy,
|
db, protokolliere, echteIp, sitzungLesen, istLeitung, istSpicy,
|
||||||
sichtbareCreatorIds, ROLLEN_SORTIERUNG, heuteLokal,
|
sichtbareCreatorIds, ROLLEN_SORTIERUNG, heuteLokal,
|
||||||
} from "./workspace.js";
|
} from "./workspace.js";
|
||||||
|
import { kandidatenFinden, listeAmPfad, zuTagen } from "./workspace-tiktok-datei.js";
|
||||||
|
|
||||||
export const leistungRouter = express.Router();
|
export const leistungRouter = express.Router();
|
||||||
|
|
||||||
@@ -867,6 +868,139 @@ leistungRouter.post("/workspace/api/leistung/netzwerk-import", gleicheHerkunft,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* =====================================================================
|
||||||
|
DIE EIGENE TIKTOK-DATEI EINES CREATORS (11.09.2026)
|
||||||
|
|
||||||
|
Der letzte verbliebene Weg aus dem Plan vom 10.09.: Login Kit und
|
||||||
|
Datenportabilitäts-API hängen beide an einem TikTok-Entwicklerkonto,
|
||||||
|
und das wird es nicht geben ("hab ich nicht und werd ich nicht
|
||||||
|
bekommen"). Dieser hier braucht keines -- der Creator lädt seine
|
||||||
|
eigenen Daten bei TikTok herunter und gibt die Datei her.
|
||||||
|
|
||||||
|
Das Suchen und Umrechnen steht in workspace-tiktok-datei.js; hier
|
||||||
|
stehen nur die beiden Wege und die Rechte.
|
||||||
|
|
||||||
|
DIE DATEI WIRD NICHT GESPEICHERT. Sie wird gelesen, ausgewertet und
|
||||||
|
fällt danach weg. In ihr stehen auch Direktnachrichten und der
|
||||||
|
Ansehverlauf -- das ist nichts, was auf einem Server liegen soll,
|
||||||
|
der es nicht braucht.
|
||||||
|
===================================================================== */
|
||||||
|
leistungRouter.post("/workspace/api/leistung/:creatorId/tiktok-datei/vorschau",
|
||||||
|
gleicheHerkunft, express.json({ limit: "60mb" }), (req, res) => {
|
||||||
|
try {
|
||||||
|
const creatorId = Number(req.params.creatorId);
|
||||||
|
if (!Number.isInteger(creatorId)) return res.status(400).json({ fehler: "ungueltig" });
|
||||||
|
if (!darfEintragen(req.person)) return res.status(403).json({ fehler: "nicht_erlaubt" });
|
||||||
|
if (!darfSehen(req.person, creatorId)) return res.status(404).json({ fehler: "nicht_gefunden" });
|
||||||
|
|
||||||
|
const inhalt = req.body?.inhalt;
|
||||||
|
if (!inhalt || typeof inhalt !== "object") {
|
||||||
|
return res.status(400).json({ fehler: "Das ist keine gelesene JSON-Datei." });
|
||||||
|
}
|
||||||
|
const kandidaten = kandidatenFinden(inhalt);
|
||||||
|
if (!kandidaten.length) {
|
||||||
|
return res.status(400).json({
|
||||||
|
fehler: "In dieser Datei steht keine Liste mit Datumsangaben. "
|
||||||
|
+ "Wurde beim Herunterladen wirklich JSON gewählt (nicht TXT) und "
|
||||||
|
+ "„Alles auswählen“ angehakt?",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/* Zu jedem Vorschlag gleich zeigen, was dabei herauskäme -- sonst
|
||||||
|
muss der Mensch aus Schlüsselnamen raten, welcher der richtige
|
||||||
|
ist. */
|
||||||
|
const mitVorschau = kandidaten.map((k) => {
|
||||||
|
const { tage } = zuTagen(k.beispiele.length ? listeAmPfad(inhalt, k.pfad) || [] : [], k.vorschlag);
|
||||||
|
return {
|
||||||
|
...k,
|
||||||
|
tage_gesamt: tage.length,
|
||||||
|
tage_beispiel: tage.slice(-3),
|
||||||
|
/* Die Beispielzeilen gekürzt: In einem Vollarchiv hängt an
|
||||||
|
einem Eintrag manchmal ein ganzer Kommentartext. */
|
||||||
|
beispiele: k.beispiele.map((b) => {
|
||||||
|
const klein = {};
|
||||||
|
for (const [s, w] of Object.entries(b)) klein[s] = String(w ?? "").slice(0, 80);
|
||||||
|
return klein;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
res.json({ kandidaten: mitVorschau });
|
||||||
|
} catch (fehler) {
|
||||||
|
console.error("[leistung] TikTok-Datei Vorschau:", fehler?.message);
|
||||||
|
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
leistungRouter.post("/workspace/api/leistung/:creatorId/tiktok-datei",
|
||||||
|
gleicheHerkunft, express.json({ limit: "60mb" }), (req, res) => {
|
||||||
|
try {
|
||||||
|
const creatorId = Number(req.params.creatorId);
|
||||||
|
if (!Number.isInteger(creatorId)) return res.status(400).json({ fehler: "ungueltig" });
|
||||||
|
if (!darfEintragen(req.person)) return res.status(403).json({ fehler: "nicht_erlaubt" });
|
||||||
|
if (!darfSehen(req.person, creatorId)) return res.status(404).json({ fehler: "nicht_gefunden" });
|
||||||
|
|
||||||
|
const inhalt = req.body?.inhalt;
|
||||||
|
const pfad = String(req.body?.pfad || "");
|
||||||
|
const zuordnung = req.body?.zuordnung;
|
||||||
|
if (!inhalt || !pfad || !zuordnung?.tag) {
|
||||||
|
return res.status(400).json({ fehler: "Es fehlt die Auswahl, was gelesen werden soll." });
|
||||||
|
}
|
||||||
|
const liste = listeAmPfad(inhalt, pfad);
|
||||||
|
if (!liste) return res.status(400).json({ fehler: "Diese Liste gibt es in der Datei nicht." });
|
||||||
|
|
||||||
|
const { tage, uebersprungen } = zuTagen(liste, zuordnung);
|
||||||
|
const heute = heuteLokal();
|
||||||
|
const brauchbar = tage.filter((t) => t.tag <= heute
|
||||||
|
/* Ein Tag ohne eine einzige Zahl ist keine Messung. Dieselbe
|
||||||
|
Regel wie beim Backstage-Import. */
|
||||||
|
&& (t.dauer_min !== null || t.diamanten !== null || t.zuschauer_max !== null));
|
||||||
|
if (!brauchbar.length) return res.status(400).json({ fehler: "keine_brauchbaren_tage" });
|
||||||
|
|
||||||
|
const d = db();
|
||||||
|
const schreiben = d.prepare(`
|
||||||
|
INSERT INTO leistung
|
||||||
|
(creator_id, tag, diamanten, dauer_min, gueltiger_tag, zuschauer_max,
|
||||||
|
erfasst, erfasst_von, quelle)
|
||||||
|
VALUES (?,?,?,?,?,?,?,?,'import')
|
||||||
|
ON CONFLICT(creator_id, tag) DO UPDATE SET
|
||||||
|
/* NUR FÜLLEN, NICHT ÜBERSCHREIBEN.
|
||||||
|
|
||||||
|
Anders als beim Backstage-Import, der die Wahrheit der
|
||||||
|
Agentur bringt: Diese Datei kommt vom Creator und ist eine
|
||||||
|
ZWEITE Quelle. Wo schon eine Zahl steht -- von Hand
|
||||||
|
eingetragen oder aus Backstage --, bleibt sie stehen.
|
||||||
|
Andersherum würde ein Dateiupload stillschweigend die
|
||||||
|
offiziellen Zahlen ersetzen, und niemand wüsste hinterher,
|
||||||
|
welche gilt. */
|
||||||
|
diamanten = COALESCE(leistung.diamanten, excluded.diamanten),
|
||||||
|
dauer_min = COALESCE(leistung.dauer_min, excluded.dauer_min),
|
||||||
|
zuschauer_max = COALESCE(leistung.zuschauer_max, excluded.zuschauer_max),
|
||||||
|
gueltiger_tag = MAX(leistung.gueltiger_tag, excluded.gueltiger_tag)`);
|
||||||
|
|
||||||
|
let geschrieben = 0, ergaenzt = 0;
|
||||||
|
const vorhanden = d.prepare("SELECT 1 FROM leistung WHERE creator_id = ? AND tag = ?");
|
||||||
|
d.exec("BEGIN");
|
||||||
|
try {
|
||||||
|
for (const t of brauchbar) {
|
||||||
|
const gabEs = !!vorhanden.get(creatorId, t.tag);
|
||||||
|
schreiben.run(creatorId, t.tag, t.diamanten, t.dauer_min,
|
||||||
|
(t.dauer_min ?? 0) > 0 ? 1 : 0, t.zuschauer_max,
|
||||||
|
new Date().toISOString(), req.person.id);
|
||||||
|
if (gabEs) ergaenzt++; else geschrieben++;
|
||||||
|
}
|
||||||
|
d.exec("COMMIT");
|
||||||
|
} catch (f) { d.exec("ROLLBACK"); throw f; }
|
||||||
|
|
||||||
|
protokolliere("leistung_tiktok_datei", {
|
||||||
|
personId: req.person.id, rolle: req.person.rolle, ip: echteIp(req),
|
||||||
|
detail: `Creator #${creatorId}: ${geschrieben} neu, ${ergaenzt} ergaenzt`.slice(0, 120),
|
||||||
|
});
|
||||||
|
res.json({ geschrieben, ergaenzt, uebersprungen: uebersprungen.length });
|
||||||
|
} catch (fehler) {
|
||||||
|
console.error("[leistung] TikTok-Datei:", fehler?.message);
|
||||||
|
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/** Vorschau: Was WÜRDE passieren? Schreibt nichts. */
|
/** Vorschau: Was WÜRDE passieren? Schreibt nichts. */
|
||||||
leistungRouter.post("/workspace/api/leistung/:creatorId/import/vorschau", gleicheHerkunft,
|
leistungRouter.post("/workspace/api/leistung/:creatorId/import/vorschau", gleicheHerkunft,
|
||||||
express.json({ limit: "2mb" }), (req, res) => {
|
express.json({ limit: "2mb" }), (req, res) => {
|
||||||
|
|||||||
@@ -0,0 +1,263 @@
|
|||||||
|
/* =====================================================================
|
||||||
|
workspace-tiktok-datei.js — die eigenen TikTok-Daten eines Creators.
|
||||||
|
|
||||||
|
Filipe, 10.09.2026: "wie sehr wir diese seite hier mit dem backstage
|
||||||
|
verbinden könnten von tiktok. ohne probleme und ganz schnell."
|
||||||
|
Am 11.09.2026: "tiktok entwicklerkonto hab ich nicht und werd ich
|
||||||
|
nicht bekommen."
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
WARUM ES DIESEN WEG ÜBERHAUPT GIBT
|
||||||
|
|
||||||
|
Die Recherche vom 10.09. hat drei Wege ergeben. Zwei davon sind seit
|
||||||
|
dem 11.09. erledigt: Login Kit und die Datenportabilitäts-API hängen
|
||||||
|
beide an einem Entwicklerkonto bei TikTok, und das wird es nicht
|
||||||
|
geben.
|
||||||
|
|
||||||
|
Der dritte braucht keines. Jeder TikTok-Nutzer kann seine eigenen
|
||||||
|
Daten selbst herunterladen -- Profil → Einstellungen → Konto → Deine
|
||||||
|
Daten herunterladen, Format JSON. Die Datei enthält laut TikToks
|
||||||
|
eigener Datentypen-Liste einen Abschnitt "TikTok LIVE" mit dem
|
||||||
|
Go-LIVE-Verlauf. Der Creator lädt sie hier hoch, und zwar mit seinen
|
||||||
|
eigenen Händen -- legitimer wird es nicht.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
DAS EIGENTLICHE PROBLEM: ICH KENNE DAS FORMAT NICHT
|
||||||
|
|
||||||
|
Ich habe keine echte Datei gesehen. TikTok dokumentiert, DASS es
|
||||||
|
"Go LIVE History" gibt, nicht WIE die Schlüssel heissen. Sie können
|
||||||
|
deutsch oder englisch sein, verschachtelt oder flach, und sie können
|
||||||
|
sich ändern, ohne dass jemand Bescheid sagt.
|
||||||
|
|
||||||
|
DER NAHELIEGENDE WEG WÄRE, Schlüsselnamen zu raten und einen Leser
|
||||||
|
darauf zu bauen. Das wäre die schlechteste Lösung: Er würde bei der
|
||||||
|
ersten echten Datei auseinanderfallen, und zwar STILL -- "0 Einträge
|
||||||
|
gefunden" sieht aus wie "der Creator war nicht live".
|
||||||
|
|
||||||
|
DESHALB WIRD NICHT GERATEN, SONDERN GESUCHT. Der Leser geht die
|
||||||
|
Datei durch, sammelt alle Listen von Einträgen, die ein Datum
|
||||||
|
enthalten, und legt sie zur Auswahl vor -- mit Anzahl, Zeitraum und
|
||||||
|
Beispielzeile. Der Mensch bestätigt, was davon der LIVE-Verlauf ist.
|
||||||
|
|
||||||
|
Damit ist der Leser unabhängig davon, wie die Felder heissen. Er
|
||||||
|
schlägt etwas vor (nach Namensmustern), aber er entscheidet nicht.
|
||||||
|
Und wenn TikTok das Format ändert, ändert sich nur der Vorschlag,
|
||||||
|
nicht die Brauchbarkeit.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
WAS BEWUSST NICHT GELESEN WIRD
|
||||||
|
|
||||||
|
Das Vollarchiv enthält auch "Income and Wallet" -- Transaktionen und
|
||||||
|
Auszahlungen. Das bleibt liegen. Diamanten sind Leistung,
|
||||||
|
Auszahlungen sind Gehalt, und diese Seite ist eine Arbeitslage, keine
|
||||||
|
Gehaltsakte (dieselbe Linie wie bei der Team-Lage).
|
||||||
|
|
||||||
|
Ebenso liegen bleiben: Direktnachrichten, Suchverlauf, Ansehverlauf.
|
||||||
|
Sie stehen in derselben Datei. Der Leser rührt sie nicht an, und die
|
||||||
|
Datei selbst wird NICHT gespeichert -- gelesen, ausgewertet,
|
||||||
|
verworfen.
|
||||||
|
===================================================================== */
|
||||||
|
|
||||||
|
/** Wie tief darf gesucht werden? Ein Vollarchiv ist verschachtelt, aber
|
||||||
|
* nicht beliebig tief. Die Grenze verhindert, dass eine kaputte Datei
|
||||||
|
* den Server beschäftigt. */
|
||||||
|
const MAX_TIEFE = 8;
|
||||||
|
/** Mehr als so viele Listen werden nicht zur Auswahl gestellt -- wer
|
||||||
|
* fünfzig Vorschläge bekommt, liest keinen. */
|
||||||
|
const MAX_KANDIDATEN = 8;
|
||||||
|
|
||||||
|
/** Ein Datum aus einem beliebigen Wert. Gibt "JJJJ-MM-TT" oder null.
|
||||||
|
*
|
||||||
|
* TikTok schreibt Zeitpunkte üblicherweise als "2026-09-10 21:14:03"
|
||||||
|
* oder als ISO-Zeichenkette; Sekundenstempel kommen ebenfalls vor.
|
||||||
|
* Alle drei werden erkannt -- und alles andere ausdrücklich nicht. */
|
||||||
|
export function tagAus(wert) {
|
||||||
|
if (wert === null || wert === undefined) return null;
|
||||||
|
if (typeof wert === "number") {
|
||||||
|
/* Sekunden oder Millisekunden? Ein Stempel in Sekunden liegt 2026
|
||||||
|
bei rund 1,8 Milliarden, in Millisekunden bei 1,8 Billionen.
|
||||||
|
Die Grenze dazwischen ist eindeutig. */
|
||||||
|
const ms = wert > 1e11 ? wert : wert * 1000;
|
||||||
|
const d = new Date(ms);
|
||||||
|
if (Number.isNaN(d.getTime())) return null;
|
||||||
|
const j = d.getFullYear();
|
||||||
|
if (j < 2016 || j > 2100) return null; // TikTok gibt es seit 2016
|
||||||
|
return d.toISOString().slice(0, 10);
|
||||||
|
}
|
||||||
|
const t = String(wert).trim();
|
||||||
|
const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(t);
|
||||||
|
if (m) {
|
||||||
|
const j = Number(m[1]);
|
||||||
|
if (j < 2016 || j > 2100) return null;
|
||||||
|
return `${m[1]}-${m[2]}-${m[3]}`;
|
||||||
|
}
|
||||||
|
const d = /^(\d{1,2})\.(\d{1,2})\.(\d{4})/.exec(t);
|
||||||
|
if (d) return `${d[3]}-${String(d[2]).padStart(2, "0")}-${String(d[1]).padStart(2, "0")}`;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Eine Dauer in MINUTEN aus einem beliebigen Wert.
|
||||||
|
*
|
||||||
|
* DIE EINHEIT IST DIE FALLE. "83" kann 83 Sekunden, 83 Minuten oder
|
||||||
|
* 83 Stunden heissen. Geraten wird deshalb NICHT aus der Zahl, sondern
|
||||||
|
* aus dem SCHLÜSSELNAMEN -- und wo der nichts sagt, aus der Form des
|
||||||
|
* Wertes ("01:23:45" ist eindeutig).
|
||||||
|
*
|
||||||
|
* Bleibt beides stumm, wird null zurückgegeben statt einer plausiblen
|
||||||
|
* Zahl. Eine Dauer, die um den Faktor 60 danebenliegt, sieht richtig
|
||||||
|
* aus und ist es nicht. */
|
||||||
|
export function minutenAus(wert, schluessel = "") {
|
||||||
|
if (wert === null || wert === undefined || wert === "") return null;
|
||||||
|
const name = String(schluessel).toLowerCase();
|
||||||
|
|
||||||
|
const t = String(wert).trim();
|
||||||
|
/* "01:23:45" oder "23:45" -- eindeutig, unabhängig vom Namen. */
|
||||||
|
const uhr = /^(\d{1,3}):(\d{2})(?::(\d{2}))?$/.exec(t);
|
||||||
|
if (uhr) {
|
||||||
|
return uhr[3] !== undefined
|
||||||
|
? Number(uhr[1]) * 60 + Number(uhr[2]) + Number(uhr[3]) / 60
|
||||||
|
: Number(uhr[1]) + Number(uhr[2]) / 60;
|
||||||
|
}
|
||||||
|
/* "2h 15m", "2 Std 15 Min" */
|
||||||
|
const hm = /(\d+)\s*(?:h|std|stunde)/i.exec(t);
|
||||||
|
const mm = /(\d+)\s*(?:m(?!s)|min)/i.exec(t);
|
||||||
|
if (hm || mm) return (hm ? Number(hm[1]) * 60 : 0) + (mm ? Number(mm[1]) : 0);
|
||||||
|
|
||||||
|
const zahl = Number(String(wert).replace(/[^\d.]/g, ""));
|
||||||
|
if (!Number.isFinite(zahl)) return null;
|
||||||
|
if (/millisec|_ms\b|\bms\b/.test(name)) return zahl / 60000;
|
||||||
|
if (/sekund|second|_s\b|\bsec/.test(name)) return zahl / 60;
|
||||||
|
if (/minut|minute|_min/.test(name)) return zahl;
|
||||||
|
if (/stunde|hour/.test(name)) return zahl * 60;
|
||||||
|
return null; // lieber nichts als falsch
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Wie gut passt dieser Schlüsselname zu dem, was wir suchen? */
|
||||||
|
const MUSTER = {
|
||||||
|
tag: /date|datum|zeit|time|start|begin/i,
|
||||||
|
dauer: /duration|dauer|laenge|length|minute|second|sekund|stunde|hour|watch|live.?time|time.?live/i,
|
||||||
|
diamanten: /diamond|diamant|coin|gift|geschenk|earn|einnahm/i,
|
||||||
|
zuschauer: /viewer|zuschauer|audience|watcher/i,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Findet in einem beliebigen Objekt alle Listen, die ein Datum tragen.
|
||||||
|
*
|
||||||
|
* Rückgabe je Fund: Pfad, Anzahl, Schlüssel, Vorschlag für die
|
||||||
|
* Zuordnung, Zeitraum und zwei Beispielzeilen. */
|
||||||
|
export function kandidatenFinden(wurzel) {
|
||||||
|
const gefunden = [];
|
||||||
|
|
||||||
|
const gehe = (knoten, pfad, tiefe) => {
|
||||||
|
if (tiefe > MAX_TIEFE || knoten === null || typeof knoten !== "object") return;
|
||||||
|
|
||||||
|
if (Array.isArray(knoten)) {
|
||||||
|
const objekte = knoten.filter((e) => e && typeof e === "object" && !Array.isArray(e));
|
||||||
|
/* Eine Liste mit weniger als zwei Einträgen ist kein Verlauf.
|
||||||
|
(Ein einziger LIVE wäre einer -- aber dann lohnt der ganze
|
||||||
|
Weg nicht, und die Auswahl bliebe voller Rauschen.) */
|
||||||
|
if (objekte.length >= 2) {
|
||||||
|
const schluessel = [...new Set(objekte.flatMap((e) => Object.keys(e)))];
|
||||||
|
/* Welcher Schlüssel trägt ein Datum? Nicht nach dem Namen
|
||||||
|
gesucht, sondern nach dem INHALT -- ein Feld namens "date",
|
||||||
|
in dem kein Datum steht, hilft niemandem. */
|
||||||
|
let tagSchluessel = null;
|
||||||
|
let beste = 0;
|
||||||
|
for (const s of schluessel) {
|
||||||
|
const treffer = objekte.filter((e) => tagAus(e[s])).length;
|
||||||
|
/* Mindestens die Hälfte der Einträge muss ein lesbares Datum
|
||||||
|
haben -- sonst ist es ein Feld, das zufällig manchmal wie
|
||||||
|
eines aussieht. */
|
||||||
|
if (treffer > beste && treffer >= objekte.length / 2) {
|
||||||
|
beste = treffer; tagSchluessel = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tagSchluessel) {
|
||||||
|
const passt = (art) => schluessel.find((s) => MUSTER[art].test(s) && s !== tagSchluessel) || null;
|
||||||
|
const tage = objekte.map((e) => tagAus(e[tagSchluessel])).filter(Boolean).sort();
|
||||||
|
gefunden.push({
|
||||||
|
pfad, anzahl: objekte.length, schluessel,
|
||||||
|
vorschlag: {
|
||||||
|
tag: tagSchluessel,
|
||||||
|
dauer: passt("dauer"),
|
||||||
|
diamanten: passt("diamanten"),
|
||||||
|
zuschauer: passt("zuschauer"),
|
||||||
|
},
|
||||||
|
von: tage[0] || null, bis: tage[tage.length - 1] || null,
|
||||||
|
/* LIVE IM PFAD IST EIN STARKES ZEICHEN, aber kein Beweis --
|
||||||
|
deshalb nur ein Punkt bei der Sortierung, keine
|
||||||
|
Vorentscheidung. */
|
||||||
|
punkte: (/live/i.test(pfad) ? 10 : 0)
|
||||||
|
+ (passt("dauer") ? 4 : 0) + (passt("diamanten") ? 3 : 0)
|
||||||
|
+ Math.min(3, Math.floor(objekte.length / 10)),
|
||||||
|
beispiele: objekte.slice(0, 2),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Auch IN der Liste weitersuchen -- aber nur im ersten Eintrag.
|
||||||
|
Alle durchzugehen kostet bei einem Vollarchiv Minuten und
|
||||||
|
bringt nichts Neues: Die Einträge einer Liste sind gleich
|
||||||
|
gebaut. */
|
||||||
|
if (knoten[0] && typeof knoten[0] === "object") gehe(knoten[0], `${pfad}[0]`, tiefe + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const [s, w] of Object.entries(knoten)) {
|
||||||
|
gehe(w, pfad ? `${pfad}.${s}` : s, tiefe + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
gehe(wurzel, "", 0);
|
||||||
|
gefunden.sort((a, b) => b.punkte - a.punkte || b.anzahl - a.anzahl);
|
||||||
|
return gefunden.slice(0, MAX_KANDIDATEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holt die Liste an einem Pfad wieder heraus. */
|
||||||
|
export function listeAmPfad(wurzel, pfad) {
|
||||||
|
let hier = wurzel;
|
||||||
|
for (const teil of String(pfad).split(".")) {
|
||||||
|
if (hier === null || typeof hier !== "object") return null;
|
||||||
|
const m = /^(.*)\[(\d+)\]$/.exec(teil);
|
||||||
|
if (m) {
|
||||||
|
hier = m[1] ? hier[m[1]] : hier;
|
||||||
|
if (!Array.isArray(hier)) return null;
|
||||||
|
hier = hier[Number(m[2])];
|
||||||
|
} else {
|
||||||
|
hier = hier[teil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Array.isArray(hier) ? hier : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Aus den Einträgen werden TAGE.
|
||||||
|
*
|
||||||
|
* MEHRERE LIVES AN EINEM TAG SIND EIN TAG. Die Dauer wird addiert,
|
||||||
|
* die Diamanten ebenfalls, bei den Zuschauern gewinnt der höchste
|
||||||
|
* Wert -- ein Durchschnitt aus zwei Streams wäre eine Zahl, die es
|
||||||
|
* nie gegeben hat.
|
||||||
|
*
|
||||||
|
* Ein Tag mit LIVE-Zeit gilt als gültiger Tag. Das ist dieselbe Regel
|
||||||
|
* wie beim Backstage-Import; sie steht bewusst an beiden Stellen
|
||||||
|
* gleich und nicht einmal so und einmal anders. */
|
||||||
|
export function zuTagen(eintraege, zuordnung) {
|
||||||
|
const nachTag = new Map();
|
||||||
|
const uebersprungen = [];
|
||||||
|
|
||||||
|
eintraege.forEach((e, i) => {
|
||||||
|
const tag = tagAus(e[zuordnung.tag]);
|
||||||
|
if (!tag) { uebersprungen.push({ nr: i + 1, grund: "kein lesbares Datum" }); return; }
|
||||||
|
const minuten = zuordnung.dauer ? minutenAus(e[zuordnung.dauer], zuordnung.dauer) : null;
|
||||||
|
const diamanten = zuordnung.diamanten ? Number(String(e[zuordnung.diamanten]).replace(/[^\d]/g, "")) : null;
|
||||||
|
const zuschauer = zuordnung.zuschauer ? Number(String(e[zuordnung.zuschauer]).replace(/[^\d]/g, "")) : null;
|
||||||
|
|
||||||
|
const v = nachTag.get(tag) || { tag, dauer_min: null, diamanten: null, zuschauer_max: null, lives: 0 };
|
||||||
|
v.lives++;
|
||||||
|
if (minuten !== null && Number.isFinite(minuten)) v.dauer_min = (v.dauer_min ?? 0) + minuten;
|
||||||
|
if (Number.isFinite(diamanten)) v.diamanten = (v.diamanten ?? 0) + diamanten;
|
||||||
|
if (Number.isFinite(zuschauer)) v.zuschauer_max = Math.max(v.zuschauer_max ?? 0, zuschauer);
|
||||||
|
nachTag.set(tag, v);
|
||||||
|
});
|
||||||
|
|
||||||
|
const tage = [...nachTag.values()]
|
||||||
|
.map((v) => ({ ...v, dauer_min: v.dauer_min === null ? null : Math.round(v.dauer_min) }))
|
||||||
|
.sort((a, b) => a.tag.localeCompare(b.tag));
|
||||||
|
return { tage, uebersprungen };
|
||||||
|
}
|
||||||
@@ -13,25 +13,25 @@
|
|||||||
"theme_color": "#06090f",
|
"theme_color": "#06090f",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/workspace-192.png?v=202609111126",
|
"src": "/assets/img/app-symbole/workspace-192.png?v=202609111201",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/workspace-512.png?v=202609111126",
|
"src": "/assets/img/app-symbole/workspace-512.png?v=202609111201",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609111126",
|
"src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609111201",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609111126",
|
"src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609111201",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
|
|||||||
@@ -316,3 +316,35 @@
|
|||||||
.import-vorschau__zeile[data-art="still"] {
|
.import-vorschau__zeile[data-art="still"] {
|
||||||
color: var(--text-still); font-size: .8rem;
|
color: var(--text-still); font-size: .8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- Die Auswahl in der TikTok-Datei (11.09.2026) -------------------
|
||||||
|
Das Format der Datei ist nicht dokumentiert. Der Server schlägt vor,
|
||||||
|
der Mensch entscheidet -- und eine Entscheidung gehört als sichtbare
|
||||||
|
Auswahl auf die Seite, nicht in ein Aufklappfeld, in dem man die
|
||||||
|
erste Zeile für gesetzt hält. */
|
||||||
|
.tt-wahl {
|
||||||
|
display: flex; align-items: flex-start; gap: 10px;
|
||||||
|
margin: 6px 0;
|
||||||
|
padding: 9px 11px;
|
||||||
|
border: 1px solid var(--rand); border-radius: 11px;
|
||||||
|
background: rgba(255, 255, 255, .02);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.tt-wahl:hover { border-color: var(--rand-hell); }
|
||||||
|
.tt-wahl:has(input:checked) {
|
||||||
|
border-color: color-mix(in srgb, var(--akzent) 55%, transparent);
|
||||||
|
background: color-mix(in srgb, var(--akzent) 10%, transparent);
|
||||||
|
}
|
||||||
|
.tt-wahl input { margin-top: 3px; flex: none; }
|
||||||
|
.tt-wahl__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
||||||
|
.tt-wahl__text strong {
|
||||||
|
font-family: ui-monospace, "Cascadia Code", "Consolas", monospace;
|
||||||
|
font-size: .82rem; color: var(--text);
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
.tt-wahl__zahl { font-size: .8rem; color: var(--text-leise); }
|
||||||
|
.tt-wahl__felder {
|
||||||
|
font-size: .76rem; color: var(--text-still);
|
||||||
|
font-family: ui-monospace, "Cascadia Code", "Consolas", monospace;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|||||||
@@ -181,6 +181,9 @@
|
|||||||
darum, niemandem einen Knopf hinzustellen, der eine Absage
|
darum, niemandem einen Knopf hinzustellen, der eine Absage
|
||||||
bringt. */
|
bringt. */
|
||||||
$('netz-oeffnen').hidden = !LEITUNG.has(ich?.rolle);
|
$('netz-oeffnen').hidden = !LEITUNG.has(ich?.rolle);
|
||||||
|
/* Die Datei gehoert EINEM Creator -- deshalb sichtbar fuer alle,
|
||||||
|
die fuer ihn eintragen duerfen, also auch fuer seinen Scout. */
|
||||||
|
$('tt-oeffnen').hidden = !darfEintragen();
|
||||||
|
|
||||||
if (!z || (!z.diamanten && !z.tage && !z.verweildauer)) {
|
if (!z || (!z.diamanten && !z.tage && !z.verweildauer)) {
|
||||||
ziel.append(el('p', 'leistung__leer',
|
ziel.append(el('p', 'leistung__leer',
|
||||||
@@ -548,6 +551,109 @@
|
|||||||
$('tag-form').addEventListener('submit', tagSpeichern);
|
$('tag-form').addEventListener('submit', tagSpeichern);
|
||||||
$('tag-zu').addEventListener('click', () => $('tag-dialog').close());
|
$('tag-zu').addEventListener('click', () => $('tag-dialog').close());
|
||||||
$('tag-loeschen').addEventListener('click', tagLoeschen);
|
$('tag-loeschen').addEventListener('click', tagLoeschen);
|
||||||
|
/* =====================================================================
|
||||||
|
DIE TIKTOK-DATEI DES CREATORS
|
||||||
|
|
||||||
|
Das Format ist nicht dokumentiert. Deshalb wird hier nichts
|
||||||
|
geraten: Der Server durchsucht die Datei nach Listen mit Datum und
|
||||||
|
schickt sie zur Auswahl zurück -- mit Anzahl, Zeitraum und dem,
|
||||||
|
was dabei herauskäme. Bestätigt wird von Hand.
|
||||||
|
===================================================================== */
|
||||||
|
let ttInhalt = null; /* die gelesene Datei -- bleibt im Browser */
|
||||||
|
let ttWahl = null; /* der bestätigte Kandidat */
|
||||||
|
|
||||||
|
async function ttDateiGewaehlt(ereignis) {
|
||||||
|
const datei = ereignis.target.files?.[0];
|
||||||
|
$('tt-fehler').textContent = '';
|
||||||
|
$('tt-vorschau').hidden = true;
|
||||||
|
$('tt-los').disabled = true;
|
||||||
|
ttInhalt = null; ttWahl = null;
|
||||||
|
if (!datei) return;
|
||||||
|
|
||||||
|
/* Ein Vollarchiv kann zweistellige Megabyte haben. Das Lesen
|
||||||
|
passiert im Browser; auf den Server geht es erst danach -- und
|
||||||
|
nur einmal, nicht bei jedem Klick. */
|
||||||
|
$('tt-fehler').textContent = 'Datei wird gelesen …';
|
||||||
|
let text;
|
||||||
|
try { text = await datei.text(); } catch { $('tt-fehler').textContent = 'Die Datei ließ sich nicht lesen.'; return; }
|
||||||
|
try { ttInhalt = JSON.parse(text); } catch {
|
||||||
|
$('tt-fehler').textContent = 'Das ist keine JSON-Datei. Beim Herunterladen bei TikTok '
|
||||||
|
+ 'muss als Format JSON gewählt werden, nicht TXT.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('tt-fehler').textContent = 'Datei wird durchsucht …';
|
||||||
|
|
||||||
|
const a = await hole(`/workspace/api/leistung/${offenerCreator}/tiktok-datei/vorschau`, {
|
||||||
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ inhalt: ttInhalt }),
|
||||||
|
}).catch(() => null);
|
||||||
|
if (!a) { $('tt-fehler').textContent = 'Die Datei konnte nicht geprüft werden.'; return; }
|
||||||
|
const d = await a.json().catch(() => ({}));
|
||||||
|
if (!a.ok) { $('tt-fehler').textContent = d.fehler || 'Die Datei wurde nicht verstanden.'; return; }
|
||||||
|
$('tt-fehler').textContent = '';
|
||||||
|
|
||||||
|
const v = $('tt-vorschau');
|
||||||
|
v.textContent = ''; v.hidden = false;
|
||||||
|
const zeile = (text2, art) => {
|
||||||
|
const p = el('p', 'import-vorschau__zeile');
|
||||||
|
if (art) p.dataset.art = art;
|
||||||
|
p.textContent = text2;
|
||||||
|
v.append(p);
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
|
||||||
|
zeile(`${d.kandidaten.length} Liste(n) mit Datum gefunden. Welche ist der LIVE-Verlauf?`);
|
||||||
|
|
||||||
|
/* Die Auswahl als echte Radioknöpfe: Es ist eine Entscheidung, und
|
||||||
|
eine Entscheidung gehört nicht in ein Aufklappfeld, in dem man
|
||||||
|
die erste Zeile für gesetzt hält. */
|
||||||
|
d.kandidaten.forEach((k, i) => {
|
||||||
|
const box = el('label', 'tt-wahl');
|
||||||
|
const r = document.createElement('input');
|
||||||
|
r.type = 'radio'; r.name = 'tt-kandidat'; r.value = String(i);
|
||||||
|
if (i === 0) { r.checked = true; ttWahl = k; }
|
||||||
|
r.addEventListener('change', () => { ttWahl = k; $('tt-los').disabled = false; });
|
||||||
|
const t = el('span', 'tt-wahl__text');
|
||||||
|
t.append(el('strong', null, k.pfad || '(oberste Ebene)'));
|
||||||
|
t.append(el('span', 'tt-wahl__zahl',
|
||||||
|
` ${k.anzahl} Einträge · ${k.tage_gesamt} Tage`
|
||||||
|
+ (k.von ? ` · ${k.von} bis ${k.bis}` : '')));
|
||||||
|
const felder = ['tag', 'dauer', 'diamanten', 'zuschauer']
|
||||||
|
.filter((f) => k.vorschlag[f])
|
||||||
|
.map((f) => `${f}: ${k.vorschlag[f]}`).join(' · ');
|
||||||
|
t.append(el('span', 'tt-wahl__felder', felder || 'nur ein Datum erkannt'));
|
||||||
|
box.append(r, t);
|
||||||
|
v.append(box);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ttWahl) $('tt-los').disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ttUebernehmen(ereignis) {
|
||||||
|
ereignis.preventDefault();
|
||||||
|
if (!ttInhalt || !ttWahl) return;
|
||||||
|
$('tt-los').disabled = true;
|
||||||
|
const a = await hole(`/workspace/api/leistung/${offenerCreator}/tiktok-datei`, {
|
||||||
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ inhalt: ttInhalt, pfad: ttWahl.pfad, zuordnung: ttWahl.vorschlag }),
|
||||||
|
}).catch(() => null);
|
||||||
|
if (!a) { $('tt-los').disabled = false; return; }
|
||||||
|
const d = await a.json().catch(() => ({}));
|
||||||
|
if (!a.ok) {
|
||||||
|
$('tt-fehler').textContent = d.fehler === 'keine_brauchbaren_tage'
|
||||||
|
? 'In dieser Liste stehen keine Tage mit Zahlen.'
|
||||||
|
: (d.fehler || 'Übernehmen ging nicht.');
|
||||||
|
$('tt-los').disabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Die Datei loslassen, sobald sie nicht mehr gebraucht wird. */
|
||||||
|
ttInhalt = null; ttWahl = null;
|
||||||
|
$('tt-dialog').close();
|
||||||
|
melde(`${d.geschrieben} Tage neu, ${d.ergaenzt} ergänzt`);
|
||||||
|
setTimeout(() => melde(''), 6000);
|
||||||
|
await laden();
|
||||||
|
}
|
||||||
|
|
||||||
/* =====================================================================
|
/* =====================================================================
|
||||||
DIE BACKSTAGE-TABELLE — Vorschau und Übernahme
|
DIE BACKSTAGE-TABELLE — Vorschau und Übernahme
|
||||||
===================================================================== */
|
===================================================================== */
|
||||||
@@ -660,6 +766,14 @@
|
|||||||
$('netz-text').focus();
|
$('netz-text').focus();
|
||||||
});
|
});
|
||||||
$('netz-zu').addEventListener('click', () => $('netz-dialog').close());
|
$('netz-zu').addEventListener('click', () => $('netz-dialog').close());
|
||||||
|
$('tt-oeffnen').addEventListener('click', () => {
|
||||||
|
$('tt-vorschau').hidden = true; $('tt-los').disabled = true;
|
||||||
|
$('tt-fehler').textContent = ''; $('tt-datei').value = '';
|
||||||
|
$('tt-dialog').showModal();
|
||||||
|
});
|
||||||
|
$('tt-zu').addEventListener('click', () => $('tt-dialog').close());
|
||||||
|
$('tt-datei').addEventListener('change', ttDateiGewaehlt);
|
||||||
|
$('tt-form').addEventListener('submit', ttUebernehmen);
|
||||||
/* Beim EINFÜGEN sofort nachsehen -- nicht erst auf einen Knopf warten.
|
/* Beim EINFÜGEN sofort nachsehen -- nicht erst auf einen Knopf warten.
|
||||||
Wer eine Tabelle einfügt, will wissen, ob sie erkannt wurde; ein
|
Wer eine Tabelle einfügt, will wissen, ob sie erkannt wurde; ein
|
||||||
zweiter Klick dazwischen ist nur eine Gelegenheit, es nicht zu tun. */
|
zweiter Klick dazwischen ist nur eine Gelegenheit, es nicht zu tun. */
|
||||||
|
|||||||
+12
-12
@@ -12,19 +12,19 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -252,10 +252,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/aufgaben.js?v=202609111126" defer></script>
|
<script src="assets/js/aufgaben.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/automation.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/automation.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -147,10 +147,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/automation.js?v=202609111126" defer></script>
|
<script src="assets/js/automation.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+17
-17
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/bereich.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/bereich.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -181,14 +181,14 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/checkliste.js?v=202609111126" defer></script>
|
<script src="assets/js/checkliste.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/ampel.js?v=202609111126" defer></script>
|
<script src="assets/js/ampel.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/schulung.js?v=202609111126" defer></script>
|
<script src="assets/js/schulung.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/vorlagen.js?v=202609111126" defer></script>
|
<script src="assets/js/vorlagen.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereich.js?v=202609111126" defer></script>
|
<script src="assets/js/bereich.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/calls.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/calls.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -89,11 +89,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609111126" defer></script>
|
<script src="assets/js/ki.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/calls.js?v=202609111126" defer></script>
|
<script src="assets/js/calls.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,26 +12,26 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<!-- aufgaben.css bringt die Dialog- und Formularstile mit (.dialog,
|
<!-- aufgaben.css bringt die Dialog- und Formularstile mit (.dialog,
|
||||||
.neu__zeile, .dialog__knoepfe). Sie stehen dort seit dem
|
.neu__zeile, .dialog__knoepfe). Sie stehen dort seit dem
|
||||||
Aufgabenbrett; sie hierher zu kopieren hiesse, sie an zwei Stellen
|
Aufgabenbrett; sie hierher zu kopieren hiesse, sie an zwei Stellen
|
||||||
zu pflegen. Dieselbe Lösung nutzen kalender.html und content.html.
|
zu pflegen. Dieselbe Lösung nutzen kalender.html und content.html.
|
||||||
Gemeldet von pruef-css-klassen.mjs, bevor jemand einen ungestylten
|
Gemeldet von pruef-css-klassen.mjs, bevor jemand einen ungestylten
|
||||||
Dialog zu sehen bekam. -->
|
Dialog zu sehen bekam. -->
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/chat.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/chat.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -289,10 +289,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/bereiche.js?v=202609111126"></script>
|
<script src="assets/js/bereiche.js?v=202609111201"></script>
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126"></script>
|
<script src="assets/js/kopf.js?v=202609111201"></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126"></script>
|
<script src="assets/js/glocke.js?v=202609111201"></script>
|
||||||
<script src="assets/js/chat.js?v=202609111126"></script>
|
<script src="assets/js/chat.js?v=202609111201"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+15
-15
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/content.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/content.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -179,12 +179,12 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/checkliste.js?v=202609111126" defer></script>
|
<script src="assets/js/checkliste.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/vorlagen.js?v=202609111126" defer></script>
|
<script src="assets/js/vorlagen.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/content.js?v=202609111126" defer></script>
|
<script src="assets/js/content.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -30,15 +30,15 @@
|
|||||||
<link rel="preload" as="image" href="assets/img/buehne/crew-gate-hoch-580.webp"
|
<link rel="preload" as="image" href="assets/img/buehne/crew-gate-hoch-580.webp"
|
||||||
type="image/webp" media="(max-width: 899px)" />
|
type="image/webp" media="(max-width: 899px)" />
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/crew-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/crew-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/crew-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/crew-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<!-- Diese Wand steht NUR auf der Adresse von Team Dogi (ueberall sonst
|
<!-- Diese Wand steht NUR auf der Adresse von Team Dogi (ueberall sonst
|
||||||
404, siehe crewWeiche). Sie darf das Haus deshalb direkt nennen
|
404, siehe crewWeiche). Sie darf das Haus deshalb direkt nennen
|
||||||
statt ueber den Platzhalter haus.css zu gehen -- und sie MUSS es:
|
statt ueber den Platzhalter haus.css zu gehen -- und sie MUSS es:
|
||||||
Eine Zugangswand, die sich erst nach dem Umbiegen faerbt, waere
|
Eine Zugangswand, die sich erst nach dem Umbiegen faerbt, waere
|
||||||
die eine Seite, auf der man das Umfaerben sieht. -->
|
die eine Seite, auf der man das Umfaerben sieht. -->
|
||||||
<link rel="stylesheet" href="assets/css/crew-haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/crew-haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="gate gate--crew">
|
<body class="gate gate--crew">
|
||||||
@@ -252,6 +252,6 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/gate.js?v=202609111126" defer></script>
|
<script src="assets/js/gate.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -13,25 +13,25 @@
|
|||||||
"theme_color": "#06090f",
|
"theme_color": "#06090f",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/crew-192.png?v=202609111126",
|
"src": "/assets/img/app-symbole/crew-192.png?v=202609111201",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/crew-512.png?v=202609111126",
|
"src": "/assets/img/app-symbole/crew-512.png?v=202609111201",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609111126",
|
"src": "/assets/img/app-symbole/crew-192-maskable.png?v=202609111201",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609111126",
|
"src": "/assets/img/app-symbole/crew-512-maskable.png?v=202609111201",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/dateien.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/dateien.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -108,10 +108,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/dateien.js?v=202609111126" defer></script>
|
<script src="assets/js/dateien.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -30,9 +30,9 @@
|
|||||||
<link rel="preload" as="image" href="assets/img/buehne/gate-hoch-580.webp"
|
<link rel="preload" as="image" href="assets/img/buehne/gate-hoch-580.webp"
|
||||||
type="image/webp" media="(max-width: 899px)" />
|
type="image/webp" media="(max-width: 899px)" />
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="gate">
|
<body class="gate">
|
||||||
@@ -401,6 +401,6 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/gate.js?v=202609111126" defer></script>
|
<script src="assets/js/gate.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/kalender.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/kalender.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -377,11 +377,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kalender.js?v=202609111126" defer></script>
|
<script src="assets/js/kalender.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kalender-abo.js?v=202609111126" defer></script>
|
<script src="assets/js/kalender-abo.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+56
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/leistung.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/leistung.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -115,6 +115,12 @@
|
|||||||
<button type="button" class="knopf knopf--klein" id="netz-oeffnen" hidden>
|
<button type="button" class="knopf knopf--klein" id="netz-oeffnen" hidden>
|
||||||
Backstage-Tabelle einfügen
|
Backstage-Tabelle einfügen
|
||||||
</button>
|
</button>
|
||||||
|
<!-- DIE EIGENE TIKTOK-DATEI DES CREATORS (11.09.2026).
|
||||||
|
Der einzige Weg an TikTok-Daten, der ohne Entwicklerkonto
|
||||||
|
auskommt: Der Creator lädt sie selbst herunter. -->
|
||||||
|
<button type="button" class="knopf knopf--klein" id="tt-oeffnen" hidden>
|
||||||
|
TikTok-Datei des Creators
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tagetabelle" id="tagetabelle"></div>
|
<div class="tagetabelle" id="tagetabelle"></div>
|
||||||
@@ -225,6 +231,43 @@
|
|||||||
jede Zeile zu einer anderen Person gehört – die Zuordnung ist die
|
jede Zeile zu einer anderen Person gehört – die Zuordnung ist die
|
||||||
eigentliche Arbeit, und die will man sehen, bevor geschrieben wird.
|
eigentliche Arbeit, und die will man sehen, bevor geschrieben wird.
|
||||||
==================================================================== -->
|
==================================================================== -->
|
||||||
|
<!-- ====================================================================
|
||||||
|
DIE TIKTOK-DATEI DES CREATORS (11.09.2026)
|
||||||
|
|
||||||
|
Warum hier eine AUSWAHL steht und nicht einfach eingelesen wird:
|
||||||
|
Das Format der Datei ist nicht dokumentiert. Statt Schlüsselnamen
|
||||||
|
zu raten, durchsucht der Server die Datei nach Listen mit Datum und
|
||||||
|
legt sie vor – bestätigt wird von Hand. Damit funktioniert es auch
|
||||||
|
dann noch, wenn TikTok die Felder umbenennt.
|
||||||
|
==================================================================== -->
|
||||||
|
<dialog class="dialog dialog--breit" id="tt-dialog">
|
||||||
|
<form method="dialog" id="tt-form" class="neu neu--blank">
|
||||||
|
<h2 class="dialog__titel">TikTok-Datei einlesen</h2>
|
||||||
|
<p class="dialog__unter">
|
||||||
|
Die Datei, die der Creator sich selbst bei TikTok herunterlädt:
|
||||||
|
<strong>Profil → Einstellungen → Konto → Deine Daten herunterladen</strong>,
|
||||||
|
Format <strong>JSON</strong>, „Alles auswählen“. TikTok braucht dafür
|
||||||
|
ein bis vier Tage. Die Datei wird hier gelesen und <strong>nicht
|
||||||
|
gespeichert</strong> – in ihr stehen auch Nachrichten und Verläufe,
|
||||||
|
die hier nichts zu suchen haben.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="neu__zeile">
|
||||||
|
<label class="feld-schild" for="tt-datei">Datei wählen</label>
|
||||||
|
<input id="tt-datei" type="file" accept=".json,application/json" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="import-vorschau" id="tt-vorschau" hidden></div>
|
||||||
|
|
||||||
|
<p class="fehler" id="tt-fehler" role="alert" aria-live="polite"></p>
|
||||||
|
|
||||||
|
<div class="dialog__knoepfe">
|
||||||
|
<button type="submit" class="knopf knopf--klein" id="tt-los" disabled>Übernehmen</button>
|
||||||
|
<button type="button" class="abmelden" id="tt-zu">Abbrechen</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
<dialog class="dialog dialog--breit" id="netz-dialog">
|
<dialog class="dialog dialog--breit" id="netz-dialog">
|
||||||
<form method="dialog" id="netz-form" class="neu neu--blank">
|
<form method="dialog" id="netz-form" class="neu neu--blank">
|
||||||
<h2 class="dialog__titel">Backstage-Tabelle einfügen</h2>
|
<h2 class="dialog__titel">Backstage-Tabelle einfügen</h2>
|
||||||
@@ -282,10 +325,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126"></script>
|
<script src="assets/js/wahl.js?v=202609111201"></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126"></script>
|
<script src="assets/js/bereiche.js?v=202609111201"></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126"></script>
|
<script src="assets/js/kopf.js?v=202609111201"></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126"></script>
|
<script src="assets/js/glocke.js?v=202609111201"></script>
|
||||||
<script src="assets/js/leistung.js?v=202609111126"></script>
|
<script src="assets/js/leistung.js?v=202609111201"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/personen.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/personen.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -396,10 +396,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/personen.js?v=202609111126" defer></script>
|
<script src="assets/js/personen.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/profil.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/profil.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -214,11 +214,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/steckbrief.js?v=202609111126" defer></script>
|
<script src="assets/js/steckbrief.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/profil.js?v=202609111126" defer></script>
|
<script src="assets/js/profil.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/report.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/report.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -106,11 +106,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609111126" defer></script>
|
<script src="assets/js/ki.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/report.js?v=202609111126" defer></script>
|
<script src="assets/js/report.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/scouting.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/scouting.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -173,10 +173,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/scouting.js?v=202609111126" defer></script>
|
<script src="assets/js/scouting.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+12
-12
@@ -12,21 +12,21 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<!-- Nur die Startseite: Begrüßungskachel, Uhr, Glockenmulde. Siehe
|
<!-- Nur die Startseite: Begrüßungskachel, Uhr, Glockenmulde. Siehe
|
||||||
den Hinweis in start.css -- dort stand es bis zum 07.09.2026. -->
|
den Hinweis in start.css -- dort stand es bis zum 07.09.2026. -->
|
||||||
<link rel="stylesheet" href="assets/css/heim.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/heim.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -674,10 +674,10 @@
|
|||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/start.js?v=202609111126" defer></script>
|
<script src="assets/js/start.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+14
-14
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/startcheck.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/startcheck.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -85,11 +85,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/ki.js?v=202609111126" defer></script>
|
<script src="assets/js/ki.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/startcheck.js?v=202609111126" defer></script>
|
<script src="assets/js/startcheck.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/profil.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/profil.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -126,10 +126,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/steckbrief.js?v=202609111126" defer></script>
|
<script src="assets/js/steckbrief.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -7,20 +7,20 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/team.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/team.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -110,10 +110,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/team.js?v=202609111126" defer></script>
|
<script src="assets/js/team.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+12
-12
@@ -7,20 +7,20 @@
|
|||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
<link rel="manifest" href="/workspace/app.webmanifest" />
|
<link rel="manifest" href="/workspace/app.webmanifest" />
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/team.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/team.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<!-- `data-buehne` steht hier fest und nicht im Skript: Die Kachel zu
|
<!-- `data-buehne` steht hier fest und nicht im Skript: Die Kachel zu
|
||||||
@@ -84,9 +84,9 @@
|
|||||||
Kaputt ist dabei nichts -- er funktioniert. Genau deshalb faellt
|
Kaputt ist dabei nichts -- er funktioniert. Genau deshalb faellt
|
||||||
es niemandem auf, und deshalb prueft pruef-css-klassen die
|
es niemandem auf, und deshalb prueft pruef-css-klassen die
|
||||||
ABHAENGIGKEIT statt der Optik. Hier hat sie angeschlagen. -->
|
ABHAENGIGKEIT statt der Optik. Hier hat sie angeschlagen. -->
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/teamlage.js?v=202609111126" defer></script>
|
<script src="assets/js/teamlage.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,22 +12,22 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<!-- Formular- und Dialogstile: seit dem 07.09.2026 steht hier der
|
<!-- Formular- und Dialogstile: seit dem 07.09.2026 steht hier der
|
||||||
Dialog "Creator anlegen". -->
|
Dialog "Creator anlegen". -->
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -149,11 +149,11 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/uebersicht.js?v=202609111126" defer></script>
|
<script src="assets/js/uebersicht.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+13
-13
@@ -12,20 +12,20 @@
|
|||||||
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite
|
||||||
eine Flaeche sind statt zweier. -->
|
eine Flaeche sind statt zweier. -->
|
||||||
<meta name="theme-color" content="#06090f" />
|
<meta name="theme-color" content="#06090f" />
|
||||||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111126" />
|
<link rel="icon" type="image/png" href="/assets/img/app-symbole/workspace-32.png?v=202609111201" />
|
||||||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111126" />
|
<link rel="apple-touch-icon" href="/assets/img/app-symbole/workspace-180.png?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/gate.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/gate.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/start.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/start.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/wissen.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/wissen.css?v=202609111201" />
|
||||||
<link rel="stylesheet" href="assets/css/module.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/module.css?v=202609111201" />
|
||||||
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
<!-- haus.css MUSS die letzte Stilvorlage sein (10.09.2026).
|
||||||
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
Auf der Agenturadresse ist sie leer -- das Haus hier IST der
|
||||||
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
Grundzustand. Auf der Adresse von Team Dogi biegt der Server
|
||||||
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
genau diesen Dateinamen auf crew-haus.css um, und die Seite
|
||||||
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
kommt schon beim ERSTEN Abruf in Lila und Babyblau an --
|
||||||
ohne Umfaerben im Browser, ohne Flackern. -->
|
ohne Umfaerben im Browser, ohne Flackern. -->
|
||||||
<link rel="stylesheet" href="assets/css/haus.css?v=202609111126" />
|
<link rel="stylesheet" href="assets/css/haus.css?v=202609111201" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="start">
|
<body class="start">
|
||||||
@@ -190,10 +190,10 @@
|
|||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="assets/js/wahl.js?v=202609111126" defer></script>
|
<script src="assets/js/wahl.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/bereiche.js?v=202609111126" defer></script>
|
<script src="assets/js/bereiche.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/kopf.js?v=202609111126" defer></script>
|
<script src="assets/js/kopf.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/glocke.js?v=202609111126" defer></script>
|
<script src="assets/js/glocke.js?v=202609111201" defer></script>
|
||||||
<script src="assets/js/wissen.js?v=202609111126" defer></script>
|
<script src="assets/js/wissen.js?v=202609111201" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user