@rslsp1/fa-app-tools 5.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -149,15 +149,15 @@ function resolveRef(ref, baseId, schemas) {
149
149
  const target = hash === -1 ? ref : ref.slice(0, hash);
150
150
  const pointer = hash === -1 ? "" : ref.slice(hash + 1);
151
151
  const documentId = target === "" ? baseId : new URL(target, baseId).href;
152
- const document = schemas.byId.get(documentId);
153
- if (!document) {
152
+ const document2 = schemas.byId.get(documentId);
153
+ if (!document2) {
154
154
  throw new UnsupportedSchemaError(`Referenz "${ref}" zeigt auf unbekanntes Schema ${documentId}.`);
155
155
  }
156
- if (pointer === "" || pointer === "/") return { schema: document, baseId: documentId };
156
+ if (pointer === "" || pointer === "/") return { schema: document2, baseId: documentId };
157
157
  if (!pointer.startsWith("/")) {
158
158
  throw new UnsupportedSchemaError(`Referenz "${ref}": nur JSON-Pointer werden aufgeloest.`);
159
159
  }
160
- let node = document;
160
+ let node = document2;
161
161
  for (const rawSegment of pointer.slice(1).split("/")) {
162
162
  const segment = unescapePointer(rawSegment);
163
163
  if (!isObject(node) || !(segment in node)) {
@@ -5225,6 +5225,133 @@ function findPromptRun(events, runId) {
5225
5225
  return collectPromptRuns(events).find((run) => run.run_id === runId) ?? null;
5226
5226
  }
5227
5227
 
5228
+ // src/lib/szenen/seedListe.ts
5229
+ var DEFAULT_SEED_VORLAGE = {
5230
+ name: "Default",
5231
+ seeds: "1; 10; 100; 1000",
5232
+ builtin: true
5233
+ };
5234
+ function parseSeedListe(eingabe) {
5235
+ if (!eingabe) return [];
5236
+ return eingabe.split(/[,;]/).map((teil) => teil.trim()).filter((teil) => teil.length > 0);
5237
+ }
5238
+ function formatSeedListe(tokens) {
5239
+ return tokens.join("; ");
5240
+ }
5241
+ var GANZZAHL = /^-?\d+$/;
5242
+ function ordneSeedsZu(eingabe, anzahl) {
5243
+ const tokens = Array.isArray(eingabe) ? [...eingabe] : parseSeedListe(eingabe);
5244
+ const eintraege = [];
5245
+ for (let position = 0; position < anzahl; position++) {
5246
+ const roh = tokens[position] ?? null;
5247
+ if (roh === null) {
5248
+ eintraege.push({ position, roh: null, seed: null, ungueltig: false });
5249
+ continue;
5250
+ }
5251
+ const zahl = GANZZAHL.test(roh) ? Number(roh) : Number.NaN;
5252
+ const gueltig = Number.isSafeInteger(zahl);
5253
+ eintraege.push({
5254
+ position,
5255
+ roh,
5256
+ seed: gueltig ? zahl : null,
5257
+ ungueltig: !gueltig
5258
+ });
5259
+ }
5260
+ return {
5261
+ eintraege,
5262
+ ungueltige: eintraege.filter((e) => e.ungueltig),
5263
+ ueberzaehlig: Math.max(0, tokens.length - anzahl)
5264
+ };
5265
+ }
5266
+ function seedFehlerText(ungueltige) {
5267
+ const teile = ungueltige.map((e) => `Bild ${e.position + 1}: "${e.roh}"`);
5268
+ return `Die Seedliste enth\xE4lt keine ganze Zahl an ${teile.length === 1 ? "Position" : "Positionen"} \u2014 ${teile.join(", ")}. Kein Bild wurde importiert.`;
5269
+ }
5270
+ function mitDefaultVorlage(custom) {
5271
+ return [DEFAULT_SEED_VORLAGE, ...custom.filter((v) => !v.builtin)];
5272
+ }
5273
+
5274
+ // src/lib/szenen/zipBilder.ts
5275
+ var BILD_ENDUNGEN = {
5276
+ png: "image/png",
5277
+ jpg: "image/jpeg",
5278
+ jpeg: "image/jpeg",
5279
+ webp: "image/webp"
5280
+ };
5281
+ var UPLOAD_MAX_BYTES = 45 * 1024 * 1024;
5282
+ function byteLaenge(base64) {
5283
+ const fuellzeichen = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0;
5284
+ return Math.floor(base64.length * 3 / 4) - fuellzeichen;
5285
+ }
5286
+ function angekuendigteGroesse(eintrag) {
5287
+ const roh = eintrag._data?.uncompressedSize;
5288
+ return typeof roh === "number" && Number.isFinite(roh) && roh >= 0 ? roh : null;
5289
+ }
5290
+ function bildGroesseVerdikt(archiv, pfad, bytes) {
5291
+ if (bytes === null || bytes <= UPLOAD_MAX_BYTES) return null;
5292
+ return `${archiv}: Das Bild ${pfad} ist entpackt ${mb(bytes)} MB gro\xDF \u2014 die Grenze f\xFCr eine einzelne Bilddatei liegt bei ${UPLOAD_MAX_BYTES / 1024 / 1024} MB. Kein Bild wurde importiert.`;
5293
+ }
5294
+ function mb(bytes) {
5295
+ return (bytes / 1024 / 1024).toFixed(1);
5296
+ }
5297
+ function istZipDatei(datei) {
5298
+ return /\.zip$/i.test(datei.name);
5299
+ }
5300
+ function endungVon(pfad) {
5301
+ const punkt = pfad.lastIndexOf(".");
5302
+ return punkt >= 0 ? pfad.slice(punkt + 1).toLowerCase() : "";
5303
+ }
5304
+ function istImportierbar(pfad, istVerzeichnis) {
5305
+ if (istVerzeichnis) return false;
5306
+ if (pfad.startsWith("__MACOSX/")) return false;
5307
+ const datei = pfad.slice(pfad.lastIndexOf("/") + 1);
5308
+ if (datei.startsWith(".")) return false;
5309
+ return endungVon(datei) in BILD_ENDUNGEN;
5310
+ }
5311
+ function nachPfad(a, b) {
5312
+ return a.localeCompare(b, "en", { numeric: true, sensitivity: "base" }) || (a < b ? -1 : a > b ? 1 : 0);
5313
+ }
5314
+ async function leseBilderAusZip(datei) {
5315
+ const name = datei.name ?? "Archiv";
5316
+ if (datei.size > UPLOAD_MAX_BYTES) {
5317
+ throw new Error(
5318
+ `${name} ist ${mb(datei.size)} MB gro\xDF \u2014 die Grenze liegt bei ${UPLOAD_MAX_BYTES / 1024 / 1024} MB.`
5319
+ );
5320
+ }
5321
+ const { default: JSZip } = await import("jszip");
5322
+ const archiv = await JSZip.loadAsync(datei).catch((fehler4) => {
5323
+ throw new Error(
5324
+ `${name} konnte nicht als ZIP gelesen werden: ${fehler4 instanceof Error ? fehler4.message : String(fehler4)}`
5325
+ );
5326
+ });
5327
+ const pfade = [];
5328
+ archiv.forEach((pfad, eintrag) => {
5329
+ if (istImportierbar(pfad, eintrag.dir)) pfade.push(pfad);
5330
+ });
5331
+ pfade.sort(nachPfad);
5332
+ if (pfade.length === 0) {
5333
+ throw new Error(
5334
+ `${name} enth\xE4lt kein unterst\xFCtztes Bild (erwartet: ${Object.keys(BILD_ENDUNGEN).map((e) => `.${e}`).join(", ")}).`
5335
+ );
5336
+ }
5337
+ const bilder = [];
5338
+ for (const pfad of pfade) {
5339
+ const eintrag = archiv.file(pfad);
5340
+ if (!eintrag) continue;
5341
+ const angekuendigt = bildGroesseVerdikt(name, pfad, angekuendigteGroesse(eintrag));
5342
+ if (angekuendigt) throw new Error(angekuendigt);
5343
+ const base64 = await eintrag.async("base64");
5344
+ const nachgemessen = bildGroesseVerdikt(name, pfad, byteLaenge(base64));
5345
+ if (nachgemessen) throw new Error(nachgemessen);
5346
+ bilder.push({
5347
+ name: pfad,
5348
+ base64,
5349
+ mimeType: BILD_ENDUNGEN[endungVon(pfad)]
5350
+ });
5351
+ }
5352
+ return bilder;
5353
+ }
5354
+
5228
5355
  // src/lib/szenen/bildVorschau.ts
5229
5356
  async function ladeVorschauen(port, mediaRefs, fertig, optionen = {}) {
5230
5357
  const laden = port.loadPreview;
@@ -5241,6 +5368,7 @@ async function ladeVorschauen(port, mediaRefs, fertig, optionen = {}) {
5241
5368
  const ergebnis = await laden.call(port, ref);
5242
5369
  if (lauf?.abgebrochen) return;
5243
5370
  if (ergebnis.kind === "ok") fertig(ref, ergebnis.value);
5371
+ else optionen.gescheitert?.(ref, ergebnis.message);
5244
5372
  }
5245
5373
  }
5246
5374
  await Promise.all(
@@ -6206,10 +6334,10 @@ async function runSceneDerivation(input, port, userPrompt) {
6206
6334
  }
6207
6335
 
6208
6336
  // src/features/szenen/SzenenView.tsx
6209
- import { useMemo as useMemo4, useState as useState16 } from "react";
6337
+ import { useMemo as useMemo4, useState as useState17 } from "react";
6210
6338
 
6211
6339
  // src/features/szenen/areas/ElementsArea.tsx
6212
- import { useState as useState11 } from "react";
6340
+ import { useState as useState12 } from "react";
6213
6341
 
6214
6342
  // src/features/szenen/areas/usePortQuery.ts
6215
6343
  import { useEffect, useRef, useState } from "react";
@@ -6241,7 +6369,7 @@ function usePortQuery(frage, abhaengigkeiten) {
6241
6369
  }
6242
6370
 
6243
6371
  // src/features/szenen/areas/ElementDetail.tsx
6244
- import { useEffect as useEffect3, useMemo as useMemo2, useState as useState9 } from "react";
6372
+ import { useEffect as useEffect6, useMemo as useMemo2, useState as useState10 } from "react";
6245
6373
 
6246
6374
  // src/features/szenen/elementLabels.ts
6247
6375
  var LABELS = {
@@ -6601,6 +6729,9 @@ var LABELS2 = {
6601
6729
  user_instruction: "Nutzeranweisung",
6602
6730
  prompt_render_settings: "Prompt-Erzeugung",
6603
6731
  blender_render_settings: "Blender-Ausgabe",
6732
+ // Nur Darstellung, keine Schemaaenderung (A4): Der Schluessel bleibt
6733
+ // `overrides`, und er steht als `<code>` weiterhin daneben.
6734
+ overrides: "Render-Abweichungen",
6604
6735
  camera_rig: "Kamera-Rig",
6605
6736
  media_refs: "Medien",
6606
6737
  external_refs: "Externe Referenzen",
@@ -7579,41 +7710,91 @@ var FeldControl = (props) => {
7579
7710
  );
7580
7711
  }
7581
7712
  };
7713
+ var LANGE_ERKLAERUNG = 120;
7714
+ function ersterSatz(text) {
7715
+ const ende = /[.!?](\s|$)/.exec(text);
7716
+ return ende ? text.slice(0, ende.index + 1) : text;
7717
+ }
7718
+ var Erklaerung = ({ text, testId }) => {
7719
+ const ganz = text.trim();
7720
+ const kern = ersterSatz(ganz);
7721
+ const rest = ganz.slice(kern.length).trim();
7722
+ if (ganz.length <= LANGE_ERKLAERUNG || !rest) {
7723
+ return /* @__PURE__ */ jsx("small", { "data-testid": `erklaerung-${testId}`, children: ganz });
7724
+ }
7725
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7726
+ /* @__PURE__ */ jsx("small", { "data-testid": `erklaerung-${testId}`, children: kern }),
7727
+ /* @__PURE__ */ jsxs("details", { className: "szenen-detail__warum", "data-testid": `warum-${testId}`, children: [
7728
+ /* @__PURE__ */ jsx("summary", { children: "Warum?" }),
7729
+ /* @__PURE__ */ jsx("small", { children: rest })
7730
+ ] })
7731
+ ] });
7732
+ };
7733
+ function gruppeKonfiguriert(feld, formular) {
7734
+ return Object.keys(payloadFromForm([feld], formular)).length > 0;
7735
+ }
7582
7736
  var SchemaFieldRow = (props) => {
7583
7737
  const { feld, elementType, formular } = props;
7584
7738
  const label = feldLabel(elementType, feld.path, feld.name);
7585
7739
  if (feld.kind === "group") {
7586
- return /* @__PURE__ */ jsxs("fieldset", { className: "szenen-detail__group", "data-testid": `gruppe-${feld.path}`, children: [
7587
- /* @__PURE__ */ jsxs("legend", { children: [
7588
- label,
7589
- feld.required && /* @__PURE__ */ jsx("strong", { title: "Pflichtfeld", children: " *" })
7590
- ] }),
7591
- feld.description && /* @__PURE__ */ jsx("small", { children: feld.description }),
7592
- (feld.children ?? []).map((kind) => /* @__PURE__ */ jsx(SchemaFieldRow, { ...props, feld: kind }, kind.path))
7593
- ] });
7740
+ const konfiguriert = gruppeKonfiguriert(feld, formular);
7741
+ return /* @__PURE__ */ jsxs(
7742
+ "details",
7743
+ {
7744
+ className: "szenen-detail__group",
7745
+ "data-testid": `gruppe-${feld.path}`,
7746
+ "data-konfiguriert": konfiguriert ? "ja" : "nein",
7747
+ open: feld.required,
7748
+ children: [
7749
+ /* @__PURE__ */ jsxs("summary", { children: [
7750
+ /* @__PURE__ */ jsx("span", { className: "szenen-detail__group-titel", children: label }),
7751
+ feld.required ? /* @__PURE__ */ jsx("strong", { title: "Pflichtfeld", children: " *" }) : (
7752
+ // A2: Dass hier schon etwas steht, muss man im
7753
+ // geschlossenen Zustand sehen — sonst übersieht man
7754
+ // eine gesetzte Blender-Ausgabe genau so lange, bis
7755
+ // sie im Ergebnis auftaucht.
7756
+ /* @__PURE__ */ jsx(
7757
+ "span",
7758
+ {
7759
+ className: "szenen-detail__group-status",
7760
+ "data-testid": `gruppe-${feld.path}-status`,
7761
+ children: konfiguriert ? "konfiguriert" : "optional"
7762
+ }
7763
+ )
7764
+ )
7765
+ ] }),
7766
+ /* @__PURE__ */ jsxs("div", { className: "szenen-detail__group-inhalt", children: [
7767
+ feld.description && /* @__PURE__ */ jsx(Erklaerung, { text: feld.description, testId: `gruppe-${feld.path}` }),
7768
+ (feld.children ?? []).map((kind) => /* @__PURE__ */ jsx(SchemaFieldRow, { ...props, feld: kind }, kind.path))
7769
+ ] })
7770
+ ]
7771
+ }
7772
+ );
7594
7773
  }
7595
7774
  const wert = formular[feld.path] ?? "";
7596
- return /* @__PURE__ */ jsxs("label", { className: "szenen-detail__field", "data-feld": feld.path, children: [
7597
- /* @__PURE__ */ jsxs("span", { children: [
7598
- label,
7599
- feld.required && /* @__PURE__ */ jsx("strong", { title: "Pflichtfeld", children: " *" }),
7600
- /* @__PURE__ */ jsx("code", { className: "szenen-detail__field-key", children: feld.name }),
7601
- feld.complexHint && !hatFachlicheBedienung(elementType, feld) && /* @__PURE__ */ jsxs("em", { children: [
7602
- " \u2014 ",
7603
- feld.complexHint
7604
- ] })
7775
+ return /* @__PURE__ */ jsxs("div", { className: "szenen-detail__fieldrow", "data-feld": feld.path, children: [
7776
+ /* @__PURE__ */ jsxs("label", { className: "szenen-detail__field", children: [
7777
+ /* @__PURE__ */ jsxs("span", { children: [
7778
+ /* @__PURE__ */ jsx("span", { className: "szenen-detail__field-label", children: label }),
7779
+ feld.required && /* @__PURE__ */ jsx("strong", { title: "Pflichtfeld", children: " *" }),
7780
+ label !== feld.name && /* @__PURE__ */ jsx("code", { className: "szenen-detail__field-key", children: feld.name }),
7781
+ feld.complexHint && !hatFachlicheBedienung(elementType, feld) && /* @__PURE__ */ jsxs("em", { children: [
7782
+ " \u2014 ",
7783
+ feld.complexHint
7784
+ ] })
7785
+ ] }),
7786
+ /* @__PURE__ */ jsx(FeldControl, { ...props, wert }),
7787
+ feld.nullable && feld.kind !== "complex" && !hatFachlicheBedienung(elementType, feld) && /* @__PURE__ */ jsx(
7788
+ NullSchalter,
7789
+ {
7790
+ feld,
7791
+ wert,
7792
+ onChange: props.onChange,
7793
+ readOnly: props.readOnly
7794
+ }
7795
+ )
7605
7796
  ] }),
7606
- /* @__PURE__ */ jsx(FeldControl, { ...props, wert }),
7607
- feld.nullable && feld.kind !== "complex" && !hatFachlicheBedienung(elementType, feld) && /* @__PURE__ */ jsx(
7608
- NullSchalter,
7609
- {
7610
- feld,
7611
- wert,
7612
- onChange: props.onChange,
7613
- readOnly: props.readOnly
7614
- }
7615
- ),
7616
- feld.description && /* @__PURE__ */ jsx("small", { children: feld.description })
7797
+ feld.description && /* @__PURE__ */ jsx(Erklaerung, { text: feld.description, testId: feld.path })
7617
7798
  ] });
7618
7799
  };
7619
7800
 
@@ -8280,11 +8461,162 @@ var VersionNavigator = ({
8280
8461
  };
8281
8462
 
8282
8463
  // src/features/szenen/areas/RunsPanel.tsx
8283
- import { useState as useState8 } from "react";
8464
+ import { useEffect as useEffect5, useRef as useRef3, useState as useState9 } from "react";
8284
8465
 
8285
8466
  // src/features/szenen/areas/RunImagesPanel.tsx
8286
- import { useState as useState7 } from "react";
8467
+ import React7, { useEffect as useEffect4, useRef as useRef2, useState as useState8 } from "react";
8468
+
8469
+ // src/features/szenen/areas/Bildbausteine.tsx
8470
+ import { useCallback, useEffect as useEffect3, useState as useState7 } from "react";
8287
8471
  import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
8472
+ var Kachel = ({
8473
+ quelle,
8474
+ alt,
8475
+ leerText
8476
+ }) => /* @__PURE__ */ jsx7("span", { className: "szenen-bildkachel", children: quelle ? /* @__PURE__ */ jsx7("img", { src: quelle, alt, loading: "lazy" }) : /* @__PURE__ */ jsx7("span", { className: "szenen-bildkachel__leer", title: leerText ?? alt, children: leerText ? /* @__PURE__ */ jsx7("span", { className: "szenen-bildkachel__zeichen", children: "?" }) : null }) });
8477
+ var BildViewer = ({
8478
+ bilder,
8479
+ position,
8480
+ onWechseln,
8481
+ onSchliessen,
8482
+ satzTitel,
8483
+ testId
8484
+ }) => {
8485
+ const anzahl = bilder.length;
8486
+ const bild = bilder[position];
8487
+ const blaettern = useCallback((schritt) => {
8488
+ if (anzahl === 0) return;
8489
+ onWechseln((position + schritt + anzahl) % anzahl);
8490
+ }, [anzahl, position, onWechseln]);
8491
+ useEffect3(() => {
8492
+ const taste = (e) => {
8493
+ if (e.key === "Escape") onSchliessen();
8494
+ else if (e.key === "ArrowLeft") blaettern(-1);
8495
+ else if (e.key === "ArrowRight") blaettern(1);
8496
+ };
8497
+ document.addEventListener("keydown", taste);
8498
+ return () => document.removeEventListener("keydown", taste);
8499
+ }, [blaettern, onSchliessen]);
8500
+ if (!bild) return null;
8501
+ return /* @__PURE__ */ jsxs7(
8502
+ "div",
8503
+ {
8504
+ className: "szenen-bildviewer",
8505
+ "data-testid": testId,
8506
+ role: "dialog",
8507
+ "aria-modal": "true",
8508
+ "aria-label": satzTitel ? `${satzTitel} \u2014 ${bild.titel}` : bild.titel,
8509
+ children: [
8510
+ /* @__PURE__ */ jsxs7("header", { className: "szenen-bildviewer__kopf", children: [
8511
+ /* @__PURE__ */ jsxs7("span", { className: "szenen-bildviewer__titel", children: [
8512
+ satzTitel ? `${satzTitel} \xB7 ` : "",
8513
+ bild.titel
8514
+ ] }),
8515
+ /* @__PURE__ */ jsxs7("span", { className: "szenen-bildviewer__zaehler", "data-testid": `${testId}-zaehler`, children: [
8516
+ position + 1,
8517
+ " / ",
8518
+ anzahl
8519
+ ] }),
8520
+ /* @__PURE__ */ jsx7(
8521
+ "button",
8522
+ {
8523
+ type: "button",
8524
+ className: "szenen-bildviewer__schliessen",
8525
+ onClick: onSchliessen,
8526
+ "data-testid": `${testId}-schliessen`,
8527
+ children: "Schliessen"
8528
+ }
8529
+ )
8530
+ ] }),
8531
+ /* @__PURE__ */ jsxs7("div", { className: "szenen-bildviewer__buehne", children: [
8532
+ anzahl > 1 && /* @__PURE__ */ jsx7(
8533
+ "button",
8534
+ {
8535
+ type: "button",
8536
+ className: "szenen-bildviewer__blaettern",
8537
+ onClick: () => blaettern(-1),
8538
+ "aria-label": "Vorheriges Bild",
8539
+ "data-testid": `${testId}-zurueck`,
8540
+ children: "\u2039"
8541
+ }
8542
+ ),
8543
+ /* @__PURE__ */ jsx7("span", { className: "szenen-bildviewer__rahmen", children: bild.quelle ? /* @__PURE__ */ jsx7(
8544
+ "img",
8545
+ {
8546
+ className: "szenen-bildviewer__bild",
8547
+ src: bild.quelle,
8548
+ alt: bild.titel,
8549
+ "data-testid": `${testId}-bild`
8550
+ }
8551
+ ) : (
8552
+ // Auch gross bleibt eine fehlende Quelle eine Auskunft
8553
+ // und kein Textblock (R12.3).
8554
+ /* @__PURE__ */ jsx7("span", { className: "szenen-bildviewer__leer", "data-testid": `${testId}-leer`, children: bild.leerText ?? "F\xFCr dieses Bild gibt es keine anzeigbare Quelle." })
8555
+ ) }),
8556
+ anzahl > 1 && /* @__PURE__ */ jsx7(
8557
+ "button",
8558
+ {
8559
+ type: "button",
8560
+ className: "szenen-bildviewer__blaettern",
8561
+ onClick: () => blaettern(1),
8562
+ "aria-label": "N\xE4chstes Bild",
8563
+ "data-testid": `${testId}-weiter`,
8564
+ children: "\u203A"
8565
+ }
8566
+ )
8567
+ ] }),
8568
+ bild.details && /* @__PURE__ */ jsx7("div", { className: "szenen-bildviewer__details", "data-testid": `${testId}-details`, children: bild.details })
8569
+ ]
8570
+ }
8571
+ );
8572
+ };
8573
+ var BildGalerie = ({ bilder, testId, satzTitel }) => {
8574
+ const [offen, setOffen] = useState7(null);
8575
+ useEffect3(() => {
8576
+ setOffen((vorher) => vorher !== null && vorher >= bilder.length ? null : vorher);
8577
+ }, [bilder.length]);
8578
+ if (bilder.length === 0) return null;
8579
+ return /* @__PURE__ */ jsxs7(Fragment3, { children: [
8580
+ /* @__PURE__ */ jsx7("ul", { className: "szenen-bildgalerie", "data-testid": testId, children: bilder.map((bild, position) => /* @__PURE__ */ jsx7("li", { children: /* @__PURE__ */ jsxs7(
8581
+ "button",
8582
+ {
8583
+ type: "button",
8584
+ className: "szenen-bildgalerie__kachel",
8585
+ onClick: () => setOffen(position),
8586
+ "data-testid": `${testId}-oeffnen-${bild.id}`,
8587
+ title: bild.titel,
8588
+ children: [
8589
+ /* @__PURE__ */ jsx7(
8590
+ Kachel,
8591
+ {
8592
+ quelle: bild.quelle,
8593
+ alt: bild.titel,
8594
+ ...bild.leerText ? { leerText: bild.leerText } : {}
8595
+ }
8596
+ ),
8597
+ /* @__PURE__ */ jsxs7("span", { className: "szenen-bildgalerie__nummer", children: [
8598
+ "#",
8599
+ position + 1
8600
+ ] })
8601
+ ]
8602
+ }
8603
+ ) }, bild.id)) }),
8604
+ offen !== null && /* @__PURE__ */ jsx7(
8605
+ BildViewer,
8606
+ {
8607
+ bilder,
8608
+ position: offen,
8609
+ onWechseln: setOffen,
8610
+ onSchliessen: () => setOffen(null),
8611
+ testId: `${testId}-viewer`,
8612
+ ...satzTitel ? { satzTitel } : {}
8613
+ }
8614
+ )
8615
+ ] });
8616
+ };
8617
+
8618
+ // src/features/szenen/areas/RunImagesPanel.tsx
8619
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
8288
8620
  var AUFTRAG_TEXT = {
8289
8621
  // „gestartet/unterbrochen" in einem: Aus dem Log allein ist beides nicht
8290
8622
  // unterscheidbar, und genau das ist beabsichtigt — es gibt keinen
@@ -8296,8 +8628,10 @@ var AUFTRAG_TEXT = {
8296
8628
  };
8297
8629
  var RunImagesPanel = ({ port, lauf }) => {
8298
8630
  const faehig = capabilitiesOf(port);
8299
- const [nachladen, setNachladen] = useState7(0);
8631
+ const [nachladen, setNachladen] = useState8(0);
8300
8632
  const neuLesen = () => setNachladen((n) => n + 1);
8633
+ const [erzeugenOffen, setErzeugenOffen] = useState8(null);
8634
+ const [zuordnenOffen, setZuordnenOffen] = useState8(null);
8301
8635
  const quelle = sourceOf(lauf);
8302
8636
  const [wahlPhase] = usePortQuery(
8303
8637
  () => port.imageGeneration ? port.imageGeneration.imageModelChoiceForRun(lauf.run_id) : Promise.resolve({ kind: "ok", value: null }),
@@ -8314,38 +8648,40 @@ var RunImagesPanel = ({ port, lauf }) => {
8314
8648
  );
8315
8649
  const auftraege = auftraegePhase.status === "ready" ? auftraegePhase.value : [];
8316
8650
  const batches = batchesPhase.status === "ready" ? batchesPhase.value : [];
8317
- return /* @__PURE__ */ jsxs7("div", { className: "szenen-bilder", "data-testid": `bilder-${lauf.run_id}`, children: [
8318
- /* @__PURE__ */ jsxs7("section", { className: "szenen-bilder__eingang", "data-testid": `eingang-${lauf.run_id}`, children: [
8319
- /* @__PURE__ */ jsx7("h5", { children: "Eingang \u2014 woraus dieser Prompt entstand" }),
8320
- /* @__PURE__ */ jsxs7("p", { className: "szenen-bilder__ids", children: [
8321
- /* @__PURE__ */ jsxs7("span", { children: [
8651
+ const auffaellige = auftraege.filter((a) => a.status !== "succeeded");
8652
+ const erzeugenAuf = erzeugenOffen ?? batches.length === 0;
8653
+ return /* @__PURE__ */ jsxs8("div", { className: "szenen-bilder", "data-testid": `bilder-${lauf.run_id}`, children: [
8654
+ /* @__PURE__ */ jsxs8("section", { className: "szenen-bilder__eingang", "data-testid": `eingang-${lauf.run_id}`, children: [
8655
+ /* @__PURE__ */ jsx8("h5", { children: "Eingang \u2014 woraus dieser Prompt entstand" }),
8656
+ /* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__ids", children: [
8657
+ /* @__PURE__ */ jsxs8("span", { children: [
8322
8658
  "Lauf ",
8323
- /* @__PURE__ */ jsx7("code", { "data-testid": `eingang-lauf-${lauf.run_id}`, children: lauf.run_id })
8659
+ /* @__PURE__ */ jsx8("code", { "data-testid": `eingang-lauf-${lauf.run_id}`, children: lauf.run_id })
8324
8660
  ] }),
8325
- quelle.kind === "published" && /* @__PURE__ */ jsxs7("span", { "data-testid": `eingang-herkunft-${lauf.run_id}`, children: [
8661
+ quelle.kind === "published" && /* @__PURE__ */ jsxs8("span", { "data-testid": `eingang-herkunft-${lauf.run_id}`, children: [
8326
8662
  "ver\xF6ffentlichte Shot-Version ",
8327
- /* @__PURE__ */ jsx7("code", { children: quelle.shot_version_id })
8663
+ /* @__PURE__ */ jsx8("code", { children: quelle.shot_version_id })
8328
8664
  ] }),
8329
- quelle.kind === "draft_chain" && /* @__PURE__ */ jsxs7("span", { "data-testid": `eingang-herkunft-${lauf.run_id}`, children: [
8665
+ quelle.kind === "draft_chain" && /* @__PURE__ */ jsxs8("span", { "data-testid": `eingang-herkunft-${lauf.run_id}`, children: [
8330
8666
  "Draft-Kette ",
8331
- /* @__PURE__ */ jsx7("code", { children: quelle.chain_id })
8667
+ /* @__PURE__ */ jsx8("code", { children: quelle.chain_id })
8332
8668
  ] }),
8333
- quelle.kind === "scene_direct" && /* @__PURE__ */ jsxs7("span", { "data-testid": `eingang-herkunft-${lauf.run_id}`, children: [
8669
+ quelle.kind === "scene_direct" && /* @__PURE__ */ jsxs8("span", { "data-testid": `eingang-herkunft-${lauf.run_id}`, children: [
8334
8670
  "Szene ",
8335
- /* @__PURE__ */ jsx7("code", { children: quelle.scene.element_id }),
8336
- quelle.scene.draft_id ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
8671
+ /* @__PURE__ */ jsx8("code", { children: quelle.scene.element_id }),
8672
+ quelle.scene.draft_id ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
8337
8673
  " \xB7 Entwurf ",
8338
- /* @__PURE__ */ jsx7("code", { children: quelle.scene.draft_id }),
8674
+ /* @__PURE__ */ jsx8("code", { children: quelle.scene.draft_id }),
8339
8675
  " (Revision ",
8340
8676
  quelle.scene.revision,
8341
8677
  ")"
8342
- ] }) : /* @__PURE__ */ jsxs7(Fragment3, { children: [
8678
+ ] }) : /* @__PURE__ */ jsxs8(Fragment4, { children: [
8343
8679
  " \xB7 Version ",
8344
- /* @__PURE__ */ jsx7("code", { children: quelle.scene.version_id })
8680
+ /* @__PURE__ */ jsx8("code", { children: quelle.scene.version_id })
8345
8681
  ] })
8346
8682
  ] })
8347
8683
  ] }),
8348
- quelle.kind === "draft_chain" && quelle.derivation_run_id ? /* @__PURE__ */ jsx7(
8684
+ quelle.kind === "draft_chain" && quelle.derivation_run_id ? /* @__PURE__ */ jsx8(
8349
8685
  InputBilder,
8350
8686
  {
8351
8687
  port,
@@ -8356,67 +8692,148 @@ var RunImagesPanel = ({ port, lauf }) => {
8356
8692
  // Nichts raten: Ein Lauf vor 6.7 trägt die
8357
8693
  // Rekonstruktionsherkunft nicht, und ein veröffentlichter
8358
8694
  // Lauf hat keine (D-123).
8359
- /* @__PURE__ */ jsx7("p", { "data-testid": `eingang-ohne-bilder-${lauf.run_id}`, children: "Zu diesem Lauf ist kein Rekonstruktionslauf hinterlegt \u2014 die Eingangsbilder sind darum nicht sicher aufl\xF6sbar und werden nicht geraten." })
8695
+ /* @__PURE__ */ jsx8("p", { "data-testid": `eingang-ohne-bilder-${lauf.run_id}`, children: "Zu diesem Lauf ist kein Rekonstruktionslauf hinterlegt \u2014 die Eingangsbilder sind darum nicht sicher aufl\xF6sbar und werden nicht geraten." })
8360
8696
  )
8361
8697
  ] }),
8362
- /* @__PURE__ */ jsxs7("section", { className: "szenen-bilder__ausgang", "data-testid": `ausgang-${lauf.run_id}`, children: [
8363
- /* @__PURE__ */ jsx7("h5", { children: "Ausgang \u2014 die Bilder aus diesem Prompt" }),
8364
- !faehig.imageOrderHistory && /* @__PURE__ */ jsx7("p", { "data-testid": `auftraege-unsupported-${lauf.run_id}`, children: "Dieser Host liest keine Bildgenerierungsauftr\xE4ge. Bereits gespeicherte Batches sind unten trotzdem sichtbar." }),
8365
- auftraegePhase.status === "error" && /* @__PURE__ */ jsxs7("p", { "data-testid": `auftraege-fehler-${lauf.run_id}`, role: "alert", children: [
8698
+ /* @__PURE__ */ jsxs8("section", { className: "szenen-bilder__ausgang", "data-testid": `ausgang-${lauf.run_id}`, children: [
8699
+ /* @__PURE__ */ jsx8("h5", { children: "Ausgang \u2014 die Bilder aus diesem Prompt" }),
8700
+ !faehig.imageBatchHistory && /* @__PURE__ */ jsx8("p", { "data-testid": `batches-unsupported-${lauf.run_id}`, children: "Dieser Host liest keine Bild-Batches. Das ist kein Fehler und kein vor\xFCbergehender Zustand." }),
8701
+ batchesPhase.status === "error" && /* @__PURE__ */ jsxs8("p", { "data-testid": `batches-fehler-${lauf.run_id}`, role: "alert", children: [
8702
+ "Batches konnten nicht geladen werden: ",
8703
+ batchesPhase.message
8704
+ ] }),
8705
+ faehig.imageBatchHistory && batchesPhase.status === "ready" && batches.length === 0 && /* @__PURE__ */ jsx8("p", { "data-testid": `keine-batches-${lauf.run_id}`, children: "Zu diesem Lauf ist noch kein Bild gespeichert." }),
8706
+ batches.map((batch) => /* @__PURE__ */ jsx8(BatchKachel, { port, batch }, batch.item_id)),
8707
+ !faehig.imageOrderHistory && /* @__PURE__ */ jsx8("p", { "data-testid": `auftraege-unsupported-${lauf.run_id}`, children: "Dieser Host liest keine Bildgenerierungsauftr\xE4ge. Bereits gespeicherte Batches sind oben trotzdem sichtbar." }),
8708
+ auftraegePhase.status === "error" && /* @__PURE__ */ jsxs8("p", { "data-testid": `auftraege-fehler-${lauf.run_id}`, role: "alert", children: [
8366
8709
  "Auftr\xE4ge konnten nicht geladen werden: ",
8367
8710
  auftraegePhase.message
8368
8711
  ] }),
8369
- faehig.imageOrderHistory && auftraegePhase.status === "ready" && auftraege.length === 0 && /* @__PURE__ */ jsx7("p", { "data-testid": `keine-auftraege-${lauf.run_id}`, children: "F\xFCr diesen Lauf wurde noch kein Bildauftrag gestartet." }),
8370
- auftraege.length > 0 && /* @__PURE__ */ jsx7("ul", { className: "szenen-bilder__auftraege", "data-testid": `auftraege-${lauf.run_id}`, children: auftraege.map((auftrag) => /* @__PURE__ */ jsxs7(
8371
- "li",
8712
+ faehig.imageOrderHistory && auftraegePhase.status === "ready" && auftraege.length === 0 && /* @__PURE__ */ jsx8("p", { "data-testid": `keine-auftraege-${lauf.run_id}`, children: "F\xFCr diesen Lauf wurde noch kein Bildauftrag gestartet." }),
8713
+ auffaellige.length > 0 && /* @__PURE__ */ jsxs8(
8714
+ "p",
8372
8715
  {
8373
- "data-testid": `auftrag-${auftrag.generation_batch_id}`,
8374
- "data-status": auftrag.status,
8716
+ className: "szenen-bilder__auffaellig",
8717
+ "data-testid": `auftraege-auffaellig-${lauf.run_id}`,
8718
+ role: "alert",
8375
8719
  children: [
8376
- /* @__PURE__ */ jsx7("strong", { children: AUFTRAG_TEXT[auftrag.status] }),
8377
- /* @__PURE__ */ jsx7("code", { children: auftrag.generation_batch_id }),
8378
- /* @__PURE__ */ jsxs7("span", { "data-testid": `auftrag-modell-${auftrag.generation_batch_id}`, children: [
8379
- auftrag.request?.image_count ?? "?",
8380
- " Bild(er) \xB7",
8381
- " ",
8382
- auftrag.request?.callable_model_id ?? "Modell unbekannt",
8383
- auftrag.request?.provider ? ` bei ${auftrag.request.provider}` : ""
8384
- ] }),
8385
- auftrag.request?.prompt_target_model_key && auftrag.request.target_model_matched === false && /* @__PURE__ */ jsxs7("span", { "data-testid": `auftrag-abweichung-${auftrag.generation_batch_id}`, children: [
8386
- "abweichend \u2014 Prompt optimiert f\xFCr",
8387
- " ",
8388
- /* @__PURE__ */ jsx7("code", { children: auftrag.request.prompt_target_model_key })
8389
- ] }),
8390
- auftrag.request?.negative_prompt_transmitted === false && /* @__PURE__ */ jsx7("span", { "data-testid": `auftrag-negativ-${auftrag.generation_batch_id}`, children: "Ein negativer Prompt lief \xFCber dieses Profil nicht mit." }),
8391
- auftrag.item_id && /* @__PURE__ */ jsxs7("span", { "data-testid": `auftrag-item-${auftrag.generation_batch_id}`, children: [
8392
- "Item ",
8393
- /* @__PURE__ */ jsx7("code", { children: auftrag.item_id })
8720
+ auffaellige.length === 1 ? `Ein Bildauftrag ist ${AUFTRAG_TEXT[auffaellige[0].status]}.` : `${auffaellige.length} Bildauftr\xE4ge sind nicht sauber durchgelaufen.`,
8721
+ " ",
8722
+ "Einzelheiten im Verlauf."
8723
+ ]
8724
+ }
8725
+ ),
8726
+ auftraege.length > 0 && /* @__PURE__ */ jsxs8(
8727
+ "details",
8728
+ {
8729
+ className: "szenen-bilder__verlauf",
8730
+ "data-testid": `auftraege-verlauf-${lauf.run_id}`,
8731
+ open: auffaellige.length > 0,
8732
+ children: [
8733
+ /* @__PURE__ */ jsxs8("summary", { children: [
8734
+ "Bildauftr\xE4ge / Verlauf (",
8735
+ auftraege.length,
8736
+ ")"
8394
8737
  ] }),
8395
- auftrag.status === "started" && /* @__PURE__ */ jsx7("span", { "data-testid": `auftrag-hinweis-${auftrag.generation_batch_id}`, children: "Kein automatischer neuer Versuch \u2014 ob noch einmal erzeugt wird, entscheiden Sie." }),
8396
- auftrag.diagnostic && /* @__PURE__ */ jsx7("span", { "data-testid": `auftrag-diagnose-${auftrag.generation_batch_id}`, children: auftrag.diagnostic })
8738
+ /* @__PURE__ */ jsx8("ul", { className: "szenen-bilder__auftraege", "data-testid": `auftraege-${lauf.run_id}`, children: auftraege.map((auftrag) => /* @__PURE__ */ jsxs8(
8739
+ "li",
8740
+ {
8741
+ "data-testid": `auftrag-${auftrag.generation_batch_id}`,
8742
+ "data-status": auftrag.status,
8743
+ children: [
8744
+ /* @__PURE__ */ jsx8("strong", { children: AUFTRAG_TEXT[auftrag.status] }),
8745
+ /* @__PURE__ */ jsxs8("span", { "data-testid": `auftrag-modell-${auftrag.generation_batch_id}`, children: [
8746
+ auftrag.request?.image_count ?? "?",
8747
+ " Bild(er) \xB7",
8748
+ " ",
8749
+ auftrag.request?.callable_model_id ?? "Modell unbekannt",
8750
+ auftrag.request?.provider ? ` bei ${auftrag.request.provider}` : ""
8751
+ ] }),
8752
+ auftrag.request?.prompt_target_model_key && auftrag.request.target_model_matched === false && /* @__PURE__ */ jsxs8("span", { "data-testid": `auftrag-abweichung-${auftrag.generation_batch_id}`, children: [
8753
+ "abweichend \u2014 Prompt optimiert f\xFCr",
8754
+ " ",
8755
+ /* @__PURE__ */ jsx8("code", { children: auftrag.request.prompt_target_model_key })
8756
+ ] }),
8757
+ auftrag.request?.negative_prompt_transmitted === false && /* @__PURE__ */ jsx8("span", { "data-testid": `auftrag-negativ-${auftrag.generation_batch_id}`, children: "Ein negativer Prompt lief \xFCber dieses Profil nicht mit." }),
8758
+ auftrag.item_id && /* @__PURE__ */ jsxs8("span", { "data-testid": `auftrag-item-${auftrag.generation_batch_id}`, children: [
8759
+ "Item ",
8760
+ /* @__PURE__ */ jsx8("code", { children: auftrag.item_id })
8761
+ ] }),
8762
+ auftrag.status === "started" && /* @__PURE__ */ jsx8("span", { "data-testid": `auftrag-hinweis-${auftrag.generation_batch_id}`, children: "Kein automatischer neuer Versuch \u2014 ob noch einmal erzeugt wird, entscheiden Sie." }),
8763
+ auftrag.diagnostic && /* @__PURE__ */ jsx8("span", { "data-testid": `auftrag-diagnose-${auftrag.generation_batch_id}`, children: auftrag.diagnostic }),
8764
+ /* @__PURE__ */ jsx8("code", { className: "szenen-bilder__auftragskennung", children: auftrag.generation_batch_id })
8765
+ ]
8766
+ },
8767
+ auftrag.generation_batch_id
8768
+ )) })
8397
8769
  ]
8398
- },
8399
- auftrag.generation_batch_id
8400
- )) }),
8401
- !faehig.imageBatchHistory && /* @__PURE__ */ jsx7("p", { "data-testid": `batches-unsupported-${lauf.run_id}`, children: "Dieser Host liest keine Bild-Batches. Das ist kein Fehler und kein vor\xFCbergehender Zustand." }),
8402
- batchesPhase.status === "error" && /* @__PURE__ */ jsxs7("p", { "data-testid": `batches-fehler-${lauf.run_id}`, role: "alert", children: [
8403
- "Batches konnten nicht geladen werden: ",
8404
- batchesPhase.message
8405
- ] }),
8406
- faehig.imageBatchHistory && batchesPhase.status === "ready" && batches.length === 0 && /* @__PURE__ */ jsx7("p", { "data-testid": `keine-batches-${lauf.run_id}`, children: "Zu diesem Lauf ist noch kein Bild gespeichert." }),
8407
- batches.map((batch) => /* @__PURE__ */ jsx7(BatchKachel, { port, batch }, batch.item_id))
8770
+ }
8771
+ )
8408
8772
  ] }),
8409
- /* @__PURE__ */ jsx7(
8410
- ErzeugenAktion,
8773
+ /* @__PURE__ */ jsxs8(
8774
+ "details",
8411
8775
  {
8412
- port,
8413
- lauf,
8414
- wahl,
8415
- wahlFehler: wahlPhase.status === "error" ? wahlPhase.message : null,
8416
- onFertig: neuLesen
8776
+ className: "szenen-bilder__aktion",
8777
+ "data-testid": `erzeugen-bereich-${lauf.run_id}`,
8778
+ open: erzeugenAuf,
8779
+ children: [
8780
+ /* @__PURE__ */ jsx8(
8781
+ "summary",
8782
+ {
8783
+ onClick: (e) => {
8784
+ e.preventDefault();
8785
+ setErzeugenOffen(!erzeugenAuf);
8786
+ },
8787
+ children: "Bilder aus diesem Prompt erzeugen"
8788
+ }
8789
+ ),
8790
+ /* @__PURE__ */ jsx8(
8791
+ ErzeugenAktion,
8792
+ {
8793
+ port,
8794
+ lauf,
8795
+ wahl,
8796
+ wahlFehler: wahlPhase.status === "error" ? wahlPhase.message : null,
8797
+ onFertig: () => {
8798
+ setErzeugenOffen(true);
8799
+ neuLesen();
8800
+ }
8801
+ }
8802
+ )
8803
+ ]
8417
8804
  }
8418
8805
  ),
8419
- /* @__PURE__ */ jsx7(ZuordnenAktion, { port, lauf, onFertig: neuLesen })
8806
+ /* @__PURE__ */ jsxs8(
8807
+ "details",
8808
+ {
8809
+ className: "szenen-bilder__aktion",
8810
+ "data-testid": `zuordnen-bereich-${lauf.run_id}`,
8811
+ open: zuordnenOffen ?? false,
8812
+ children: [
8813
+ /* @__PURE__ */ jsx8(
8814
+ "summary",
8815
+ {
8816
+ onClick: (e) => {
8817
+ e.preventDefault();
8818
+ setZuordnenOffen(!(zuordnenOffen ?? false));
8819
+ },
8820
+ children: "Externe Bilder diesem Lauf zuordnen"
8821
+ }
8822
+ ),
8823
+ /* @__PURE__ */ jsx8(
8824
+ ZuordnenAktion,
8825
+ {
8826
+ port,
8827
+ lauf,
8828
+ onFertig: () => {
8829
+ setZuordnenOffen(true);
8830
+ neuLesen();
8831
+ }
8832
+ }
8833
+ )
8834
+ ]
8835
+ }
8836
+ )
8420
8837
  ] });
8421
8838
  };
8422
8839
  var InputBilder = ({ port, runId, derivationRunId }) => {
@@ -8424,9 +8841,9 @@ var InputBilder = ({ port, runId, derivationRunId }) => {
8424
8841
  () => port.derivation ? port.derivation.getDerivation(derivationRunId) : Promise.resolve({ kind: "ok", value: null }),
8425
8842
  [port, derivationRunId]
8426
8843
  );
8427
- if (phase.status === "loading") return /* @__PURE__ */ jsx7("p", { children: "Rekonstruktionslauf wird geladen \u2026" });
8844
+ if (phase.status === "loading") return /* @__PURE__ */ jsx8("p", { children: "Rekonstruktionslauf wird geladen \u2026" });
8428
8845
  if (phase.status === "error") {
8429
- return /* @__PURE__ */ jsxs7("p", { "data-testid": `eingang-fehler-${runId}`, role: "alert", children: [
8846
+ return /* @__PURE__ */ jsxs8("p", { "data-testid": `eingang-fehler-${runId}`, role: "alert", children: [
8430
8847
  "Der Rekonstruktionslauf ",
8431
8848
  derivationRunId,
8432
8849
  " konnte nicht geladen werden: ",
@@ -8434,22 +8851,22 @@ var InputBilder = ({ port, runId, derivationRunId }) => {
8434
8851
  ] });
8435
8852
  }
8436
8853
  if (!phase.value) {
8437
- return /* @__PURE__ */ jsxs7("p", { "data-testid": `eingang-unbekannt-${runId}`, children: [
8854
+ return /* @__PURE__ */ jsxs8("p", { "data-testid": `eingang-unbekannt-${runId}`, children: [
8438
8855
  "Der Rekonstruktionslauf ",
8439
- /* @__PURE__ */ jsx7("code", { children: derivationRunId }),
8856
+ /* @__PURE__ */ jsx8("code", { children: derivationRunId }),
8440
8857
  " ist in diesem Host nicht auffindbar."
8441
8858
  ] });
8442
8859
  }
8443
8860
  const bilder = phase.value.input.images;
8444
- return /* @__PURE__ */ jsxs7("div", { "data-testid": `eingang-bilder-${runId}`, children: [
8445
- /* @__PURE__ */ jsxs7("p", { children: [
8861
+ return /* @__PURE__ */ jsxs8("div", { "data-testid": `eingang-bilder-${runId}`, children: [
8862
+ /* @__PURE__ */ jsxs8("p", { children: [
8446
8863
  "aus Rekonstruktionslauf ",
8447
- /* @__PURE__ */ jsx7("code", { children: derivationRunId }),
8864
+ /* @__PURE__ */ jsx8("code", { children: derivationRunId }),
8448
8865
  phase.value.input.prompt_text ? " \xB7 mit Referenzprompt" : ""
8449
8866
  ] }),
8450
- bilder.length === 0 ? /* @__PURE__ */ jsx7("p", { children: "Der Rekonstruktionslauf lief ohne Eingangsbild." }) : /* @__PURE__ */ jsx7("ul", { className: "szenen-bilder__eingangsliste", children: bilder.map((bild, index) => /* @__PURE__ */ jsx7("li", { "data-kind": bild.kind, children: bild.kind === "library" ? /* @__PURE__ */ jsx7(BestandsBild, { port, mediaRef: bild.media_ref }) : /* @__PURE__ */ jsxs7("span", { children: [
8867
+ bilder.length === 0 ? /* @__PURE__ */ jsx8("p", { children: "Der Rekonstruktionslauf lief ohne Eingangsbild." }) : /* @__PURE__ */ jsx8("ul", { className: "szenen-bilder__eingangsliste", children: bilder.map((bild, index) => /* @__PURE__ */ jsx8("li", { "data-kind": bild.kind, children: bild.kind === "library" ? /* @__PURE__ */ jsx8(BestandsBild, { port, mediaRef: bild.media_ref }) : /* @__PURE__ */ jsxs8("span", { children: [
8451
8868
  "Upload, nur \xFCber seinen Digest belegt (",
8452
- /* @__PURE__ */ jsxs7("code", { children: [
8869
+ /* @__PURE__ */ jsxs8("code", { children: [
8453
8870
  bild.sha256.slice(0, 12),
8454
8871
  "\u2026"
8455
8872
  ] }),
@@ -8467,113 +8884,219 @@ var BestandsBild = ({ port, mediaRef }) => {
8467
8884
  () => port.imageLibrary ? port.imageLibrary.resolveImage(mediaRef) : Promise.resolve({ kind: "ok", value: null }),
8468
8885
  [port, mediaRef]
8469
8886
  );
8470
- return /* @__PURE__ */ jsxs7("span", { "data-testid": `eingangsbild-${mediaRef}`, children: [
8471
- phase.status === "ready" && phase.value && /* @__PURE__ */ jsx7(
8472
- "img",
8887
+ const quelle = phase.status === "ready" && phase.value ? `data:${phase.value.mime_type};base64,${phase.value.data}` : null;
8888
+ return /* @__PURE__ */ jsxs8("span", { "data-testid": `eingangsbild-${mediaRef}`, children: [
8889
+ /* @__PURE__ */ jsx8(
8890
+ Kachel,
8473
8891
  {
8474
- src: `data:${phase.value.mime_type};base64,${phase.value.data}`,
8475
- alt: `Eingangsbild ${mediaRef}`
8892
+ quelle,
8893
+ alt: `Eingangsbild ${mediaRef}`,
8894
+ ...phase.status === "error" ? { leerText: "Nicht ladbar" } : {}
8476
8895
  }
8477
8896
  ),
8478
8897
  phase.status === "error" && // Verzeichnet, aber nicht lesbar ist etwas anderes als
8479
8898
  // unbekannt — der Unterschied gehoert sichtbar.
8480
- /* @__PURE__ */ jsx7("em", { "data-testid": `eingangsbild-fehler-${mediaRef}`, children: phase.message }),
8481
- /* @__PURE__ */ jsx7("code", { children: mediaRef })
8899
+ /* @__PURE__ */ jsx8("em", { "data-testid": `eingangsbild-fehler-${mediaRef}`, children: phase.message }),
8900
+ /* @__PURE__ */ jsx8("code", { children: mediaRef })
8482
8901
  ] });
8483
8902
  };
8484
- var BatchBild = ({ port, bild }) => {
8485
- const [phase] = usePortQuery(
8486
- () => port.imageLibrary ? port.imageLibrary.resolveImage(bild.media_ref, bild.mime_type ?? null) : Promise.resolve({ kind: "ok", value: null }),
8487
- [port, bild.media_ref, bild.mime_type]
8488
- );
8489
- return /* @__PURE__ */ jsxs7("li", { "data-testid": `batchbild-${bild.media_ref}`, children: [
8490
- phase.status === "ready" && phase.value && /* @__PURE__ */ jsx7(
8491
- "img",
8492
- {
8493
- src: `data:${phase.value.mime_type};base64,${phase.value.data}`,
8494
- alt: `Ausgabebild ${bild.media_ref}, Position ${bild.position}`
8903
+ function useBildQuellen(port, bilder) {
8904
+ const [stand, setStand] = useState8(() => ({ quellen: /* @__PURE__ */ new Map(), fehler: /* @__PURE__ */ new Map() }));
8905
+ const gehalten = useRef2(/* @__PURE__ */ new Map());
8906
+ const gescheitert = useRef2(/* @__PURE__ */ new Map());
8907
+ const [versuch, setVersuch] = useState8(0);
8908
+ const schluessel = bilder.map((b) => `${b.media_ref}|${b.mime_type ?? ""}`).join(" ");
8909
+ useEffect4(() => {
8910
+ const bestand = port.imageLibrary;
8911
+ if (!bestand) return void 0;
8912
+ let abgebrochen = false;
8913
+ void (async () => {
8914
+ for (const bild of bilder) {
8915
+ if (abgebrochen) return;
8916
+ const vorher = gescheitert.current.get(bild.media_ref);
8917
+ const endgueltig = vorher !== void 0 && !vorher.retryable;
8918
+ if (gehalten.current.has(bild.media_ref) || endgueltig) continue;
8919
+ const ergebnis = await bestand.resolveImage(bild.media_ref, bild.mime_type ?? null);
8920
+ if (abgebrochen) return;
8921
+ if (ergebnis.kind === "ok" && ergebnis.value) {
8922
+ gehalten.current.set(
8923
+ bild.media_ref,
8924
+ `data:${ergebnis.value.mime_type};base64,${ergebnis.value.data}`
8925
+ );
8926
+ gescheitert.current.delete(bild.media_ref);
8927
+ } else if (ergebnis.kind === "error") {
8928
+ gescheitert.current.set(bild.media_ref, {
8929
+ message: ergebnis.message,
8930
+ retryable: ergebnis.retryable
8931
+ });
8932
+ }
8933
+ setStand({
8934
+ quellen: new Map(gehalten.current),
8935
+ fehler: new Map(gescheitert.current)
8936
+ });
8495
8937
  }
8496
- ),
8497
- phase.status === "error" && // Verzeichnet, aber nicht lesbar ist etwas anderes als
8498
- // unbekannt — der Unterschied gehört sichtbar dran, nicht in
8499
- // ein stilles Weglassen (A5).
8500
- /* @__PURE__ */ jsx7("em", { "data-testid": `batchbild-fehler-${bild.media_ref}`, children: phase.message }),
8501
- !port.imageLibrary && // Capability-Grenze, kein Fehler: Dieser Host kann Batches
8502
- // lesen, aber keine Bilder auflösen (E). Kein erfundener
8503
- // Fallback auf eine Serverroute (A6).
8504
- /* @__PURE__ */ jsx7("em", { "data-testid": `batchbild-unsupported-${bild.media_ref}`, children: "Dieser Host l\xF6st keine Bilder auf \u2014 nur die Metadaten sind bekannt." }),
8505
- /* @__PURE__ */ jsx7("code", { children: bild.media_ref }),
8506
- /* @__PURE__ */ jsxs7("span", { children: [
8507
- "Position ",
8508
- bild.position
8509
- ] }),
8510
- /* @__PURE__ */ jsx7("span", { children: bild.model || "Modell unbekannt" }),
8511
- /* @__PURE__ */ jsx7("span", { children: bild.seed === null || bild.seed === void 0 || bild.seed === -1 ? "ohne Seed" : `Seed ${bild.seed}` }),
8512
- bild.width && bild.height ? /* @__PURE__ */ jsxs7("span", { children: [
8513
- bild.width,
8514
- "\xD7",
8515
- bild.height
8516
- ] }) : null
8517
- ] });
8938
+ })();
8939
+ return () => {
8940
+ abgebrochen = true;
8941
+ };
8942
+ }, [port, schluessel, versuch]);
8943
+ const fehlerNachricht = /* @__PURE__ */ new Map();
8944
+ let wiederholbar = false;
8945
+ for (const [ref, f] of stand.fehler) {
8946
+ fehlerNachricht.set(ref, f.message);
8947
+ if (f.retryable) wiederholbar = true;
8948
+ }
8949
+ return {
8950
+ quellen: stand.quellen,
8951
+ fehler: fehlerNachricht,
8952
+ wiederholbar,
8953
+ erneutVersuchen: () => setVersuch((n) => n + 1)
8954
+ };
8955
+ }
8956
+ var BildDetails = ({ bild, fehler: fehler4, aufloesbar }) => /* @__PURE__ */ jsxs8("span", { className: "szenen-bilder__meta", "data-testid": `batchbild-${bild.media_ref}`, children: [
8957
+ /* @__PURE__ */ jsx8("code", { children: bild.media_ref }),
8958
+ /* @__PURE__ */ jsxs8("span", { children: [
8959
+ "Position ",
8960
+ bild.position
8961
+ ] }),
8962
+ /* @__PURE__ */ jsx8("span", { children: bild.model || "Modell unbekannt" }),
8963
+ /* @__PURE__ */ jsx8("span", { children: bild.seed === null || bild.seed === void 0 || bild.seed === -1 ? "ohne Seed" : `Seed ${bild.seed}` }),
8964
+ bild.width && bild.height ? /* @__PURE__ */ jsxs8("span", { children: [
8965
+ bild.width,
8966
+ "\xD7",
8967
+ bild.height
8968
+ ] }) : null,
8969
+ fehler4 && /* @__PURE__ */ jsx8("em", { "data-testid": `batchbild-fehler-${bild.media_ref}`, children: fehler4 }),
8970
+ !aufloesbar && // Capability-Grenze, kein Fehler: Dieser Host kann Batches lesen,
8971
+ // aber keine Bilder auflösen (E). Kein erfundener Fallback auf eine
8972
+ // Serverroute (A6).
8973
+ /* @__PURE__ */ jsx8("em", { "data-testid": `batchbild-unsupported-${bild.media_ref}`, children: "Dieser Host l\xF6st keine Bilder auf \u2014 nur die Metadaten sind bekannt." })
8974
+ ] });
8975
+ var HERKUNFT_TEXT = {
8976
+ generated_in_app: "in der App erzeugt",
8977
+ external_import: "extern importiert",
8978
+ mixed: "gemischte Herkunft"
8518
8979
  };
8519
- var BatchKachel = ({ port, batch }) => /* @__PURE__ */ jsxs7(
8520
- "div",
8521
- {
8522
- className: "szenen-bilder__batch",
8523
- "data-testid": `batch-${batch.item_id}`,
8524
- "data-source-kind": batch.source_kind,
8525
- children: [
8526
- /* @__PURE__ */ jsxs7("p", { className: "szenen-bilder__ids", children: [
8527
- /* @__PURE__ */ jsx7("strong", { children: batch.title }),
8528
- /* @__PURE__ */ jsx7("span", { children: batch.source_kind === "generated_in_app" ? "in der App erzeugt" : "extern importiert" }),
8529
- /* @__PURE__ */ jsxs7("span", { children: [
8530
- "Item ",
8531
- /* @__PURE__ */ jsx7("code", { "data-testid": `batch-item-${batch.item_id}`, children: batch.item_id })
8980
+ var HERKUNFT_KURZ = {
8981
+ generated_in_app: "in der App erzeugt",
8982
+ external_import: "extern importiert"
8983
+ };
8984
+ var BatchKachel = ({ port, batch }) => {
8985
+ const { quellen, fehler: fehler4, wiederholbar, erneutVersuchen } = useBildQuellen(port, batch.images);
8986
+ const aufloesbar = Boolean(port.imageLibrary);
8987
+ const bilder = batch.images.map((bild) => ({
8988
+ id: bild.media_ref,
8989
+ quelle: quellen.get(bild.media_ref) ?? null,
8990
+ titel: `Bild ${bild.position + 1}`,
8991
+ ...fehler4.get(bild.media_ref) ? { leerText: "Nicht ladbar" } : {},
8992
+ details: /* @__PURE__ */ jsx8(
8993
+ BildDetails,
8994
+ {
8995
+ bild,
8996
+ fehler: fehler4.get(bild.media_ref) ?? null,
8997
+ aufloesbar
8998
+ }
8999
+ )
9000
+ }));
9001
+ return /* @__PURE__ */ jsxs8(
9002
+ "section",
9003
+ {
9004
+ className: "szenen-bilder__batch",
9005
+ "data-testid": `batch-${batch.item_id}`,
9006
+ "data-source-kind": batch.source_kind,
9007
+ children: [
9008
+ /* @__PURE__ */ jsxs8("header", { className: "szenen-bilder__batchkopf", children: [
9009
+ /* @__PURE__ */ jsx8("strong", { children: batch.title }),
9010
+ /* @__PURE__ */ jsxs8("span", { className: "szenen-bilder__herkunft", children: [
9011
+ HERKUNFT_TEXT[batch.source_kind],
9012
+ " \xB7 ",
9013
+ batch.images.length,
9014
+ " Bild(er)"
9015
+ ] })
8532
9016
  ] }),
8533
- /* @__PURE__ */ jsxs7("span", { children: [
8534
- "Batches ",
8535
- /* @__PURE__ */ jsx7("code", { children: batch.generation_batch_ids.join(", ") })
9017
+ /* @__PURE__ */ jsx8(
9018
+ BildGalerie,
9019
+ {
9020
+ bilder,
9021
+ testId: `batchgalerie-${batch.item_id}`,
9022
+ satzTitel: batch.title
9023
+ }
9024
+ ),
9025
+ wiederholbar && /* @__PURE__ */ jsx8(
9026
+ "button",
9027
+ {
9028
+ type: "button",
9029
+ className: "szenen-bilder__retry",
9030
+ onClick: erneutVersuchen,
9031
+ "data-testid": `batch-retry-${batch.item_id}`,
9032
+ children: "Bilder erneut laden"
9033
+ }
9034
+ ),
9035
+ /* @__PURE__ */ jsxs8("details", { className: "szenen-bilder__technik", "data-testid": `batch-technik-${batch.item_id}`, children: [
9036
+ /* @__PURE__ */ jsx8("summary", { children: "Technische Details" }),
9037
+ /* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__ids", children: [
9038
+ /* @__PURE__ */ jsxs8("span", { children: [
9039
+ "Item ",
9040
+ /* @__PURE__ */ jsx8("code", { "data-testid": `batch-item-${batch.item_id}`, children: batch.item_id })
9041
+ ] }),
9042
+ /* @__PURE__ */ jsxs8("span", { children: [
9043
+ "Batches",
9044
+ " ",
9045
+ batch.origins.length > 0 ? batch.origins.map((h, i) => /* @__PURE__ */ jsxs8(React7.Fragment, { children: [
9046
+ i > 0 ? ", " : "",
9047
+ /* @__PURE__ */ jsx8("code", { children: h.generation_batch_id }),
9048
+ ` (${HERKUNFT_KURZ[h.source_kind]})`
9049
+ ] }, h.generation_batch_id)) : /* @__PURE__ */ jsx8("code", { children: batch.generation_batch_ids.join(", ") })
9050
+ ] })
9051
+ ] }),
9052
+ /* @__PURE__ */ jsx8("ul", { className: "szenen-bilder__batchliste", children: batch.images.map((bild) => /* @__PURE__ */ jsx8("li", { children: /* @__PURE__ */ jsx8(
9053
+ BildDetails,
9054
+ {
9055
+ bild,
9056
+ fehler: fehler4.get(bild.media_ref) ?? null,
9057
+ aufloesbar
9058
+ }
9059
+ ) }, bild.media_ref)) })
8536
9060
  ] })
8537
- ] }),
8538
- /* @__PURE__ */ jsx7("ul", { className: "szenen-bilder__batchliste", children: batch.images.map((bild) => /* @__PURE__ */ jsx7(BatchBild, { port, bild }, bild.media_ref)) })
8539
- ]
8540
- }
8541
- );
9061
+ ]
9062
+ }
9063
+ );
9064
+ };
8542
9065
  var ProfilBefunde = ({ wahl, runId }) => {
8543
9066
  if (wahl.invalid_profiles.length === 0) return null;
8544
- return /* @__PURE__ */ jsxs7("p", { "data-testid": `erzeugen-profilbefunde-${runId}`, role: "alert", children: [
9067
+ return /* @__PURE__ */ jsxs8("p", { "data-testid": `erzeugen-profilbefunde-${runId}`, role: "alert", children: [
8545
9068
  "Nicht angeboten, weil das Profil unvollst\xE4ndig ist:",
8546
9069
  " ",
8547
9070
  wahl.invalid_profiles.join(" \xB7 ")
8548
9071
  ] });
8549
9072
  };
8550
9073
  var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
8551
- const [modellWahl, setModellWahl] = useState7(null);
8552
- const [anzahlText, setAnzahlText] = useState7("1");
8553
- const [seitenverhaeltnis, setSeitenverhaeltnis] = useState7("");
8554
- const [laeuft, setLaeuft] = useState7(false);
8555
- const [notiz, setNotiz] = useState7(null);
9074
+ const [modellWahl, setModellWahl] = useState8(null);
9075
+ const [anzahlText, setAnzahlText] = useState8("1");
9076
+ const [seitenverhaeltnis, setSeitenverhaeltnis] = useState8("");
9077
+ const [laeuft, setLaeuft] = useState8(false);
9078
+ const [notiz, setNotiz] = useState8(null);
8556
9079
  if (!port.imageGeneration) {
8557
- return /* @__PURE__ */ jsx7("p", { "data-testid": `erzeugen-unsupported-${lauf.run_id}`, children: "Dieser Host erzeugt keine Bilder \u2014 entweder fehlt der Providerzugang oder der gesicherte Speicherweg. Externe Bilder lassen sich trotzdem zuordnen." });
9080
+ return /* @__PURE__ */ jsx8("p", { "data-testid": `erzeugen-unsupported-${lauf.run_id}`, children: "Dieser Host erzeugt keine Bilder \u2014 entweder fehlt der Providerzugang oder der gesicherte Speicherweg. Externe Bilder lassen sich trotzdem zuordnen." });
8558
9081
  }
8559
9082
  if (wahlFehler) {
8560
- return /* @__PURE__ */ jsxs7("p", { "data-testid": `erzeugen-fehler-${lauf.run_id}`, role: "alert", children: [
9083
+ return /* @__PURE__ */ jsxs8("p", { "data-testid": `erzeugen-fehler-${lauf.run_id}`, role: "alert", children: [
8561
9084
  "Die F\xE4higkeitsauskunft schlug fehl: ",
8562
9085
  wahlFehler
8563
9086
  ] });
8564
9087
  }
8565
- if (!wahl) return /* @__PURE__ */ jsx7("p", { children: "Bildf\xE4higkeit wird gepr\xFCft \u2026" });
9088
+ if (!wahl) return /* @__PURE__ */ jsx8("p", { children: "Bildf\xE4higkeit wird gepr\xFCft \u2026" });
8566
9089
  if (wahl.models.length === 0) {
8567
9090
  return (
8568
9091
  // Kein Fehler und kein Grund, den Lauf zu sperren: Der externe
8569
9092
  // Importweg bleibt daneben stehen (D-104.5).
8570
- /* @__PURE__ */ jsxs7(Fragment3, { children: [
8571
- /* @__PURE__ */ jsxs7("p", { "data-testid": `erzeugen-unsupported-modell-${lauf.run_id}`, children: [
9093
+ /* @__PURE__ */ jsxs8(Fragment4, { children: [
9094
+ /* @__PURE__ */ jsxs8("p", { "data-testid": `erzeugen-unsupported-modell-${lauf.run_id}`, children: [
8572
9095
  "Hier kann derzeit kein Bild erzeugt werden:",
8573
9096
  " ",
8574
9097
  wahl.reason ?? "Kein sichtbares Zielmodell tr\xE4gt ein ausf\xFChrbares Profil."
8575
9098
  ] }),
8576
- /* @__PURE__ */ jsx7(ProfilBefunde, { wahl, runId: lauf.run_id })
9099
+ /* @__PURE__ */ jsx8(ProfilBefunde, { wahl, runId: lauf.run_id })
8577
9100
  ] })
8578
9101
  );
8579
9102
  }
@@ -8622,22 +9145,21 @@ var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
8622
9145
  onFertig();
8623
9146
  };
8624
9147
  const negativVorhanden = Boolean(lauf.output?.negative && lauf.output.negative.trim());
8625
- return /* @__PURE__ */ jsxs7("div", { className: "szenen-bilder__aktion", "data-testid": `erzeugen-${lauf.run_id}`, children: [
8626
- /* @__PURE__ */ jsx7("h5", { children: "Bilder aus diesem Prompt erzeugen" }),
8627
- /* @__PURE__ */ jsx7(ProfilBefunde, { wahl, runId: lauf.run_id }),
8628
- /* @__PURE__ */ jsx7("p", { "data-testid": `erzeugen-zielmodell-${lauf.run_id}`, children: wahl.prompt_target_model_key ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
9148
+ return /* @__PURE__ */ jsxs8("div", { className: "szenen-bilder__aktion-inhalt", "data-testid": `erzeugen-${lauf.run_id}`, children: [
9149
+ /* @__PURE__ */ jsx8(ProfilBefunde, { wahl, runId: lauf.run_id }),
9150
+ /* @__PURE__ */ jsx8("p", { "data-testid": `erzeugen-zielmodell-${lauf.run_id}`, children: wahl.prompt_target_model_key ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
8629
9151
  "Prompt optimiert f\xFCr ",
8630
- /* @__PURE__ */ jsx7("code", { children: wahl.prompt_target_model_key })
9152
+ /* @__PURE__ */ jsx8("code", { children: wahl.prompt_target_model_key })
8631
9153
  ] }) : "Dieser Lauf tr\xE4gt keine Optimierungsabsicht (kein target_model)." }),
8632
- /* @__PURE__ */ jsxs7("label", { children: [
9154
+ /* @__PURE__ */ jsxs8("label", { children: [
8633
9155
  "Bildmodell",
8634
- /* @__PURE__ */ jsx7(
9156
+ /* @__PURE__ */ jsx8(
8635
9157
  "select",
8636
9158
  {
8637
9159
  value: aktiv.selection_id,
8638
9160
  "data-testid": `erzeugen-modellwahl-${lauf.run_id}`,
8639
9161
  onChange: (e) => modellWechseln(e.target.value),
8640
- children: wahl.models.map((m) => /* @__PURE__ */ jsxs7("option", { value: m.selection_id, children: [
9162
+ children: wahl.models.map((m) => /* @__PURE__ */ jsxs8("option", { value: m.selection_id, children: [
8641
9163
  m.display_name,
8642
9164
  " (",
8643
9165
  m.provider,
@@ -8647,7 +9169,7 @@ var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
8647
9169
  }
8648
9170
  )
8649
9171
  ] }),
8650
- /* @__PURE__ */ jsxs7("p", { "data-testid": `erzeugen-modell-${lauf.run_id}`, children: [
9172
+ /* @__PURE__ */ jsxs8("p", { "data-testid": `erzeugen-modell-${lauf.run_id}`, children: [
8651
9173
  aktiv.display_name,
8652
9174
  " bei ",
8653
9175
  aktiv.provider,
@@ -8656,26 +9178,26 @@ var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
8656
9178
  aktiv.max_images,
8657
9179
  " Bilder je Auftrag"
8658
9180
  ] }),
8659
- wahl.prompt_target_model_key && !aktiv.is_prompt_target && /* @__PURE__ */ jsxs7("p", { "data-testid": `erzeugen-abweichung-${lauf.run_id}`, children: [
9181
+ wahl.prompt_target_model_key && !aktiv.is_prompt_target && /* @__PURE__ */ jsxs8("p", { "data-testid": `erzeugen-abweichung-${lauf.run_id}`, children: [
8660
9182
  "Hinweis: Prompt optimiert f\xFCr ",
8661
- /* @__PURE__ */ jsx7("code", { children: wahl.prompt_target_model_key }),
9183
+ /* @__PURE__ */ jsx8("code", { children: wahl.prompt_target_model_key }),
8662
9184
  ", Bilder werden mit ",
8663
- /* @__PURE__ */ jsx7("code", { children: aktiv.display_name }),
9185
+ /* @__PURE__ */ jsx8("code", { children: aktiv.display_name }),
8664
9186
  " erzeugt. Das ist zul\xE4ssig \u2014 ein abweichendes Ergebnis liegt dann nicht zwingend am Prompt."
8665
9187
  ] }),
8666
9188
  negativVorhanden && !aktiv.accepts_negative_prompt && // Nicht still verlieren: Der eingefrorene Lauf trägt einen
8667
9189
  // negativen Prompt, den dieser Modellweg nicht führt. Wer das
8668
9190
  // weiß, kann ihn in den positiven Prompt einarbeiten — wer es
8669
9191
  // nicht weiß, wundert sich über das Bild.
8670
- /* @__PURE__ */ jsxs7("p", { "data-testid": `erzeugen-negativ-hinweis-${lauf.run_id}`, children: [
9192
+ /* @__PURE__ */ jsxs8("p", { "data-testid": `erzeugen-negativ-hinweis-${lauf.run_id}`, children: [
8671
9193
  "Achtung: Dieser Lauf tr\xE4gt einen negativen Prompt.",
8672
9194
  " ",
8673
9195
  aktiv.display_name,
8674
9196
  " f\xFChrt diesen Promptkanal nicht \u2014 der negative Prompt l\xE4uft nicht mit."
8675
9197
  ] }),
8676
- /* @__PURE__ */ jsxs7("label", { children: [
9198
+ /* @__PURE__ */ jsxs8("label", { children: [
8677
9199
  "Anzahl",
8678
- /* @__PURE__ */ jsx7(
9200
+ /* @__PURE__ */ jsx8(
8679
9201
  "input",
8680
9202
  {
8681
9203
  type: "number",
@@ -8687,27 +9209,27 @@ var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
8687
9209
  }
8688
9210
  )
8689
9211
  ] }),
8690
- /* @__PURE__ */ jsxs7("label", { children: [
9212
+ /* @__PURE__ */ jsxs8("label", { children: [
8691
9213
  "Seitenverh\xE4ltnis",
8692
- /* @__PURE__ */ jsxs7(
9214
+ /* @__PURE__ */ jsxs8(
8693
9215
  "select",
8694
9216
  {
8695
9217
  value: seitenverhaeltnis,
8696
9218
  "data-testid": `erzeugen-format-${lauf.run_id}`,
8697
9219
  onChange: (e) => setSeitenverhaeltnis(e.target.value),
8698
9220
  children: [
8699
- /* @__PURE__ */ jsx7("option", { value: "", children: "(Vorgabe des Modells)" }),
8700
- aktiv.aspect_ratios.map((v) => /* @__PURE__ */ jsx7("option", { value: v, children: v }, v))
9221
+ /* @__PURE__ */ jsx8("option", { value: "", children: "(Vorgabe des Modells)" }),
9222
+ aktiv.aspect_ratios.map((v) => /* @__PURE__ */ jsx8("option", { value: v, children: v }, v))
8701
9223
  ]
8702
9224
  }
8703
9225
  )
8704
9226
  ] }),
8705
- !aktiv.accepts_seed && /* @__PURE__ */ jsxs7("p", { "data-testid": `erzeugen-ohne-seed-${lauf.run_id}`, children: [
9227
+ !aktiv.accepts_seed && /* @__PURE__ */ jsxs8("p", { "data-testid": `erzeugen-ohne-seed-${lauf.run_id}`, children: [
8706
9228
  aktiv.display_name,
8707
9229
  " kennt keinen Seed \u2014 er wird deshalb weder angeboten noch protokolliert."
8708
9230
  ] }),
8709
- parameterBefunde.length > 0 && /* @__PURE__ */ jsx7("p", { "data-testid": `erzeugen-parameterbefund-${lauf.run_id}`, role: "alert", children: parameterBefunde.join(" ") }),
8710
- /* @__PURE__ */ jsx7(
9231
+ parameterBefunde.length > 0 && /* @__PURE__ */ jsx8("p", { "data-testid": `erzeugen-parameterbefund-${lauf.run_id}`, role: "alert", children: parameterBefunde.join(" ") }),
9232
+ /* @__PURE__ */ jsx8(
8711
9233
  "button",
8712
9234
  {
8713
9235
  type: "button",
@@ -8717,7 +9239,7 @@ var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
8717
9239
  children: laeuft ? "Bilder werden erzeugt \u2026" : "Bilder erzeugen"
8718
9240
  }
8719
9241
  ),
8720
- notiz && /* @__PURE__ */ jsx7(
9242
+ notiz && /* @__PURE__ */ jsx8(
8721
9243
  "p",
8722
9244
  {
8723
9245
  "data-testid": `erzeugen-notiz-${lauf.run_id}`,
@@ -8728,21 +9250,114 @@ var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
8728
9250
  )
8729
9251
  ] });
8730
9252
  };
9253
+ var DEFAULT_VORLAGE_KEY = "__default__";
8731
9254
  var ZuordnenAktion = ({ port, lauf, onFertig }) => {
8732
- const [dateien, setDateien] = useState7([]);
8733
- const [seeds, setSeeds] = useState7({});
8734
- const [modell, setModell] = useState7("");
8735
- const [itemId, setItemId] = useState7("");
8736
- const [laeuft, setLaeuft] = useState7(false);
8737
- const [notiz, setNotiz] = useState7(null);
9255
+ const [dateien, setDateien] = useState8([]);
9256
+ const [seeds, setSeeds] = useState8({});
9257
+ const [zip, setZip] = useState8(null);
9258
+ const [zipLaedt, setZipLaedt] = useState8(false);
9259
+ const [seedListe, setSeedListe] = useState8("");
9260
+ const [vorlagen, setVorlagen] = useState8([DEFAULT_SEED_VORLAGE]);
9261
+ const [vorlageKey, setVorlageKey] = useState8(DEFAULT_VORLAGE_KEY);
9262
+ const [vorlagenStand, setVorlagenStand] = useState8(0);
9263
+ const [vorlageBenennen, setVorlageBenennen] = useState8(false);
9264
+ const [vorlageName, setVorlageName] = useState8("");
9265
+ const [modell, setModell] = useState8("");
9266
+ const [itemId, setItemId] = useState8("");
9267
+ const [laeuft, setLaeuft] = useState8(false);
9268
+ const [notiz, setNotiz] = useState8(null);
9269
+ const auswahlMarke = useRef2(0);
9270
+ const zipAktiv = zip !== null;
9271
+ useEffect4(() => {
9272
+ if (!zipAktiv) return;
9273
+ let abgebrochen = false;
9274
+ void (async () => {
9275
+ const gelesen = port.seedTemplates ? await port.seedTemplates.listSeedTemplates() : null;
9276
+ if (abgebrochen) return;
9277
+ setVorlagen(mitDefaultVorlage(
9278
+ gelesen && gelesen.kind === "ok" ? gelesen.value : []
9279
+ ));
9280
+ })();
9281
+ return () => {
9282
+ abgebrochen = true;
9283
+ };
9284
+ }, [zipAktiv, port, vorlagenStand]);
8738
9285
  if (!port.imageBatchWrite) {
8739
- return /* @__PURE__ */ jsx7("p", { "data-testid": `zuordnen-unsupported-${lauf.run_id}`, children: "Dieser Host ordnet keine externen Bilder zu \u2014 er hat keinen gesicherten Batch-Schreibweg. Die Historie oben bleibt trotzdem sichtbar." });
8740
- }
8741
- const importieren = async () => {
9286
+ return /* @__PURE__ */ jsx8("p", { "data-testid": `zuordnen-unsupported-${lauf.run_id}`, children: "Dieser Host ordnet keine externen Bilder zu \u2014 er hat keinen gesicherten Batch-Schreibweg. Die Historie oben bleibt trotzdem sichtbar." });
9287
+ }
9288
+ const zuordnung = zip ? ordneSeedsZu(seedListe, zip.bilder.length) : null;
9289
+ const dateiWahl = async (liste) => {
9290
+ const gewaehlt = [...liste ?? []];
9291
+ const warZip = zip !== null;
9292
+ const meine = auswahlMarke.current += 1;
9293
+ const veraltet = () => auswahlMarke.current !== meine;
9294
+ const zips = gewaehlt.filter(istZipDatei);
9295
+ const nurEinZip = zips.length === 1 && gewaehlt.length === 1;
9296
+ setNotiz(null);
9297
+ setSeeds({});
9298
+ setZip(null);
9299
+ setDateien(zips.length === 0 ? gewaehlt : []);
9300
+ setZipLaedt(nurEinZip);
9301
+ if (zips.length > 0 && zips.length !== gewaehlt.length) {
9302
+ setNotiz({
9303
+ tone: "error",
9304
+ text: `Die Auswahl enth\xE4lt ${zips.length} ZIP-Datei(en) und ${gewaehlt.length - zips.length} Bilddatei(en). Bitte entweder ein ZIP oder einzelne Bilder w\xE4hlen \u2014 nicht beides in einem Import.`
9305
+ });
9306
+ return;
9307
+ }
9308
+ if (zips.length > 1) {
9309
+ setNotiz({
9310
+ tone: "error",
9311
+ text: `${zips.length} ZIP-Dateien gew\xE4hlt (${zips.map((z) => z.name).join(", ")}). Ein Import nimmt genau ein ZIP.`
9312
+ });
9313
+ return;
9314
+ }
9315
+ if (!nurEinZip) return;
9316
+ const datei = zips[0];
9317
+ try {
9318
+ const bilder = await leseBilderAusZip(datei);
9319
+ if (veraltet()) return;
9320
+ setZip({ datei, bilder });
9321
+ if (!warZip) {
9322
+ setSeedListe(DEFAULT_SEED_VORLAGE.seeds);
9323
+ setVorlageKey(DEFAULT_VORLAGE_KEY);
9324
+ }
9325
+ } catch (fehler4) {
9326
+ if (veraltet()) return;
9327
+ setNotiz({
9328
+ tone: "error",
9329
+ text: fehler4 instanceof Error ? fehler4.message : String(fehler4)
9330
+ });
9331
+ }
9332
+ if (veraltet()) return;
9333
+ setZipLaedt(false);
9334
+ };
9335
+ const schreiben = async (bilder, generationBatchId, titel) => {
8742
9336
  setLaeuft(true);
8743
9337
  setNotiz(null);
8744
9338
  try {
8745
- const bilder = [];
9339
+ const ergebnis = await port.imageBatchWrite.importBatch({
9340
+ runId: lauf.run_id,
9341
+ generationBatchId,
9342
+ images: bilder,
9343
+ title: titel
9344
+ });
9345
+ setNotiz(
9346
+ ergebnis.kind === "ok" ? { tone: "ok", text: `Importiert als Item ${ergebnis.value.item_id} mit ${bilder.length} Bild(ern).` } : noticeFor(ergebnis, "Externe Bilder importieren")
9347
+ );
9348
+ } catch (fehler4) {
9349
+ setNotiz({
9350
+ tone: "error",
9351
+ text: `Externe Bilder importieren: ${fehler4 instanceof Error ? fehler4.message : String(fehler4)}`
9352
+ });
9353
+ }
9354
+ setLaeuft(false);
9355
+ onFertig();
9356
+ };
9357
+ const importieren = async () => {
9358
+ let bilder;
9359
+ try {
9360
+ bilder = [];
8746
9361
  for (let index = 0; index < dateien.length; index++) {
8747
9362
  const roh = (seeds[index] ?? "").trim();
8748
9363
  const seed = roh === "" ? void 0 : Number.parseInt(roh, 10);
@@ -8755,25 +9370,42 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
8755
9370
  ...seed !== void 0 ? { seed } : {}
8756
9371
  });
8757
9372
  }
8758
- const ergebnis = await port.imageBatchWrite.importBatch({
8759
- runId: lauf.run_id,
8760
- // Vor dem Aufruf gebildet und stabil (D-113): eine Wiederholung
8761
- // derselben Einreichung erzeugt kein zweites Item.
8762
- generationBatchId: `imp-${lauf.run_id}-${dateien.length}-${dateien.map((d) => d.size).join("_")}`,
8763
- images: bilder,
8764
- title: `Externer Import zu Lauf ${lauf.run_id}`
8765
- });
8766
- setNotiz(
8767
- ergebnis.kind === "ok" ? { tone: "ok", text: `Importiert als Item ${ergebnis.value.item_id} mit ${bilder.length} Bild(ern).` } : noticeFor(ergebnis, "Externe Bilder importieren")
8768
- );
8769
9373
  } catch (fehler4) {
8770
9374
  setNotiz({
8771
9375
  tone: "error",
8772
9376
  text: `Externe Bilder importieren: ${fehler4 instanceof Error ? fehler4.message : String(fehler4)}`
8773
9377
  });
9378
+ return;
8774
9379
  }
8775
- setLaeuft(false);
8776
- onFertig();
9380
+ await schreiben(
9381
+ bilder,
9382
+ // Vor dem Aufruf gebildet und stabil (D-113): eine Wiederholung
9383
+ // derselben Einreichung erzeugt kein zweites Item.
9384
+ `imp-${lauf.run_id}-${dateien.length}-${dateien.map((d) => d.size).join("_")}`,
9385
+ `Externer Import zu Lauf ${lauf.run_id}`
9386
+ );
9387
+ };
9388
+ const zipImportieren = async () => {
9389
+ if (!zip || !zuordnung) return;
9390
+ if (zuordnung.ungueltige.length > 0) {
9391
+ setNotiz({ tone: "error", text: seedFehlerText(zuordnung.ungueltige) });
9392
+ return;
9393
+ }
9394
+ const bilder = zip.bilder.map((bild, index) => {
9395
+ const seed = zuordnung.eintraege[index]?.seed ?? null;
9396
+ return {
9397
+ imageBase64: bild.base64,
9398
+ ...modell.trim() ? { model: modell.trim() } : {},
9399
+ // Unbekannt bleibt unbekannt: kein Feld statt eines erfundenen
9400
+ // Werts (§6.1).
9401
+ ...seed !== null ? { seed } : {}
9402
+ };
9403
+ });
9404
+ await schreiben(
9405
+ bilder,
9406
+ `imp-${lauf.run_id}-zip-${zip.datei.size}-${bilder.length}`,
9407
+ `Externer Import zu Lauf ${lauf.run_id} (${zip.datei.name})`
9408
+ );
8777
9409
  };
8778
9410
  const zuordnen = async () => {
8779
9411
  setLaeuft(true);
@@ -8791,46 +9423,73 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
8791
9423
  setLaeuft(false);
8792
9424
  onFertig();
8793
9425
  };
8794
- return /* @__PURE__ */ jsxs7("div", { className: "szenen-bilder__aktion", "data-testid": `zuordnen-${lauf.run_id}`, children: [
8795
- /* @__PURE__ */ jsx7("h5", { children: "Externe Bilder diesem Lauf zuordnen" }),
8796
- /* @__PURE__ */ jsxs7("label", { children: [
8797
- "Bilddateien",
8798
- /* @__PURE__ */ jsx7(
9426
+ const vorlageWaehlen = (key) => {
9427
+ setVorlageKey(key);
9428
+ const vorlage = key === DEFAULT_VORLAGE_KEY ? DEFAULT_SEED_VORLAGE : vorlagen.find((v) => String(v.id) === key);
9429
+ if (vorlage) setSeedListe(vorlage.seeds);
9430
+ };
9431
+ const vorlageSpeichern = async () => {
9432
+ const name = vorlageName.trim();
9433
+ if (!name || !seedListe.trim() || !port.seedTemplates?.saveSeedTemplate) return;
9434
+ const ergebnis = await port.seedTemplates.saveSeedTemplate({ name, seeds: seedListe.trim() });
9435
+ if (ergebnis.kind !== "ok") {
9436
+ setNotiz(noticeFor(ergebnis, "Seed-Vorlage speichern"));
9437
+ return;
9438
+ }
9439
+ setVorlageBenennen(false);
9440
+ setVorlageName("");
9441
+ if (ergebnis.value.id !== void 0) setVorlageKey(String(ergebnis.value.id));
9442
+ setVorlagenStand((n) => n + 1);
9443
+ };
9444
+ const vorlageLoeschen = async () => {
9445
+ if (vorlageKey === DEFAULT_VORLAGE_KEY || !port.seedTemplates?.deleteSeedTemplate) return;
9446
+ const ergebnis = await port.seedTemplates.deleteSeedTemplate(vorlageKey);
9447
+ if (ergebnis.kind !== "ok") {
9448
+ setNotiz(noticeFor(ergebnis, "Seed-Vorlage l\xF6schen"));
9449
+ return;
9450
+ }
9451
+ setVorlageKey(DEFAULT_VORLAGE_KEY);
9452
+ setVorlagenStand((n) => n + 1);
9453
+ };
9454
+ return /* @__PURE__ */ jsxs8("div", { className: "szenen-bilder__aktion-inhalt", "data-testid": `zuordnen-${lauf.run_id}`, children: [
9455
+ /* @__PURE__ */ jsxs8("label", { children: [
9456
+ "Bilddateien oder ein ZIP",
9457
+ /* @__PURE__ */ jsx8(
8799
9458
  "input",
8800
9459
  {
8801
9460
  type: "file",
8802
- accept: "image/*",
9461
+ accept: "image/*,.zip",
8803
9462
  multiple: true,
8804
9463
  "data-testid": `zuordnen-dateien-${lauf.run_id}`,
8805
9464
  onChange: (e) => {
8806
- setDateien([...e.target.files ?? []]);
8807
- setSeeds({});
9465
+ void dateiWahl(e.target.files);
8808
9466
  }
8809
9467
  }
8810
9468
  )
8811
9469
  ] }),
8812
- dateien.length > 0 && /* @__PURE__ */ jsxs7(Fragment3, { children: [
8813
- /* @__PURE__ */ jsxs7("label", { children: [
8814
- "Modell (f\xFCr alle Bilder, leer = unbekannt)",
8815
- /* @__PURE__ */ jsx7(
8816
- "input",
8817
- {
8818
- value: modell,
8819
- "data-testid": `zuordnen-modell-${lauf.run_id}`,
8820
- onChange: (e) => setModell(e.target.value)
8821
- }
8822
- )
8823
- ] }),
8824
- /* @__PURE__ */ jsx7("ol", { "data-testid": `zuordnen-vorschau-${lauf.run_id}`, children: dateien.map((datei, index) => /* @__PURE__ */ jsxs7("li", { children: [
8825
- /* @__PURE__ */ jsxs7("span", { children: [
9470
+ zipLaedt && /* @__PURE__ */ jsx8("p", { "data-testid": `zuordnen-zip-laedt-${lauf.run_id}`, children: "ZIP wird gelesen \u2026" }),
9471
+ (dateien.length > 0 || zip) && /* @__PURE__ */ jsxs8("label", { children: [
9472
+ "Modell (f\xFCr alle Bilder, leer = unbekannt)",
9473
+ /* @__PURE__ */ jsx8(
9474
+ "input",
9475
+ {
9476
+ value: modell,
9477
+ "data-testid": `zuordnen-modell-${lauf.run_id}`,
9478
+ onChange: (e) => setModell(e.target.value)
9479
+ }
9480
+ )
9481
+ ] }),
9482
+ dateien.length > 0 && /* @__PURE__ */ jsxs8(Fragment4, { children: [
9483
+ /* @__PURE__ */ jsx8("ol", { "data-testid": `zuordnen-vorschau-${lauf.run_id}`, children: dateien.map((datei, index) => /* @__PURE__ */ jsxs8("li", { children: [
9484
+ /* @__PURE__ */ jsxs8("span", { children: [
8826
9485
  "Position ",
8827
9486
  index,
8828
9487
  ": ",
8829
9488
  datei.name
8830
9489
  ] }),
8831
- /* @__PURE__ */ jsxs7("label", { children: [
9490
+ /* @__PURE__ */ jsxs8("label", { children: [
8832
9491
  "Seed (leer = unbekannt)",
8833
- /* @__PURE__ */ jsx7(
9492
+ /* @__PURE__ */ jsx8(
8834
9493
  "input",
8835
9494
  {
8836
9495
  "data-testid": `zuordnen-seed-${lauf.run_id}-${index}`,
@@ -8840,7 +9499,7 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
8840
9499
  )
8841
9500
  ] })
8842
9501
  ] }, `${datei.name}-${index}`)) }),
8843
- /* @__PURE__ */ jsxs7(
9502
+ /* @__PURE__ */ jsxs8(
8844
9503
  "button",
8845
9504
  {
8846
9505
  type: "button",
@@ -8854,9 +9513,160 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
8854
9513
  }
8855
9514
  )
8856
9515
  ] }),
8857
- /* @__PURE__ */ jsxs7("label", { children: [
9516
+ zip && zuordnung && /* @__PURE__ */ jsxs8("div", { className: "szenen-bilder__zip", "data-testid": `zuordnen-zip-${lauf.run_id}`, children: [
9517
+ /* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__zipkopf", children: [
9518
+ "ZIP ",
9519
+ /* @__PURE__ */ jsx8("code", { children: zip.datei.name }),
9520
+ " \u2014 ",
9521
+ zip.bilder.length,
9522
+ " Bild(er) erkannt"
9523
+ ] }),
9524
+ /* @__PURE__ */ jsxs8("label", { children: [
9525
+ "Seeds (pro Bild ein Seed, Trenner , oder ;)",
9526
+ /* @__PURE__ */ jsx8(
9527
+ "input",
9528
+ {
9529
+ "data-testid": `zuordnen-seedliste-${lauf.run_id}`,
9530
+ value: seedListe,
9531
+ placeholder: "z. B. 1; 10; 100; 1000",
9532
+ onChange: (e) => setSeedListe(e.target.value)
9533
+ }
9534
+ )
9535
+ ] }),
9536
+ /* @__PURE__ */ jsxs8("label", { children: [
9537
+ "Seed-Vorlage",
9538
+ /* @__PURE__ */ jsxs8(
9539
+ "select",
9540
+ {
9541
+ "data-testid": `zuordnen-seedvorlage-${lauf.run_id}`,
9542
+ value: vorlageKey,
9543
+ onChange: (e) => vorlageWaehlen(e.target.value),
9544
+ children: [
9545
+ /* @__PURE__ */ jsxs8("option", { value: DEFAULT_VORLAGE_KEY, children: [
9546
+ "Default (",
9547
+ DEFAULT_SEED_VORLAGE.seeds,
9548
+ ")"
9549
+ ] }),
9550
+ vorlagen.filter((v) => !v.builtin).map((v) => /* @__PURE__ */ jsxs8("option", { value: String(v.id), children: [
9551
+ v.name,
9552
+ " (",
9553
+ v.seeds,
9554
+ ")"
9555
+ ] }, String(v.id)))
9556
+ ]
9557
+ }
9558
+ )
9559
+ ] }),
9560
+ (port.seedTemplates?.saveSeedTemplate || port.seedTemplates?.deleteSeedTemplate) && /* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__zipvorlagen", children: [
9561
+ port.seedTemplates?.saveSeedTemplate && !vorlageBenennen && /* @__PURE__ */ jsx8(
9562
+ "button",
9563
+ {
9564
+ type: "button",
9565
+ "data-testid": `zuordnen-vorlage-neu-${lauf.run_id}`,
9566
+ disabled: !seedListe.trim(),
9567
+ onClick: () => {
9568
+ setVorlageName("");
9569
+ setVorlageBenennen(true);
9570
+ },
9571
+ children: "Als Vorlage speichern"
9572
+ }
9573
+ ),
9574
+ port.seedTemplates?.deleteSeedTemplate && /* @__PURE__ */ jsx8(
9575
+ "button",
9576
+ {
9577
+ type: "button",
9578
+ "data-testid": `zuordnen-vorlage-loeschen-${lauf.run_id}`,
9579
+ disabled: vorlageKey === DEFAULT_VORLAGE_KEY,
9580
+ onClick: () => {
9581
+ void vorlageLoeschen();
9582
+ },
9583
+ children: "Vorlage l\xF6schen"
9584
+ }
9585
+ )
9586
+ ] }),
9587
+ vorlageBenennen && /* @__PURE__ */ jsxs8(Fragment4, { children: [
9588
+ /* @__PURE__ */ jsxs8("label", { children: [
9589
+ "Name der Vorlage",
9590
+ /* @__PURE__ */ jsx8(
9591
+ "input",
9592
+ {
9593
+ "data-testid": `zuordnen-vorlage-name-${lauf.run_id}`,
9594
+ value: vorlageName,
9595
+ onChange: (e) => setVorlageName(e.target.value)
9596
+ }
9597
+ )
9598
+ ] }),
9599
+ /* @__PURE__ */ jsxs8("p", { className: "szenen-bilder__zipvorlagen", children: [
9600
+ /* @__PURE__ */ jsx8(
9601
+ "button",
9602
+ {
9603
+ type: "button",
9604
+ "data-testid": `zuordnen-vorlage-sichern-${lauf.run_id}`,
9605
+ disabled: !vorlageName.trim(),
9606
+ onClick: () => {
9607
+ void vorlageSpeichern();
9608
+ },
9609
+ children: "Speichern"
9610
+ }
9611
+ ),
9612
+ /* @__PURE__ */ jsx8(
9613
+ "button",
9614
+ {
9615
+ type: "button",
9616
+ "data-testid": `zuordnen-vorlage-abbrechen-${lauf.run_id}`,
9617
+ onClick: () => setVorlageBenennen(false),
9618
+ children: "Abbrechen"
9619
+ }
9620
+ )
9621
+ ] })
9622
+ ] }),
9623
+ zuordnung.ueberzaehlig > 0 && /* @__PURE__ */ jsxs8("p", { "data-testid": `zuordnen-ueberzaehlig-${lauf.run_id}`, children: [
9624
+ zuordnung.ueberzaehlig,
9625
+ " Seed(s) mehr als Bilder \u2014 die \xFCberz\xE4hligen werden nicht geschrieben."
9626
+ ] }),
9627
+ /* @__PURE__ */ jsx8(
9628
+ "ol",
9629
+ {
9630
+ className: "szenen-bilder__zipliste",
9631
+ "data-testid": `zuordnen-zip-vorschau-${lauf.run_id}`,
9632
+ children: zip.bilder.map((bild, index) => {
9633
+ const eintrag = zuordnung.eintraege[index];
9634
+ return /* @__PURE__ */ jsxs8("li", { children: [
9635
+ /* @__PURE__ */ jsxs8("span", { children: [
9636
+ "Position ",
9637
+ index,
9638
+ ": ",
9639
+ bild.name
9640
+ ] }),
9641
+ /* @__PURE__ */ jsx8(
9642
+ "span",
9643
+ {
9644
+ "data-testid": `zuordnen-zip-seed-${lauf.run_id}-${index}`,
9645
+ "data-seed": eintrag.seed === null ? "" : String(eintrag.seed),
9646
+ children: eintrag.ungueltig ? `Seed ung\xFCltig: "${eintrag.roh}"` : eintrag.seed === null ? "Seed unbekannt" : `Seed ${eintrag.seed}`
9647
+ }
9648
+ )
9649
+ ] }, `${bild.name}-${index}`);
9650
+ })
9651
+ }
9652
+ ),
9653
+ /* @__PURE__ */ jsxs8(
9654
+ "button",
9655
+ {
9656
+ type: "button",
9657
+ "data-testid": `zuordnen-zip-import-${lauf.run_id}`,
9658
+ disabled: laeuft || zipLaedt,
9659
+ onClick: zipImportieren,
9660
+ children: [
9661
+ zip.bilder.length,
9662
+ " Bild(er) aus ZIP importieren"
9663
+ ]
9664
+ }
9665
+ )
9666
+ ] }),
9667
+ /* @__PURE__ */ jsxs8("label", { children: [
8858
9668
  "Oder ein bestehendes Library-Item",
8859
- /* @__PURE__ */ jsx7(
9669
+ /* @__PURE__ */ jsx8(
8860
9670
  "input",
8861
9671
  {
8862
9672
  value: itemId,
@@ -8866,7 +9676,7 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
8866
9676
  }
8867
9677
  )
8868
9678
  ] }),
8869
- /* @__PURE__ */ jsx7(
9679
+ /* @__PURE__ */ jsx8(
8870
9680
  "button",
8871
9681
  {
8872
9682
  type: "button",
@@ -8876,7 +9686,7 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
8876
9686
  children: "Bestehendes Item zuordnen"
8877
9687
  }
8878
9688
  ),
8879
- notiz && /* @__PURE__ */ jsx7(
9689
+ notiz && /* @__PURE__ */ jsx8(
8880
9690
  "p",
8881
9691
  {
8882
9692
  "data-testid": `zuordnen-notiz-${lauf.run_id}`,
@@ -8901,14 +9711,16 @@ function readAsBase64(datei) {
8901
9711
  }
8902
9712
 
8903
9713
  // src/features/szenen/areas/RunsPanel.tsx
8904
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
9714
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
8905
9715
  var RunsPanel = ({ port, source, contextId }) => {
8906
- const [anweisung, setAnweisung] = useState8("");
8907
- const [laeuft, setLaeuft] = useState8(false);
8908
- const [notiz, setNotiz] = useState8(null);
8909
- const [nachladen, setNachladen] = useState8(0);
9716
+ const [anweisung, setAnweisung] = useState9("");
9717
+ const [laeuft, setLaeuft] = useState9(false);
9718
+ const [notiz, setNotiz] = useState9(null);
9719
+ const [nachladen, setNachladen] = useState9(0);
8910
9720
  const faehig = capabilitiesOf(port);
8911
9721
  const quellSchluessel = source.kind === "published" ? source.shotVersionId : source.kind === "draft_chain" ? source.chainId : source.sceneElementId;
9722
+ const aktuelleQuelle = useRef3({ kind: source.kind, id: quellSchluessel });
9723
+ aktuelleQuelle.current = { kind: source.kind, id: quellSchluessel };
8912
9724
  const [phase, neuLaden] = usePortQuery(
8913
9725
  () => {
8914
9726
  if (source.kind === "published") return port.runs.listRunsForShot(source.shotVersionId);
@@ -8919,24 +9731,37 @@ var RunsPanel = ({ port, source, contextId }) => {
8919
9731
  );
8920
9732
  const starten = async () => {
8921
9733
  if (source.kind !== "published") return;
9734
+ const gestartetFuer = { kind: source.kind, id: source.shotVersionId };
8922
9735
  setLaeuft(true);
8923
9736
  const ergebnis = await port.runs.startRun({
8924
9737
  shotVersionId: source.shotVersionId,
8925
9738
  ...anweisung.trim() ? { userInstruction: anweisung.trim() } : {},
8926
9739
  contextId
8927
9740
  });
9741
+ if (aktuelleQuelle.current.kind !== gestartetFuer.kind || aktuelleQuelle.current.id !== gestartetFuer.id) {
9742
+ return;
9743
+ }
8928
9744
  setNotiz(noticeFor(ergebnis, "Prompt-Lauf starten"));
8929
9745
  setLaeuft(false);
8930
9746
  setNachladen((n) => n + 1);
8931
9747
  neuLaden();
8932
9748
  };
8933
9749
  const laeufe = phase.status === "ready" ? phase.value : [];
8934
- return /* @__PURE__ */ jsxs8("div", { className: "szenen-runs", "data-testid": "laeufe-bereich", "data-shot-version": quellSchluessel, children: [
8935
- /* @__PURE__ */ jsx8("h4", { children: "Prompt-L\xE4ufe" }),
8936
- source.kind === "published" && /* @__PURE__ */ jsxs8("div", { className: "szenen-runs__start", children: [
8937
- /* @__PURE__ */ jsxs8("label", { children: [
9750
+ const [gewaehlteRunde, setGewaehlteRunde] = useState9(void 0);
9751
+ const neueste = laeufe.length > 0 ? laeufe[laeufe.length - 1].run_id : null;
9752
+ const offeneRunde = gewaehlteRunde === void 0 ? neueste : gewaehlteRunde;
9753
+ useEffect5(() => {
9754
+ setGewaehlteRunde(void 0);
9755
+ setAnweisung("");
9756
+ setNotiz(null);
9757
+ setLaeuft(false);
9758
+ }, [source.kind, quellSchluessel]);
9759
+ return /* @__PURE__ */ jsxs9("div", { className: "szenen-runs", "data-testid": "laeufe-bereich", "data-shot-version": quellSchluessel, children: [
9760
+ /* @__PURE__ */ jsx9("h4", { children: "Prompt-L\xE4ufe" }),
9761
+ source.kind === "published" && /* @__PURE__ */ jsxs9("div", { className: "szenen-runs__start", children: [
9762
+ /* @__PURE__ */ jsxs9("label", { children: [
8938
9763
  "Anweisung (optional)",
8939
- /* @__PURE__ */ jsx8(
9764
+ /* @__PURE__ */ jsx9(
8940
9765
  "input",
8941
9766
  {
8942
9767
  "data-testid": "lauf-anweisung",
@@ -8945,21 +9770,25 @@ var RunsPanel = ({ port, source, contextId }) => {
8945
9770
  }
8946
9771
  )
8947
9772
  ] }),
8948
- /* @__PURE__ */ jsx8("button", { type: "button", "data-testid": "lauf-starten", disabled: laeuft, onClick: starten, children: "Prompt-Lauf starten" })
9773
+ /* @__PURE__ */ jsx9("button", { type: "button", "data-testid": "lauf-starten", disabled: laeuft, onClick: starten, children: "Prompt-Lauf starten" })
8949
9774
  ] }),
8950
- notiz && /* @__PURE__ */ jsx8("p", { "data-testid": "lauf-notiz", "data-tone": notiz.tone, role: notiz.tone === "error" ? "alert" : "status", children: notiz.text }),
8951
- phase.status === "loading" && /* @__PURE__ */ jsx8("p", { "data-testid": "laeufe-laden", children: "L\xE4ufe werden geladen \u2026" }),
8952
- phase.status === "error" && /* @__PURE__ */ jsxs8("p", { "data-testid": "laeufe-fehler", role: "alert", children: [
9775
+ notiz && /* @__PURE__ */ jsx9("p", { "data-testid": "lauf-notiz", "data-tone": notiz.tone, role: notiz.tone === "error" ? "alert" : "status", children: notiz.text }),
9776
+ phase.status === "loading" && /* @__PURE__ */ jsx9("p", { "data-testid": "laeufe-laden", children: "L\xE4ufe werden geladen \u2026" }),
9777
+ phase.status === "error" && /* @__PURE__ */ jsxs9("p", { "data-testid": "laeufe-fehler", role: "alert", children: [
8953
9778
  "L\xE4ufe konnten nicht geladen werden: ",
8954
9779
  phase.message
8955
9780
  ] }),
8956
- phase.status === "ready" && laeufe.length === 0 && /* @__PURE__ */ jsx8("p", { "data-testid": "keine-laeufe", children: source.kind === "published" ? "F\xFCr diese Shot-Version gibt es noch keinen Lauf." : source.kind === "draft_chain" ? "F\xFCr diese Draft-Kette gibt es noch keinen Lauf." : "F\xFCr diese Szene gibt es noch keinen direkten Lauf." }),
8957
- /* @__PURE__ */ jsx8("ol", { "data-testid": "runden-liste", children: laeufe.map((lauf) => /* @__PURE__ */ jsx8(
9781
+ phase.status === "ready" && laeufe.length === 0 && /* @__PURE__ */ jsx9("p", { "data-testid": "keine-laeufe", children: source.kind === "published" ? "F\xFCr diese Shot-Version gibt es noch keinen Lauf." : source.kind === "draft_chain" ? "F\xFCr diese Draft-Kette gibt es noch keinen Lauf." : "F\xFCr diese Szene gibt es noch keinen direkten Lauf." }),
9782
+ /* @__PURE__ */ jsx9("ol", { "data-testid": "runden-liste", children: laeufe.map((lauf) => /* @__PURE__ */ jsx9(
8958
9783
  RundenEintrag,
8959
9784
  {
8960
9785
  port,
8961
9786
  lauf,
8962
9787
  runde: roundOfRun(lauf, laeufe),
9788
+ offen: lauf.run_id === offeneRunde,
9789
+ onUmschalten: () => setGewaehlteRunde(
9790
+ lauf.run_id === offeneRunde ? null : lauf.run_id
9791
+ ),
8963
9792
  itemMoeglich: faehig.saveRunAsItem,
8964
9793
  onItemGespeichert: () => setNachladen((n) => n + 1)
8965
9794
  },
@@ -8967,13 +9796,63 @@ var RunsPanel = ({ port, source, contextId }) => {
8967
9796
  )) })
8968
9797
  ] });
8969
9798
  };
8970
- var RundenEintrag = ({ port, lauf, runde, itemMoeglich, onItemGespeichert }) => {
8971
- const [notiz, setNotiz] = useState8(null);
8972
- const [laeuft, setLaeuft] = useState8(false);
8973
- const [nachladen, setNachladen] = useState8(0);
9799
+ var AUSZUG = 90;
9800
+ function auszug(text, laenge = AUSZUG) {
9801
+ const sauber = text.replace(/\s+/g, " ").trim();
9802
+ if (sauber.length <= laenge) return sauber;
9803
+ const schnitt = sauber.lastIndexOf(" ", laenge);
9804
+ return `${sauber.slice(0, schnitt > laenge / 2 ? schnitt : laenge)} \u2026`;
9805
+ }
9806
+ var STATUS_TEXT = {
9807
+ succeeded: "erfolgreich",
9808
+ failed: "fehlgeschlagen"
9809
+ };
9810
+ var LANGER_TEXT = 240;
9811
+ var Sekundaertext = ({ titel, text, testId }) => {
9812
+ const [ganz, setGanz] = useState9(false);
9813
+ const lang = text.length > LANGER_TEXT;
9814
+ return /* @__PURE__ */ jsxs9("section", { className: "szenen-runs__sekundaer", children: [
9815
+ /* @__PURE__ */ jsx9("h5", { children: titel }),
9816
+ /* @__PURE__ */ jsx9("p", { "data-testid": testId, children: lang && !ganz ? auszug(text, LANGER_TEXT) : text }),
9817
+ lang && /* @__PURE__ */ jsx9(
9818
+ "button",
9819
+ {
9820
+ type: "button",
9821
+ className: "szenen-runs__mehr",
9822
+ onClick: () => setGanz(!ganz),
9823
+ "data-testid": `${testId}-mehr`,
9824
+ children: ganz ? "weniger anzeigen" : "vollst\xE4ndig anzeigen"
9825
+ }
9826
+ )
9827
+ ] });
9828
+ };
9829
+ var LISTE_ANFANG = 3;
9830
+ var SekundaerListe = ({ titel, eintraege, testId, className }) => {
9831
+ const [alle, setAlle] = useState9(false);
9832
+ const lang = eintraege.length > LISTE_ANFANG;
9833
+ const gezeigt = lang && !alle ? eintraege.slice(0, LISTE_ANFANG) : eintraege;
9834
+ return /* @__PURE__ */ jsxs9("section", { className: "szenen-runs__sekundaer", children: [
9835
+ /* @__PURE__ */ jsx9("h5", { children: titel }),
9836
+ /* @__PURE__ */ jsx9("ul", { className, "data-testid": testId, children: gezeigt.map((eintrag, i) => /* @__PURE__ */ jsx9("li", { children: eintrag }, i)) }),
9837
+ lang && /* @__PURE__ */ jsx9(
9838
+ "button",
9839
+ {
9840
+ type: "button",
9841
+ className: "szenen-runs__mehr",
9842
+ onClick: () => setAlle(!alle),
9843
+ "data-testid": `${testId}-mehr`,
9844
+ children: alle ? "weniger anzeigen" : `${eintraege.length - LISTE_ANFANG} weitere anzeigen`
9845
+ }
9846
+ )
9847
+ ] });
9848
+ };
9849
+ var RundenEintrag = ({ port, lauf, runde, offen, onUmschalten, itemMoeglich, onItemGespeichert }) => {
9850
+ const [notiz, setNotiz] = useState9(null);
9851
+ const [laeuft, setLaeuft] = useState9(false);
9852
+ const [nachladen, setNachladen] = useState9(0);
8974
9853
  const [itemPhase] = usePortQuery(
8975
- () => port.items ? port.items.getItemForRun(lauf.run_id) : Promise.resolve({ kind: "ok", value: null }),
8976
- [port, lauf.run_id, nachladen]
9854
+ () => offen && port.items ? port.items.getItemForRun(lauf.run_id) : Promise.resolve({ kind: "ok", value: null }),
9855
+ [port, lauf.run_id, nachladen, offen]
8977
9856
  );
8978
9857
  const item = itemPhase.status === "ready" ? itemPhase.value : null;
8979
9858
  const speichern = async () => {
@@ -8987,75 +9866,133 @@ var RundenEintrag = ({ port, lauf, runde, itemMoeglich, onItemGespeichert }) =>
8987
9866
  setNachladen((n) => n + 1);
8988
9867
  onItemGespeichert();
8989
9868
  };
8990
- return /* @__PURE__ */ jsxs8("li", { "data-testid": `runde-${lauf.run_id}`, "data-runde": runde, "data-status": lauf.status, children: [
8991
- /* @__PURE__ */ jsxs8("header", { children: [
8992
- /* @__PURE__ */ jsxs8("strong", { children: [
8993
- "Runde ",
8994
- runde
9869
+ const zusammenfassung = lauf.status === "succeeded" && lauf.output ? auszug(lauf.output.positive) : null;
9870
+ return /* @__PURE__ */ jsxs9("li", { "data-testid": `runde-${lauf.run_id}`, "data-runde": runde, "data-status": lauf.status, children: [
9871
+ /* @__PURE__ */ jsxs9(
9872
+ "button",
9873
+ {
9874
+ type: "button",
9875
+ className: "szenen-runs__kopf",
9876
+ onClick: onUmschalten,
9877
+ "aria-expanded": offen,
9878
+ "data-testid": `runde-umschalten-${lauf.run_id}`,
9879
+ children: [
9880
+ /* @__PURE__ */ jsxs9("span", { className: "szenen-runs__marke", children: [
9881
+ "Runde ",
9882
+ runde
9883
+ ] }),
9884
+ /* @__PURE__ */ jsx9(
9885
+ "span",
9886
+ {
9887
+ className: "szenen-runs__status",
9888
+ "data-status": lauf.status,
9889
+ "data-testid": `status-${lauf.run_id}`,
9890
+ children: STATUS_TEXT[lauf.status]
9891
+ }
9892
+ ),
9893
+ /* @__PURE__ */ jsxs9("span", { className: "szenen-runs__modell", "data-testid": `provider-${lauf.run_id}`, children: [
9894
+ lauf.provider,
9895
+ " \xB7 ",
9896
+ lauf.model_id
9897
+ ] }),
9898
+ zusammenfassung && /* @__PURE__ */ jsx9(
9899
+ "span",
9900
+ {
9901
+ className: "szenen-runs__auszug",
9902
+ "data-testid": `auszug-${lauf.run_id}`,
9903
+ children: zusammenfassung
9904
+ }
9905
+ )
9906
+ ]
9907
+ }
9908
+ ),
9909
+ lauf.status === "failed" && lauf.failure && /* @__PURE__ */ jsxs9("div", { className: "szenen-runs__fehler", "data-testid": `fehler-${lauf.run_id}`, role: "alert", children: [
9910
+ /* @__PURE__ */ jsxs9("strong", { children: [
9911
+ "Fehlgeschlagen \u2014 ",
9912
+ lauf.failure.class
8995
9913
  ] }),
8996
- /* @__PURE__ */ jsx8("code", { children: lauf.run_id }),
8997
- /* @__PURE__ */ jsx8("span", { "data-testid": `status-${lauf.run_id}`, children: lauf.status }),
8998
- /* @__PURE__ */ jsxs8("span", { "data-testid": `provider-${lauf.run_id}`, children: [
8999
- lauf.provider,
9000
- " \xB7 ",
9001
- lauf.model_id
9002
- ] })
9914
+ /* @__PURE__ */ jsx9("p", { children: lauf.failure.message })
9003
9915
  ] }),
9004
- lauf.status === "succeeded" && lauf.output && /* @__PURE__ */ jsxs8("div", { "data-testid": `ausgabe-${lauf.run_id}`, children: [
9005
- /* @__PURE__ */ jsxs8("section", { children: [
9006
- /* @__PURE__ */ jsx8("h5", { children: "Positiver Prompt" }),
9007
- /* @__PURE__ */ jsx8("p", { "data-testid": `positiv-${lauf.run_id}`, children: lauf.output.positive })
9008
- ] }),
9009
- /* @__PURE__ */ jsxs8("section", { children: [
9010
- /* @__PURE__ */ jsx8("h5", { children: "Negativer Prompt" }),
9011
- /* @__PURE__ */ jsx8("p", { "data-testid": `negativ-${lauf.run_id}`, children: lauf.output.negative ?? "(keiner)" })
9916
+ offen && /* @__PURE__ */ jsxs9("div", { className: "szenen-runs__inhalt", "data-testid": `runde-inhalt-${lauf.run_id}`, children: [
9917
+ lauf.status === "succeeded" && lauf.output && /* @__PURE__ */ jsxs9("div", { "data-testid": `ausgabe-${lauf.run_id}`, children: [
9918
+ /* @__PURE__ */ jsxs9("section", { className: "szenen-runs__prompt", children: [
9919
+ /* @__PURE__ */ jsx9("h5", { children: "Positiver Prompt" }),
9920
+ /* @__PURE__ */ jsx9("p", { "data-testid": `positiv-${lauf.run_id}`, children: lauf.output.positive })
9921
+ ] }),
9922
+ /* @__PURE__ */ jsxs9("section", { className: "szenen-runs__prompt szenen-runs__prompt--negativ", children: [
9923
+ /* @__PURE__ */ jsx9("h5", { children: "Negativer Prompt" }),
9924
+ /* @__PURE__ */ jsx9("p", { "data-testid": `negativ-${lauf.run_id}`, children: lauf.output.negative ?? "(keiner)" })
9925
+ ] }),
9926
+ /* @__PURE__ */ jsx9(
9927
+ Sekundaertext,
9928
+ {
9929
+ titel: "Erl\xE4uterung",
9930
+ text: lauf.output.feedback,
9931
+ testId: `feedback-${lauf.run_id}`
9932
+ }
9933
+ ),
9934
+ lauf.output.visibility.assumptions.length > 0 && /* @__PURE__ */ jsx9(
9935
+ SekundaerListe,
9936
+ {
9937
+ titel: "Annahmen",
9938
+ eintraege: lauf.output.visibility.assumptions,
9939
+ testId: `annahmen-${lauf.run_id}`
9940
+ }
9941
+ ),
9942
+ lauf.output.notes.length > 0 && /* @__PURE__ */ jsx9(
9943
+ SekundaerListe,
9944
+ {
9945
+ titel: "Notizen",
9946
+ eintraege: lauf.output.notes,
9947
+ testId: `notizen-${lauf.run_id}`,
9948
+ className: "szenen-runs__notizen"
9949
+ }
9950
+ )
9012
9951
  ] }),
9013
- /* @__PURE__ */ jsxs8("section", { children: [
9014
- /* @__PURE__ */ jsx8("h5", { children: "Erl\xE4uterung" }),
9015
- /* @__PURE__ */ jsx8("p", { "data-testid": `feedback-${lauf.run_id}`, children: lauf.output.feedback })
9952
+ lauf.raw_output && /* @__PURE__ */ jsxs9("details", { "data-testid": `diagnose-${lauf.run_id}`, children: [
9953
+ /* @__PURE__ */ jsx9("summary", { children: "Rohantwort (Diagnose)" }),
9954
+ /* @__PURE__ */ jsx9("pre", { children: lauf.raw_output })
9016
9955
  ] }),
9017
- lauf.output.visibility.assumptions.length > 0 && /* @__PURE__ */ jsxs8("section", { children: [
9018
- /* @__PURE__ */ jsx8("h5", { children: "Annahmen" }),
9019
- /* @__PURE__ */ jsx8("ul", { "data-testid": `annahmen-${lauf.run_id}`, children: lauf.output.visibility.assumptions.map((a, i) => /* @__PURE__ */ jsx8("li", { children: a }, i)) })
9956
+ /* @__PURE__ */ jsxs9("details", { className: "szenen-runs__technisch", "data-testid": `technisch-${lauf.run_id}`, children: [
9957
+ /* @__PURE__ */ jsx9("summary", { children: "Technische Informationen" }),
9958
+ /* @__PURE__ */ jsxs9("p", { children: [
9959
+ "Lauf-ID: ",
9960
+ /* @__PURE__ */ jsx9("code", { "data-testid": `run-id-${lauf.run_id}`, children: lauf.run_id })
9961
+ ] }),
9962
+ /* @__PURE__ */ jsxs9("p", { children: [
9963
+ "Modell: ",
9964
+ /* @__PURE__ */ jsx9("code", { children: lauf.model_id }),
9965
+ " bei ",
9966
+ /* @__PURE__ */ jsx9("code", { children: lauf.provider })
9967
+ ] }),
9968
+ /* @__PURE__ */ jsxs9("p", { children: [
9969
+ "erzeugt: ",
9970
+ /* @__PURE__ */ jsx9("code", { children: lauf.created_at })
9971
+ ] })
9020
9972
  ] }),
9021
- lauf.output.notes.length > 0 && /* @__PURE__ */ jsx8("ul", { "data-testid": `notizen-${lauf.run_id}`, children: lauf.output.notes.map((n, i) => /* @__PURE__ */ jsx8("li", { children: n }, i)) })
9022
- ] }),
9023
- lauf.status === "failed" && lauf.failure && /* @__PURE__ */ jsxs8("div", { "data-testid": `fehler-${lauf.run_id}`, role: "alert", children: [
9024
- /* @__PURE__ */ jsxs8("h5", { children: [
9025
- "Fehlgeschlagen \u2014 ",
9026
- lauf.failure.class
9973
+ lauf.status === "succeeded" && itemMoeglich && !item && /* @__PURE__ */ jsx9("button", { type: "button", "data-testid": `als-item-${lauf.run_id}`, disabled: laeuft, onClick: speichern, children: "als Item speichern" }),
9974
+ item && /* @__PURE__ */ jsxs9("p", { "data-testid": `item-${lauf.run_id}`, children: [
9975
+ "Bereits als Item gespeichert: ",
9976
+ /* @__PURE__ */ jsx9("code", { children: item.itemId })
9027
9977
  ] }),
9028
- /* @__PURE__ */ jsx8("p", { children: lauf.failure.message })
9029
- ] }),
9030
- lauf.raw_output && /* @__PURE__ */ jsxs8("details", { "data-testid": `diagnose-${lauf.run_id}`, children: [
9031
- /* @__PURE__ */ jsx8("summary", { children: "Rohantwort (Diagnose)" }),
9032
- /* @__PURE__ */ jsx8("pre", { children: lauf.raw_output })
9033
- ] }),
9034
- lauf.status === "succeeded" && itemMoeglich && !item && /* @__PURE__ */ jsx8("button", { type: "button", "data-testid": `als-item-${lauf.run_id}`, disabled: laeuft, onClick: speichern, children: "als Item speichern" }),
9035
- item && /* @__PURE__ */ jsxs8("p", { "data-testid": `item-${lauf.run_id}`, children: [
9036
- "Bereits als Item gespeichert: ",
9037
- /* @__PURE__ */ jsx8("code", { children: item.itemId })
9038
- ] }),
9039
- lauf.status === "succeeded" && !itemMoeglich && /* @__PURE__ */ jsx8("p", { "data-testid": `item-unsupported-${lauf.run_id}`, children: "Dieser Host speichert keine Runden als Item. Das ist kein Fehler und kein vor\xFCbergehender Zustand." }),
9040
- notiz && /* @__PURE__ */ jsx8("p", { "data-testid": `item-notiz-${lauf.run_id}`, "data-tone": notiz.tone, children: notiz.text }),
9041
- lauf.status === "succeeded" && /* @__PURE__ */ jsxs8("details", { "data-testid": `bilder-bereich-${lauf.run_id}`, children: [
9042
- /* @__PURE__ */ jsx8("summary", { children: "Bilder zu diesem Lauf" }),
9043
- /* @__PURE__ */ jsx8(RunImagesPanel, { port, lauf })
9978
+ lauf.status === "succeeded" && !itemMoeglich && /* @__PURE__ */ jsx9("p", { "data-testid": `item-unsupported-${lauf.run_id}`, children: "Dieser Host speichert keine Runden als Item. Das ist kein Fehler und kein vor\xFCbergehender Zustand." }),
9979
+ notiz && /* @__PURE__ */ jsx9("p", { "data-testid": `item-notiz-${lauf.run_id}`, "data-tone": notiz.tone, children: notiz.text }),
9980
+ lauf.status === "succeeded" && /* @__PURE__ */ jsx9(RunImagesPanel, { port, lauf })
9044
9981
  ] })
9045
9982
  ] });
9046
9983
  };
9047
9984
 
9048
9985
  // src/features/szenen/areas/ElementDetail.tsx
9049
- import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
9986
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
9050
9987
  var STRUKTURELL_BEDIENT = {
9051
9988
  scene: ["nodes", "relations"]
9052
9989
  };
9053
9990
  var AbgeleitetesBildmodell = ({ schluessel }) => {
9054
9991
  if (!schluessel) return null;
9055
- return /* @__PURE__ */ jsxs9("section", { className: "szenen-detail__derived", "data-testid": "abgeleitetes-bildmodell", children: [
9056
- /* @__PURE__ */ jsx9("h4", { children: "Bildgenerierung \u2014 wo das Modell entschieden wird" }),
9057
- /* @__PURE__ */ jsxs9("p", { "data-testid": "bildmodell-hinweis", children: [
9058
- /* @__PURE__ */ jsx9("code", { children: schluessel }),
9992
+ return /* @__PURE__ */ jsxs10("section", { className: "szenen-detail__derived", "data-testid": "abgeleitetes-bildmodell", children: [
9993
+ /* @__PURE__ */ jsx10("h4", { children: "Bildgenerierung \u2014 wo das Modell entschieden wird" }),
9994
+ /* @__PURE__ */ jsxs10("p", { "data-testid": "bildmodell-hinweis", children: [
9995
+ /* @__PURE__ */ jsx10("code", { children: schluessel }),
9059
9996
  " beschreibt, wof\xFCr dieser Prompt optimiert wird \u2014 nicht, mit welchem Bildmodell er ausgef\xFChrt wird. Welche Bildmodelle wirklich ausf\xFChrbar sind, ist Konfiguration der jeweiligen Umgebung und wird an der Bildaktion eines Laufs gew\xE4hlt (D-129)."
9060
9997
  ] })
9061
9998
  ] });
@@ -9067,16 +10004,16 @@ var ElementDetail = ({
9067
10004
  author,
9068
10005
  onChanged
9069
10006
  }) => {
9070
- const [nachladen, setNachladen] = useState9(0);
10007
+ const [nachladen, setNachladen] = useState10(0);
9071
10008
  const [phase] = usePortQuery(
9072
10009
  () => port.elements.getElement(elementId),
9073
10010
  [port, elementId, nachladen]
9074
10011
  );
9075
- const [entwurf, setEntwurf] = useState9({});
9076
- const [notiz, setNotiz] = useState9(null);
9077
- const [laeuft, setLaeuft] = useState9(false);
9078
- const [wahl, setWahl] = useState9(null);
9079
- const [basiswechsel, setBasiswechsel] = useState9(null);
10012
+ const [entwurf, setEntwurf] = useState10({});
10013
+ const [notiz, setNotiz] = useState10(null);
10014
+ const [laeuft, setLaeuft] = useState10(false);
10015
+ const [wahl, setWahl] = useState10(null);
10016
+ const [basiswechsel, setBasiswechsel] = useState10(null);
9080
10017
  const [kettenPhase] = usePortQuery(
9081
10018
  () => port.context.chainFor(contextId),
9082
10019
  [port, contextId]
@@ -9098,7 +10035,7 @@ var ElementDetail = ({
9098
10035
  () => schnappschuss ? fieldsForType(schnappschuss.element.type) : [],
9099
10036
  [schnappschuss?.element.type]
9100
10037
  );
9101
- useEffect3(() => {
10038
+ useEffect6(() => {
9102
10039
  setWahl(null);
9103
10040
  setBasiswechsel(null);
9104
10041
  setNotiz(null);
@@ -9129,7 +10066,7 @@ var ElementDetail = ({
9129
10066
  return {};
9130
10067
  }, [schnappschuss, angezeigt]);
9131
10068
  const anzeigeSchluessel = angezeigt.kind === "version" ? `v:${angezeigt.versionId}` : angezeigt.kind;
9132
- useEffect3(() => {
10069
+ useEffect6(() => {
9133
10070
  if (!schnappschuss) return;
9134
10071
  setEntwurf(formFromPayload(felder, angezeigtePayload));
9135
10072
  }, [
@@ -9188,9 +10125,9 @@ var ElementDetail = ({
9188
10125
  return { valid: false, errors: [{ instancePath: "", message: String(e) }] };
9189
10126
  }
9190
10127
  }, [entwurf, felder, schnappschuss?.element.type, kettenfeld]);
9191
- if (phase.status === "loading") return /* @__PURE__ */ jsx9("p", { "data-testid": "element-laden", children: "Element wird geladen \u2026" });
10128
+ if (phase.status === "loading") return /* @__PURE__ */ jsx10("p", { "data-testid": "element-laden", children: "Element wird geladen \u2026" });
9192
10129
  if (phase.status === "error") {
9193
- return /* @__PURE__ */ jsxs9("p", { "data-testid": "element-fehler", role: "alert", children: [
10130
+ return /* @__PURE__ */ jsxs10("p", { "data-testid": "element-fehler", role: "alert", children: [
9194
10131
  "Element ",
9195
10132
  elementId,
9196
10133
  " konnte nicht geladen werden: ",
@@ -9198,7 +10135,7 @@ var ElementDetail = ({
9198
10135
  ] });
9199
10136
  }
9200
10137
  if (!schnappschuss) {
9201
- return /* @__PURE__ */ jsxs9("p", { "data-testid": "element-unbekannt", children: [
10138
+ return /* @__PURE__ */ jsxs10("p", { "data-testid": "element-unbekannt", children: [
9202
10139
  "Element ",
9203
10140
  elementId,
9204
10141
  " ist unbekannt."
@@ -9304,28 +10241,28 @@ var ElementDetail = ({
9304
10241
  formular: entwurf
9305
10242
  };
9306
10243
  const laufVersionId = angezeigt.kind === "version" ? angezeigt.versionId : usableHeadVersionId(kopfAufloesung);
9307
- return /* @__PURE__ */ jsxs9("div", { className: "szenen-detail", "data-testid": "element-detail", "data-element-id": elementId, children: [
9308
- /* @__PURE__ */ jsxs9("header", { children: [
9309
- /* @__PURE__ */ jsx9("h3", { children: schnappschuss.metadata?.title ?? "(ohne Titel)" }),
9310
- /* @__PURE__ */ jsxs9("p", { className: "szenen-detail__ids", children: [
9311
- /* @__PURE__ */ jsx9("span", { "data-testid": "element-typ", children: elementTypLabel(typ) }),
9312
- schnappschuss.element.retired && /* @__PURE__ */ jsx9("span", { "data-testid": "ist-stillgelegt", children: "stillgelegt" })
10244
+ return /* @__PURE__ */ jsxs10("div", { className: "szenen-detail", "data-testid": "element-detail", "data-element-id": elementId, children: [
10245
+ /* @__PURE__ */ jsxs10("header", { children: [
10246
+ /* @__PURE__ */ jsx10("h3", { children: schnappschuss.metadata?.title ?? "(ohne Titel)" }),
10247
+ /* @__PURE__ */ jsxs10("p", { className: "szenen-detail__ids", children: [
10248
+ /* @__PURE__ */ jsx10("span", { "data-testid": "element-typ", children: elementTypLabel(typ) }),
10249
+ schnappschuss.element.retired && /* @__PURE__ */ jsx10("span", { "data-testid": "ist-stillgelegt", children: "stillgelegt" })
9313
10250
  ] })
9314
10251
  ] }),
9315
- kontextkette.status === "error" && /* @__PURE__ */ jsxs9("p", { role: "alert", "data-testid": "kontextkette-fehler", className: "szenen-detail__hint", children: [
10252
+ kontextkette.status === "error" && /* @__PURE__ */ jsxs10("p", { role: "alert", "data-testid": "kontextkette-fehler", className: "szenen-detail__hint", children: [
9316
10253
  "Die Kontextkette konnte nicht gelesen werden: ",
9317
10254
  kontextkette.message,
9318
10255
  ". Solange das so ist, lassen sich weder der bevorzugte Kopf noch die ausw\xE4hlbaren Referenzen bestimmen \u2014 sie sind ",
9319
- /* @__PURE__ */ jsx9("strong", { children: "unbekannt" }),
10256
+ /* @__PURE__ */ jsx10("strong", { children: "unbekannt" }),
9320
10257
  ", nicht leer."
9321
10258
  ] }),
9322
- kopfErgebnis?.kind === "dag_fehler" && /* @__PURE__ */ jsxs9("p", { role: "alert", "data-testid": "versionsgraph-fehler", className: "szenen-detail__hint", children: [
10259
+ kopfErgebnis?.kind === "dag_fehler" && /* @__PURE__ */ jsxs10("p", { role: "alert", "data-testid": "versionsgraph-fehler", className: "szenen-detail__hint", children: [
9323
10260
  "Der Versionsgraph dieses Elements ist nicht aufbaubar:",
9324
10261
  " ",
9325
10262
  kopfErgebnis.message,
9326
10263
  ". Die Versionen bleiben einzeln anzeigbar; ein bevorzugter Kopf l\xE4sst sich daraus nicht ableiten."
9327
10264
  ] }),
9328
- /* @__PURE__ */ jsx9(
10265
+ /* @__PURE__ */ jsx10(
9329
10266
  VersionNavigator,
9330
10267
  {
9331
10268
  versions: schnappschuss.versions,
@@ -9348,22 +10285,22 @@ var ElementDetail = ({
9348
10285
  }
9349
10286
  }
9350
10287
  ),
9351
- basiswechsel && draft && /* @__PURE__ */ jsxs9("div", { className: "szenen-detail__confirm", "data-testid": "basiswechsel-bestaetigung", role: "alertdialog", children: [
9352
- /* @__PURE__ */ jsxs9("p", { children: [
10288
+ basiswechsel && draft && /* @__PURE__ */ jsxs10("div", { className: "szenen-detail__confirm", "data-testid": "basiswechsel-bestaetigung", role: "alertdialog", children: [
10289
+ /* @__PURE__ */ jsxs10("p", { children: [
9353
10290
  "Es gibt bereits einen Entwurf (Revision ",
9354
10291
  draft.revision,
9355
- draft.base_version_id ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
10292
+ draft.base_version_id ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
9356
10293
  " auf Basis ",
9357
- /* @__PURE__ */ jsx9("code", { children: draft.base_version_id })
9358
- ] }) : /* @__PURE__ */ jsx9(Fragment4, { children: " ohne Basis" }),
10294
+ /* @__PURE__ */ jsx10("code", { children: draft.base_version_id })
10295
+ ] }) : /* @__PURE__ */ jsx10(Fragment5, { children: " ohne Basis" }),
9359
10296
  "). Ihn auf Version ",
9360
- /* @__PURE__ */ jsx9("code", { children: basiswechsel }),
10297
+ /* @__PURE__ */ jsx10("code", { children: basiswechsel }),
9361
10298
  " neu aufzusetzen",
9362
10299
  " ",
9363
- /* @__PURE__ */ jsx9("strong", { children: "ersetzt seinen Inhalt" }),
10300
+ /* @__PURE__ */ jsx10("strong", { children: "ersetzt seinen Inhalt" }),
9364
10301
  " durch die Payload dieser Version."
9365
10302
  ] }),
9366
- /* @__PURE__ */ jsx9(
10303
+ /* @__PURE__ */ jsx10(
9367
10304
  "button",
9368
10305
  {
9369
10306
  type: "button",
@@ -9375,7 +10312,7 @@ var ElementDetail = ({
9375
10312
  children: "Entwurf auf diese Version neu aufsetzen"
9376
10313
  }
9377
10314
  ),
9378
- /* @__PURE__ */ jsx9(
10315
+ /* @__PURE__ */ jsx10(
9379
10316
  "button",
9380
10317
  {
9381
10318
  type: "button",
@@ -9386,26 +10323,26 @@ var ElementDetail = ({
9386
10323
  }
9387
10324
  )
9388
10325
  ] }),
9389
- /* @__PURE__ */ jsxs9("section", { className: "szenen-detail__draft", "data-testid": "draft-bereich", children: [
9390
- /* @__PURE__ */ jsx9("h4", { children: bearbeitbar ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
10326
+ /* @__PURE__ */ jsxs10("section", { className: "szenen-detail__draft", "data-testid": "draft-bereich", children: [
10327
+ /* @__PURE__ */ jsx10("h4", { children: bearbeitbar ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
9391
10328
  "Entwurf",
9392
- draft && /* @__PURE__ */ jsxs9("span", { children: [
10329
+ draft && /* @__PURE__ */ jsxs10("span", { children: [
9393
10330
  " \xB7 Revision ",
9394
10331
  draft.revision
9395
10332
  ] })
9396
- ] }) : /* @__PURE__ */ jsx9(Fragment4, { children: "Ver\xF6ffentlichte Version \u2014 nur Ansicht" }) }),
9397
- angezeigt.kind === "keiner" && /* @__PURE__ */ jsxs9("p", { "data-testid": "nichts-angezeigt", children: [
10333
+ ] }) : /* @__PURE__ */ jsx10(Fragment5, { children: "Ver\xF6ffentlichte Version \u2014 nur Ansicht" }) }),
10334
+ angezeigt.kind === "keiner" && /* @__PURE__ */ jsxs10("p", { "data-testid": "nichts-angezeigt", children: [
9398
10335
  "Es ist kein Stand ausgew\xE4hlt. Oben eine Version anzeigen oder \xFCber ",
9399
- /* @__PURE__ */ jsx9("strong", { children: "als Grundlage bearbeiten" }),
10336
+ /* @__PURE__ */ jsx10("strong", { children: "als Grundlage bearbeiten" }),
9400
10337
  " einen Entwurf beginnen."
9401
10338
  ] }),
9402
- !bearbeitbar && angezeigt.kind === "version" && /* @__PURE__ */ jsxs9("p", { "data-testid": "nur-ansicht", className: "szenen-detail__hint", children: [
10339
+ !bearbeitbar && angezeigt.kind === "version" && /* @__PURE__ */ jsxs10("p", { "data-testid": "nur-ansicht", className: "szenen-detail__hint", children: [
9403
10340
  "Ver\xF6ffentlichte Versionen sind unver\xE4nderlich (D-02). Zum Bearbeiten oben ",
9404
- /* @__PURE__ */ jsx9("strong", { children: "als Grundlage bearbeiten" }),
10341
+ /* @__PURE__ */ jsx10("strong", { children: "als Grundlage bearbeiten" }),
9405
10342
  " w\xE4hlen \u2014 das erzeugt einen Entwurf mit genau dieser Version als Basis."
9406
10343
  ] }),
9407
- angezeigt.kind !== "keiner" && /* @__PURE__ */ jsxs9(Fragment4, { children: [
9408
- typ === "scene" && /* @__PURE__ */ jsx9(
10344
+ angezeigt.kind !== "keiner" && /* @__PURE__ */ jsxs10(Fragment5, { children: [
10345
+ typ === "scene" && /* @__PURE__ */ jsx10(
9409
10346
  SceneEditor,
9410
10347
  {
9411
10348
  port,
@@ -9419,57 +10356,57 @@ var ElementDetail = ({
9419
10356
  }))
9420
10357
  }
9421
10358
  ),
9422
- felder.length === 0 && /* @__PURE__ */ jsxs9("p", { "data-testid": "kein-schema", children: [
10359
+ felder.length === 0 && /* @__PURE__ */ jsxs10("p", { "data-testid": "kein-schema", children: [
9423
10360
  "F\xFCr den Typ ",
9424
10361
  typ,
9425
10362
  " liegt kein Payload-Schema vor."
9426
10363
  ] }),
9427
- primaer.map((feld) => /* @__PURE__ */ jsx9(SchemaFieldRow, { ...feldProps, feld }, feld.path)),
9428
- advanced.length > 0 && /* @__PURE__ */ jsxs9("details", { className: "szenen-detail__technical", "data-testid": "technische-felder", children: [
9429
- /* @__PURE__ */ jsxs9("summary", { children: [
10364
+ primaer.map((feld) => /* @__PURE__ */ jsx10(SchemaFieldRow, { ...feldProps, feld }, feld.path)),
10365
+ advanced.length > 0 && /* @__PURE__ */ jsxs10("details", { className: "szenen-detail__technical", "data-testid": "technische-felder", children: [
10366
+ /* @__PURE__ */ jsxs10("summary", { children: [
9430
10367
  "Technische Felder / JSON (",
9431
10368
  advanced.length,
9432
10369
  ")"
9433
10370
  ] }),
9434
- advanced.map((feld) => /* @__PURE__ */ jsx9(SchemaFieldRow, { ...feldProps, feld }, feld.path))
10371
+ advanced.map((feld) => /* @__PURE__ */ jsx10(SchemaFieldRow, { ...feldProps, feld }, feld.path))
9435
10372
  ] }),
9436
- /* @__PURE__ */ jsxs9("details", { className: "szenen-detail__technical", "data-testid": "technische-informationen", children: [
9437
- /* @__PURE__ */ jsx9("summary", { children: "Technische Informationen" }),
9438
- /* @__PURE__ */ jsxs9("p", { children: [
10373
+ /* @__PURE__ */ jsxs10("details", { className: "szenen-detail__technical", "data-testid": "technische-informationen", children: [
10374
+ /* @__PURE__ */ jsx10("summary", { children: "Technische Informationen" }),
10375
+ /* @__PURE__ */ jsxs10("p", { children: [
9439
10376
  "Element-ID: ",
9440
- /* @__PURE__ */ jsx9("code", { children: schnappschuss.element.element_id })
10377
+ /* @__PURE__ */ jsx10("code", { children: schnappschuss.element.element_id })
9441
10378
  ] }),
9442
- /* @__PURE__ */ jsxs9("p", { children: [
10379
+ /* @__PURE__ */ jsxs10("p", { children: [
9443
10380
  "angezeigter Stand:",
9444
10381
  " ",
9445
- /* @__PURE__ */ jsx9("code", { "data-testid": "angezeigter-stand", children: angezeigt.kind === "version" ? angezeigt.versionId : "Entwurf" })
10382
+ /* @__PURE__ */ jsx10("code", { "data-testid": "angezeigter-stand", children: angezeigt.kind === "version" ? angezeigt.versionId : "Entwurf" })
9446
10383
  ] }),
9447
- draft && /* @__PURE__ */ jsxs9("p", { children: [
10384
+ draft && /* @__PURE__ */ jsxs10("p", { children: [
9448
10385
  "Basis des Entwurfs:",
9449
10386
  " ",
9450
- /* @__PURE__ */ jsx9("code", { children: draft.base_version_id ?? "(keine)" })
10387
+ /* @__PURE__ */ jsx10("code", { children: draft.base_version_id ?? "(keine)" })
9451
10388
  ] })
9452
10389
  ] })
9453
10390
  ] }),
9454
- bearbeitbar && vorschau && !vorschau.valid && /* @__PURE__ */ jsx9("ul", { "data-testid": "vorschau-befunde", className: "szenen-detail__preview-errors", children: vorschau.errors.map((f, i) => /* @__PURE__ */ jsxs9("li", { children: [
10391
+ bearbeitbar && vorschau && !vorschau.valid && /* @__PURE__ */ jsx10("ul", { "data-testid": "vorschau-befunde", className: "szenen-detail__preview-errors", children: vorschau.errors.map((f, i) => /* @__PURE__ */ jsxs10("li", { children: [
9455
10392
  f.instancePath || "/",
9456
10393
  ": ",
9457
10394
  f.message
9458
10395
  ] }, i)) }),
9459
- kettenfeld && /* @__PURE__ */ jsxs9("p", { "data-testid": "kettenfeld-hinweis", className: "szenen-detail__hint", children: [
10396
+ kettenfeld && /* @__PURE__ */ jsxs10("p", { "data-testid": "kettenfeld-hinweis", className: "szenen-detail__hint", children: [
9460
10397
  "Der Verweis ",
9461
- /* @__PURE__ */ jsx9("code", { children: kettenfeld }),
10398
+ /* @__PURE__ */ jsx10("code", { children: kettenfeld }),
9462
10399
  " steht in den Kettenmetadaten, nicht in der Payload (D-96) \u2014 f\xFCr den Prompt-Lauf aus der Kette gen\xFCgt das. Zum",
9463
10400
  " ",
9464
- /* @__PURE__ */ jsx9("strong", { children: "Ver\xF6ffentlichen" }),
10401
+ /* @__PURE__ */ jsx10("strong", { children: "Ver\xF6ffentlichen" }),
9465
10402
  " muss er als regul\xE4re Referenz auf eine ver\xF6ffentlichte Version gesetzt werden."
9466
10403
  ] }),
9467
- bearbeitbar && /* @__PURE__ */ jsxs9("div", { className: "szenen-detail__actions", children: [
9468
- /* @__PURE__ */ jsx9("button", { type: "button", "data-testid": "draft-speichern", disabled: laeuft, onClick: speichern, children: "Entwurf speichern" }),
9469
- /* @__PURE__ */ jsx9("button", { type: "button", "data-testid": "veroeffentlichen", disabled: laeuft, onClick: veroeffentlichen, children: "ver\xF6ffentlichen" })
10404
+ bearbeitbar && /* @__PURE__ */ jsxs10("div", { className: "szenen-detail__actions", children: [
10405
+ /* @__PURE__ */ jsx10("button", { type: "button", "data-testid": "draft-speichern", disabled: laeuft, onClick: speichern, children: "Entwurf speichern" }),
10406
+ /* @__PURE__ */ jsx10("button", { type: "button", "data-testid": "veroeffentlichen", disabled: laeuft, onClick: veroeffentlichen, children: "ver\xF6ffentlichen" })
9470
10407
  ] })
9471
10408
  ] }),
9472
- typ === "target_model" && /* @__PURE__ */ jsx9(
10409
+ typ === "target_model" && /* @__PURE__ */ jsx10(
9473
10410
  AbgeleitetesBildmodell,
9474
10411
  {
9475
10412
  schluessel: (() => {
@@ -9484,8 +10421,8 @@ var ElementDetail = ({
9484
10421
  // einer Draft-Kette, fuehrt der Weg ueber das Einfrieren —
9485
10422
  // der alte Satz „setzen eine veroeffentlichte Version
9486
10423
  // voraus" gilt nur noch fuer den Einzel-Shot.
9487
- draft?.chain ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
9488
- /* @__PURE__ */ jsx9(
10424
+ draft?.chain ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
10425
+ /* @__PURE__ */ jsx10(
9489
10426
  PromptStartAction,
9490
10427
  {
9491
10428
  port,
@@ -9495,7 +10432,7 @@ var ElementDetail = ({
9495
10432
  }
9496
10433
  }
9497
10434
  ),
9498
- /* @__PURE__ */ jsx9(
10435
+ /* @__PURE__ */ jsx10(
9499
10436
  RunsPanel,
9500
10437
  {
9501
10438
  port,
@@ -9503,17 +10440,17 @@ var ElementDetail = ({
9503
10440
  source: { kind: "draft_chain", chainId: draft.chain.chain_id }
9504
10441
  }
9505
10442
  )
9506
- ] }) : /* @__PURE__ */ jsx9("p", { "data-testid": "shot-ohne-version", children: "Dieser Shot ist noch nicht ver\xF6ffentlicht und geh\xF6rt zu keiner Draft-Kette. Ein Prompt-Lauf braucht hier eine ver\xF6ffentlichte Version \u2014 oder einen Shot, der aus einer Rekonstruktion als Kette entstanden ist." })
9507
- ) : laufVersionId ? /* @__PURE__ */ jsx9(
10443
+ ] }) : /* @__PURE__ */ jsx10("p", { "data-testid": "shot-ohne-version", children: "Dieser Shot ist noch nicht ver\xF6ffentlicht und geh\xF6rt zu keiner Draft-Kette. Ein Prompt-Lauf braucht hier eine ver\xF6ffentlichte Version \u2014 oder einen Shot, der aus einer Rekonstruktion als Kette entstanden ist." })
10444
+ ) : laufVersionId ? /* @__PURE__ */ jsx10(
9508
10445
  RunsPanel,
9509
10446
  {
9510
10447
  port,
9511
10448
  contextId,
9512
10449
  source: { kind: "published", shotVersionId: laufVersionId }
9513
10450
  }
9514
- ) : /* @__PURE__ */ jsx9("p", { "data-testid": "laufquelle-unklar", children: "Dieser Shot hat mehrere ver\xF6ffentlichte Versionen und keinen bevorzugten Kopf in diesem Kontext. Welche davon einen Lauf tr\xE4gt, entscheidet keine Reihenfolge \u2014 bitte oben eine Version anzeigen oder als bevorzugt setzen." })),
9515
- typ === "scene" && /* @__PURE__ */ jsxs9(Fragment4, { children: [
9516
- /* @__PURE__ */ jsx9(
10451
+ ) : /* @__PURE__ */ jsx10("p", { "data-testid": "laufquelle-unklar", children: "Dieser Shot hat mehrere ver\xF6ffentlichte Versionen und keinen bevorzugten Kopf in diesem Kontext. Welche davon einen Lauf tr\xE4gt, entscheidet keine Reihenfolge \u2014 bitte oben eine Version anzeigen oder als bevorzugt setzen." })),
10452
+ typ === "scene" && /* @__PURE__ */ jsxs10(Fragment5, { children: [
10453
+ /* @__PURE__ */ jsx10(
9517
10454
  PromptStartAction,
9518
10455
  {
9519
10456
  port,
@@ -9527,7 +10464,7 @@ var ElementDetail = ({
9527
10464
  onLauf: () => setNachladen((n) => n + 1)
9528
10465
  }
9529
10466
  ),
9530
- /* @__PURE__ */ jsx9(
10467
+ /* @__PURE__ */ jsx10(
9531
10468
  RunsPanel,
9532
10469
  {
9533
10470
  port,
@@ -9536,7 +10473,7 @@ var ElementDetail = ({
9536
10473
  }
9537
10474
  )
9538
10475
  ] }),
9539
- typ === "scene_setup" && /* @__PURE__ */ jsx9(
10476
+ typ === "scene_setup" && /* @__PURE__ */ jsx10(
9540
10477
  CapabilityPanel,
9541
10478
  {
9542
10479
  port,
@@ -9544,7 +10481,7 @@ var ElementDetail = ({
9544
10481
  setupPayload: payloadAusFormular()
9545
10482
  }
9546
10483
  ),
9547
- notiz && /* @__PURE__ */ jsxs9(
10484
+ notiz && /* @__PURE__ */ jsxs10(
9548
10485
  "div",
9549
10486
  {
9550
10487
  className: `szenen-detail__notice szenen-detail__notice--${notiz.tone}`,
@@ -9552,8 +10489,8 @@ var ElementDetail = ({
9552
10489
  "data-tone": notiz.tone,
9553
10490
  role: notiz.tone === "error" ? "alert" : "status",
9554
10491
  children: [
9555
- /* @__PURE__ */ jsx9("p", { children: notiz.text }),
9556
- notiz.details && notiz.details.length > 0 && /* @__PURE__ */ jsx9("ul", { "data-testid": "notiz-befunde", children: notiz.details.map((d, i) => /* @__PURE__ */ jsx9("li", { children: d }, i)) })
10492
+ /* @__PURE__ */ jsx10("p", { children: notiz.text }),
10493
+ notiz.details && notiz.details.length > 0 && /* @__PURE__ */ jsx10("ul", { "data-testid": "notiz-befunde", children: notiz.details.map((d, i) => /* @__PURE__ */ jsx10("li", { children: d }, i)) })
9557
10494
  ]
9558
10495
  }
9559
10496
  )
@@ -9561,15 +10498,15 @@ var ElementDetail = ({
9561
10498
  };
9562
10499
 
9563
10500
  // src/features/szenen/areas/useSchmalesDisplay.ts
9564
- import { useEffect as useEffect4, useState as useState10 } from "react";
10501
+ import { useEffect as useEffect7, useState as useState11 } from "react";
9565
10502
  var SCHMALE_ANSICHT = "(max-width: 760px)";
9566
10503
  function messen(abfrage) {
9567
10504
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
9568
10505
  return window.matchMedia(abfrage).matches;
9569
10506
  }
9570
10507
  function useSchmalesDisplay(abfrage = SCHMALE_ANSICHT) {
9571
- const [schmal, setSchmal] = useState10(() => messen(abfrage));
9572
- useEffect4(() => {
10508
+ const [schmal, setSchmal] = useState11(() => messen(abfrage));
10509
+ useEffect7(() => {
9573
10510
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
9574
10511
  const liste = window.matchMedia(abfrage);
9575
10512
  const aktualisieren = () => setSchmal(liste.matches);
@@ -9581,7 +10518,7 @@ function useSchmalesDisplay(abfrage = SCHMALE_ANSICHT) {
9581
10518
  }
9582
10519
 
9583
10520
  // src/features/szenen/areas/ElementsArea.tsx
9584
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
10521
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
9585
10522
  var ElementsArea = ({
9586
10523
  port,
9587
10524
  contextId,
@@ -9596,16 +10533,16 @@ var ElementsArea = ({
9596
10533
  const gemischt = auswahlTypen.length > 1;
9597
10534
  const ueberschrift = listTitle ?? (einzelTyp ? elementTypPlural(einzelTyp) : "Bausteine");
9598
10535
  const einzahl = einzelTyp ? elementTypLabel(einzelTyp) : "Objekt";
9599
- const [typ, setTyp] = useState11(einzelTyp ?? "");
9600
- const [zeigeStillgelegte, setZeigeStillgelegte] = useState11(false);
9601
- const [gewaehlt, setGewaehlt] = useState11(null);
9602
- const [neuerTitel, setNeuerTitel] = useState11("");
9603
- const [neuerTyp, setNeuerTyp] = useState11(auswahlTypen[0]);
9604
- const [notiz, setNotiz] = useState11(null);
9605
- const [anlegend, setAnlegend] = useState11(false);
9606
- const [anlageOffen, setAnlageOffen] = useState11(false);
10536
+ const [typ, setTyp] = useState12(einzelTyp ?? "");
10537
+ const [zeigeStillgelegte, setZeigeStillgelegte] = useState12(false);
10538
+ const [gewaehlt, setGewaehlt] = useState12(null);
10539
+ const [neuerTitel, setNeuerTitel] = useState12("");
10540
+ const [neuerTyp, setNeuerTyp] = useState12(auswahlTypen[0]);
10541
+ const [notiz, setNotiz] = useState12(null);
10542
+ const [anlegend, setAnlegend] = useState12(false);
10543
+ const [anlageOffen, setAnlageOffen] = useState12(false);
9607
10544
  const schmal = useSchmalesDisplay();
9608
- const [ansicht, setAnsicht] = useState11("liste");
10545
+ const [ansicht, setAnsicht] = useState12("liste");
9609
10546
  const zeigeListe = !schmal || ansicht === "liste";
9610
10547
  const zeigeDetail = !schmal || ansicht === "detail";
9611
10548
  const waehle = (elementId) => {
@@ -9625,17 +10562,17 @@ var ElementsArea = ({
9625
10562
  setAnlageOffen(false);
9626
10563
  setNeuerTitel("");
9627
10564
  };
9628
- return /* @__PURE__ */ jsxs10(
10565
+ return /* @__PURE__ */ jsxs11(
9629
10566
  "div",
9630
10567
  {
9631
10568
  className: "szenen-elements",
9632
10569
  "data-testid": "bereich-elemente",
9633
10570
  "data-ansicht": schmal ? ansicht : "beide",
9634
10571
  children: [
9635
- zeigeListe && /* @__PURE__ */ jsxs10("div", { className: "szenen-elements__master", "data-testid": "elemente-master", children: [
9636
- /* @__PURE__ */ jsxs10("div", { className: "szenen-elements__toolbar", children: [
9637
- /* @__PURE__ */ jsx10("h3", { className: "szenen-elements__heading", children: ueberschrift }),
9638
- /* @__PURE__ */ jsx10(
10572
+ zeigeListe && /* @__PURE__ */ jsxs11("div", { className: "szenen-elements__master", "data-testid": "elemente-master", children: [
10573
+ /* @__PURE__ */ jsxs11("div", { className: "szenen-elements__toolbar", children: [
10574
+ /* @__PURE__ */ jsx11("h3", { className: "szenen-elements__heading", children: ueberschrift }),
10575
+ /* @__PURE__ */ jsx11(
9639
10576
  "button",
9640
10577
  {
9641
10578
  type: "button",
@@ -9651,22 +10588,22 @@ var ElementsArea = ({
9651
10588
  }
9652
10589
  )
9653
10590
  ] }),
9654
- gemischt && /* @__PURE__ */ jsxs10("label", { className: "szenen-elements__scope", children: [
10591
+ gemischt && /* @__PURE__ */ jsxs11("label", { className: "szenen-elements__scope", children: [
9655
10592
  "Art",
9656
- /* @__PURE__ */ jsxs10(
10593
+ /* @__PURE__ */ jsxs11(
9657
10594
  "select",
9658
10595
  {
9659
10596
  "data-testid": "filter-typ",
9660
10597
  value: typ,
9661
10598
  onChange: (e) => setTyp(e.target.value),
9662
10599
  children: [
9663
- /* @__PURE__ */ jsx10("option", { value: "", children: allTypesLabel ?? "alle Typen" }),
9664
- auswahlTypen.map((t) => /* @__PURE__ */ jsx10("option", { value: t, children: elementTypPlural(t) }, t))
10600
+ /* @__PURE__ */ jsx11("option", { value: "", children: allTypesLabel ?? "alle Typen" }),
10601
+ auswahlTypen.map((t) => /* @__PURE__ */ jsx11("option", { value: t, children: elementTypPlural(t) }, t))
9665
10602
  ]
9666
10603
  }
9667
10604
  )
9668
10605
  ] }),
9669
- anlageOffen && /* @__PURE__ */ jsxs10(
10606
+ anlageOffen && /* @__PURE__ */ jsxs11(
9670
10607
  "form",
9671
10608
  {
9672
10609
  className: "szenen-elements__create",
@@ -9694,9 +10631,9 @@ var ElementsArea = ({
9694
10631
  }
9695
10632
  },
9696
10633
  children: [
9697
- /* @__PURE__ */ jsxs10("label", { className: "szenen-elements__create-title", children: [
10634
+ /* @__PURE__ */ jsxs11("label", { className: "szenen-elements__create-title", children: [
9698
10635
  einzelTyp ? `Neue ${einzahl}` : "Titel",
9699
- /* @__PURE__ */ jsx10(
10636
+ /* @__PURE__ */ jsx11(
9700
10637
  "input",
9701
10638
  {
9702
10639
  "data-testid": "neuer-titel",
@@ -9707,20 +10644,20 @@ var ElementsArea = ({
9707
10644
  }
9708
10645
  )
9709
10646
  ] }),
9710
- gemischt && /* @__PURE__ */ jsxs10("label", { className: "szenen-elements__create-type", children: [
10647
+ gemischt && /* @__PURE__ */ jsxs11("label", { className: "szenen-elements__create-type", children: [
9711
10648
  "Art",
9712
- /* @__PURE__ */ jsx10(
10649
+ /* @__PURE__ */ jsx11(
9713
10650
  "select",
9714
10651
  {
9715
10652
  "data-testid": "neuer-typ",
9716
10653
  value: neuerTyp,
9717
10654
  onChange: (e) => setNeuerTyp(e.target.value),
9718
- children: auswahlTypen.map((t) => /* @__PURE__ */ jsx10("option", { value: t, children: elementTypLabel(t) }, t))
10655
+ children: auswahlTypen.map((t) => /* @__PURE__ */ jsx11("option", { value: t, children: elementTypLabel(t) }, t))
9719
10656
  }
9720
10657
  )
9721
10658
  ] }),
9722
- /* @__PURE__ */ jsxs10("div", { className: "szenen-elements__create-actions", children: [
9723
- /* @__PURE__ */ jsx10(
10659
+ /* @__PURE__ */ jsxs11("div", { className: "szenen-elements__create-actions", children: [
10660
+ /* @__PURE__ */ jsx11(
9724
10661
  "button",
9725
10662
  {
9726
10663
  type: "submit",
@@ -9729,7 +10666,7 @@ var ElementsArea = ({
9729
10666
  children: "anlegen"
9730
10667
  }
9731
10668
  ),
9732
- /* @__PURE__ */ jsx10(
10669
+ /* @__PURE__ */ jsx11(
9733
10670
  "button",
9734
10671
  {
9735
10672
  type: "button",
@@ -9742,19 +10679,19 @@ var ElementsArea = ({
9742
10679
  ]
9743
10680
  }
9744
10681
  ),
9745
- notiz && /* @__PURE__ */ jsx10("p", { "data-testid": "anlegen-notiz", "data-tone": notiz.tone, children: notiz.text }),
9746
- phase.status === "loading" && /* @__PURE__ */ jsx10("p", { "data-testid": "elemente-laden", children: "Elemente werden geladen \u2026" }),
9747
- phase.status === "error" && /* @__PURE__ */ jsxs10("p", { "data-testid": "elemente-fehler", role: "alert", children: [
10682
+ notiz && /* @__PURE__ */ jsx11("p", { "data-testid": "anlegen-notiz", "data-tone": notiz.tone, children: notiz.text }),
10683
+ phase.status === "loading" && /* @__PURE__ */ jsx11("p", { "data-testid": "elemente-laden", children: "Elemente werden geladen \u2026" }),
10684
+ phase.status === "error" && /* @__PURE__ */ jsxs11("p", { "data-testid": "elemente-fehler", role: "alert", children: [
9748
10685
  "Elemente konnten nicht geladen werden: ",
9749
10686
  phase.message,
9750
10687
  phase.retryable && " \u2014 ein erneuter Versuch kann helfen."
9751
10688
  ] }),
9752
- phase.status === "ready" && phase.value.length === 0 && /* @__PURE__ */ jsxs10("p", { "data-testid": "elemente-leer", children: [
10689
+ phase.status === "ready" && phase.value.length === 0 && /* @__PURE__ */ jsxs11("p", { "data-testid": "elemente-leer", children: [
9753
10690
  typ ? `Keine ${elementTypPlural(typ)} in diesem Kontext.` : "Nichts in diesem Kontext.",
9754
10691
  " ",
9755
10692
  'Mit \u201E+ Neu" anlegen.'
9756
10693
  ] }),
9757
- phase.status === "ready" && phase.value.length > 0 && /* @__PURE__ */ jsx10("ul", { className: "szenen-elements__list", "data-testid": "elemente-liste", children: phase.value.map((element) => /* @__PURE__ */ jsx10("li", { "data-element-id": element.element_id, children: /* @__PURE__ */ jsxs10(
10694
+ phase.status === "ready" && phase.value.length > 0 && /* @__PURE__ */ jsx11("ul", { className: "szenen-elements__list", "data-testid": "elemente-liste", children: phase.value.map((element) => /* @__PURE__ */ jsx11("li", { "data-element-id": element.element_id, children: /* @__PURE__ */ jsxs11(
9758
10695
  "button",
9759
10696
  {
9760
10697
  type: "button",
@@ -9763,18 +10700,18 @@ var ElementsArea = ({
9763
10700
  className: element.element_id === gewaehlt ? "is-selected" : void 0,
9764
10701
  onClick: () => waehle(element.element_id),
9765
10702
  children: [
9766
- /* @__PURE__ */ jsx10("strong", { className: "szenen-elements__title", children: element.title || "Unbenanntes Element" }),
9767
- gemischt && /* @__PURE__ */ jsx10("span", { className: "szenen-elements__type", children: elementTypLabel(element.type) }),
9768
- element.subtype && /* @__PURE__ */ jsx10("span", { className: "szenen-elements__subtype", children: element.subtype }),
9769
- element.retired && /* @__PURE__ */ jsx10("span", { className: "szenen-elements__retired", children: "stillgelegt" })
10703
+ /* @__PURE__ */ jsx11("strong", { className: "szenen-elements__title", children: element.title || "Unbenanntes Element" }),
10704
+ gemischt && /* @__PURE__ */ jsx11("span", { className: "szenen-elements__type", children: elementTypLabel(element.type) }),
10705
+ element.subtype && /* @__PURE__ */ jsx11("span", { className: "szenen-elements__subtype", children: element.subtype }),
10706
+ element.retired && /* @__PURE__ */ jsx11("span", { className: "szenen-elements__retired", children: "stillgelegt" })
9770
10707
  ]
9771
10708
  }
9772
10709
  ) }, element.element_id)) }),
9773
- /* @__PURE__ */ jsxs10("details", { className: "szenen-elements__options", "data-testid": "listen-optionen", children: [
9774
- /* @__PURE__ */ jsx10("summary", { children: "Listenoptionen" }),
9775
- /* @__PURE__ */ jsxs10("div", { className: "szenen-elements__filter", children: [
9776
- /* @__PURE__ */ jsxs10("label", { children: [
9777
- /* @__PURE__ */ jsx10(
10710
+ /* @__PURE__ */ jsxs11("details", { className: "szenen-elements__options", "data-testid": "listen-optionen", children: [
10711
+ /* @__PURE__ */ jsx11("summary", { children: "Listenoptionen" }),
10712
+ /* @__PURE__ */ jsxs11("div", { className: "szenen-elements__filter", children: [
10713
+ /* @__PURE__ */ jsxs11("label", { children: [
10714
+ /* @__PURE__ */ jsx11(
9778
10715
  "input",
9779
10716
  {
9780
10717
  type: "checkbox",
@@ -9785,12 +10722,12 @@ var ElementsArea = ({
9785
10722
  ),
9786
10723
  "stillgelegte Elemente einblenden"
9787
10724
  ] }),
9788
- /* @__PURE__ */ jsx10("button", { type: "button", "data-testid": "neu-laden", onClick: neuLaden, children: "neu laden" })
10725
+ /* @__PURE__ */ jsx11("button", { type: "button", "data-testid": "neu-laden", onClick: neuLaden, children: "neu laden" })
9789
10726
  ] })
9790
10727
  ] })
9791
10728
  ] }),
9792
- zeigeDetail && /* @__PURE__ */ jsxs10("div", { className: "szenen-elements__detail", "data-testid": "elemente-detail-spalte", children: [
9793
- schmal && /* @__PURE__ */ jsx10(
10729
+ zeigeDetail && /* @__PURE__ */ jsxs11("div", { className: "szenen-elements__detail", "data-testid": "elemente-detail-spalte", children: [
10730
+ schmal && /* @__PURE__ */ jsx11(
9794
10731
  "button",
9795
10732
  {
9796
10733
  type: "button",
@@ -9800,7 +10737,7 @@ var ElementsArea = ({
9800
10737
  children: "\u2190 Zur\xFCck zur Liste"
9801
10738
  }
9802
10739
  ),
9803
- gewaehlt ? /* @__PURE__ */ jsx10(
10740
+ gewaehlt ? /* @__PURE__ */ jsx11(
9804
10741
  ElementDetail,
9805
10742
  {
9806
10743
  port,
@@ -9809,7 +10746,7 @@ var ElementsArea = ({
9809
10746
  author,
9810
10747
  onChanged: neuLaden
9811
10748
  }
9812
- ) : /* @__PURE__ */ jsx10("p", { className: "szenen-elements__empty-detail", "data-testid": "keine-auswahl", children: "Nichts ausgew\xE4hlt. Ein Eintrag aus der Liste \xF6ffnet die Bearbeitung." })
10749
+ ) : /* @__PURE__ */ jsx11("p", { className: "szenen-elements__empty-detail", "data-testid": "keine-auswahl", children: "Nichts ausgew\xE4hlt. Ein Eintrag aus der Liste \xF6ffnet die Bearbeitung." })
9813
10750
  ] })
9814
10751
  ]
9815
10752
  }
@@ -9817,17 +10754,17 @@ var ElementsArea = ({
9817
10754
  };
9818
10755
 
9819
10756
  // src/features/szenen/areas/SceneArea.tsx
9820
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
9821
- var SceneArea = ({ port, contextId }) => /* @__PURE__ */ jsxs11("div", { className: "szenen-scene", "data-testid": "bereich-szene", children: [
9822
- /* @__PURE__ */ jsx11("p", { className: "szenen-area__lead", children: "Szenen dieses Kontexts. Auswahl \xF6ffnet die Bearbeitung der Nodes und Beziehungen." }),
9823
- /* @__PURE__ */ jsx11(ElementsArea, { port, contextId, restrictToTypes: ["scene"] })
10757
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
10758
+ var SceneArea = ({ port, contextId }) => /* @__PURE__ */ jsxs12("div", { className: "szenen-scene", "data-testid": "bereich-szene", children: [
10759
+ /* @__PURE__ */ jsx12("p", { className: "szenen-area__lead", children: "Szenen dieses Kontexts. Auswahl \xF6ffnet die Bearbeitung der Nodes und Beziehungen." }),
10760
+ /* @__PURE__ */ jsx12(ElementsArea, { port, contextId, restrictToTypes: ["scene"] })
9824
10761
  ] });
9825
10762
 
9826
10763
  // src/features/szenen/areas/SetupArea.tsx
9827
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
9828
- var SetupArea = ({ port, contextId }) => /* @__PURE__ */ jsxs12("div", { className: "szenen-setup", "data-testid": "bereich-setup", children: [
9829
- /* @__PURE__ */ jsx12("p", { className: "szenen-area__lead", children: "Bildaufbauten, Kameras und Stile dieses Kontexts." }),
9830
- /* @__PURE__ */ jsx12(
10764
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
10765
+ var SetupArea = ({ port, contextId }) => /* @__PURE__ */ jsxs13("div", { className: "szenen-setup", "data-testid": "bereich-setup", children: [
10766
+ /* @__PURE__ */ jsx13("p", { className: "szenen-area__lead", children: "Bildaufbauten, Kameras und Stile dieses Kontexts." }),
10767
+ /* @__PURE__ */ jsx13(
9831
10768
  ElementsArea,
9832
10769
  {
9833
10770
  port,
@@ -9840,10 +10777,10 @@ var SetupArea = ({ port, contextId }) => /* @__PURE__ */ jsxs12("div", { classNa
9840
10777
  ] });
9841
10778
 
9842
10779
  // src/features/szenen/areas/ShotArea.tsx
9843
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
9844
- var ShotArea = ({ port, contextId }) => /* @__PURE__ */ jsxs13("div", { className: "szenen-shot", "data-testid": "bereich-shot", children: [
9845
- /* @__PURE__ */ jsx13("p", { className: "szenen-area__lead", children: "Prompts dieses Kontexts. Auswahl zeigt Runden und startet Prompt-L\xE4ufe." }),
9846
- /* @__PURE__ */ jsx13(
10780
+ import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
10781
+ var ShotArea = ({ port, contextId }) => /* @__PURE__ */ jsxs14("div", { className: "szenen-shot", "data-testid": "bereich-shot", children: [
10782
+ /* @__PURE__ */ jsx14("p", { className: "szenen-area__lead", children: "Prompts dieses Kontexts. Auswahl zeigt Runden und startet Prompt-L\xE4ufe." }),
10783
+ /* @__PURE__ */ jsx14(
9847
10784
  ElementsArea,
9848
10785
  {
9849
10786
  port,
@@ -9856,21 +10793,21 @@ var ShotArea = ({ port, contextId }) => /* @__PURE__ */ jsxs13("div", { classNam
9856
10793
  ] });
9857
10794
 
9858
10795
  // src/features/szenen/areas/MediaArea.tsx
9859
- import { useState as useState12 } from "react";
9860
- import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
10796
+ import { useState as useState13 } from "react";
10797
+ import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
9861
10798
  var leer = async () => ({ kind: "ok", value: [] });
9862
10799
  var MediaArea = ({ port }) => {
9863
10800
  const media = port.media;
9864
- const [versionInput, setVersionInput] = useState12("");
9865
- const [versionId, setVersionId] = useState12("");
9866
- const [itemInput, setItemInput] = useState12("");
9867
- const [itemId, setItemId] = useState12("");
9868
- const [assetId, setAssetId] = useState12("");
9869
- const [role, setRole] = useState12("reference");
9870
- const [position, setPosition] = useState12("0");
9871
- const [notiz, setNotiz] = useState12(null);
9872
- const [busy, setBusy] = useState12(false);
9873
- const [refresh, setRefresh] = useState12(0);
10801
+ const [versionInput, setVersionInput] = useState13("");
10802
+ const [versionId, setVersionId] = useState13("");
10803
+ const [itemInput, setItemInput] = useState13("");
10804
+ const [itemId, setItemId] = useState13("");
10805
+ const [assetId, setAssetId] = useState13("");
10806
+ const [role, setRole] = useState13("reference");
10807
+ const [position, setPosition] = useState13("0");
10808
+ const [notiz, setNotiz] = useState13(null);
10809
+ const [busy, setBusy] = useState13(false);
10810
+ const [refresh, setRefresh] = useState13(0);
9874
10811
  const [versionPhase] = usePortQuery(
9875
10812
  () => versionId ? media.listVersionMedia(versionId) : leer(),
9876
10813
  [media, versionId, refresh]
@@ -9916,145 +10853,145 @@ var MediaArea = ({ port }) => {
9916
10853
  };
9917
10854
  const versionMedien = versionPhase.status === "ready" ? versionPhase.value : [];
9918
10855
  const itemMedien = itemPhase.status === "ready" ? itemPhase.value : [];
9919
- return /* @__PURE__ */ jsxs14("div", { className: "szenen-media", "data-testid": "bereich-medien", children: [
9920
- /* @__PURE__ */ jsx14("p", { className: "szenen-area__lead", children: "Bereits vorhandene Medien-Assets einer Elementversion zuordnen. Hochgeladen wird hier nichts \u2014 Medien entstehen \xFCber den bestehenden Speicherweg aus Stufe 5." }),
9921
- /* @__PURE__ */ jsxs14("section", { children: [
9922
- /* @__PURE__ */ jsx14("h3", { children: "Version" }),
9923
- /* @__PURE__ */ jsxs14("div", { className: "szenen-media__lookup", children: [
9924
- /* @__PURE__ */ jsxs14("label", { children: [
10856
+ return /* @__PURE__ */ jsxs15("div", { className: "szenen-media", "data-testid": "bereich-medien", children: [
10857
+ /* @__PURE__ */ jsx15("p", { className: "szenen-area__lead", children: "Bereits vorhandene Medien-Assets einer Elementversion zuordnen. Hochgeladen wird hier nichts \u2014 Medien entstehen \xFCber den bestehenden Speicherweg aus Stufe 5." }),
10858
+ /* @__PURE__ */ jsxs15("section", { children: [
10859
+ /* @__PURE__ */ jsx15("h3", { children: "Version" }),
10860
+ /* @__PURE__ */ jsxs15("div", { className: "szenen-media__lookup", children: [
10861
+ /* @__PURE__ */ jsxs15("label", { children: [
9925
10862
  "Version-ID",
9926
- /* @__PURE__ */ jsx14("input", { value: versionInput, onChange: (event) => setVersionInput(event.target.value) })
10863
+ /* @__PURE__ */ jsx15("input", { value: versionInput, onChange: (event) => setVersionInput(event.target.value) })
9927
10864
  ] }),
9928
- /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setVersionId(versionInput.trim()), children: "Medien laden" })
10865
+ /* @__PURE__ */ jsx15("button", { type: "button", onClick: () => setVersionId(versionInput.trim()), children: "Medien laden" })
9929
10866
  ] }),
9930
- /* @__PURE__ */ jsxs14("div", { className: "szenen-media__attach", children: [
9931
- /* @__PURE__ */ jsxs14("label", { children: [
10867
+ /* @__PURE__ */ jsxs15("div", { className: "szenen-media__attach", children: [
10868
+ /* @__PURE__ */ jsxs15("label", { children: [
9932
10869
  "Asset-ID",
9933
- /* @__PURE__ */ jsx14("input", { value: assetId, onChange: (event) => setAssetId(event.target.value) })
10870
+ /* @__PURE__ */ jsx15("input", { value: assetId, onChange: (event) => setAssetId(event.target.value) })
9934
10871
  ] }),
9935
- /* @__PURE__ */ jsxs14("label", { children: [
10872
+ /* @__PURE__ */ jsxs15("label", { children: [
9936
10873
  "Rolle",
9937
- /* @__PURE__ */ jsxs14("select", { value: role, onChange: (event) => setRole(event.target.value), children: [
9938
- /* @__PURE__ */ jsx14("option", { value: "reference", children: "reference" }),
9939
- /* @__PURE__ */ jsx14("option", { value: "mask", children: "mask" }),
9940
- /* @__PURE__ */ jsx14("option", { value: "palette", children: "palette" }),
9941
- /* @__PURE__ */ jsx14("option", { value: "example", children: "example" })
10874
+ /* @__PURE__ */ jsxs15("select", { value: role, onChange: (event) => setRole(event.target.value), children: [
10875
+ /* @__PURE__ */ jsx15("option", { value: "reference", children: "reference" }),
10876
+ /* @__PURE__ */ jsx15("option", { value: "mask", children: "mask" }),
10877
+ /* @__PURE__ */ jsx15("option", { value: "palette", children: "palette" }),
10878
+ /* @__PURE__ */ jsx15("option", { value: "example", children: "example" })
9942
10879
  ] })
9943
10880
  ] }),
9944
- /* @__PURE__ */ jsxs14("label", { children: [
10881
+ /* @__PURE__ */ jsxs15("label", { children: [
9945
10882
  "Position",
9946
- /* @__PURE__ */ jsx14("input", { type: "number", min: "0", value: position, onChange: (event) => setPosition(event.target.value) })
10883
+ /* @__PURE__ */ jsx15("input", { type: "number", min: "0", value: position, onChange: (event) => setPosition(event.target.value) })
9947
10884
  ] }),
9948
- /* @__PURE__ */ jsx14("button", { type: "button", disabled: busy, onClick: zuordnen, children: "zuordnen" })
10885
+ /* @__PURE__ */ jsx15("button", { type: "button", disabled: busy, onClick: zuordnen, children: "zuordnen" })
9949
10886
  ] }),
9950
- versionPhase.status === "loading" && versionId && /* @__PURE__ */ jsx14("p", { children: "Versionsmedien werden geladen \u2026" }),
9951
- versionPhase.status === "error" && /* @__PURE__ */ jsxs14("p", { role: "alert", children: [
10887
+ versionPhase.status === "loading" && versionId && /* @__PURE__ */ jsx15("p", { children: "Versionsmedien werden geladen \u2026" }),
10888
+ versionPhase.status === "error" && /* @__PURE__ */ jsxs15("p", { role: "alert", children: [
9952
10889
  "Versionsmedien konnten nicht geladen werden: ",
9953
10890
  versionPhase.message
9954
10891
  ] }),
9955
- versionPhase.status === "ready" && versionId && versionMedien.length === 0 && /* @__PURE__ */ jsxs14("p", { children: [
10892
+ versionPhase.status === "ready" && versionId && versionMedien.length === 0 && /* @__PURE__ */ jsxs15("p", { children: [
9956
10893
  "Version ",
9957
10894
  versionId,
9958
10895
  " hat keine Medien."
9959
10896
  ] }),
9960
- /* @__PURE__ */ jsx14("ul", { className: "szenen-media__list", children: versionMedien.map((medium) => /* @__PURE__ */ jsxs14("li", { children: [
9961
- /* @__PURE__ */ jsx14("code", { children: medium.assetId }),
9962
- /* @__PURE__ */ jsxs14("span", { children: [
10897
+ /* @__PURE__ */ jsx15("ul", { className: "szenen-media__list", children: versionMedien.map((medium) => /* @__PURE__ */ jsxs15("li", { children: [
10898
+ /* @__PURE__ */ jsx15("code", { children: medium.assetId }),
10899
+ /* @__PURE__ */ jsxs15("span", { children: [
9963
10900
  medium.role,
9964
10901
  " \xB7 Position ",
9965
10902
  medium.position
9966
10903
  ] }),
9967
- medium.url && /* @__PURE__ */ jsx14("a", { href: medium.url, target: "_blank", rel: "noreferrer", children: "\xF6ffnen" }),
9968
- /* @__PURE__ */ jsx14("button", { type: "button", disabled: busy, onClick: () => entfernen(medium), children: "entfernen" })
10904
+ medium.url && /* @__PURE__ */ jsx15("a", { href: medium.url, target: "_blank", rel: "noreferrer", children: "\xF6ffnen" }),
10905
+ /* @__PURE__ */ jsx15("button", { type: "button", disabled: busy, onClick: () => entfernen(medium), children: "entfernen" })
9969
10906
  ] }, `${medium.assetId}:${medium.role}`)) })
9970
10907
  ] }),
9971
- /* @__PURE__ */ jsxs14("section", { children: [
9972
- /* @__PURE__ */ jsx14("h3", { children: "Item-Medien" }),
9973
- /* @__PURE__ */ jsxs14("div", { className: "szenen-media__lookup", children: [
9974
- /* @__PURE__ */ jsxs14("label", { children: [
10908
+ /* @__PURE__ */ jsxs15("section", { children: [
10909
+ /* @__PURE__ */ jsx15("h3", { children: "Item-Medien" }),
10910
+ /* @__PURE__ */ jsxs15("div", { className: "szenen-media__lookup", children: [
10911
+ /* @__PURE__ */ jsxs15("label", { children: [
9975
10912
  "Item-ID",
9976
- /* @__PURE__ */ jsx14("input", { value: itemInput, onChange: (event) => setItemInput(event.target.value) })
10913
+ /* @__PURE__ */ jsx15("input", { value: itemInput, onChange: (event) => setItemInput(event.target.value) })
9977
10914
  ] }),
9978
- /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setItemId(itemInput.trim()), children: "Item-Medien laden" })
10915
+ /* @__PURE__ */ jsx15("button", { type: "button", onClick: () => setItemId(itemInput.trim()), children: "Item-Medien laden" })
9979
10916
  ] }),
9980
- itemPhase.status === "error" && /* @__PURE__ */ jsxs14("p", { role: "alert", children: [
10917
+ itemPhase.status === "error" && /* @__PURE__ */ jsxs15("p", { role: "alert", children: [
9981
10918
  "Item-Medien konnten nicht geladen werden: ",
9982
10919
  itemPhase.message
9983
10920
  ] }),
9984
- /* @__PURE__ */ jsx14("ul", { className: "szenen-media__list", children: itemMedien.map((medium) => /* @__PURE__ */ jsxs14("li", { children: [
9985
- /* @__PURE__ */ jsx14("code", { children: medium.assetId }),
9986
- /* @__PURE__ */ jsxs14("span", { children: [
10921
+ /* @__PURE__ */ jsx15("ul", { className: "szenen-media__list", children: itemMedien.map((medium) => /* @__PURE__ */ jsxs15("li", { children: [
10922
+ /* @__PURE__ */ jsx15("code", { children: medium.assetId }),
10923
+ /* @__PURE__ */ jsxs15("span", { children: [
9987
10924
  medium.role,
9988
10925
  " \xB7 Position ",
9989
10926
  medium.position
9990
10927
  ] }),
9991
- medium.url && /* @__PURE__ */ jsx14("a", { href: medium.url, target: "_blank", rel: "noreferrer", children: "\xF6ffnen" })
10928
+ medium.url && /* @__PURE__ */ jsx15("a", { href: medium.url, target: "_blank", rel: "noreferrer", children: "\xF6ffnen" })
9992
10929
  ] }, `${medium.assetId}:${medium.role}:${medium.position}`)) })
9993
10930
  ] }),
9994
- notiz && /* @__PURE__ */ jsx14("p", { role: notiz.tone === "error" ? "alert" : "status", "data-tone": notiz.tone, children: notiz.text })
10931
+ notiz && /* @__PURE__ */ jsx15("p", { role: notiz.tone === "error" ? "alert" : "status", "data-tone": notiz.tone, children: notiz.text })
9995
10932
  ] });
9996
10933
  };
9997
10934
 
9998
10935
  // src/features/szenen/areas/DeriveArea.tsx
9999
- import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef2, useState as useState15 } from "react";
10936
+ import { useEffect as useEffect8, useMemo as useMemo3, useRef as useRef4, useState as useState16 } from "react";
10000
10937
 
10001
10938
  // src/features/szenen/areas/RecoveryPanel.tsx
10002
- import { useState as useState13 } from "react";
10003
- import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
10939
+ import { useState as useState14 } from "react";
10940
+ import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
10004
10941
  var Diagnosen = ({ befunde, testId }) => {
10005
10942
  if (befunde.length === 0) return null;
10006
- return /* @__PURE__ */ jsx15("ul", { className: "szenen-diagnose__liste", "data-testid": testId, children: befunde.map((d, i) => /* @__PURE__ */ jsxs15("li", { "data-severity": d.severity, children: [
10007
- /* @__PURE__ */ jsx15("code", { children: d.code }),
10008
- d.proposal_type && /* @__PURE__ */ jsxs15(Fragment5, { children: [
10943
+ return /* @__PURE__ */ jsx16("ul", { className: "szenen-diagnose__liste", "data-testid": testId, children: befunde.map((d, i) => /* @__PURE__ */ jsxs16("li", { "data-severity": d.severity, children: [
10944
+ /* @__PURE__ */ jsx16("code", { children: d.code }),
10945
+ d.proposal_type && /* @__PURE__ */ jsxs16(Fragment6, { children: [
10009
10946
  " \xB7 ",
10010
- /* @__PURE__ */ jsx15("strong", { children: d.proposal_type })
10947
+ /* @__PURE__ */ jsx16("strong", { children: d.proposal_type })
10011
10948
  ] }),
10012
- d.pointer && /* @__PURE__ */ jsxs15(Fragment5, { children: [
10949
+ d.pointer && /* @__PURE__ */ jsxs16(Fragment6, { children: [
10013
10950
  " \xB7 ",
10014
- /* @__PURE__ */ jsx15("code", { children: d.pointer })
10951
+ /* @__PURE__ */ jsx16("code", { children: d.pointer })
10015
10952
  ] }),
10016
- typeof d.line === "number" && /* @__PURE__ */ jsxs15(Fragment5, { children: [
10953
+ typeof d.line === "number" && /* @__PURE__ */ jsxs16(Fragment6, { children: [
10017
10954
  " \xB7 Zeile ",
10018
10955
  d.line,
10019
10956
  ", Spalte ",
10020
10957
  d.column
10021
10958
  ] }),
10022
- /* @__PURE__ */ jsx15("div", { children: d.message })
10959
+ /* @__PURE__ */ jsx16("div", { children: d.message })
10023
10960
  ] }, i)) });
10024
10961
  };
10025
- var Ausbeute = ({ bewertung }) => /* @__PURE__ */ jsxs15("div", { className: "szenen-diagnose", "data-testid": "rettung-ergebnis", children: [
10026
- /* @__PURE__ */ jsxs15("p", { "data-testid": "rettung-status", children: [
10962
+ var Ausbeute = ({ bewertung }) => /* @__PURE__ */ jsxs16("div", { className: "szenen-diagnose", "data-testid": "rettung-ergebnis", children: [
10963
+ /* @__PURE__ */ jsxs16("p", { "data-testid": "rettung-status", children: [
10027
10964
  bewertung.status === "usable" && "Diese Fassung ist vollst\xE4ndig verwertbar.",
10028
10965
  bewertung.status === "partial" && "Diese Fassung ist teilweise verwertbar \u2014 nicht alles kommt durch.",
10029
10966
  bewertung.status === "invalid" && "Aus dieser Fassung ist nichts zu \xFCbernehmen."
10030
10967
  ] }),
10031
- bewertung.proposals.length > 0 && /* @__PURE__ */ jsxs15(Fragment5, { children: [
10032
- /* @__PURE__ */ jsx15("h5", { children: "Verwertbar" }),
10033
- /* @__PURE__ */ jsx15("ul", { "data-testid": "rettung-verwertbar", children: bewertung.proposals.map((p) => /* @__PURE__ */ jsxs15("li", { "data-testid": `rettung-verwertbar-${p.type}`, children: [
10034
- /* @__PURE__ */ jsx15("strong", { children: p.type }),
10968
+ bewertung.proposals.length > 0 && /* @__PURE__ */ jsxs16(Fragment6, { children: [
10969
+ /* @__PURE__ */ jsx16("h5", { children: "Verwertbar" }),
10970
+ /* @__PURE__ */ jsx16("ul", { "data-testid": "rettung-verwertbar", children: bewertung.proposals.map((p) => /* @__PURE__ */ jsxs16("li", { "data-testid": `rettung-verwertbar-${p.type}`, children: [
10971
+ /* @__PURE__ */ jsx16("strong", { children: p.type }),
10035
10972
  " \u2014 ",
10036
10973
  p.status === "complete" ? "vollst\xE4ndig" : "teilweise; vor dem Ver\xF6ffentlichen zu erg\xE4nzen",
10037
- p.status === "partial" && p.gaps && p.gaps.length > 0 && /* @__PURE__ */ jsx15("ul", { children: p.gaps.map((l, i) => /* @__PURE__ */ jsxs15("li", { children: [
10038
- /* @__PURE__ */ jsx15("code", { children: l.pointer }),
10974
+ p.status === "partial" && p.gaps && p.gaps.length > 0 && /* @__PURE__ */ jsx16("ul", { children: p.gaps.map((l, i) => /* @__PURE__ */ jsxs16("li", { children: [
10975
+ /* @__PURE__ */ jsx16("code", { children: l.pointer }),
10039
10976
  ": ",
10040
10977
  l.reason
10041
10978
  ] }, i)) })
10042
10979
  ] }, p.type)) })
10043
10980
  ] }),
10044
- bewertung.rejected.length > 0 && /* @__PURE__ */ jsxs15(Fragment5, { children: [
10045
- /* @__PURE__ */ jsx15("h5", { children: "Nicht verwertbar" }),
10046
- /* @__PURE__ */ jsx15("ul", { "data-testid": "rettung-abgelehnt", children: bewertung.rejected.map((r) => /* @__PURE__ */ jsxs15("li", { "data-testid": `rettung-abgelehnt-${r.type}`, children: [
10047
- /* @__PURE__ */ jsx15("strong", { children: r.type }),
10048
- /* @__PURE__ */ jsx15(Diagnosen, { befunde: r.diagnostics, testId: `rettung-grund-${r.type}` })
10981
+ bewertung.rejected.length > 0 && /* @__PURE__ */ jsxs16(Fragment6, { children: [
10982
+ /* @__PURE__ */ jsx16("h5", { children: "Nicht verwertbar" }),
10983
+ /* @__PURE__ */ jsx16("ul", { "data-testid": "rettung-abgelehnt", children: bewertung.rejected.map((r) => /* @__PURE__ */ jsxs16("li", { "data-testid": `rettung-abgelehnt-${r.type}`, children: [
10984
+ /* @__PURE__ */ jsx16("strong", { children: r.type }),
10985
+ /* @__PURE__ */ jsx16(Diagnosen, { befunde: r.diagnostics, testId: `rettung-grund-${r.type}` })
10049
10986
  ] }, r.type)) })
10050
10987
  ] })
10051
10988
  ] });
10052
10989
  var RecoveryPanel = ({ port, lauf }) => {
10053
- const [arbeitskopie, setArbeitskopie] = useState13(null);
10054
- const [bewertung, setBewertung] = useState13(null);
10055
- const [gesichert, setGesichert] = useState13(null);
10056
- const [meldung, setMeldung] = useState13(null);
10057
- const [laeuft, setLaeuft] = useState13(false);
10990
+ const [arbeitskopie, setArbeitskopie] = useState14(null);
10991
+ const [bewertung, setBewertung] = useState14(null);
10992
+ const [gesichert, setGesichert] = useState14(null);
10993
+ const [meldung, setMeldung] = useState14(null);
10994
+ const [laeuft, setLaeuft] = useState14(false);
10058
10995
  if (!port.derivation) return null;
10059
10996
  if (typeof lauf.raw_output !== "string" || lauf.raw_output.length === 0) return null;
10060
10997
  const derivation = port.derivation;
@@ -10090,16 +11027,16 @@ var RecoveryPanel = ({ port, lauf }) => {
10090
11027
  setLaeuft(false);
10091
11028
  }
10092
11029
  }
10093
- return /* @__PURE__ */ jsxs15("section", { className: "szenen-rettung", "data-testid": "rettung", children: [
10094
- /* @__PURE__ */ jsx15("h4", { children: "Antwort retten" }),
10095
- /* @__PURE__ */ jsxs15("p", { className: "szenen-area__lead", children: [
11030
+ return /* @__PURE__ */ jsxs16("section", { className: "szenen-rettung", "data-testid": "rettung", children: [
11031
+ /* @__PURE__ */ jsx16("h4", { children: "Antwort retten" }),
11032
+ /* @__PURE__ */ jsxs16("p", { className: "szenen-area__lead", children: [
10096
11033
  "Der Lauf ist bezahlt und seine Antwort liegt vor. Sie l\xE4sst sich hier pr\xFCfen und korrigieren \u2014 ",
10097
- /* @__PURE__ */ jsx15("strong", { children: "ohne" }),
11034
+ /* @__PURE__ */ jsx16("strong", { children: "ohne" }),
10098
11035
  " einen weiteren Modellaufruf. Das Original bleibt unver\xE4ndert."
10099
11036
  ] }),
10100
- /* @__PURE__ */ jsxs15("label", { className: "szenen-field", children: [
10101
- /* @__PURE__ */ jsx15("span", { children: "Original der Modellantwort (unver\xE4nderlich)" }),
10102
- /* @__PURE__ */ jsx15(
11037
+ /* @__PURE__ */ jsxs16("label", { className: "szenen-field", children: [
11038
+ /* @__PURE__ */ jsx16("span", { children: "Original der Modellantwort (unver\xE4nderlich)" }),
11039
+ /* @__PURE__ */ jsx16(
10103
11040
  "textarea",
10104
11041
  {
10105
11042
  readOnly: true,
@@ -10110,12 +11047,12 @@ var RecoveryPanel = ({ port, lauf }) => {
10110
11047
  }
10111
11048
  )
10112
11049
  ] }),
10113
- /* @__PURE__ */ jsxs15("label", { className: "szenen-field", children: [
10114
- /* @__PURE__ */ jsxs15("span", { children: [
11050
+ /* @__PURE__ */ jsxs16("label", { className: "szenen-field", children: [
11051
+ /* @__PURE__ */ jsxs16("span", { children: [
10115
11052
  "Arbeitskopie",
10116
11053
  bearbeitet ? " (bearbeitet)" : ""
10117
11054
  ] }),
10118
- /* @__PURE__ */ jsx15(
11055
+ /* @__PURE__ */ jsx16(
10119
11056
  "textarea",
10120
11057
  {
10121
11058
  rows: 8,
@@ -10125,8 +11062,8 @@ var RecoveryPanel = ({ port, lauf }) => {
10125
11062
  }
10126
11063
  )
10127
11064
  ] }),
10128
- /* @__PURE__ */ jsxs15("div", { className: "szenen-rettung__aktionen", children: [
10129
- /* @__PURE__ */ jsx15(
11065
+ /* @__PURE__ */ jsxs16("div", { className: "szenen-rettung__aktionen", children: [
11066
+ /* @__PURE__ */ jsx16(
10130
11067
  "button",
10131
11068
  {
10132
11069
  type: "button",
@@ -10136,7 +11073,7 @@ var RecoveryPanel = ({ port, lauf }) => {
10136
11073
  children: "Arbeitskopie pr\xFCfen (kein Modellaufruf)"
10137
11074
  }
10138
11075
  ),
10139
- /* @__PURE__ */ jsx15(
11076
+ /* @__PURE__ */ jsx16(
10140
11077
  "button",
10141
11078
  {
10142
11079
  type: "button",
@@ -10146,7 +11083,7 @@ var RecoveryPanel = ({ port, lauf }) => {
10146
11083
  children: "Arbeitsfassung speichern"
10147
11084
  }
10148
11085
  ),
10149
- arbeitskopie !== null && /* @__PURE__ */ jsx15(
11086
+ arbeitskopie !== null && /* @__PURE__ */ jsx16(
10150
11087
  "button",
10151
11088
  {
10152
11089
  type: "button",
@@ -10161,15 +11098,15 @@ var RecoveryPanel = ({ port, lauf }) => {
10161
11098
  }
10162
11099
  )
10163
11100
  ] }),
10164
- meldung && /* @__PURE__ */ jsx15("p", { className: "szenen-error", role: "alert", "data-testid": "rettung-meldung", children: meldung }),
10165
- bewertung && /* @__PURE__ */ jsx15(Ausbeute, { bewertung }),
10166
- bewertung && bewertung.diagnostics.length > 0 && /* @__PURE__ */ jsxs15("div", { className: "szenen-diagnose", children: [
10167
- /* @__PURE__ */ jsx15("h5", { children: "Befunde an dieser Fassung" }),
10168
- /* @__PURE__ */ jsx15(Diagnosen, { befunde: bewertung.diagnostics, testId: "rettung-befunde" })
11101
+ meldung && /* @__PURE__ */ jsx16("p", { className: "szenen-error", role: "alert", "data-testid": "rettung-meldung", children: meldung }),
11102
+ bewertung && /* @__PURE__ */ jsx16(Ausbeute, { bewertung }),
11103
+ bewertung && bewertung.diagnostics.length > 0 && /* @__PURE__ */ jsxs16("div", { className: "szenen-diagnose", children: [
11104
+ /* @__PURE__ */ jsx16("h5", { children: "Befunde an dieser Fassung" }),
11105
+ /* @__PURE__ */ jsx16(Diagnosen, { befunde: bewertung.diagnostics, testId: "rettung-befunde" })
10169
11106
  ] }),
10170
- gesichert && /* @__PURE__ */ jsxs15("p", { "data-testid": "rettung-gesichert", children: [
11107
+ gesichert && /* @__PURE__ */ jsxs16("p", { "data-testid": "rettung-gesichert", children: [
10171
11108
  "Gespeichert als Arbeitsfassung ",
10172
- /* @__PURE__ */ jsx15("code", { children: gesichert.recovery_id }),
11109
+ /* @__PURE__ */ jsx16("code", { children: gesichert.recovery_id }),
10173
11110
  gesichert.edited ? " (bearbeitet)" : " (unver\xE4ndert)",
10174
11111
  ". Das Original des Laufs ist davon unber\xFChrt."
10175
11112
  ] })
@@ -10177,12 +11114,12 @@ var RecoveryPanel = ({ port, lauf }) => {
10177
11114
  };
10178
11115
 
10179
11116
  // src/features/szenen/areas/ChainActions.tsx
10180
- import { useState as useState14 } from "react";
10181
- import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
11117
+ import { useState as useState15 } from "react";
11118
+ import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
10182
11119
  var ChainActions = ({ port, runId, recoveryId }) => {
10183
- const [graph, setGraph] = useState14(null);
10184
- const [meldung, setMeldung] = useState14(null);
10185
- const [laeuft, setLaeuft] = useState14(false);
11120
+ const [graph, setGraph] = useState15(null);
11121
+ const [meldung, setMeldung] = useState15(null);
11122
+ const [laeuft, setLaeuft] = useState15(false);
10186
11123
  if (!port.derivation) return null;
10187
11124
  const derivation = port.derivation;
10188
11125
  const runs = port.runs;
@@ -10204,14 +11141,14 @@ var ChainActions = ({ port, runId, recoveryId }) => {
10204
11141
  setLaeuft(false);
10205
11142
  }
10206
11143
  }
10207
- return /* @__PURE__ */ jsxs16("section", { className: "szenen-kette", "data-testid": "kette", children: [
10208
- /* @__PURE__ */ jsx16("h4", { children: "Draft-Kette" }),
10209
- /* @__PURE__ */ jsxs16("p", { className: "szenen-area__lead", children: [
11144
+ return /* @__PURE__ */ jsxs17("section", { className: "szenen-kette", "data-testid": "kette", children: [
11145
+ /* @__PURE__ */ jsx17("h4", { children: "Draft-Kette" }),
11146
+ /* @__PURE__ */ jsxs17("p", { className: "szenen-area__lead", children: [
10210
11147
  "Szene, Aufbau und Shot entstehen als zusammenh\xE4ngende Entw\xFCrfe. Daraus l\xE4sst sich sofort ein Prompt erzeugen \u2014 ",
10211
- /* @__PURE__ */ jsx16("strong", { children: "ohne" }),
11148
+ /* @__PURE__ */ jsx17("strong", { children: "ohne" }),
10212
11149
  " vorher etwas zu ver\xF6ffentlichen."
10213
11150
  ] }),
10214
- !graph && /* @__PURE__ */ jsx16(
11151
+ !graph && /* @__PURE__ */ jsx17(
10215
11152
  "button",
10216
11153
  {
10217
11154
  type: "button",
@@ -10221,34 +11158,34 @@ var ChainActions = ({ port, runId, recoveryId }) => {
10221
11158
  children: "Als Draft-Kette \xFCbernehmen"
10222
11159
  }
10223
11160
  ),
10224
- graph && /* @__PURE__ */ jsxs16("div", { "data-testid": "kette-ergebnis", children: [
10225
- /* @__PURE__ */ jsxs16("p", { children: [
11161
+ graph && /* @__PURE__ */ jsxs17("div", { "data-testid": "kette-ergebnis", children: [
11162
+ /* @__PURE__ */ jsxs17("p", { children: [
10226
11163
  "Kette ",
10227
- /* @__PURE__ */ jsx16("code", { children: graph.chainId }),
11164
+ /* @__PURE__ */ jsx17("code", { children: graph.chainId }),
10228
11165
  " angelegt. Kein Knoten ist ver\xF6ffentlicht."
10229
11166
  ] }),
10230
- /* @__PURE__ */ jsx16("ul", { "data-testid": "kette-knoten", children: graph.created.map((k) => /* @__PURE__ */ jsxs16("li", { "data-testid": `kette-knoten-${k.type}`, children: [
10231
- /* @__PURE__ */ jsx16("strong", { children: k.type }),
11167
+ /* @__PURE__ */ jsx17("ul", { "data-testid": "kette-knoten", children: graph.created.map((k) => /* @__PURE__ */ jsxs17("li", { "data-testid": `kette-knoten-${k.type}`, children: [
11168
+ /* @__PURE__ */ jsx17("strong", { children: k.type }),
10232
11169
  " \u2014 Element ",
10233
- /* @__PURE__ */ jsx16("code", { children: k.elementId }),
11170
+ /* @__PURE__ */ jsx17("code", { children: k.elementId }),
10234
11171
  ", Entwurf ",
10235
- /* @__PURE__ */ jsx16("code", { children: k.draftId }),
11172
+ /* @__PURE__ */ jsx17("code", { children: k.draftId }),
10236
11173
  " (Revision ",
10237
11174
  k.revision,
10238
11175
  ")"
10239
11176
  ] }, k.type)) }),
10240
- graph.missing.length > 0 && /* @__PURE__ */ jsxs16("div", { className: "szenen-diagnose", "data-testid": "kette-fehlend", children: [
10241
- /* @__PURE__ */ jsx16("h5", { children: "Unvollst\xE4ndig erzeugt" }),
10242
- /* @__PURE__ */ jsx16("ul", { children: graph.missing.map((m) => /* @__PURE__ */ jsxs16("li", { children: [
10243
- /* @__PURE__ */ jsx16("strong", { children: m.type }),
11177
+ graph.missing.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "szenen-diagnose", "data-testid": "kette-fehlend", children: [
11178
+ /* @__PURE__ */ jsx17("h5", { children: "Unvollst\xE4ndig erzeugt" }),
11179
+ /* @__PURE__ */ jsx17("ul", { children: graph.missing.map((m) => /* @__PURE__ */ jsxs17("li", { children: [
11180
+ /* @__PURE__ */ jsx17("strong", { children: m.type }),
10244
11181
  ": ",
10245
11182
  m.reason
10246
11183
  ] }, m.type)) })
10247
11184
  ] })
10248
11185
  ] }),
10249
- shotKnoten && /* @__PURE__ */ jsxs16(Fragment6, { children: [
10250
- /* @__PURE__ */ jsx16("p", { children: 'Die Entw\xFCrfe lassen sich jetzt unter \u201E1 \xB7 Bausteine" \xE4ndern. Der Prompt-Lauf friert den Stand ein, den er dabei vorfindet \u2014 dieselbe Aktion steht auch am Shot selbst, unter \u201E4 \xB7 Prompt".' }),
10251
- /* @__PURE__ */ jsx16(
11186
+ shotKnoten && /* @__PURE__ */ jsxs17(Fragment7, { children: [
11187
+ /* @__PURE__ */ jsx17("p", { children: 'Die Entw\xFCrfe lassen sich jetzt unter \u201E1 \xB7 Bausteine" \xE4ndern. Der Prompt-Lauf friert den Stand ein, den er dabei vorfindet \u2014 dieselbe Aktion steht auch am Shot selbst, unter \u201E4 \xB7 Prompt".' }),
11188
+ /* @__PURE__ */ jsx17(
10252
11189
  PromptStartAction,
10253
11190
  {
10254
11191
  port,
@@ -10256,20 +11193,20 @@ var ChainActions = ({ port, runId, recoveryId }) => {
10256
11193
  }
10257
11194
  )
10258
11195
  ] }),
10259
- meldung && /* @__PURE__ */ jsx16("p", { className: "szenen-error", role: "alert", "data-testid": "kette-meldung", children: meldung })
11196
+ meldung && /* @__PURE__ */ jsx17("p", { className: "szenen-error", role: "alert", "data-testid": "kette-meldung", children: meldung })
10260
11197
  ] });
10261
11198
  };
10262
11199
 
10263
11200
  // src/features/szenen/areas/DeriveArea.tsx
10264
- import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
11201
+ import { Fragment as Fragment8, jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
10265
11202
  var MODUS_TEXT = {
10266
11203
  prompt: "Nur Prompt",
10267
11204
  image: "Nur Bild",
10268
11205
  image_prompt: "Bild und Prompt"
10269
11206
  };
10270
11207
  var BelegFeld = ({ titel, text, testId, offen }) => {
10271
- const [kopiert, setKopiert] = useState15(false);
10272
- const feld = useRef2(null);
11208
+ const [kopiert, setKopiert] = useState16(false);
11209
+ const feld = useRef4(null);
10273
11210
  async function kopieren() {
10274
11211
  try {
10275
11212
  await navigator.clipboard.writeText(text);
@@ -10279,15 +11216,15 @@ var BelegFeld = ({ titel, text, testId, offen }) => {
10279
11216
  setKopiert(false);
10280
11217
  }
10281
11218
  }
10282
- return /* @__PURE__ */ jsxs17("details", { open: offen, "data-testid": `belege-${testId}`, children: [
10283
- /* @__PURE__ */ jsxs17("summary", { children: [
11219
+ return /* @__PURE__ */ jsxs18("details", { open: offen, "data-testid": `belege-${testId}`, children: [
11220
+ /* @__PURE__ */ jsxs18("summary", { children: [
10284
11221
  titel,
10285
11222
  " (",
10286
11223
  text.length,
10287
11224
  " Zeichen)"
10288
11225
  ] }),
10289
- /* @__PURE__ */ jsxs17("div", { className: "szenen-beleg__kopf", children: [
10290
- /* @__PURE__ */ jsx17(
11226
+ /* @__PURE__ */ jsxs18("div", { className: "szenen-beleg__kopf", children: [
11227
+ /* @__PURE__ */ jsx18(
10291
11228
  "button",
10292
11229
  {
10293
11230
  type: "button",
@@ -10296,9 +11233,9 @@ var BelegFeld = ({ titel, text, testId, offen }) => {
10296
11233
  children: "Kopieren"
10297
11234
  }
10298
11235
  ),
10299
- kopiert && /* @__PURE__ */ jsx17("span", { "data-testid": `kopiert-${testId}`, children: "Kopiert." })
11236
+ kopiert && /* @__PURE__ */ jsx18("span", { "data-testid": `kopiert-${testId}`, children: "Kopiert." })
10300
11237
  ] }),
10301
- /* @__PURE__ */ jsx17(
11238
+ /* @__PURE__ */ jsx18(
10302
11239
  "textarea",
10303
11240
  {
10304
11241
  ref: feld,
@@ -10312,8 +11249,8 @@ var BelegFeld = ({ titel, text, testId, offen }) => {
10312
11249
  )
10313
11250
  ] });
10314
11251
  };
10315
- var Belege = ({ lauf }) => /* @__PURE__ */ jsxs17("div", { className: "szenen-diagnose", "data-testid": "belege", children: [
10316
- lauf.raw_output ? /* @__PURE__ */ jsx17(
11252
+ var Belege = ({ lauf }) => /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose", "data-testid": "belege", children: [
11253
+ lauf.raw_output ? /* @__PURE__ */ jsx18(
10317
11254
  BelegFeld,
10318
11255
  {
10319
11256
  titel: "Rohantwort des Modells",
@@ -10324,9 +11261,9 @@ var Belege = ({ lauf }) => /* @__PURE__ */ jsxs17("div", { className: "szenen-di
10324
11261
  ) : (
10325
11262
  /* Kein Text ist auch eine Auskunft: Der Provider hat nichts geliefert,
10326
11263
  das Modell hat also nicht „falsch geantwortet". */
10327
- /* @__PURE__ */ jsx17("p", { "data-testid": "roh-antwort-fehlt", children: "Es gibt keine Rohantwort \u2014 der Lauf ist gescheitert, bevor ein Text ankam (etwa Netz, Sperre oder Providerfehler)." })
11264
+ /* @__PURE__ */ jsx18("p", { "data-testid": "roh-antwort-fehlt", children: "Es gibt keine Rohantwort \u2014 der Lauf ist gescheitert, bevor ein Text ankam (etwa Netz, Sperre oder Providerfehler)." })
10328
11265
  ),
10329
- /* @__PURE__ */ jsx17(
11266
+ /* @__PURE__ */ jsx18(
10330
11267
  BelegFeld,
10331
11268
  {
10332
11269
  titel: "Systemprompt dieses Laufs",
@@ -10338,18 +11275,18 @@ var Belege = ({ lauf }) => /* @__PURE__ */ jsxs17("div", { className: "szenen-di
10338
11275
  ] });
10339
11276
  var Herkunft = ({ lauf }) => {
10340
11277
  if (!lauf.follows) return null;
10341
- return /* @__PURE__ */ jsxs17("p", { className: "szenen-run__herkunft", "data-testid": "folgt-auf", children: [
11278
+ return /* @__PURE__ */ jsxs18("p", { className: "szenen-run__herkunft", "data-testid": "folgt-auf", children: [
10342
11279
  "Folgt auf Lauf ",
10343
- /* @__PURE__ */ jsx17("code", { children: lauf.follows.run_id }),
11280
+ /* @__PURE__ */ jsx18("code", { children: lauf.follows.run_id }),
10344
11281
  ".",
10345
11282
  lauf.status === "succeeded" && " Im Folgelauf gelungen."
10346
11283
  ] });
10347
11284
  };
10348
11285
  var Widerspruch = ({ lauf }) => {
10349
11286
  if (!lauf.reply) return null;
10350
- return /* @__PURE__ */ jsxs17("div", { className: "szenen-diagnose szenen-diagnose--antwort", "data-testid": "modell-antwort", children: [
10351
- /* @__PURE__ */ jsx17("h4", { children: "Das Modell antwortet auf die Beanstandung" }),
10352
- /* @__PURE__ */ jsx17("p", { children: lauf.reply })
11287
+ return /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose szenen-diagnose--antwort", "data-testid": "modell-antwort", children: [
11288
+ /* @__PURE__ */ jsx18("h4", { children: "Das Modell antwortet auf die Beanstandung" }),
11289
+ /* @__PURE__ */ jsx18("p", { children: lauf.reply })
10353
11290
  ] });
10354
11291
  };
10355
11292
  function readAsBase642(datei) {
@@ -10364,11 +11301,33 @@ function readAsBase642(datei) {
10364
11301
  leser.readAsDataURL(datei);
10365
11302
  });
10366
11303
  }
11304
+ var ERSTE_KACHELN = 12;
11305
+ function useSichtbareKacheln(alle, wurzel) {
11306
+ const [gesehen, setGesehen] = useState16([]);
11307
+ const schluessel = alle.join(" ");
11308
+ useEffect8(() => {
11309
+ const ziel = wurzel.current;
11310
+ if (!ziel || typeof IntersectionObserver === "undefined") return void 0;
11311
+ const beobachter = new IntersectionObserver((eintraege) => {
11312
+ const neue = eintraege.filter((e) => e.isIntersecting).map((e) => e.target.dataset.mediaRef).filter((r) => Boolean(r));
11313
+ if (neue.length === 0) return;
11314
+ setGesehen((bisher) => [.../* @__PURE__ */ new Set([...bisher, ...neue])]);
11315
+ for (const e of eintraege) if (e.isIntersecting) beobachter.unobserve(e.target);
11316
+ }, { root: ziel, rootMargin: "200px" });
11317
+ ziel.querySelectorAll("[data-media-ref]").forEach((el) => beobachter.observe(el));
11318
+ return () => beobachter.disconnect();
11319
+ }, [wurzel, schluessel]);
11320
+ return useMemo3(
11321
+ () => [.../* @__PURE__ */ new Set([...alle.slice(0, ERSTE_KACHELN), ...gesehen])],
11322
+ [schluessel, gesehen]
11323
+ );
11324
+ }
10367
11325
  function useVorschauen(port, mediaRefs) {
10368
- const [quellen, setQuellen] = useState15(() => /* @__PURE__ */ new Map());
10369
- const gehalten = useRef2(/* @__PURE__ */ new Map());
11326
+ const [stand, setStand] = useState16(() => ({ quellen: /* @__PURE__ */ new Map(), gescheitert: /* @__PURE__ */ new Set() }));
11327
+ const gehalten = useRef4(/* @__PURE__ */ new Map());
11328
+ const ohneBild = useRef4(/* @__PURE__ */ new Set());
10370
11329
  const schluessel = mediaRefs.join(" ");
10371
- useEffect5(() => {
11330
+ useEffect8(() => {
10372
11331
  const bestand = port.imageLibrary;
10373
11332
  if (!bestand?.loadPreview) return void 0;
10374
11333
  const refs = schluessel ? schluessel.split(" ") : [];
@@ -10377,53 +11336,67 @@ function useVorschauen(port, mediaRefs) {
10377
11336
  bestand,
10378
11337
  refs,
10379
11338
  (mediaRef, quelle) => {
10380
- gehalten.current.set(mediaRef, quelle);
10381
- setQuellen(new Map(gehalten.current));
11339
+ if (quelle) gehalten.current.set(mediaRef, quelle);
11340
+ else ohneBild.current.add(mediaRef);
11341
+ setStand({
11342
+ quellen: new Map(gehalten.current),
11343
+ gescheitert: new Set(ohneBild.current)
11344
+ });
10382
11345
  },
10383
- { parallel: 4, hat: (ref) => gehalten.current.has(ref), lauf }
11346
+ {
11347
+ parallel: 4,
11348
+ hat: (ref) => gehalten.current.has(ref) || ohneBild.current.has(ref),
11349
+ lauf,
11350
+ // Ein Fehlschlag ist eine Auskunft, kein Grund weiterzuprobieren:
11351
+ // Die Kachel bekommt einen Platzhalter, das Werk bleibt wählbar.
11352
+ gescheitert: (ref) => {
11353
+ ohneBild.current.add(ref);
11354
+ setStand({
11355
+ quellen: new Map(gehalten.current),
11356
+ gescheitert: new Set(ohneBild.current)
11357
+ });
11358
+ }
11359
+ }
10384
11360
  );
10385
11361
  return () => {
10386
11362
  lauf.abgebrochen = true;
10387
11363
  };
10388
11364
  }, [port, schluessel]);
10389
- return quellen;
11365
+ return stand;
10390
11366
  }
10391
- var Kachel = ({ quelle, alt }) => /* @__PURE__ */ jsx17("span", { className: "szenen-bildkachel", children: quelle ? /* @__PURE__ */ jsx17("img", { src: quelle, alt, loading: "lazy" }) : /* @__PURE__ */ jsx17("span", { className: "szenen-bildkachel__leer", "aria-hidden": "true" }) });
10392
11367
  var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
10393
- const [suche, setSuche] = useState15("");
10394
- const [offenesWerk, setOffenesWerk] = useState15(null);
11368
+ const [suche, setSuche] = useState16("");
11369
+ const [fokus, setFokus] = useState16(null);
11370
+ const browser = useRef4(null);
10395
11371
  const [items] = usePortQuery(
10396
11372
  () => port.imageLibrary.listItems({ search: suche.trim() || void 0, limit: 60 }),
10397
11373
  [port, suche]
10398
11374
  );
10399
- const werk = items.status === "ready" ? items.value.find((i) => i.itemRef === offenesWerk) ?? null : null;
10400
- const sichtbar = useMemo3(() => {
10401
- const refs = werk ? werk.images.map((b) => b.mediaRef) : items.status === "ready" ? items.value.map((i) => i.images[0]?.mediaRef).filter((r) => Boolean(r)) : [];
10402
- return [.../* @__PURE__ */ new Set([...refs, ...gewaehlt.map((b) => b.mediaRef)])];
10403
- }, [items, werk, gewaehlt]);
10404
- const quellen = useVorschauen(port, sichtbar);
11375
+ const werke = items.status === "ready" ? items.value : [];
11376
+ const werk = werke.find((i) => i.itemRef === fokus) ?? null;
11377
+ const deckbilder = useMemo3(
11378
+ () => werke.map((i) => i.images[0]?.mediaRef).filter((r) => Boolean(r)),
11379
+ [werke]
11380
+ );
11381
+ const sichtbareDeckbilder = useSichtbareKacheln(deckbilder, browser);
11382
+ const anzufordern = useMemo3(() => [.../* @__PURE__ */ new Set([
11383
+ ...sichtbareDeckbilder,
11384
+ ...werk ? werk.images.map((b) => b.mediaRef) : [],
11385
+ ...gewaehlt.map((b) => b.mediaRef)
11386
+ ])], [sichtbareDeckbilder, werk, gewaehlt]);
11387
+ const { quellen, gescheitert } = useVorschauen(port, anzufordern);
10405
11388
  const quelleVon = (bild) => bild.thumbUrl || quellen.get(bild.mediaRef) || null;
10406
- return /* @__PURE__ */ jsxs17("div", { className: "szenen-bildwahl", "data-testid": "bildwahl", children: [
10407
- werk ? /* @__PURE__ */ jsxs17("div", { className: "szenen-bildwahl__kopf", children: [
10408
- /* @__PURE__ */ jsx17(
10409
- "button",
10410
- {
10411
- type: "button",
10412
- className: "szenen-bildwahl__zurueck",
10413
- onClick: () => setOffenesWerk(null),
10414
- "data-testid": "bildwahl-zurueck",
10415
- children: "Zurueck zur Auswahl"
10416
- }
10417
- ),
10418
- /* @__PURE__ */ jsxs17("span", { className: "szenen-bildwahl__werktitel", "data-testid": "bildwahl-werktitel", children: [
10419
- werk.title,
10420
- " \xB7 ",
10421
- werk.images.length,
10422
- " Bilder"
10423
- ] })
10424
- ] }) : /* @__PURE__ */ jsxs17("label", { className: "szenen-field", children: [
10425
- /* @__PURE__ */ jsx17("span", { children: "Bild aus dem Bestand" }),
10426
- /* @__PURE__ */ jsx17(
11389
+ const istGewaehlt = (mediaRef) => gewaehlt.some((b) => b.mediaRef === mediaRef);
11390
+ function werkAntippen(item) {
11391
+ const deckbild = item.images[0];
11392
+ if (!deckbild) return;
11393
+ if (item.images.length === 1) onWaehlen(deckbild);
11394
+ else setFokus(item.itemRef === fokus ? null : item.itemRef);
11395
+ }
11396
+ return /* @__PURE__ */ jsxs18("div", { className: "szenen-bildwahl", "data-testid": "bildwahl", children: [
11397
+ /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
11398
+ /* @__PURE__ */ jsx18("span", { children: "Bild aus dem Bestand" }),
11399
+ /* @__PURE__ */ jsx18(
10427
11400
  "input",
10428
11401
  {
10429
11402
  type: "search",
@@ -10437,63 +11410,107 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
10437
11410
  }
10438
11411
  )
10439
11412
  ] }),
10440
- items.status === "loading" && /* @__PURE__ */ jsx17("p", { children: "Bilder werden geladen \u2026" }),
10441
- items.status === "error" && /* @__PURE__ */ jsxs17("p", { className: "szenen-error", role: "alert", children: [
11413
+ items.status === "loading" && /* @__PURE__ */ jsx18("p", { children: "Bilder werden geladen \u2026" }),
11414
+ items.status === "error" && /* @__PURE__ */ jsxs18("p", { className: "szenen-error", role: "alert", children: [
10442
11415
  "Der Bildbestand ist nicht lesbar: ",
10443
11416
  items.message
10444
11417
  ] }),
10445
- items.status === "ready" && items.value.length === 0 && /* @__PURE__ */ jsx17("p", { className: "szenen-empty", "data-testid": "bildwahl-leer", children: "Zu dieser Suche gibt es kein Bild. Ohne Treffer bleibt der Upload." }),
10446
- werk && /* @__PURE__ */ jsx17("ul", { className: "szenen-bildwahl__raster", "data-testid": "bildwahl-galerie", children: werk.images.map((bild, position) => /* @__PURE__ */ jsx17("li", { children: /* @__PURE__ */ jsxs17(
10447
- "button",
11418
+ items.status === "ready" && werke.length === 0 && /* @__PURE__ */ jsx18("p", { className: "szenen-empty", "data-testid": "bildwahl-leer", children: "Zu dieser Suche gibt es kein Bild. Ohne Treffer bleibt der Upload." }),
11419
+ werke.length > 0 && /* @__PURE__ */ jsx18(
11420
+ "div",
10448
11421
  {
10449
- type: "button",
10450
- onClick: () => {
10451
- onWaehlen(bild);
10452
- setOffenesWerk(null);
10453
- },
10454
- "data-testid": `bild-waehlen-${bild.mediaRef}`,
10455
- title: bild.title,
10456
- children: [
10457
- /* @__PURE__ */ jsx17(Kachel, { quelle: quelleVon(bild), alt: bild.title }),
10458
- /* @__PURE__ */ jsxs17("span", { className: "szenen-bildwahl__nummer", children: [
10459
- "#",
10460
- position + 1
10461
- ] })
10462
- ]
11422
+ className: "szenen-bildwahl__browser",
11423
+ ref: browser,
11424
+ "data-testid": "bildwahl-werke",
11425
+ children: /* @__PURE__ */ jsx18("ul", { className: "szenen-bildwahl__raster", children: werke.map((item) => {
11426
+ const deckbild = item.images[0];
11427
+ if (!deckbild) return null;
11428
+ const fokussiert = item.itemRef === fokus;
11429
+ return /* @__PURE__ */ jsx18("li", { "data-media-ref": deckbild.mediaRef, children: /* @__PURE__ */ jsxs18(
11430
+ "button",
11431
+ {
11432
+ type: "button",
11433
+ className: `szenen-bildwahl__karte${fokussiert ? " is-fokus" : ""}`,
11434
+ onClick: () => werkAntippen(item),
11435
+ "aria-pressed": fokussiert,
11436
+ "data-testid": `item-waehlen-${item.itemRef}`,
11437
+ title: item.title,
11438
+ children: [
11439
+ /* @__PURE__ */ jsx18(
11440
+ Kachel,
11441
+ {
11442
+ quelle: quelleVon(deckbild),
11443
+ alt: item.title,
11444
+ ...gescheitert.has(deckbild.mediaRef) ? { leerText: "Vorschau fehlt" } : {}
11445
+ }
11446
+ ),
11447
+ item.images.length > 1 && /* @__PURE__ */ jsxs18(
11448
+ "span",
11449
+ {
11450
+ className: "szenen-bildwahl__anzahl",
11451
+ "data-testid": `item-anzahl-${item.itemRef}`,
11452
+ children: [
11453
+ item.images.length,
11454
+ "x"
11455
+ ]
11456
+ }
11457
+ ),
11458
+ /* @__PURE__ */ jsx18("span", { className: "szenen-bildwahl__kacheltitel", children: item.title })
11459
+ ]
11460
+ }
11461
+ ) }, item.itemRef);
11462
+ }) })
10463
11463
  }
10464
- ) }, bild.mediaRef)) }),
10465
- !werk && items.status === "ready" && items.value.length > 0 && /* @__PURE__ */ jsx17("ul", { className: "szenen-bildwahl__raster", "data-testid": "bildwahl-werke", children: items.value.map((item) => {
10466
- const deckbild = item.images[0];
10467
- if (!deckbild) return null;
10468
- return /* @__PURE__ */ jsx17("li", { children: /* @__PURE__ */ jsxs17(
11464
+ ),
11465
+ werk && /* @__PURE__ */ jsxs18("section", { className: "szenen-bildwahl__inspector", "data-testid": "bildwahl-galerie", children: [
11466
+ /* @__PURE__ */ jsxs18("header", { className: "szenen-bildwahl__inspektorkopf", children: [
11467
+ /* @__PURE__ */ jsxs18("span", { className: "szenen-bildwahl__werktitel", "data-testid": "bildwahl-werktitel", children: [
11468
+ werk.title,
11469
+ " \xB7 ",
11470
+ werk.images.length,
11471
+ " Bilder"
11472
+ ] }),
11473
+ /* @__PURE__ */ jsx18(
11474
+ "button",
11475
+ {
11476
+ type: "button",
11477
+ className: "szenen-bildwahl__zurueck",
11478
+ onClick: () => setFokus(null),
11479
+ "data-testid": "bildwahl-zurueck",
11480
+ children: "Schliessen"
11481
+ }
11482
+ )
11483
+ ] }),
11484
+ /* @__PURE__ */ jsx18("ul", { className: "szenen-bildwahl__streifen", children: werk.images.map((bild, position) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsxs18(
10469
11485
  "button",
10470
11486
  {
10471
11487
  type: "button",
10472
- onClick: () => item.images.length === 1 ? onWaehlen(deckbild) : setOffenesWerk(item.itemRef),
10473
- "data-testid": `item-waehlen-${item.itemRef}`,
10474
- title: item.title,
11488
+ className: `szenen-bildwahl__variante${istGewaehlt(bild.mediaRef) ? " is-gewaehlt" : ""}`,
11489
+ onClick: () => onWaehlen(bild),
11490
+ "aria-pressed": istGewaehlt(bild.mediaRef),
11491
+ "data-testid": `bild-waehlen-${bild.mediaRef}`,
11492
+ title: bild.title,
10475
11493
  children: [
10476
- /* @__PURE__ */ jsx17(Kachel, { quelle: quelleVon(deckbild), alt: item.title }),
10477
- item.images.length > 1 && /* @__PURE__ */ jsxs17(
10478
- "span",
11494
+ /* @__PURE__ */ jsx18(
11495
+ Kachel,
10479
11496
  {
10480
- className: "szenen-bildwahl__anzahl",
10481
- "data-testid": `item-anzahl-${item.itemRef}`,
10482
- children: [
10483
- item.images.length,
10484
- "x"
10485
- ]
11497
+ quelle: quelleVon(bild),
11498
+ alt: bild.title,
11499
+ ...gescheitert.has(bild.mediaRef) ? { leerText: "Vorschau fehlt" } : {}
10486
11500
  }
10487
11501
  ),
10488
- /* @__PURE__ */ jsx17("span", { className: "szenen-bildwahl__titel", children: item.title })
11502
+ /* @__PURE__ */ jsxs18("span", { className: "szenen-bildwahl__nummer", children: [
11503
+ "#",
11504
+ position + 1
11505
+ ] })
10489
11506
  ]
10490
11507
  }
10491
- ) }, item.itemRef);
10492
- }) }),
10493
- gewaehlt.length > 0 && /* @__PURE__ */ jsx17("ul", { className: "szenen-bildwahl__gewaehlt", "data-testid": "bilder-gewaehlt", children: gewaehlt.map((bild) => /* @__PURE__ */ jsxs17("li", { children: [
10494
- /* @__PURE__ */ jsx17(Kachel, { quelle: quelleVon(bild), alt: bild.title }),
10495
- /* @__PURE__ */ jsx17("span", { className: "szenen-bildwahl__titel", children: bild.title }),
10496
- /* @__PURE__ */ jsx17(
11508
+ ) }, bild.mediaRef)) })
11509
+ ] }),
11510
+ gewaehlt.length > 0 && /* @__PURE__ */ jsx18("ul", { className: "szenen-bildwahl__gewaehlt", "data-testid": "bilder-gewaehlt", children: gewaehlt.map((bild) => /* @__PURE__ */ jsxs18("li", { children: [
11511
+ /* @__PURE__ */ jsx18(Kachel, { quelle: quelleVon(bild), alt: bild.title }),
11512
+ /* @__PURE__ */ jsx18("span", { className: "szenen-bildwahl__kacheltitel", children: bild.title }),
11513
+ /* @__PURE__ */ jsx18(
10497
11514
  "button",
10498
11515
  {
10499
11516
  type: "button",
@@ -10512,19 +11529,19 @@ async function digestOf(datei) {
10512
11529
  return [...new Uint8Array(hash)].map((b) => b.toString(16).padStart(2, "0")).join("");
10513
11530
  }
10514
11531
  var DeriveArea = ({ port, contextId }) => {
10515
- const [policyVersionId, setPolicyVersionId] = useState15("");
10516
- const [modus, setModus] = useState15("prompt");
10517
- const [promptText, setPromptText] = useState15("");
10518
- const [dateien, setDateien] = useState15([]);
10519
- const [bestandsbilder, setBestandsbilder] = useState15([]);
10520
- const [laeuft, setLaeuft] = useState15(false);
10521
- const [lauf, setLauf] = useState15(null);
10522
- const [meldung, setMeldung] = useState15(null);
10523
- const [uebernommen, setUebernommen] = useState15({});
10524
- const [titel, setTitel] = useState15({});
10525
- const [referenzen, setReferenzen] = useState15({});
10526
- const [beanstandung, setBeanstandung] = useState15(null);
10527
- const [zusatz, setZusatz] = useState15("");
11532
+ const [policyVersionId, setPolicyVersionId] = useState16("");
11533
+ const [modus, setModus] = useState16("prompt");
11534
+ const [promptText, setPromptText] = useState16("");
11535
+ const [dateien, setDateien] = useState16([]);
11536
+ const [bestandsbilder, setBestandsbilder] = useState16([]);
11537
+ const [laeuft, setLaeuft] = useState16(false);
11538
+ const [lauf, setLauf] = useState16(null);
11539
+ const [meldung, setMeldung] = useState16(null);
11540
+ const [uebernommen, setUebernommen] = useState16({});
11541
+ const [titel, setTitel] = useState16({});
11542
+ const [referenzen, setReferenzen] = useState16({});
11543
+ const [beanstandung, setBeanstandung] = useState16(null);
11544
+ const [zusatz, setZusatz] = useState16("");
10528
11545
  const [regeln] = usePortQuery(
10529
11546
  () => port.derivation.listPolicies(contextId),
10530
11547
  [port, contextId]
@@ -10577,8 +11594,6 @@ var DeriveArea = ({ port, contextId }) => {
10577
11594
  if (ergebnis.kind === "ok") setLauf(ergebnis.value);
10578
11595
  else if (ergebnis.kind === "unsupported") {
10579
11596
  setMeldung(`Dieser Host bietet \u201E${ergebnis.capability}" nicht an.`);
10580
- } else if (ergebnis.kind === "rejected") {
10581
- setMeldung(ergebnis.errors.map((e) => e.message).join("; "));
10582
11597
  } else {
10583
11598
  setMeldung(ergebnis.message);
10584
11599
  }
@@ -10605,12 +11620,12 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10605
11620
  const text = beanstandung ?? vorgabeBeanstandung(satz);
10606
11621
  const bilderFehlen = satz.input.images.some((bild) => bild.kind !== "library");
10607
11622
  const bereit = Boolean(text.trim()) && !bilderFehlen && !laeuft;
10608
- return /* @__PURE__ */ jsxs17("div", { className: "szenen-folgelauf", "data-testid": "folgelauf", children: [
10609
- /* @__PURE__ */ jsx17("h4", { children: "Korrektur- oder Erg\xE4nzungslauf" }),
10610
- /* @__PURE__ */ jsx17("p", { className: "szenen-area__lead", children: satz.status === "failed" ? "Das Modell bekommt seine Antwort und die Beanstandung noch einmal vorgelegt." : "Das Ergebnis steht. Wenn etwas offen blieb, kann das Modell nachbessern." }),
10611
- /* @__PURE__ */ jsxs17("label", { className: "szenen-field", children: [
10612
- /* @__PURE__ */ jsx17("span", { children: "Beanstandung" }),
10613
- /* @__PURE__ */ jsx17(
11623
+ return /* @__PURE__ */ jsxs18("div", { className: "szenen-folgelauf", "data-testid": "folgelauf", children: [
11624
+ /* @__PURE__ */ jsx18("h4", { children: "Korrektur- oder Erg\xE4nzungslauf" }),
11625
+ /* @__PURE__ */ jsx18("p", { className: "szenen-area__lead", children: satz.status === "failed" ? "Das Modell bekommt seine Antwort und die Beanstandung noch einmal vorgelegt." : "Das Ergebnis steht. Wenn etwas offen blieb, kann das Modell nachbessern." }),
11626
+ /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
11627
+ /* @__PURE__ */ jsx18("span", { children: "Beanstandung" }),
11628
+ /* @__PURE__ */ jsx18(
10614
11629
  "textarea",
10615
11630
  {
10616
11631
  rows: 4,
@@ -10620,9 +11635,9 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10620
11635
  }
10621
11636
  )
10622
11637
  ] }),
10623
- /* @__PURE__ */ jsxs17("label", { className: "szenen-field", children: [
10624
- /* @__PURE__ */ jsx17("span", { children: "Zus\xE4tzliche Anweisung (optional)" }),
10625
- /* @__PURE__ */ jsx17(
11638
+ /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
11639
+ /* @__PURE__ */ jsx18("span", { children: "Zus\xE4tzliche Anweisung (optional)" }),
11640
+ /* @__PURE__ */ jsx18(
10626
11641
  "textarea",
10627
11642
  {
10628
11643
  rows: 2,
@@ -10633,8 +11648,8 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10633
11648
  }
10634
11649
  )
10635
11650
  ] }),
10636
- bilderFehlen && /* @__PURE__ */ jsx17("p", { className: "szenen-error", "data-testid": "folgelauf-ohne-bild", children: "Die Bilder dieses Laufs wurden nicht im Bestand abgelegt \u2014 er ist \xE4lter als diese M\xF6glichkeit. Ein Folgelauf ohne sie k\xF6nnte ein fehlendes Pflichtfeld nur erfinden. Starten Sie einen neuen Lauf mit dem Referenzbild; dessen Bilder bleiben dann erhalten." }),
10637
- /* @__PURE__ */ jsx17(
11651
+ bilderFehlen && /* @__PURE__ */ jsx18("p", { className: "szenen-error", "data-testid": "folgelauf-ohne-bild", children: "Die Bilder dieses Laufs wurden nicht im Bestand abgelegt \u2014 er ist \xE4lter als diese M\xF6glichkeit. Ein Folgelauf ohne sie k\xF6nnte ein fehlendes Pflichtfeld nur erfinden. Starten Sie einen neuen Lauf mit dem Referenzbild; dessen Bilder bleiben dann erhalten." }),
11652
+ /* @__PURE__ */ jsx18(
10638
11653
  "button",
10639
11654
  {
10640
11655
  type: "button",
@@ -10668,27 +11683,25 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10668
11683
  });
10669
11684
  if (ergebnis.kind === "ok") {
10670
11685
  setUebernommen((v) => ({ ...v, [type]: ergebnis.value.elementId }));
10671
- } else if (ergebnis.kind === "rejected") {
10672
- setMeldung(ergebnis.errors.map((e) => e.message).join("; "));
10673
11686
  } else if (ergebnis.kind === "unsupported") {
10674
11687
  setMeldung(`Dieser Host bietet \u201E${ergebnis.capability}" nicht an.`);
10675
11688
  } else {
10676
11689
  setMeldung(ergebnis.message);
10677
11690
  }
10678
11691
  }
10679
- return /* @__PURE__ */ jsxs17("div", { className: "szenen-derive", "data-testid": "bereich-rekonstruktion", children: [
10680
- /* @__PURE__ */ jsx17("p", { className: "szenen-area__lead", children: "Aus einem Referenzbild, einem Prompt oder beidem einen Szenenentwurf vorschlagen lassen. Der Vorschlag wird nie ver\xF6ffentlicht \u2014 er wird ein Entwurf, den Sie pr\xFCfen und \xE4ndern." }),
10681
- regeln.status === "loading" && /* @__PURE__ */ jsx17("p", { children: "Regeln werden geladen \u2026" }),
10682
- regeln.status === "error" && /* @__PURE__ */ jsxs17("p", { className: "szenen-error", role: "alert", children: [
11692
+ return /* @__PURE__ */ jsxs18("div", { className: "szenen-derive", "data-testid": "bereich-rekonstruktion", children: [
11693
+ /* @__PURE__ */ jsx18("p", { className: "szenen-area__lead", children: "Aus einem Referenzbild, einem Prompt oder beidem einen Szenenentwurf vorschlagen lassen. Der Vorschlag wird nie ver\xF6ffentlicht \u2014 er wird ein Entwurf, den Sie pr\xFCfen und \xE4ndern." }),
11694
+ regeln.status === "loading" && /* @__PURE__ */ jsx18("p", { children: "Regeln werden geladen \u2026" }),
11695
+ regeln.status === "error" && /* @__PURE__ */ jsxs18("p", { className: "szenen-error", role: "alert", children: [
10683
11696
  "Die Regeln konnten nicht gelesen werden: ",
10684
11697
  regeln.message
10685
11698
  ] }),
10686
- regeln.status === "ready" && regeln.value.length === 0 && /* @__PURE__ */ jsxs17("p", { className: "szenen-empty", children: [
11699
+ regeln.status === "ready" && regeln.value.length === 0 && /* @__PURE__ */ jsxs18("p", { className: "szenen-empty", children: [
10687
11700
  "In diesem Kontext ist keine Rekonstruktionsregel (",
10688
- /* @__PURE__ */ jsx17("code", { children: "scene_derivation_policy" }),
11701
+ /* @__PURE__ */ jsx18("code", { children: "scene_derivation_policy" }),
10689
11702
  ') ver\xF6ffentlicht. Ohne sie ist kein Lauf reproduzierbar \u2014 legen Sie hier eine unter \u201E1 \xB7 Bausteine" an, oder wechseln Sie in den Kontext, in dem Ihre Regel liegt. Regeln aus anderen Kontexten stehen hier bewusst nicht zur Auswahl.'
10690
11703
  ] }),
10691
- regeln.status === "ready" && regeln.value.length > 0 && /* @__PURE__ */ jsxs17(
11704
+ regeln.status === "ready" && regeln.value.length > 0 && /* @__PURE__ */ jsxs18(
10692
11705
  "form",
10693
11706
  {
10694
11707
  className: "szenen-form",
@@ -10697,17 +11710,17 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10697
11710
  void starten();
10698
11711
  },
10699
11712
  children: [
10700
- /* @__PURE__ */ jsxs17("label", { className: "szenen-field", children: [
10701
- /* @__PURE__ */ jsx17("span", { children: "Regel" }),
10702
- /* @__PURE__ */ jsxs17(
11713
+ /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
11714
+ /* @__PURE__ */ jsx18("span", { children: "Regel" }),
11715
+ /* @__PURE__ */ jsxs18(
10703
11716
  "select",
10704
11717
  {
10705
11718
  value: policyVersionId,
10706
11719
  onChange: (e) => setPolicyVersionId(e.target.value),
10707
11720
  "data-testid": "regel-auswahl",
10708
11721
  children: [
10709
- /* @__PURE__ */ jsx17("option", { value: "", children: "\u2014 bitte w\xE4hlen \u2014" }),
10710
- regeln.value.map((regel) => /* @__PURE__ */ jsxs17("option", { value: regel.versionId, children: [
11722
+ /* @__PURE__ */ jsx18("option", { value: "", children: "\u2014 bitte w\xE4hlen \u2014" }),
11723
+ regeln.value.map((regel) => /* @__PURE__ */ jsxs18("option", { value: regel.versionId, children: [
10711
11724
  regel.title,
10712
11725
  " (",
10713
11726
  regel.produces.join(", "),
@@ -10717,21 +11730,21 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10717
11730
  }
10718
11731
  )
10719
11732
  ] }),
10720
- /* @__PURE__ */ jsxs17("label", { className: "szenen-field", children: [
10721
- /* @__PURE__ */ jsx17("span", { children: "Eingang" }),
10722
- /* @__PURE__ */ jsx17(
11733
+ /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
11734
+ /* @__PURE__ */ jsx18("span", { children: "Eingang" }),
11735
+ /* @__PURE__ */ jsx18(
10723
11736
  "select",
10724
11737
  {
10725
11738
  value: modus,
10726
11739
  onChange: (e) => setModus(e.target.value),
10727
11740
  "data-testid": "modus-auswahl",
10728
- children: (gewaehlt ? gewaehlt.inputModes : ["prompt", "image", "image_prompt"]).map((m) => /* @__PURE__ */ jsx17("option", { value: m, children: MODUS_TEXT[m] }, m))
11741
+ children: (gewaehlt ? gewaehlt.inputModes : ["prompt", "image", "image_prompt"]).map((m) => /* @__PURE__ */ jsx18("option", { value: m, children: MODUS_TEXT[m] }, m))
10729
11742
  }
10730
11743
  )
10731
11744
  ] }),
10732
- modus !== "image" && /* @__PURE__ */ jsxs17("label", { className: "szenen-field", children: [
10733
- /* @__PURE__ */ jsx17("span", { children: "Referenzprompt" }),
10734
- /* @__PURE__ */ jsx17(
11745
+ modus !== "image" && /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
11746
+ /* @__PURE__ */ jsx18("span", { children: "Referenzprompt" }),
11747
+ /* @__PURE__ */ jsx18(
10735
11748
  "textarea",
10736
11749
  {
10737
11750
  value: promptText,
@@ -10741,8 +11754,8 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10741
11754
  }
10742
11755
  )
10743
11756
  ] }),
10744
- modus !== "prompt" && /* @__PURE__ */ jsxs17(Fragment7, { children: [
10745
- port.imageLibrary && /* @__PURE__ */ jsx17(
11757
+ modus !== "prompt" && /* @__PURE__ */ jsxs18(Fragment8, { children: [
11758
+ port.imageLibrary && /* @__PURE__ */ jsx18(
10746
11759
  BildWaehler,
10747
11760
  {
10748
11761
  port,
@@ -10751,9 +11764,9 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10751
11764
  onEntfernen: (ref) => setBestandsbilder((v) => v.filter((b) => b.mediaRef !== ref))
10752
11765
  }
10753
11766
  ),
10754
- /* @__PURE__ */ jsxs17("label", { className: "szenen-field", children: [
10755
- /* @__PURE__ */ jsx17("span", { children: port.imageLibrary ? "Oder hochladen" : "Referenzbild" }),
10756
- /* @__PURE__ */ jsx17(
11767
+ /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
11768
+ /* @__PURE__ */ jsx18("span", { children: port.imageLibrary ? "Oder hochladen" : "Referenzbild" }),
11769
+ /* @__PURE__ */ jsx18(
10757
11770
  "input",
10758
11771
  {
10759
11772
  type: "file",
@@ -10763,40 +11776,40 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10763
11776
  "data-testid": "bild-eingabe"
10764
11777
  }
10765
11778
  ),
10766
- port.imageLibrary && /* @__PURE__ */ jsx17("small", { "data-testid": "upload-hinweis", children: "Hochgeladene Bilder werden im Bestand abgelegt \u2014 nur so ist sp\xE4ter ein Folgelauf damit m\xF6glich." })
11779
+ port.imageLibrary && /* @__PURE__ */ jsx18("small", { "data-testid": "upload-hinweis", children: "Hochgeladene Bilder werden im Bestand abgelegt \u2014 nur so ist sp\xE4ter ein Folgelauf damit m\xF6glich." })
10767
11780
  ] })
10768
11781
  ] }),
10769
- /* @__PURE__ */ jsx17("button", { type: "submit", disabled: !gewaehlt || laeuft, "data-testid": "lauf-starten", children: laeuft ? "Rekonstruiert \u2026" : "Rekonstruieren" })
11782
+ /* @__PURE__ */ jsx18("button", { type: "submit", disabled: !gewaehlt || laeuft, "data-testid": "lauf-starten", children: laeuft ? "Rekonstruiert \u2026" : "Rekonstruieren" })
10770
11783
  ]
10771
11784
  }
10772
11785
  ),
10773
- meldung && /* @__PURE__ */ jsx17("p", { className: "szenen-error", role: "alert", "data-testid": "derive-meldung", children: meldung }),
10774
- lauf && lauf.status === "failed" && /* @__PURE__ */ jsxs17("section", { className: "szenen-run szenen-run--failed", "data-testid": "lauf-fehler", children: [
10775
- /* @__PURE__ */ jsx17("h3", { children: "Der Lauf ist gescheitert" }),
10776
- /* @__PURE__ */ jsxs17("p", { children: [
10777
- /* @__PURE__ */ jsx17("strong", { children: lauf.failure?.class }),
11786
+ meldung && /* @__PURE__ */ jsx18("p", { className: "szenen-error", role: "alert", "data-testid": "derive-meldung", children: meldung }),
11787
+ lauf && lauf.status === "failed" && /* @__PURE__ */ jsxs18("section", { className: "szenen-run szenen-run--failed", "data-testid": "lauf-fehler", children: [
11788
+ /* @__PURE__ */ jsx18("h3", { children: "Der Lauf ist gescheitert" }),
11789
+ /* @__PURE__ */ jsxs18("p", { children: [
11790
+ /* @__PURE__ */ jsx18("strong", { children: lauf.failure?.class }),
10778
11791
  " \u2014 ",
10779
11792
  lauf.failure?.message
10780
11793
  ] }),
10781
- lauf.failure?.diagnostics && lauf.failure.diagnostics.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "szenen-diagnose", "data-testid": "lauf-diagnosen", children: [
10782
- /* @__PURE__ */ jsx17("h4", { children: "Befunde" }),
10783
- /* @__PURE__ */ jsx17(Diagnosen, { befunde: lauf.failure.diagnostics, testId: "lauf-befunde" })
11794
+ lauf.failure?.diagnostics && lauf.failure.diagnostics.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose", "data-testid": "lauf-diagnosen", children: [
11795
+ /* @__PURE__ */ jsx18("h4", { children: "Befunde" }),
11796
+ /* @__PURE__ */ jsx18(Diagnosen, { befunde: lauf.failure.diagnostics, testId: "lauf-befunde" })
10784
11797
  ] }),
10785
- /* @__PURE__ */ jsx17(Herkunft, { lauf }),
10786
- /* @__PURE__ */ jsx17(Widerspruch, { lauf }),
10787
- /* @__PURE__ */ jsx17(Belege, { lauf }),
10788
- /* @__PURE__ */ jsx17(RecoveryPanel, { port, lauf }),
11798
+ /* @__PURE__ */ jsx18(Herkunft, { lauf }),
11799
+ /* @__PURE__ */ jsx18(Widerspruch, { lauf }),
11800
+ /* @__PURE__ */ jsx18(Belege, { lauf }),
11801
+ /* @__PURE__ */ jsx18(RecoveryPanel, { port, lauf }),
10789
11802
  folgeblock(lauf)
10790
11803
  ] }),
10791
- lauf && lauf.status === "succeeded" && /* @__PURE__ */ jsxs17("section", { className: "szenen-run", "data-testid": "lauf-ergebnis", children: [
10792
- /* @__PURE__ */ jsx17("h3", { children: "Vorschlag" }),
10793
- /* @__PURE__ */ jsx17(Herkunft, { lauf }),
10794
- /* @__PURE__ */ jsx17(Widerspruch, { lauf }),
10795
- /* @__PURE__ */ jsx17("p", { className: "szenen-run__feedback", children: lauf.feedback }),
10796
- lauf.conflicts.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "szenen-diagnose szenen-diagnose--konflikt", "data-testid": "konflikte", children: [
10797
- /* @__PURE__ */ jsx17("h4", { children: "Widerspr\xFCche zwischen Bild und Prompt" }),
10798
- /* @__PURE__ */ jsx17("ul", { children: lauf.conflicts.map((k, i) => /* @__PURE__ */ jsxs17("li", { children: [
10799
- /* @__PURE__ */ jsx17("code", { children: k.field }),
11804
+ lauf && lauf.status === "succeeded" && /* @__PURE__ */ jsxs18("section", { className: "szenen-run", "data-testid": "lauf-ergebnis", children: [
11805
+ /* @__PURE__ */ jsx18("h3", { children: "Vorschlag" }),
11806
+ /* @__PURE__ */ jsx18(Herkunft, { lauf }),
11807
+ /* @__PURE__ */ jsx18(Widerspruch, { lauf }),
11808
+ /* @__PURE__ */ jsx18("p", { className: "szenen-run__feedback", children: lauf.feedback }),
11809
+ lauf.conflicts.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose szenen-diagnose--konflikt", "data-testid": "konflikte", children: [
11810
+ /* @__PURE__ */ jsx18("h4", { children: "Widerspr\xFCche zwischen Bild und Prompt" }),
11811
+ /* @__PURE__ */ jsx18("ul", { children: lauf.conflicts.map((k, i) => /* @__PURE__ */ jsxs18("li", { children: [
11812
+ /* @__PURE__ */ jsx18("code", { children: k.field }),
10800
11813
  ": Bild sagt \u201E",
10801
11814
  k.from_image,
10802
11815
  '", Prompt sagt \u201E',
@@ -10804,31 +11817,31 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10804
11817
  '". Nichts davon wurde \xFCbernommen.'
10805
11818
  ] }, i)) })
10806
11819
  ] }),
10807
- lauf.not_derivable.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "szenen-diagnose", "data-testid": "nicht-ableitbar", children: [
10808
- /* @__PURE__ */ jsx17("h4", { children: "Nicht ableitbar" }),
10809
- /* @__PURE__ */ jsx17("ul", { children: lauf.not_derivable.map((n, i) => /* @__PURE__ */ jsxs17("li", { children: [
10810
- /* @__PURE__ */ jsx17("code", { children: n.field }),
11820
+ lauf.not_derivable.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose", "data-testid": "nicht-ableitbar", children: [
11821
+ /* @__PURE__ */ jsx18("h4", { children: "Nicht ableitbar" }),
11822
+ /* @__PURE__ */ jsx18("ul", { children: lauf.not_derivable.map((n, i) => /* @__PURE__ */ jsxs18("li", { children: [
11823
+ /* @__PURE__ */ jsx18("code", { children: n.field }),
10811
11824
  ": ",
10812
11825
  n.reason
10813
11826
  ] }, i)) })
10814
11827
  ] }),
10815
- lauf.assumptions.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "szenen-diagnose", "data-testid": "annahmen", children: [
10816
- /* @__PURE__ */ jsx17("h4", { children: "Erschlossen, nicht belegt" }),
10817
- /* @__PURE__ */ jsx17("ul", { children: lauf.assumptions.map((a, i) => /* @__PURE__ */ jsx17("li", { children: a }, i)) })
11828
+ lauf.assumptions.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose", "data-testid": "annahmen", children: [
11829
+ /* @__PURE__ */ jsx18("h4", { children: "Erschlossen, nicht belegt" }),
11830
+ /* @__PURE__ */ jsx18("ul", { children: lauf.assumptions.map((a, i) => /* @__PURE__ */ jsx18("li", { children: a }, i)) })
10818
11831
  ] }),
10819
11832
  lauf.proposals.map((vorschlag) => {
10820
11833
  const bezug = REFERENCE_FIELD[vorschlag.type];
10821
11834
  const fertig = uebernommen[vorschlag.type];
10822
- return /* @__PURE__ */ jsxs17(
11835
+ return /* @__PURE__ */ jsxs18(
10823
11836
  "article",
10824
11837
  {
10825
11838
  className: "szenen-proposal",
10826
11839
  "data-testid": `vorschlag-${vorschlag.type}`,
10827
11840
  children: [
10828
- /* @__PURE__ */ jsx17("h4", { children: vorschlag.type }),
10829
- !fertig && /* @__PURE__ */ jsxs17("label", { className: "szenen-field", children: [
10830
- /* @__PURE__ */ jsx17("span", { children: "Titel" }),
10831
- /* @__PURE__ */ jsx17(
11841
+ /* @__PURE__ */ jsx18("h4", { children: vorschlag.type }),
11842
+ !fertig && /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
11843
+ /* @__PURE__ */ jsx18("span", { children: "Titel" }),
11844
+ /* @__PURE__ */ jsx18(
10832
11845
  "input",
10833
11846
  {
10834
11847
  type: "text",
@@ -10842,9 +11855,9 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10842
11855
  }
10843
11856
  )
10844
11857
  ] }),
10845
- /* @__PURE__ */ jsx17("pre", { className: "szenen-proposal__payload", children: JSON.stringify(vorschlag.payload, null, 2) }),
10846
- bezug && !fertig && /* @__PURE__ */ jsxs17(Fragment7, { children: [
10847
- /* @__PURE__ */ jsx17(
11858
+ /* @__PURE__ */ jsx18("pre", { className: "szenen-proposal__payload", children: JSON.stringify(vorschlag.payload, null, 2) }),
11859
+ bezug && !fertig && /* @__PURE__ */ jsxs18(Fragment8, { children: [
11860
+ /* @__PURE__ */ jsx18(
10848
11861
  ReferencePicker,
10849
11862
  {
10850
11863
  port,
@@ -10858,30 +11871,30 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10858
11871
  }))
10859
11872
  }
10860
11873
  ),
10861
- referenzen[vorschlag.type] ? /* @__PURE__ */ jsxs17("p", { "data-testid": `referenz-gewaehlt-${vorschlag.type}`, children: [
11874
+ referenzen[vorschlag.type] ? /* @__PURE__ */ jsxs18("p", { "data-testid": `referenz-gewaehlt-${vorschlag.type}`, children: [
10862
11875
  "Zeigt auf Version ",
10863
- /* @__PURE__ */ jsx17("code", { children: referenzen[vorschlag.type] }),
11876
+ /* @__PURE__ */ jsx18("code", { children: referenzen[vorschlag.type] }),
10864
11877
  "."
10865
11878
  ] }) : (
10866
11879
  /* Der Grund steht **vor** der Handlung. Den Nutzer erst
10867
11880
  auf einen Knopf drücken zu lassen, um ihm dann eine
10868
11881
  Ablehnung zu zeigen, ist keine Auskunft. */
10869
- /* @__PURE__ */ jsxs17("p", { "data-testid": `referenz-fehlt-${vorschlag.type}`, children: [
11882
+ /* @__PURE__ */ jsxs18("p", { "data-testid": `referenz-fehlt-${vorschlag.type}`, children: [
10870
11883
  "Diese ",
10871
- /* @__PURE__ */ jsx17("strong", { children: "Einzel\xFCbernahme" }),
11884
+ /* @__PURE__ */ jsx18("strong", { children: "Einzel\xFCbernahme" }),
10872
11885
  " braucht eine ver\xF6ffentlichte ",
10873
11886
  bezug.refersTo,
10874
11887
  "-Version, auf die der Entwurf zeigt (D-03) \u2014 sie ist der Weg in einen bestehenden, l\xE4ngst ver\xF6ffentlichten Zusammenhang. Wollen Sie aus diesem Lauf erst einmal einen Prompt ausprobieren, nehmen Sie unten die ",
10875
- /* @__PURE__ */ jsx17("strong", { children: "Draft-Kette" }),
11888
+ /* @__PURE__ */ jsx18("strong", { children: "Draft-Kette" }),
10876
11889
  ": Dort entstehen Szene, Aufbau und Shot zusammenh\xE4ngend, und es muss nichts ver\xF6ffentlicht werden."
10877
11890
  ] })
10878
11891
  )
10879
11892
  ] }),
10880
- fertig ? /* @__PURE__ */ jsxs17("p", { className: "szenen-proposal__done", children: [
11893
+ fertig ? /* @__PURE__ */ jsxs18("p", { className: "szenen-proposal__done", children: [
10881
11894
  "Als Entwurf \xFCbernommen: ",
10882
- /* @__PURE__ */ jsx17("code", { children: fertig }),
11895
+ /* @__PURE__ */ jsx18("code", { children: fertig }),
10883
11896
  ". Er ist noch nicht ver\xF6ffentlicht."
10884
- ] }) : /* @__PURE__ */ jsx17(
11897
+ ] }) : /* @__PURE__ */ jsx18(
10885
11898
  "button",
10886
11899
  {
10887
11900
  type: "button",
@@ -10896,15 +11909,15 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
10896
11909
  vorschlag.type
10897
11910
  );
10898
11911
  }),
10899
- /* @__PURE__ */ jsx17(ChainActions, { port, runId: lauf.run_id }),
10900
- /* @__PURE__ */ jsx17(Belege, { lauf }),
11912
+ /* @__PURE__ */ jsx18(ChainActions, { port, runId: lauf.run_id }),
11913
+ /* @__PURE__ */ jsx18(Belege, { lauf }),
10901
11914
  folgeblock(lauf)
10902
11915
  ] })
10903
11916
  ] });
10904
11917
  };
10905
11918
 
10906
11919
  // src/features/szenen/SzenenView.tsx
10907
- import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
11920
+ import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
10908
11921
  var SzenenView = ({
10909
11922
  port,
10910
11923
  contextId = null,
@@ -10913,22 +11926,22 @@ var SzenenView = ({
10913
11926
  }) => {
10914
11927
  const bereiche = useMemo4(() => areasFor(port), [port]);
10915
11928
  const faehig = useMemo4(() => capabilitiesOf(port), [port]);
10916
- const [aktiv, setAktiv] = useState16(() => resolveArea(port, initialArea));
11929
+ const [aktiv, setAktiv] = useState17(() => resolveArea(port, initialArea));
10917
11930
  const wechsle = (id) => {
10918
11931
  setAktiv(id);
10919
11932
  onAreaChange?.(id);
10920
11933
  };
10921
11934
  const aktuellerBereich = bereiche.find((b) => b.id === aktiv) ?? bereiche[0];
10922
- return /* @__PURE__ */ jsxs18("div", { className: "szenen-view", "data-testid": "szenen-view", children: [
10923
- /* @__PURE__ */ jsxs18("header", { className: "szenen-view__intro", children: [
10924
- /* @__PURE__ */ jsxs18("div", { children: [
10925
- /* @__PURE__ */ jsx18("p", { className: "szenen-view__eyebrow", children: "Vom Motiv zum Bild" }),
10926
- /* @__PURE__ */ jsx18("h2", { children: "Bildprompt aus einer Szene" }),
10927
- /* @__PURE__ */ jsx18("p", { children: "Bausteine w\xE4hlen, Szene und Bildaufbau festlegen und daraus einen wiederholbaren Prompt erzeugen." })
11935
+ return /* @__PURE__ */ jsxs19("div", { className: "szenen-view", "data-testid": "szenen-view", children: [
11936
+ /* @__PURE__ */ jsxs19("header", { className: "szenen-view__intro", children: [
11937
+ /* @__PURE__ */ jsxs19("div", { children: [
11938
+ /* @__PURE__ */ jsx19("p", { className: "szenen-view__eyebrow", children: "Vom Motiv zum Bild" }),
11939
+ /* @__PURE__ */ jsx19("h2", { children: "Bildprompt aus einer Szene" }),
11940
+ /* @__PURE__ */ jsx19("p", { children: "Bausteine w\xE4hlen, Szene und Bildaufbau festlegen und daraus einen wiederholbaren Prompt erzeugen." })
10928
11941
  ] }),
10929
- /* @__PURE__ */ jsx18("span", { className: "szenen-view__step", children: aktuellerBereich.title })
11942
+ /* @__PURE__ */ jsx19("span", { className: "szenen-view__step", children: aktuellerBereich.title })
10930
11943
  ] }),
10931
- /* @__PURE__ */ jsx18("nav", { className: "szenen-view__nav", "aria-label": "Szenen-Bereiche", children: bereiche.map((bereich) => /* @__PURE__ */ jsx18(
11944
+ /* @__PURE__ */ jsx19("nav", { className: "szenen-view__nav", "aria-label": "Szenen-Bereiche", children: bereiche.map((bereich) => /* @__PURE__ */ jsx19(
10932
11945
  "button",
10933
11946
  {
10934
11947
  type: "button",
@@ -10942,9 +11955,9 @@ var SzenenView = ({
10942
11955
  },
10943
11956
  bereich.id
10944
11957
  )) }),
10945
- /* @__PURE__ */ jsxs18("section", { className: "szenen-view__area", "aria-label": aktuellerBereich.title, children: [
10946
- aktiv === "derive" && port.derivation && /* @__PURE__ */ jsx18(DeriveArea, { port, contextId }),
10947
- aktiv === "elements" && /* @__PURE__ */ jsx18(
11958
+ /* @__PURE__ */ jsxs19("section", { className: "szenen-view__area", "aria-label": aktuellerBereich.title, children: [
11959
+ aktiv === "derive" && port.derivation && /* @__PURE__ */ jsx19(DeriveArea, { port, contextId }),
11960
+ aktiv === "elements" && /* @__PURE__ */ jsx19(
10948
11961
  ElementsArea,
10949
11962
  {
10950
11963
  port,
@@ -10954,15 +11967,15 @@ var SzenenView = ({
10954
11967
  listTitle: "Bausteine"
10955
11968
  }
10956
11969
  ),
10957
- aktiv === "scene" && /* @__PURE__ */ jsx18(SceneArea, { port, contextId }),
10958
- aktiv === "setup" && /* @__PURE__ */ jsx18(SetupArea, { port, contextId }),
10959
- aktiv === "shot" && /* @__PURE__ */ jsx18(ShotArea, { port, contextId }),
10960
- aktiv === "media" && port.media && /* @__PURE__ */ jsx18(MediaArea, { port, contextId })
11970
+ aktiv === "scene" && /* @__PURE__ */ jsx19(SceneArea, { port, contextId }),
11971
+ aktiv === "setup" && /* @__PURE__ */ jsx19(SetupArea, { port, contextId }),
11972
+ aktiv === "shot" && /* @__PURE__ */ jsx19(ShotArea, { port, contextId }),
11973
+ aktiv === "media" && port.media && /* @__PURE__ */ jsx19(MediaArea, { port, contextId })
10961
11974
  ] }),
10962
- (!faehig.saveRunAsItem || !faehig.media) && /* @__PURE__ */ jsxs18("details", { className: "szenen-view__host-notes", children: [
10963
- /* @__PURE__ */ jsx18("summary", { children: "Funktionen dieses Hosts" }),
10964
- !faehig.saveRunAsItem && /* @__PURE__ */ jsx18("p", { className: "szenen-view__capability-note", "data-testid": "hinweis-kein-item", children: "Runden k\xF6nnen hier nicht als Library-Item gespeichert werden." }),
10965
- !faehig.media && /* @__PURE__ */ jsx18("p", { className: "szenen-view__capability-note", "data-testid": "hinweis-keine-medien", children: "Referenzmedien werden in diesem Host nicht verwaltet." })
11975
+ (!faehig.saveRunAsItem || !faehig.media) && /* @__PURE__ */ jsxs19("details", { className: "szenen-view__host-notes", children: [
11976
+ /* @__PURE__ */ jsx19("summary", { children: "Funktionen dieses Hosts" }),
11977
+ !faehig.saveRunAsItem && /* @__PURE__ */ jsx19("p", { className: "szenen-view__capability-note", "data-testid": "hinweis-kein-item", children: "Runden k\xF6nnen hier nicht als Library-Item gespeichert werden." }),
11978
+ !faehig.media && /* @__PURE__ */ jsx19("p", { className: "szenen-view__capability-note", "data-testid": "hinweis-keine-medien", children: "Referenzmedien werden in diesem Host nicht verwaltet." })
10966
11979
  ] })
10967
11980
  ] });
10968
11981
  };
@@ -14435,11 +15448,14 @@ function findImageGenerationOrder(events, batchId) {
14435
15448
 
14436
15449
  // src/lib/szenen/imageBatchStore.ts
14437
15450
  var istText6 = (wert) => typeof wert === "string" && wert.trim().length > 0;
14438
- function alsBilder(rohe) {
15451
+ function alsBilder(rohe, generationBatchId) {
14439
15452
  if (!Array.isArray(rohe)) return [];
14440
15453
  return rohe.filter((b) => !!b && typeof b === "object").filter((b) => istText6(b.media_ref) && typeof b.position === "number").map((b) => ({
14441
15454
  media_ref: b.media_ref,
14442
15455
  position: b.position,
15456
+ // Welcher Provideraufruf dieses Bild geliefert hat (§8) — aus dem
15457
+ // Ereignis, in dem es steht, nicht aus seiner Position abgeleitet.
15458
+ generation_batch_id: generationBatchId,
14443
15459
  ...istText6(b.asset_id) ? { asset_id: b.asset_id } : {},
14444
15460
  // Der bestätigte MIME-Typ (Review 2026-08-18 §5 P2) muss durch das
14445
15461
  // Rücklesen hindurch: Genau hier braucht ihn der Lesepfad, um den
@@ -14452,6 +15468,11 @@ function alsBilder(rohe) {
14452
15468
  height: b.height ?? null
14453
15469
  }));
14454
15470
  }
15471
+ function gesamtHerkunft(origins) {
15472
+ const vertreten = new Set(origins.map((o) => o.source_kind));
15473
+ if (vertreten.size === 1) return [...vertreten][0];
15474
+ return "mixed";
15475
+ }
14455
15476
  function collectImageBatches(events) {
14456
15477
  const byItemId = /* @__PURE__ */ new Map();
14457
15478
  for (const event of events) {
@@ -14461,21 +15482,29 @@ function collectImageBatches(events) {
14461
15482
  if (payload.source_kind !== "generated_in_app" && payload.source_kind !== "external_import") continue;
14462
15483
  const bestehend = byItemId.get(payload.item_id);
14463
15484
  if (bestehend?.generation_batch_ids.includes(payload.generation_batch_id)) continue;
14464
- const bilder = alsBilder(payload.images);
15485
+ const bilder = alsBilder(payload.images, payload.generation_batch_id);
15486
+ const herkunft = {
15487
+ generation_batch_id: payload.generation_batch_id,
15488
+ source_kind: payload.source_kind
15489
+ };
14465
15490
  if (!bestehend) {
14466
15491
  byItemId.set(payload.item_id, {
14467
15492
  item_id: payload.item_id,
14468
15493
  prompt_run_id: payload.prompt_run_id,
14469
15494
  generation_batch_ids: [payload.generation_batch_id],
14470
15495
  source_kind: payload.source_kind,
15496
+ origins: [herkunft],
14471
15497
  title: istText6(payload.title) ? payload.title : `Batch aus Lauf ${payload.prompt_run_id}`,
14472
15498
  images: bilder
14473
15499
  });
14474
15500
  continue;
14475
15501
  }
15502
+ const origins = [...bestehend.origins, herkunft];
14476
15503
  byItemId.set(payload.item_id, {
14477
15504
  ...bestehend,
14478
15505
  generation_batch_ids: [...bestehend.generation_batch_ids, payload.generation_batch_id],
15506
+ origins,
15507
+ source_kind: gesamtHerkunft(origins),
14479
15508
  images: [...bestehend.images, ...bilder]
14480
15509
  });
14481
15510
  }
@@ -14594,13 +15623,21 @@ async function legeBatchAb(options, input) {
14594
15623
  `Die Batch-Metadaten fuer ${input.generationBatchId} konnten nicht protokolliert werden, obwohl die Bilder bereits im Bestand liegen: ${error instanceof Error ? error.message : String(error)}`
14595
15624
  );
14596
15625
  }
15626
+ const origins = [
15627
+ ...bestehend?.origins ?? [],
15628
+ { generation_batch_id: input.generationBatchId, source_kind: input.sourceKind }
15629
+ ];
14597
15630
  const zusammengefuehrt = {
14598
15631
  item_id: itemId,
14599
15632
  prompt_run_id: input.runId,
14600
15633
  generation_batch_ids: bestehend ? [...bestehend.generation_batch_ids, input.generationBatchId] : [input.generationBatchId],
14601
- source_kind: bestehend?.source_kind ?? input.sourceKind,
15634
+ source_kind: gesamtHerkunft(origins),
15635
+ origins,
14602
15636
  title: titel,
14603
- images: [...bestehend?.images ?? [], ...abgelegt]
15637
+ images: [
15638
+ ...bestehend?.images ?? [],
15639
+ ...abgelegt.map((bild) => ({ ...bild, generation_batch_id: input.generationBatchId }))
15640
+ ]
14604
15641
  };
14605
15642
  return { kind: "ok", value: zusammengefuehrt };
14606
15643
  }
@@ -15045,6 +16082,15 @@ export {
15045
16082
  preferredHeadRevisionOf,
15046
16083
  collectPromptRuns,
15047
16084
  findPromptRun,
16085
+ DEFAULT_SEED_VORLAGE,
16086
+ parseSeedListe,
16087
+ formatSeedListe,
16088
+ ordneSeedsZu,
16089
+ seedFehlerText,
16090
+ mitDefaultVorlage,
16091
+ UPLOAD_MAX_BYTES,
16092
+ istZipDatei,
16093
+ leseBilderAusZip,
15048
16094
  ladeVorschauen,
15049
16095
  simulatedAnswerFor,
15050
16096
  SIMULATION_PROVIDER,
@@ -15127,6 +16173,7 @@ export {
15127
16173
  collectImageGenerationOrders,
15128
16174
  ordersForPromptRun,
15129
16175
  findImageGenerationOrder,
16176
+ gesamtHerkunft,
15130
16177
  collectImageBatches,
15131
16178
  batchesForPromptRun,
15132
16179
  findImageBatch,