@rslsp1/fa-app-tools 7.4.0 → 8.0.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.
@@ -443,7 +443,10 @@ function capabilitiesOf(port) {
443
443
  imageOrderHistory: typeof port.imageBatchHistory?.listOrdersForPromptRun === "function",
444
444
  imageBatchWrite: typeof port.imageBatchWrite?.importBatch === "function",
445
445
  imageGeneration: typeof port.imageGeneration?.startFromPromptRun === "function",
446
- imageJobs: typeof port.imageJobs?.claimAndRun === "function"
446
+ imageJobs: typeof port.imageJobs?.claimAndRun === "function",
447
+ // P1-A: die herkunftsuebergreifende Prompt-Sicht. Ein Host ohne sie
448
+ // verliert nur diesen Bereich — nicht die drei bestehenden Einstiege.
449
+ promptOverview: typeof port.runs.listAllRuns === "function"
447
450
  };
448
451
  }
449
452
  function unsupportedReason(capability) {
@@ -3530,37 +3533,52 @@ function formatSchemaErrors(errors) {
3530
3533
  }
3531
3534
 
3532
3535
  // src/features/szenen/szenenViewModel.ts
3533
- var KEINE_BAUSTEINE = [
3534
- "scene",
3536
+ var BAUSTEIN_TYPES = [
3537
+ "scene_component",
3538
+ "style",
3539
+ "shot_concept",
3540
+ "prompt_fragment",
3541
+ "prompt_policy"
3542
+ ];
3543
+ var ERWEITERT_REIHENFOLGE = [
3535
3544
  "scene_setup",
3536
- "shot"
3545
+ "shot",
3546
+ "camera_preset",
3547
+ "camera_pattern",
3548
+ "target_model",
3549
+ "scene_derivation_policy",
3550
+ "sequence"
3537
3551
  ];
3538
- var BAUSTEIN_TYPES = SZENEN_ELEMENT_TYPES.filter((typ) => !KEINE_BAUSTEINE.includes(typ));
3552
+ var ERWEITERT_TYPES = (() => {
3553
+ const gehoertHierher = (typ) => typ !== "scene" && !BAUSTEIN_TYPES.includes(typ);
3554
+ const bekannt = ERWEITERT_REIHENFOLGE.filter(
3555
+ (typ) => SZENEN_ELEMENT_TYPES.includes(typ) && gehoertHierher(typ)
3556
+ );
3557
+ const rest = SZENEN_ELEMENT_TYPES.filter(
3558
+ (typ) => gehoertHierher(typ) && !bekannt.includes(typ)
3559
+ );
3560
+ return [...bekannt, ...rest];
3561
+ })();
3539
3562
  var ALLE_BEREICHE = [
3540
3563
  {
3541
- id: "derive",
3542
- title: "0 \xB7 Rekonstruktion",
3543
- description: "Aus einem Bild oder Prompt einen Szenenentwurf vorschlagen lassen."
3544
- },
3545
- {
3546
- id: "elements",
3547
- title: "1 \xB7 Bausteine",
3548
- description: "Figuren, Orte, Stile und Regeln f\xFCr sp\xE4tere Bildprompts pflegen."
3564
+ id: "scene",
3565
+ title: "Szenen",
3566
+ description: "Szenen anlegen, aus Bild oder Text ableiten und daraus Prompts starten."
3549
3567
  },
3550
3568
  {
3551
- id: "scene",
3552
- title: "2 \xB7 Szene",
3553
- description: "Aus Bausteinen eine konkrete Szene und ihre Beziehungen bauen."
3569
+ id: "prompts",
3570
+ title: "Prompts",
3571
+ description: "Alle erzeugten Prompts mit ihren Bildern \u2014 unabhaengig davon, ueber welchen Weg sie entstanden sind."
3554
3572
  },
3555
3573
  {
3556
- id: "setup",
3557
- title: "3 \xB7 Bildaufbau",
3558
- description: "Stil, Komposition und Kamera f\xFCr das sp\xE4tere Bild festlegen."
3574
+ id: "elements",
3575
+ title: "Bausteine",
3576
+ description: "Figuren, Orte, Stile, Prompt-Bausteine und Prompt-Regeln pflegen."
3559
3577
  },
3560
3578
  {
3561
- id: "shot",
3562
- title: "4 \xB7 Prompt",
3563
- description: "Bildprompt erzeugen, Varianten vergleichen und als Item speichern."
3579
+ id: "advanced",
3580
+ title: "Erweitert",
3581
+ description: "Optionale Pr\xE4zisierung: Bildaufbau, Shot, Kameras, Zielmodelle, Regeln, Sequenzen."
3564
3582
  },
3565
3583
  {
3566
3584
  id: "media",
@@ -3570,16 +3588,12 @@ var ALLE_BEREICHE = [
3570
3588
  ];
3571
3589
  function areasFor(port) {
3572
3590
  const faehig = capabilitiesOf(port);
3573
- return ALLE_BEREICHE.filter((bereich) => {
3574
- if (bereich.id === "media") return faehig.media;
3575
- if (bereich.id === "derive") return faehig.derivation;
3576
- return true;
3577
- });
3591
+ return ALLE_BEREICHE.filter((bereich) => bereich.id !== "media" || faehig.media);
3578
3592
  }
3579
3593
  function resolveArea(port, gewuenscht) {
3580
3594
  const verfuegbar = areasFor(port);
3581
3595
  if (gewuenscht && verfuegbar.some((b) => b.id === gewuenscht)) return gewuenscht;
3582
- return verfuegbar.find((b) => b.id === "elements")?.id ?? verfuegbar[0].id;
3596
+ return verfuegbar.find((b) => b.id === "scene")?.id ?? verfuegbar[0].id;
3583
3597
  }
3584
3598
  function noticeFor(ergebnis, was) {
3585
3599
  switch (ergebnis.kind) {
@@ -5104,158 +5118,6 @@ function resolverFromQueries(queries, contexts) {
5104
5118
  var isProjectionCurrent = (state) => state.status === "current";
5105
5119
  var isOk = (result) => result.kind === "ok";
5106
5120
 
5107
- // src/lib/szenen/itemDerivation.ts
5108
- var SZENEN_ITEM_PREFIX = "szn-";
5109
- function itemIdForRun(runId) {
5110
- return `${SZENEN_ITEM_PREFIX}${runId}`;
5111
- }
5112
- function isSzenenItemId(itemId) {
5113
- return itemId.startsWith(SZENEN_ITEM_PREFIX);
5114
- }
5115
- function checkSzenenBatchOrigin(candidate) {
5116
- if (!istText3(candidate.prompt_run_id)) {
5117
- return {
5118
- kind: "rejected",
5119
- failure: { field: "prompt_run_id", message: '"prompt_run_id" fehlt oder ist leer.' }
5120
- };
5121
- }
5122
- if (!istText3(candidate.generation_batch_id)) {
5123
- return {
5124
- kind: "rejected",
5125
- failure: {
5126
- field: "generation_batch_id",
5127
- message: '"generation_batch_id" fehlt oder ist leer.'
5128
- }
5129
- };
5130
- }
5131
- if (candidate.source_kind !== "generated_in_app" && candidate.source_kind !== "external_import") {
5132
- return {
5133
- kind: "rejected",
5134
- failure: {
5135
- field: "source_kind",
5136
- message: `"source_kind" ist unbekannt: ${JSON.stringify(candidate.source_kind)}. Erlaubt: generated_in_app, external_import.`
5137
- }
5138
- };
5139
- }
5140
- const round = typeof candidate.round === "number" && Number.isInteger(candidate.round) ? candidate.round : void 0;
5141
- return {
5142
- kind: "ok",
5143
- value: {
5144
- prompt_run_id: candidate.prompt_run_id,
5145
- generation_batch_ids: [candidate.generation_batch_id],
5146
- source_kind: candidate.source_kind,
5147
- ...round !== void 0 ? { round } : {}
5148
- }
5149
- };
5150
- }
5151
- function mergeSzenenBatchOrigin(bestehend, neu) {
5152
- if (!bestehend) return neu;
5153
- const ids = [...bestehend.generation_batch_ids];
5154
- for (const id of neu.generation_batch_ids) {
5155
- if (!ids.includes(id)) ids.push(id);
5156
- }
5157
- return {
5158
- prompt_run_id: bestehend.prompt_run_id,
5159
- generation_batch_ids: ids,
5160
- source_kind: bestehend.source_kind,
5161
- ...bestehend.round !== void 0 ? { round: bestehend.round } : {}
5162
- };
5163
- }
5164
- var DEFAULT_FSK_LEVEL = "FSK16";
5165
- var istText3 = (v) => typeof v === "string" && v.trim().length > 0;
5166
- function roundOfRun(run, runsOfShot) {
5167
- return runsOfShot.findIndex((kandidat) => kandidat.run_id === run.run_id) + 1;
5168
- }
5169
- function deriveLineage(ownItemId, ownRound, existingItems) {
5170
- const kandidaten = existingItems.filter((item) => item.valid && item.item_id !== ownItemId).sort((a, b) => a.sequence - b.sequence);
5171
- const elternteil = kandidaten[kandidaten.length - 1];
5172
- if (!elternteil) {
5173
- return {
5174
- parent_item_id: null,
5175
- lineage_root_id: ownItemId,
5176
- generation: 0,
5177
- out_of_order: false
5178
- };
5179
- }
5180
- return {
5181
- parent_item_id: elternteil.item_id,
5182
- lineage_root_id: elternteil.lineage_root_id,
5183
- generation: elternteil.generation + 1,
5184
- // Der Elternteil kommt aus einer spaeteren Runde: rueckwaerts gespeichert.
5185
- // Kein Fehler, aber nichts, was stillschweigend passieren darf.
5186
- out_of_order: elternteil.round >= ownRound
5187
- };
5188
- }
5189
- function deriveItemFromRun(input) {
5190
- const { run, runsOfShot, existingItems, savedAt } = input;
5191
- if (run.status === "failed") {
5192
- return {
5193
- kind: "rejected",
5194
- failure: {
5195
- class: "run_failed",
5196
- message: `Der Lauf ${run.run_id} ist gescheitert (${run.failure ? run.failure.class : "unbekannt"}) und traegt keinen Prompt. Aus einem Fehlerlauf entsteht kein Item.`,
5197
- run_failure: run.failure
5198
- }
5199
- };
5200
- }
5201
- if (!run.output || !istText3(run.output.positive)) {
5202
- return {
5203
- kind: "rejected",
5204
- failure: {
5205
- class: "run_without_output",
5206
- message: `Der Lauf ${run.run_id} ist als erfolgreich protokolliert, traegt aber keinen positiven Prompt. Das ist ein Datenfehler im Lauf, kein Item.`
5207
- }
5208
- };
5209
- }
5210
- const round = roundOfRun(run, runsOfShot);
5211
- if (round === 0) {
5212
- return {
5213
- kind: "rejected",
5214
- failure: {
5215
- class: "run_not_among_siblings",
5216
- message: `Der Lauf ${run.run_id} ist unter den ${runsOfShot.length} Laeufen des Shots ${run.shot_version_id} nicht enthalten. Ohne seinen Platz gaebe es keine Rundennummer.`
5217
- }
5218
- };
5219
- }
5220
- const item_id = itemIdForRun(run.run_id);
5221
- const lineage = deriveLineage(item_id, round, existingItems);
5222
- const negative = istText3(run.output.negative) ? run.output.negative : null;
5223
- const title = istText3(input.title) ? input.title : istText3(input.shotTitle) ? `${input.shotTitle} \xB7 Runde ${round}` : `Szenen-Lauf ${round}`;
5224
- return {
5225
- kind: "ok",
5226
- value: {
5227
- item_id,
5228
- title,
5229
- content: run.output.positive,
5230
- negative_prompt: negative,
5231
- // `feedback` ist Pflicht (D-55) und ist genau die Erlaeuterung fuer den
5232
- // Menschen — also gehoert sie in das Feld fuer Notizen.
5233
- notes: istText3(input.notes) ? input.notes : run.output.feedback,
5234
- rating: typeof input.rating === "number" ? input.rating : 0,
5235
- fsk_level: istText3(input.fskLevel) ? input.fskLevel : DEFAULT_FSK_LEVEL,
5236
- tags: [],
5237
- szenen: {
5238
- prompt_run_id: run.run_id,
5239
- shot_version_id: run.shot_version_id,
5240
- shot_element_id: run.shot_element_id,
5241
- scene_setup_version_id: run.scene_setup_version_id,
5242
- camera_id: run.camera_id,
5243
- target_model_version_id: run.target_model_version_id,
5244
- provider: run.provider,
5245
- model_id: run.model_id,
5246
- run_created_at: run.created_at,
5247
- round,
5248
- created_from_draft_id: null,
5249
- saved_at: savedAt
5250
- },
5251
- lineage,
5252
- // Bestandsformat: `LibraryTab` baut den Baum aus `metadata.relationships`.
5253
- // Ein Szenen-Item ohne diese Kante waere im Baum unsichtbar.
5254
- relationships: lineage.parent_item_id ? [{ type: "parent", id: lineage.parent_item_id, role: "source_A" }] : []
5255
- }
5256
- };
5257
- }
5258
-
5259
5121
  // src/lib/szenen/elementEvents.ts
5260
5122
  var SZENEN_EVENT_PREFIX = "szenen.";
5261
5123
  var SZENEN_EVENT_TYPES = {
@@ -5694,6 +5556,243 @@ function collectPromptRuns(events) {
5694
5556
  function findPromptRun(events, runId) {
5695
5557
  return collectPromptRuns(events).find((run) => run.run_id === runId) ?? null;
5696
5558
  }
5559
+ var istKennung = (wert) => typeof wert === "string" && wert.trim().length > 0;
5560
+ function groupOf(run) {
5561
+ const quelle = sourceOf(run);
5562
+ if (quelle.kind === "published") {
5563
+ return istKennung(quelle.shot_version_id) ? {
5564
+ kind: "published",
5565
+ key: `published:${quelle.shot_version_id}`,
5566
+ shot_version_id: quelle.shot_version_id
5567
+ } : {
5568
+ kind: "unresolved",
5569
+ key: `run:${run.run_id}`,
5570
+ reason: `Der Lauf ${run.run_id} gilt als ver\xF6ffentlichte Herkunft, tr\xE4gt aber keine shot_version_id. Er steht deshalb f\xFCr sich; eine Zuordnung w\xE4re geraten.`
5571
+ };
5572
+ }
5573
+ if (quelle.kind === "draft_chain") {
5574
+ return istKennung(quelle.chain_id) ? { kind: "draft_chain", key: `chain:${quelle.chain_id}`, chain_id: quelle.chain_id } : {
5575
+ kind: "unresolved",
5576
+ key: `run:${run.run_id}`,
5577
+ reason: `Der Lauf ${run.run_id} stammt aus einer Draft-Kette ohne chain_id. Er steht deshalb f\xFCr sich; eine Zuordnung w\xE4re geraten.`
5578
+ };
5579
+ }
5580
+ const elementId = quelle.scene?.element_id;
5581
+ return istKennung(elementId) ? { kind: "scene_direct", key: `scene:${elementId}`, scene_element_id: elementId } : {
5582
+ kind: "unresolved",
5583
+ key: `run:${run.run_id}`,
5584
+ reason: `Der Lauf ${run.run_id} entstand direkt aus einer Szene, nennt aber kein Szenen-Element. Er steht deshalb f\xFCr sich; eine Zuordnung w\xE4re geraten.`
5585
+ };
5586
+ }
5587
+ function groupKeyOf(run) {
5588
+ return groupOf(run).key;
5589
+ }
5590
+ function siblingsOf(run, alle) {
5591
+ const schluessel = groupKeyOf(run);
5592
+ return alle.filter((kandidat) => groupKeyOf(kandidat) === schluessel);
5593
+ }
5594
+ function namingElementOf(run) {
5595
+ const quelle = sourceOf(run);
5596
+ if (quelle.kind === "scene_direct") {
5597
+ return istKennung(quelle.scene?.element_id) ? quelle.scene.element_id : null;
5598
+ }
5599
+ if (quelle.kind === "draft_chain") {
5600
+ const szene = (quelle.nodes ?? []).find((knoten) => knoten?.type === "scene");
5601
+ if (szene && istKennung(szene.element_id)) return szene.element_id;
5602
+ const shot = (quelle.nodes ?? []).find((knoten) => knoten?.type === "shot");
5603
+ if (shot && istKennung(shot.element_id)) return shot.element_id;
5604
+ }
5605
+ return istKennung(run.shot_element_id) ? run.shot_element_id : null;
5606
+ }
5607
+ function contextOfRun(run) {
5608
+ const kette = run.input_payload?.context_chain;
5609
+ if (!Array.isArray(kette) || kette.length === 0) return void 0;
5610
+ const erstes = kette[0];
5611
+ if (erstes === null) return null;
5612
+ return istKennung(erstes) ? erstes : void 0;
5613
+ }
5614
+ function selectPromptRuns(alle, filter = {}) {
5615
+ const status = filter.status ?? "succeeded";
5616
+ const nachKontext = filter.contextId !== void 0;
5617
+ const runs = [];
5618
+ let hiddenByStatus = 0;
5619
+ let hiddenByContext = 0;
5620
+ let withoutContext = 0;
5621
+ for (const run of alle) {
5622
+ if (status !== "all" && run.status !== status) {
5623
+ hiddenByStatus += 1;
5624
+ continue;
5625
+ }
5626
+ if (nachKontext) {
5627
+ const kontext = contextOfRun(run);
5628
+ if (kontext === void 0) {
5629
+ withoutContext += 1;
5630
+ continue;
5631
+ }
5632
+ if (kontext !== filter.contextId) {
5633
+ hiddenByContext += 1;
5634
+ continue;
5635
+ }
5636
+ }
5637
+ runs.push(run);
5638
+ }
5639
+ return { runs, hiddenByStatus, hiddenByContext, withoutContext };
5640
+ }
5641
+
5642
+ // src/lib/szenen/itemDerivation.ts
5643
+ var SZENEN_ITEM_PREFIX = "szn-";
5644
+ function itemIdForRun(runId) {
5645
+ return `${SZENEN_ITEM_PREFIX}${runId}`;
5646
+ }
5647
+ function isSzenenItemId(itemId) {
5648
+ return itemId.startsWith(SZENEN_ITEM_PREFIX);
5649
+ }
5650
+ function checkSzenenBatchOrigin(candidate) {
5651
+ if (!istText3(candidate.prompt_run_id)) {
5652
+ return {
5653
+ kind: "rejected",
5654
+ failure: { field: "prompt_run_id", message: '"prompt_run_id" fehlt oder ist leer.' }
5655
+ };
5656
+ }
5657
+ if (!istText3(candidate.generation_batch_id)) {
5658
+ return {
5659
+ kind: "rejected",
5660
+ failure: {
5661
+ field: "generation_batch_id",
5662
+ message: '"generation_batch_id" fehlt oder ist leer.'
5663
+ }
5664
+ };
5665
+ }
5666
+ if (candidate.source_kind !== "generated_in_app" && candidate.source_kind !== "external_import") {
5667
+ return {
5668
+ kind: "rejected",
5669
+ failure: {
5670
+ field: "source_kind",
5671
+ message: `"source_kind" ist unbekannt: ${JSON.stringify(candidate.source_kind)}. Erlaubt: generated_in_app, external_import.`
5672
+ }
5673
+ };
5674
+ }
5675
+ const round = typeof candidate.round === "number" && Number.isInteger(candidate.round) ? candidate.round : void 0;
5676
+ return {
5677
+ kind: "ok",
5678
+ value: {
5679
+ prompt_run_id: candidate.prompt_run_id,
5680
+ generation_batch_ids: [candidate.generation_batch_id],
5681
+ source_kind: candidate.source_kind,
5682
+ ...round !== void 0 ? { round } : {}
5683
+ }
5684
+ };
5685
+ }
5686
+ function mergeSzenenBatchOrigin(bestehend, neu) {
5687
+ if (!bestehend) return neu;
5688
+ const ids = [...bestehend.generation_batch_ids];
5689
+ for (const id of neu.generation_batch_ids) {
5690
+ if (!ids.includes(id)) ids.push(id);
5691
+ }
5692
+ return {
5693
+ prompt_run_id: bestehend.prompt_run_id,
5694
+ generation_batch_ids: ids,
5695
+ source_kind: bestehend.source_kind,
5696
+ ...bestehend.round !== void 0 ? { round: bestehend.round } : {}
5697
+ };
5698
+ }
5699
+ var DEFAULT_FSK_LEVEL = "FSK16";
5700
+ var istText3 = (v) => typeof v === "string" && v.trim().length > 0;
5701
+ function roundOfRun(run, runsOfShot) {
5702
+ return runsOfShot.findIndex((kandidat) => kandidat.run_id === run.run_id) + 1;
5703
+ }
5704
+ function deriveLineage(ownItemId, ownRound, existingItems) {
5705
+ const kandidaten = existingItems.filter((item) => item.valid && item.item_id !== ownItemId).sort((a, b) => a.sequence - b.sequence);
5706
+ const elternteil = kandidaten[kandidaten.length - 1];
5707
+ if (!elternteil) {
5708
+ return {
5709
+ parent_item_id: null,
5710
+ lineage_root_id: ownItemId,
5711
+ generation: 0,
5712
+ out_of_order: false
5713
+ };
5714
+ }
5715
+ return {
5716
+ parent_item_id: elternteil.item_id,
5717
+ lineage_root_id: elternteil.lineage_root_id,
5718
+ generation: elternteil.generation + 1,
5719
+ // Der Elternteil kommt aus einer spaeteren Runde: rueckwaerts gespeichert.
5720
+ // Kein Fehler, aber nichts, was stillschweigend passieren darf.
5721
+ out_of_order: elternteil.round >= ownRound
5722
+ };
5723
+ }
5724
+ function deriveItemFromRun(input) {
5725
+ const { run, runsOfShot, existingItems, savedAt } = input;
5726
+ if (run.status === "failed") {
5727
+ return {
5728
+ kind: "rejected",
5729
+ failure: {
5730
+ class: "run_failed",
5731
+ message: `Der Lauf ${run.run_id} ist gescheitert (${run.failure ? run.failure.class : "unbekannt"}) und traegt keinen Prompt. Aus einem Fehlerlauf entsteht kein Item.`,
5732
+ run_failure: run.failure
5733
+ }
5734
+ };
5735
+ }
5736
+ if (!run.output || !istText3(run.output.positive)) {
5737
+ return {
5738
+ kind: "rejected",
5739
+ failure: {
5740
+ class: "run_without_output",
5741
+ message: `Der Lauf ${run.run_id} ist als erfolgreich protokolliert, traegt aber keinen positiven Prompt. Das ist ein Datenfehler im Lauf, kein Item.`
5742
+ }
5743
+ };
5744
+ }
5745
+ const round = roundOfRun(run, runsOfShot);
5746
+ if (round === 0) {
5747
+ return {
5748
+ kind: "rejected",
5749
+ failure: {
5750
+ class: "run_not_among_siblings",
5751
+ // Regel 11: Die Meldung nennt die **Bezugsgruppe**, nicht ein Feld,
5752
+ // das bei einem shotlosen Lauf leer ist. „des Shots ''" war keine
5753
+ // Auskunft (P1-B).
5754
+ message: `Der Lauf ${run.run_id} ist unter den ${runsOfShot.length} Laeufen seiner Bezugsgruppe ${groupKeyOf(run)} nicht enthalten. Ohne seinen Platz gaebe es keine Rundennummer.`
5755
+ }
5756
+ };
5757
+ }
5758
+ const item_id = itemIdForRun(run.run_id);
5759
+ const lineage = deriveLineage(item_id, round, existingItems);
5760
+ const negative = istText3(run.output.negative) ? run.output.negative : null;
5761
+ const title = istText3(input.title) ? input.title : istText3(input.shotTitle) ? `${input.shotTitle} \xB7 Runde ${round}` : `Szenen-Lauf ${round}`;
5762
+ return {
5763
+ kind: "ok",
5764
+ value: {
5765
+ item_id,
5766
+ title,
5767
+ content: run.output.positive,
5768
+ negative_prompt: negative,
5769
+ // `feedback` ist Pflicht (D-55) und ist genau die Erlaeuterung fuer den
5770
+ // Menschen — also gehoert sie in das Feld fuer Notizen.
5771
+ notes: istText3(input.notes) ? input.notes : run.output.feedback,
5772
+ rating: typeof input.rating === "number" ? input.rating : 0,
5773
+ fsk_level: istText3(input.fskLevel) ? input.fskLevel : DEFAULT_FSK_LEVEL,
5774
+ tags: [],
5775
+ szenen: {
5776
+ prompt_run_id: run.run_id,
5777
+ shot_version_id: run.shot_version_id,
5778
+ shot_element_id: run.shot_element_id,
5779
+ scene_setup_version_id: run.scene_setup_version_id,
5780
+ camera_id: run.camera_id,
5781
+ target_model_version_id: run.target_model_version_id,
5782
+ provider: run.provider,
5783
+ model_id: run.model_id,
5784
+ run_created_at: run.created_at,
5785
+ round,
5786
+ created_from_draft_id: null,
5787
+ saved_at: savedAt
5788
+ },
5789
+ lineage,
5790
+ // Bestandsformat: `LibraryTab` baut den Baum aus `metadata.relationships`.
5791
+ // Ein Szenen-Item ohne diese Kante waere im Baum unsichtbar.
5792
+ relationships: lineage.parent_item_id ? [{ type: "parent", id: lineage.parent_item_id, role: "source_A" }] : []
5793
+ }
5794
+ };
5795
+ }
5697
5796
 
5698
5797
  // src/lib/szenen/seedListe.ts
5699
5798
  var DEFAULT_SEED_VORLAGE = {
@@ -6804,10 +6903,10 @@ async function runSceneDerivation(input, port, userPrompt) {
6804
6903
  }
6805
6904
 
6806
6905
  // src/features/szenen/SzenenView.tsx
6807
- import { useMemo as useMemo4, useState as useState17 } from "react";
6906
+ import { useMemo as useMemo5, useState as useState20 } from "react";
6808
6907
 
6809
6908
  // src/features/szenen/areas/ElementsArea.tsx
6810
- import { useState as useState12 } from "react";
6909
+ import { useState as useState13 } from "react";
6811
6910
 
6812
6911
  // src/features/szenen/areas/usePortQuery.ts
6813
6912
  import { useEffect, useRef, useState } from "react";
@@ -6839,7 +6938,7 @@ function usePortQuery(frage, abhaengigkeiten) {
6839
6938
  }
6840
6939
 
6841
6940
  // src/features/szenen/areas/ElementDetail.tsx
6842
- import { useEffect as useEffect6, useMemo as useMemo2, useState as useState10 } from "react";
6941
+ import { useEffect as useEffect7, useMemo as useMemo2, useState as useState11 } from "react";
6843
6942
 
6844
6943
  // src/features/szenen/elementLabels.ts
6845
6944
  var LABELS = {
@@ -8931,13 +9030,57 @@ var VersionNavigator = ({
8931
9030
  };
8932
9031
 
8933
9032
  // src/features/szenen/areas/RunsPanel.tsx
8934
- import { useEffect as useEffect5, useRef as useRef3, useState as useState9 } from "react";
9033
+ import { useEffect as useEffect6, useRef as useRef3, useState as useState10 } from "react";
9034
+
9035
+ // src/features/szenen/areas/useLaufTitel.ts
9036
+ import { useEffect as useEffect3, useState as useState7 } from "react";
9037
+ function useLaufTitel(port, laeufe) {
9038
+ const [titelJeElement, setTitelJeElement] = useState7(
9039
+ () => /* @__PURE__ */ new Map()
9040
+ );
9041
+ const gebraucht = [...new Set(
9042
+ laeufe.map(namingElementOf).filter((id) => id !== null)
9043
+ )].sort();
9044
+ const schluessel = gebraucht.join(",");
9045
+ useEffect3(() => {
9046
+ let abgemeldet = false;
9047
+ const offen = gebraucht.filter((id) => !titelJeElement.has(id));
9048
+ if (offen.length === 0) return void 0;
9049
+ void (async () => {
9050
+ const gelesen = /* @__PURE__ */ new Map();
9051
+ for (const id of offen) {
9052
+ try {
9053
+ const ergebnis = await port.elements.getElement(id);
9054
+ gelesen.set(
9055
+ id,
9056
+ ergebnis.kind === "ok" && ergebnis.value ? ergebnis.value.metadata?.title ?? null : null
9057
+ );
9058
+ } catch {
9059
+ gelesen.set(id, null);
9060
+ }
9061
+ }
9062
+ if (abgemeldet) return;
9063
+ setTitelJeElement((bisher) => new Map([...bisher, ...gelesen]));
9064
+ })();
9065
+ return () => {
9066
+ abgemeldet = true;
9067
+ };
9068
+ }, [port, schluessel]);
9069
+ const jeLauf = /* @__PURE__ */ new Map();
9070
+ for (const lauf of laeufe) {
9071
+ const elementId = namingElementOf(lauf);
9072
+ if (!elementId) continue;
9073
+ const titel = titelJeElement.get(elementId);
9074
+ if (titel) jeLauf.set(lauf.run_id, titel);
9075
+ }
9076
+ return jeLauf;
9077
+ }
8935
9078
 
8936
9079
  // src/features/szenen/areas/RunImagesPanel.tsx
8937
- import React7, { useEffect as useEffect4, useRef as useRef2, useState as useState8 } from "react";
9080
+ import React7, { useEffect as useEffect5, useRef as useRef2, useState as useState9 } from "react";
8938
9081
 
8939
9082
  // src/features/szenen/areas/Bildbausteine.tsx
8940
- import { useCallback, useEffect as useEffect3, useState as useState7 } from "react";
9083
+ import { useCallback, useEffect as useEffect4, useState as useState8 } from "react";
8941
9084
  import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
8942
9085
  var Kachel = ({
8943
9086
  quelle,
@@ -8958,7 +9101,7 @@ var BildViewer = ({
8958
9101
  if (anzahl === 0) return;
8959
9102
  onWechseln((position + schritt + anzahl) % anzahl);
8960
9103
  }, [anzahl, position, onWechseln]);
8961
- useEffect3(() => {
9104
+ useEffect4(() => {
8962
9105
  const taste = (e) => {
8963
9106
  if (e.key === "Escape") onSchliessen();
8964
9107
  else if (e.key === "ArrowLeft") blaettern(-1);
@@ -9041,8 +9184,8 @@ var BildViewer = ({
9041
9184
  );
9042
9185
  };
9043
9186
  var BildGalerie = ({ bilder, testId, satzTitel }) => {
9044
- const [offen, setOffen] = useState7(null);
9045
- useEffect3(() => {
9187
+ const [offen, setOffen] = useState8(null);
9188
+ useEffect4(() => {
9046
9189
  setOffen((vorher) => vorher !== null && vorher >= bilder.length ? null : vorher);
9047
9190
  }, [bilder.length]);
9048
9191
  if (bilder.length === 0) return null;
@@ -9098,11 +9241,11 @@ var AUFTRAG_TEXT = {
9098
9241
  };
9099
9242
  var RunImagesPanel = ({ port, lauf }) => {
9100
9243
  const faehig = capabilitiesOf(port);
9101
- const [nachladen, setNachladen] = useState8(0);
9244
+ const [nachladen, setNachladen] = useState9(0);
9102
9245
  const neuLesen = () => setNachladen((n) => n + 1);
9103
- const [erzeugenOffen, setErzeugenOffen] = useState8(null);
9104
- const [zuordnenOffen, setZuordnenOffen] = useState8(null);
9105
- const [chatAuftraegeOffen, setChatAuftraegeOffen] = useState8(null);
9246
+ const [erzeugenOffen, setErzeugenOffen] = useState9(null);
9247
+ const [zuordnenOffen, setZuordnenOffen] = useState9(null);
9248
+ const [chatAuftraegeOffen, setChatAuftraegeOffen] = useState9(null);
9106
9249
  const quelle = sourceOf(lauf);
9107
9250
  const [wahlPhase] = usePortQuery(
9108
9251
  () => port.imageGeneration ? port.imageGeneration.imageModelChoiceForRun(lauf.run_id) : Promise.resolve({ kind: "ok", value: null }),
@@ -9416,12 +9559,12 @@ var BestandsBild = ({ port, mediaRef }) => {
9416
9559
  ] });
9417
9560
  };
9418
9561
  function useBildQuellen(port, bilder) {
9419
- const [stand, setStand] = useState8(() => ({ quellen: /* @__PURE__ */ new Map(), fehler: /* @__PURE__ */ new Map() }));
9562
+ const [stand, setStand] = useState9(() => ({ quellen: /* @__PURE__ */ new Map(), fehler: /* @__PURE__ */ new Map() }));
9420
9563
  const gehalten = useRef2(/* @__PURE__ */ new Map());
9421
9564
  const gescheitert = useRef2(/* @__PURE__ */ new Map());
9422
- const [versuch, setVersuch] = useState8(0);
9565
+ const [versuch, setVersuch] = useState9(0);
9423
9566
  const schluessel = bilder.map((b) => `${b.media_ref}|${b.mime_type ?? ""}`).join(" ");
9424
- useEffect4(() => {
9567
+ useEffect5(() => {
9425
9568
  const bestand = port.imageLibrary;
9426
9569
  if (!bestand) return void 0;
9427
9570
  let abgebrochen = false;
@@ -9586,11 +9729,11 @@ var ProfilBefunde = ({ wahl, runId }) => {
9586
9729
  ] });
9587
9730
  };
9588
9731
  var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
9589
- const [modellWahl, setModellWahl] = useState8(null);
9590
- const [anzahlText, setAnzahlText] = useState8("1");
9591
- const [seitenverhaeltnis, setSeitenverhaeltnis] = useState8("");
9592
- const [laeuft, setLaeuft] = useState8(false);
9593
- const [notiz, setNotiz] = useState8(null);
9732
+ const [modellWahl, setModellWahl] = useState9(null);
9733
+ const [anzahlText, setAnzahlText] = useState9("1");
9734
+ const [seitenverhaeltnis, setSeitenverhaeltnis] = useState9("");
9735
+ const [laeuft, setLaeuft] = useState9(false);
9736
+ const [notiz, setNotiz] = useState9(null);
9594
9737
  if (!port.imageGeneration) {
9595
9738
  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." });
9596
9739
  }
@@ -9767,23 +9910,23 @@ var ErzeugenAktion = ({ port, lauf, wahl, wahlFehler, onFertig }) => {
9767
9910
  };
9768
9911
  var DEFAULT_VORLAGE_KEY = "__default__";
9769
9912
  var ZuordnenAktion = ({ port, lauf, onFertig }) => {
9770
- const [dateien, setDateien] = useState8([]);
9771
- const [seeds, setSeeds] = useState8({});
9772
- const [zip, setZip] = useState8(null);
9773
- const [zipLaedt, setZipLaedt] = useState8(false);
9774
- const [seedListe, setSeedListe] = useState8("");
9775
- const [vorlagen, setVorlagen] = useState8([DEFAULT_SEED_VORLAGE]);
9776
- const [vorlageKey, setVorlageKey] = useState8(DEFAULT_VORLAGE_KEY);
9777
- const [vorlagenStand, setVorlagenStand] = useState8(0);
9778
- const [vorlageBenennen, setVorlageBenennen] = useState8(false);
9779
- const [vorlageName, setVorlageName] = useState8("");
9780
- const [modell, setModell] = useState8("");
9781
- const [itemId, setItemId] = useState8("");
9782
- const [laeuft, setLaeuft] = useState8(false);
9783
- const [notiz, setNotiz] = useState8(null);
9913
+ const [dateien, setDateien] = useState9([]);
9914
+ const [seeds, setSeeds] = useState9({});
9915
+ const [zip, setZip] = useState9(null);
9916
+ const [zipLaedt, setZipLaedt] = useState9(false);
9917
+ const [seedListe, setSeedListe] = useState9("");
9918
+ const [vorlagen, setVorlagen] = useState9([DEFAULT_SEED_VORLAGE]);
9919
+ const [vorlageKey, setVorlageKey] = useState9(DEFAULT_VORLAGE_KEY);
9920
+ const [vorlagenStand, setVorlagenStand] = useState9(0);
9921
+ const [vorlageBenennen, setVorlageBenennen] = useState9(false);
9922
+ const [vorlageName, setVorlageName] = useState9("");
9923
+ const [modell, setModell] = useState9("");
9924
+ const [itemId, setItemId] = useState9("");
9925
+ const [laeuft, setLaeuft] = useState9(false);
9926
+ const [notiz, setNotiz] = useState9(null);
9784
9927
  const auswahlMarke = useRef2(0);
9785
9928
  const zipAktiv = zip !== null;
9786
- useEffect4(() => {
9929
+ useEffect5(() => {
9787
9930
  if (!zipAktiv) return;
9788
9931
  let abgebrochen = false;
9789
9932
  void (async () => {
@@ -10243,8 +10386,8 @@ var ChatAuftraegeAktion = ({
10243
10386
  laedt,
10244
10387
  onFertig
10245
10388
  }) => {
10246
- const [laufend, setLaufend] = useState8(null);
10247
- const [notiz, setNotiz] = useState8(null);
10389
+ const [laufend, setLaufend] = useState9(null);
10390
+ const [notiz, setNotiz] = useState9(null);
10248
10391
  async function uebernehmen(jobId) {
10249
10392
  if (!port.imageJobs) return;
10250
10393
  setLaufend(jobId);
@@ -10323,10 +10466,10 @@ var ChatAuftraegeAktion = ({
10323
10466
  // src/features/szenen/areas/RunsPanel.tsx
10324
10467
  import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
10325
10468
  var RunsPanel = ({ port, source, contextId }) => {
10326
- const [anweisung, setAnweisung] = useState9("");
10327
- const [laeuft, setLaeuft] = useState9(false);
10328
- const [notiz, setNotiz] = useState9(null);
10329
- const [nachladen, setNachladen] = useState9(0);
10469
+ const [anweisung, setAnweisung] = useState10("");
10470
+ const [laeuft, setLaeuft] = useState10(false);
10471
+ const [notiz, setNotiz] = useState10(null);
10472
+ const [nachladen, setNachladen] = useState10(0);
10330
10473
  const faehig = capabilitiesOf(port);
10331
10474
  const quellSchluessel = source.kind === "published" ? source.shotVersionId : source.kind === "draft_chain" ? source.chainId : source.sceneElementId;
10332
10475
  const aktuelleQuelle = useRef3({ kind: source.kind, id: quellSchluessel });
@@ -10357,10 +10500,11 @@ var RunsPanel = ({ port, source, contextId }) => {
10357
10500
  neuLaden();
10358
10501
  };
10359
10502
  const laeufe = phase.status === "ready" ? phase.value : [];
10360
- const [gewaehlteRunde, setGewaehlteRunde] = useState9(void 0);
10503
+ const titel = useLaufTitel(port, laeufe);
10504
+ const [gewaehlteRunde, setGewaehlteRunde] = useState10(void 0);
10361
10505
  const neueste = laeufe.length > 0 ? laeufe[laeufe.length - 1].run_id : null;
10362
10506
  const offeneRunde = gewaehlteRunde === void 0 ? neueste : gewaehlteRunde;
10363
- useEffect5(() => {
10507
+ useEffect6(() => {
10364
10508
  setGewaehlteRunde(void 0);
10365
10509
  setAnweisung("");
10366
10510
  setNotiz(null);
@@ -10395,6 +10539,7 @@ var RunsPanel = ({ port, source, contextId }) => {
10395
10539
  port,
10396
10540
  lauf,
10397
10541
  runde: roundOfRun(lauf, laeufe),
10542
+ titel: titel.get(lauf.run_id) ?? null,
10398
10543
  offen: lauf.run_id === offeneRunde,
10399
10544
  onUmschalten: () => setGewaehlteRunde(
10400
10545
  lauf.run_id === offeneRunde ? null : lauf.run_id
@@ -10419,7 +10564,7 @@ var STATUS_TEXT = {
10419
10564
  };
10420
10565
  var LANGER_TEXT = 240;
10421
10566
  var Sekundaertext = ({ titel, text, testId }) => {
10422
- const [ganz, setGanz] = useState9(false);
10567
+ const [ganz, setGanz] = useState10(false);
10423
10568
  const lang = text.length > LANGER_TEXT;
10424
10569
  return /* @__PURE__ */ jsxs9("section", { className: "szenen-runs__sekundaer", children: [
10425
10570
  /* @__PURE__ */ jsx9("h5", { children: titel }),
@@ -10438,7 +10583,7 @@ var Sekundaertext = ({ titel, text, testId }) => {
10438
10583
  };
10439
10584
  var LISTE_ANFANG = 3;
10440
10585
  var SekundaerListe = ({ titel, eintraege, testId, className }) => {
10441
- const [alle, setAlle] = useState9(false);
10586
+ const [alle, setAlle] = useState10(false);
10442
10587
  const lang = eintraege.length > LISTE_ANFANG;
10443
10588
  const gezeigt = lang && !alle ? eintraege.slice(0, LISTE_ANFANG) : eintraege;
10444
10589
  return /* @__PURE__ */ jsxs9("section", { className: "szenen-runs__sekundaer", children: [
@@ -10456,10 +10601,10 @@ var SekundaerListe = ({ titel, eintraege, testId, className }) => {
10456
10601
  )
10457
10602
  ] });
10458
10603
  };
10459
- var RundenEintrag = ({ port, lauf, runde, offen, onUmschalten, itemMoeglich, onItemGespeichert }) => {
10460
- const [notiz, setNotiz] = useState9(null);
10461
- const [laeuft, setLaeuft] = useState9(false);
10462
- const [nachladen, setNachladen] = useState9(0);
10604
+ var RundenEintrag = ({ port, lauf, runde, titel, offen, onUmschalten, itemMoeglich, onItemGespeichert }) => {
10605
+ const [notiz, setNotiz] = useState10(null);
10606
+ const [laeuft, setLaeuft] = useState10(false);
10607
+ const [nachladen, setNachladen] = useState10(0);
10463
10608
  const [itemPhase] = usePortQuery(
10464
10609
  () => offen && port.items ? port.items.getItemForRun(lauf.run_id) : Promise.resolve({ kind: "ok", value: null }),
10465
10610
  [port, lauf.run_id, nachladen, offen]
@@ -10487,10 +10632,7 @@ var RundenEintrag = ({ port, lauf, runde, offen, onUmschalten, itemMoeglich, onI
10487
10632
  "aria-expanded": offen,
10488
10633
  "data-testid": `runde-umschalten-${lauf.run_id}`,
10489
10634
  children: [
10490
- /* @__PURE__ */ jsxs9("span", { className: "szenen-runs__marke", children: [
10491
- "Runde ",
10492
- runde
10493
- ] }),
10635
+ /* @__PURE__ */ jsx9("span", { className: "szenen-runs__marke", "data-testid": `titel-${lauf.run_id}`, children: titel ? `${titel} \xB7 Runde ${runde}` : `Runde ${runde}` }),
10494
10636
  /* @__PURE__ */ jsx9(
10495
10637
  "span",
10496
10638
  {
@@ -10614,16 +10756,16 @@ var ElementDetail = ({
10614
10756
  author,
10615
10757
  onChanged
10616
10758
  }) => {
10617
- const [nachladen, setNachladen] = useState10(0);
10759
+ const [nachladen, setNachladen] = useState11(0);
10618
10760
  const [phase] = usePortQuery(
10619
10761
  () => port.elements.getElement(elementId),
10620
10762
  [port, elementId, nachladen]
10621
10763
  );
10622
- const [entwurf, setEntwurf] = useState10({});
10623
- const [notiz, setNotiz] = useState10(null);
10624
- const [laeuft, setLaeuft] = useState10(false);
10625
- const [wahl, setWahl] = useState10(null);
10626
- const [basiswechsel, setBasiswechsel] = useState10(null);
10764
+ const [entwurf, setEntwurf] = useState11({});
10765
+ const [notiz, setNotiz] = useState11(null);
10766
+ const [laeuft, setLaeuft] = useState11(false);
10767
+ const [wahl, setWahl] = useState11(null);
10768
+ const [basiswechsel, setBasiswechsel] = useState11(null);
10627
10769
  const [kettenPhase] = usePortQuery(
10628
10770
  () => port.context.chainFor(contextId),
10629
10771
  [port, contextId]
@@ -10645,7 +10787,7 @@ var ElementDetail = ({
10645
10787
  () => schnappschuss ? fieldsForType(schnappschuss.element.type) : [],
10646
10788
  [schnappschuss?.element.type]
10647
10789
  );
10648
- useEffect6(() => {
10790
+ useEffect7(() => {
10649
10791
  setWahl(null);
10650
10792
  setBasiswechsel(null);
10651
10793
  setNotiz(null);
@@ -10676,7 +10818,7 @@ var ElementDetail = ({
10676
10818
  return {};
10677
10819
  }, [schnappschuss, angezeigt]);
10678
10820
  const anzeigeSchluessel = angezeigt.kind === "version" ? `v:${angezeigt.versionId}` : angezeigt.kind;
10679
- useEffect6(() => {
10821
+ useEffect7(() => {
10680
10822
  if (!schnappschuss) return;
10681
10823
  setEntwurf(formFromPayload(felder, angezeigtePayload));
10682
10824
  }, [
@@ -11108,15 +11250,15 @@ var ElementDetail = ({
11108
11250
  };
11109
11251
 
11110
11252
  // src/features/szenen/areas/useSchmalesDisplay.ts
11111
- import { useEffect as useEffect7, useState as useState11 } from "react";
11253
+ import { useEffect as useEffect8, useState as useState12 } from "react";
11112
11254
  var SCHMALE_ANSICHT = "(max-width: 760px)";
11113
11255
  function messen(abfrage) {
11114
11256
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
11115
11257
  return window.matchMedia(abfrage).matches;
11116
11258
  }
11117
11259
  function useSchmalesDisplay(abfrage = SCHMALE_ANSICHT) {
11118
- const [schmal, setSchmal] = useState11(() => messen(abfrage));
11119
- useEffect7(() => {
11260
+ const [schmal, setSchmal] = useState12(() => messen(abfrage));
11261
+ useEffect8(() => {
11120
11262
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
11121
11263
  const liste = window.matchMedia(abfrage);
11122
11264
  const aktualisieren = () => setSchmal(liste.matches);
@@ -11143,16 +11285,16 @@ var ElementsArea = ({
11143
11285
  const gemischt = auswahlTypen.length > 1;
11144
11286
  const ueberschrift = listTitle ?? (einzelTyp ? elementTypPlural(einzelTyp) : "Bausteine");
11145
11287
  const einzahl = einzelTyp ? elementTypLabel(einzelTyp) : "Objekt";
11146
- const [typ, setTyp] = useState12(einzelTyp ?? "");
11147
- const [zeigeStillgelegte, setZeigeStillgelegte] = useState12(false);
11148
- const [gewaehlt, setGewaehlt] = useState12(null);
11149
- const [neuerTitel, setNeuerTitel] = useState12("");
11150
- const [neuerTyp, setNeuerTyp] = useState12(auswahlTypen[0]);
11151
- const [notiz, setNotiz] = useState12(null);
11152
- const [anlegend, setAnlegend] = useState12(false);
11153
- const [anlageOffen, setAnlageOffen] = useState12(false);
11288
+ const [typ, setTyp] = useState13(einzelTyp ?? "");
11289
+ const [zeigeStillgelegte, setZeigeStillgelegte] = useState13(false);
11290
+ const [gewaehlt, setGewaehlt] = useState13(null);
11291
+ const [neuerTitel, setNeuerTitel] = useState13("");
11292
+ const [neuerTyp, setNeuerTyp] = useState13(auswahlTypen[0]);
11293
+ const [notiz, setNotiz] = useState13(null);
11294
+ const [anlegend, setAnlegend] = useState13(false);
11295
+ const [anlageOffen, setAnlageOffen] = useState13(false);
11154
11296
  const schmal = useSchmalesDisplay();
11155
- const [ansicht, setAnsicht] = useState12("liste");
11297
+ const [ansicht, setAnsicht] = useState13("liste");
11156
11298
  const zeigeListe = !schmal || ansicht === "liste";
11157
11299
  const zeigeDetail = !schmal || ansicht === "detail";
11158
11300
  const waehle = (elementId) => {
@@ -11326,273 +11468,97 @@ var ElementsArea = ({
11326
11468
  {
11327
11469
  type: "checkbox",
11328
11470
  "data-testid": "filter-stillgelegt",
11329
- checked: zeigeStillgelegte,
11330
- onChange: (e) => setZeigeStillgelegte(e.target.checked)
11331
- }
11332
- ),
11333
- "stillgelegte Elemente einblenden"
11334
- ] }),
11335
- /* @__PURE__ */ jsx11("button", { type: "button", "data-testid": "neu-laden", onClick: neuLaden, children: "neu laden" })
11336
- ] })
11337
- ] })
11338
- ] }),
11339
- zeigeDetail && /* @__PURE__ */ jsxs11("div", { className: "szenen-elements__detail", "data-testid": "elemente-detail-spalte", children: [
11340
- schmal && /* @__PURE__ */ jsx11(
11341
- "button",
11342
- {
11343
- type: "button",
11344
- className: "szenen-elements__back",
11345
- "data-testid": "zurueck-zur-liste",
11346
- onClick: () => setAnsicht("liste"),
11347
- children: "\u2190 Zur\xFCck zur Liste"
11348
- }
11349
- ),
11350
- gewaehlt ? /* @__PURE__ */ jsx11(
11351
- ElementDetail,
11352
- {
11353
- port,
11354
- elementId: gewaehlt,
11355
- contextId,
11356
- author,
11357
- onChanged: neuLaden
11358
- }
11359
- ) : /* @__PURE__ */ jsx11("p", { className: "szenen-elements__empty-detail", "data-testid": "keine-auswahl", children: "Nichts ausgew\xE4hlt. Ein Eintrag aus der Liste \xF6ffnet die Bearbeitung." })
11360
- ] })
11361
- ]
11362
- }
11363
- );
11364
- };
11365
-
11366
- // src/features/szenen/areas/SceneArea.tsx
11367
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
11368
- var SceneArea = ({ port, contextId }) => /* @__PURE__ */ jsxs12("div", { className: "szenen-scene", "data-testid": "bereich-szene", children: [
11369
- /* @__PURE__ */ jsx12("p", { className: "szenen-area__lead", children: "Szenen dieses Kontexts. Auswahl \xF6ffnet die Bearbeitung der Nodes und Beziehungen." }),
11370
- /* @__PURE__ */ jsx12(ElementsArea, { port, contextId, restrictToTypes: ["scene"] })
11371
- ] });
11372
-
11373
- // src/features/szenen/areas/SetupArea.tsx
11374
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
11375
- var SetupArea = ({ port, contextId }) => /* @__PURE__ */ jsxs13("div", { className: "szenen-setup", "data-testid": "bereich-setup", children: [
11376
- /* @__PURE__ */ jsx13("p", { className: "szenen-area__lead", children: "Bildaufbauten, Kameras und Stile dieses Kontexts." }),
11377
- /* @__PURE__ */ jsx13(
11378
- ElementsArea,
11379
- {
11380
- port,
11381
- contextId,
11382
- restrictToTypes: ["scene_setup", "camera_preset", "camera_pattern", "style"],
11383
- allTypesLabel: "alle Bildaufbau-Typen",
11384
- listTitle: "Bildaufbau"
11385
- }
11386
- )
11387
- ] });
11388
-
11389
- // src/features/szenen/areas/ShotArea.tsx
11390
- import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
11391
- var ShotArea = ({ port, contextId }) => /* @__PURE__ */ jsxs14("div", { className: "szenen-shot", "data-testid": "bereich-shot", children: [
11392
- /* @__PURE__ */ jsx14("p", { className: "szenen-area__lead", children: "Prompts dieses Kontexts. Auswahl zeigt Runden und startet Prompt-L\xE4ufe." }),
11393
- /* @__PURE__ */ jsx14(
11394
- ElementsArea,
11395
- {
11396
- port,
11397
- contextId,
11398
- restrictToTypes: ["shot", "shot_concept", "target_model"],
11399
- allTypesLabel: "alle Prompt-Typen",
11400
- listTitle: "Prompts"
11401
- }
11402
- )
11403
- ] });
11404
-
11405
- // src/features/szenen/areas/MediaArea.tsx
11406
- import { useState as useState13 } from "react";
11407
- import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
11408
- var leer = async () => ({ kind: "ok", value: [] });
11409
- var MediaArea = ({ port }) => {
11410
- const media = port.media;
11411
- const [versionInput, setVersionInput] = useState13("");
11412
- const [versionId, setVersionId] = useState13("");
11413
- const [itemInput, setItemInput] = useState13("");
11414
- const [itemId, setItemId] = useState13("");
11415
- const [assetId, setAssetId] = useState13("");
11416
- const [role, setRole] = useState13("reference");
11417
- const [position, setPosition] = useState13("0");
11418
- const [notiz, setNotiz] = useState13(null);
11419
- const [busy, setBusy] = useState13(false);
11420
- const [refresh, setRefresh] = useState13(0);
11421
- const [versionPhase] = usePortQuery(
11422
- () => versionId ? media.listVersionMedia(versionId) : leer(),
11423
- [media, versionId, refresh]
11424
- );
11425
- const [itemPhase] = usePortQuery(
11426
- () => itemId ? media.listItemMedia(itemId) : Promise.resolve({ kind: "ok", value: [] }),
11427
- [media, itemId, refresh]
11428
- );
11429
- const zuordnen = async () => {
11430
- if (!versionInput.trim() || !assetId.trim()) {
11431
- setNotiz({ tone: "error", text: "Version-ID und Asset-ID sind erforderlich." });
11432
- return;
11433
- }
11434
- const parsedPosition = Number(position);
11435
- if (!Number.isInteger(parsedPosition) || parsedPosition < 0) {
11436
- setNotiz({ tone: "error", text: `Position muss eine nicht-negative Ganzzahl sein, war ${JSON.stringify(position)}.` });
11437
- return;
11438
- }
11439
- setBusy(true);
11440
- const result = await media.attachVersionMedium({
11441
- versionId: versionInput.trim(),
11442
- assetId: assetId.trim(),
11443
- role,
11444
- position: parsedPosition
11445
- });
11446
- setNotiz(noticeFor(result, "Referenzmedium zuordnen"));
11447
- if (result.kind === "ok") {
11448
- setVersionId(versionInput.trim());
11449
- setRefresh((value) => value + 1);
11450
- }
11451
- setBusy(false);
11452
- };
11453
- const entfernen = async (medium) => {
11454
- setBusy(true);
11455
- const result = await media.detachVersionMedium({
11456
- versionId,
11457
- assetId: medium.assetId,
11458
- role: medium.role
11459
- });
11460
- setNotiz(noticeFor(result, "Referenzmedium entfernen"));
11461
- if (result.kind === "ok") setRefresh((value) => value + 1);
11462
- setBusy(false);
11463
- };
11464
- const versionMedien = versionPhase.status === "ready" ? versionPhase.value : [];
11465
- const itemMedien = itemPhase.status === "ready" ? itemPhase.value : [];
11466
- return /* @__PURE__ */ jsxs15("div", { className: "szenen-media", "data-testid": "bereich-medien", children: [
11467
- /* @__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." }),
11468
- /* @__PURE__ */ jsxs15("section", { children: [
11469
- /* @__PURE__ */ jsx15("h3", { children: "Version" }),
11470
- /* @__PURE__ */ jsxs15("div", { className: "szenen-media__lookup", children: [
11471
- /* @__PURE__ */ jsxs15("label", { children: [
11472
- "Version-ID",
11473
- /* @__PURE__ */ jsx15("input", { value: versionInput, onChange: (event) => setVersionInput(event.target.value) })
11474
- ] }),
11475
- /* @__PURE__ */ jsx15("button", { type: "button", onClick: () => setVersionId(versionInput.trim()), children: "Medien laden" })
11476
- ] }),
11477
- /* @__PURE__ */ jsxs15("div", { className: "szenen-media__attach", children: [
11478
- /* @__PURE__ */ jsxs15("label", { children: [
11479
- "Asset-ID",
11480
- /* @__PURE__ */ jsx15("input", { value: assetId, onChange: (event) => setAssetId(event.target.value) })
11481
- ] }),
11482
- /* @__PURE__ */ jsxs15("label", { children: [
11483
- "Rolle",
11484
- /* @__PURE__ */ jsxs15("select", { value: role, onChange: (event) => setRole(event.target.value), children: [
11485
- /* @__PURE__ */ jsx15("option", { value: "reference", children: "reference" }),
11486
- /* @__PURE__ */ jsx15("option", { value: "mask", children: "mask" }),
11487
- /* @__PURE__ */ jsx15("option", { value: "palette", children: "palette" }),
11488
- /* @__PURE__ */ jsx15("option", { value: "example", children: "example" })
11471
+ checked: zeigeStillgelegte,
11472
+ onChange: (e) => setZeigeStillgelegte(e.target.checked)
11473
+ }
11474
+ ),
11475
+ "stillgelegte Elemente einblenden"
11476
+ ] }),
11477
+ /* @__PURE__ */ jsx11("button", { type: "button", "data-testid": "neu-laden", onClick: neuLaden, children: "neu laden" })
11478
+ ] })
11489
11479
  ] })
11490
11480
  ] }),
11491
- /* @__PURE__ */ jsxs15("label", { children: [
11492
- "Position",
11493
- /* @__PURE__ */ jsx15("input", { type: "number", min: "0", value: position, onChange: (event) => setPosition(event.target.value) })
11494
- ] }),
11495
- /* @__PURE__ */ jsx15("button", { type: "button", disabled: busy, onClick: zuordnen, children: "zuordnen" })
11496
- ] }),
11497
- versionPhase.status === "loading" && versionId && /* @__PURE__ */ jsx15("p", { children: "Versionsmedien werden geladen \u2026" }),
11498
- versionPhase.status === "error" && /* @__PURE__ */ jsxs15("p", { role: "alert", children: [
11499
- "Versionsmedien konnten nicht geladen werden: ",
11500
- versionPhase.message
11501
- ] }),
11502
- versionPhase.status === "ready" && versionId && versionMedien.length === 0 && /* @__PURE__ */ jsxs15("p", { children: [
11503
- "Version ",
11504
- versionId,
11505
- " hat keine Medien."
11506
- ] }),
11507
- /* @__PURE__ */ jsx15("ul", { className: "szenen-media__list", children: versionMedien.map((medium) => /* @__PURE__ */ jsxs15("li", { children: [
11508
- /* @__PURE__ */ jsx15("code", { children: medium.assetId }),
11509
- /* @__PURE__ */ jsxs15("span", { children: [
11510
- medium.role,
11511
- " \xB7 Position ",
11512
- medium.position
11513
- ] }),
11514
- medium.url && /* @__PURE__ */ jsx15("a", { href: medium.url, target: "_blank", rel: "noreferrer", children: "\xF6ffnen" }),
11515
- /* @__PURE__ */ jsx15("button", { type: "button", disabled: busy, onClick: () => entfernen(medium), children: "entfernen" })
11516
- ] }, `${medium.assetId}:${medium.role}`)) })
11517
- ] }),
11518
- /* @__PURE__ */ jsxs15("section", { children: [
11519
- /* @__PURE__ */ jsx15("h3", { children: "Item-Medien" }),
11520
- /* @__PURE__ */ jsxs15("div", { className: "szenen-media__lookup", children: [
11521
- /* @__PURE__ */ jsxs15("label", { children: [
11522
- "Item-ID",
11523
- /* @__PURE__ */ jsx15("input", { value: itemInput, onChange: (event) => setItemInput(event.target.value) })
11524
- ] }),
11525
- /* @__PURE__ */ jsx15("button", { type: "button", onClick: () => setItemId(itemInput.trim()), children: "Item-Medien laden" })
11526
- ] }),
11527
- itemPhase.status === "error" && /* @__PURE__ */ jsxs15("p", { role: "alert", children: [
11528
- "Item-Medien konnten nicht geladen werden: ",
11529
- itemPhase.message
11530
- ] }),
11531
- /* @__PURE__ */ jsx15("ul", { className: "szenen-media__list", children: itemMedien.map((medium) => /* @__PURE__ */ jsxs15("li", { children: [
11532
- /* @__PURE__ */ jsx15("code", { children: medium.assetId }),
11533
- /* @__PURE__ */ jsxs15("span", { children: [
11534
- medium.role,
11535
- " \xB7 Position ",
11536
- medium.position
11537
- ] }),
11538
- medium.url && /* @__PURE__ */ jsx15("a", { href: medium.url, target: "_blank", rel: "noreferrer", children: "\xF6ffnen" })
11539
- ] }, `${medium.assetId}:${medium.role}:${medium.position}`)) })
11540
- ] }),
11541
- notiz && /* @__PURE__ */ jsx15("p", { role: notiz.tone === "error" ? "alert" : "status", "data-tone": notiz.tone, children: notiz.text })
11542
- ] });
11481
+ zeigeDetail && /* @__PURE__ */ jsxs11("div", { className: "szenen-elements__detail", "data-testid": "elemente-detail-spalte", children: [
11482
+ schmal && /* @__PURE__ */ jsx11(
11483
+ "button",
11484
+ {
11485
+ type: "button",
11486
+ className: "szenen-elements__back",
11487
+ "data-testid": "zurueck-zur-liste",
11488
+ onClick: () => setAnsicht("liste"),
11489
+ children: "\u2190 Zur\xFCck zur Liste"
11490
+ }
11491
+ ),
11492
+ gewaehlt ? /* @__PURE__ */ jsx11(
11493
+ ElementDetail,
11494
+ {
11495
+ port,
11496
+ elementId: gewaehlt,
11497
+ contextId,
11498
+ author,
11499
+ onChanged: neuLaden
11500
+ }
11501
+ ) : /* @__PURE__ */ jsx11("p", { className: "szenen-elements__empty-detail", "data-testid": "keine-auswahl", children: "Nichts ausgew\xE4hlt. Ein Eintrag aus der Liste \xF6ffnet die Bearbeitung." })
11502
+ ] })
11503
+ ]
11504
+ }
11505
+ );
11543
11506
  };
11544
11507
 
11508
+ // src/features/szenen/areas/SceneArea.tsx
11509
+ import { useState as useState17 } from "react";
11510
+
11545
11511
  // src/features/szenen/areas/DeriveArea.tsx
11546
- import { useEffect as useEffect8, useMemo as useMemo3, useRef as useRef4, useState as useState16 } from "react";
11512
+ import { useEffect as useEffect9, useMemo as useMemo3, useRef as useRef4, useState as useState16 } from "react";
11547
11513
 
11548
11514
  // src/features/szenen/areas/RecoveryPanel.tsx
11549
11515
  import { useState as useState14 } from "react";
11550
- import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
11516
+ import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
11551
11517
  var Diagnosen = ({ befunde, testId }) => {
11552
11518
  if (befunde.length === 0) return null;
11553
- return /* @__PURE__ */ jsx16("ul", { className: "szenen-diagnose__liste", "data-testid": testId, children: befunde.map((d, i) => /* @__PURE__ */ jsxs16("li", { "data-severity": d.severity, children: [
11554
- /* @__PURE__ */ jsx16("code", { children: d.code }),
11555
- d.proposal_type && /* @__PURE__ */ jsxs16(Fragment6, { children: [
11519
+ return /* @__PURE__ */ jsx12("ul", { className: "szenen-diagnose__liste", "data-testid": testId, children: befunde.map((d, i) => /* @__PURE__ */ jsxs12("li", { "data-severity": d.severity, children: [
11520
+ /* @__PURE__ */ jsx12("code", { children: d.code }),
11521
+ d.proposal_type && /* @__PURE__ */ jsxs12(Fragment6, { children: [
11556
11522
  " \xB7 ",
11557
- /* @__PURE__ */ jsx16("strong", { children: d.proposal_type })
11523
+ /* @__PURE__ */ jsx12("strong", { children: d.proposal_type })
11558
11524
  ] }),
11559
- d.pointer && /* @__PURE__ */ jsxs16(Fragment6, { children: [
11525
+ d.pointer && /* @__PURE__ */ jsxs12(Fragment6, { children: [
11560
11526
  " \xB7 ",
11561
- /* @__PURE__ */ jsx16("code", { children: d.pointer })
11527
+ /* @__PURE__ */ jsx12("code", { children: d.pointer })
11562
11528
  ] }),
11563
- typeof d.line === "number" && /* @__PURE__ */ jsxs16(Fragment6, { children: [
11529
+ typeof d.line === "number" && /* @__PURE__ */ jsxs12(Fragment6, { children: [
11564
11530
  " \xB7 Zeile ",
11565
11531
  d.line,
11566
11532
  ", Spalte ",
11567
11533
  d.column
11568
11534
  ] }),
11569
- /* @__PURE__ */ jsx16("div", { children: d.message })
11535
+ /* @__PURE__ */ jsx12("div", { children: d.message })
11570
11536
  ] }, i)) });
11571
11537
  };
11572
- var Ausbeute = ({ bewertung }) => /* @__PURE__ */ jsxs16("div", { className: "szenen-diagnose", "data-testid": "rettung-ergebnis", children: [
11573
- /* @__PURE__ */ jsxs16("p", { "data-testid": "rettung-status", children: [
11538
+ var Ausbeute = ({ bewertung }) => /* @__PURE__ */ jsxs12("div", { className: "szenen-diagnose", "data-testid": "rettung-ergebnis", children: [
11539
+ /* @__PURE__ */ jsxs12("p", { "data-testid": "rettung-status", children: [
11574
11540
  bewertung.status === "usable" && "Diese Fassung ist vollst\xE4ndig verwertbar.",
11575
11541
  bewertung.status === "partial" && "Diese Fassung ist teilweise verwertbar \u2014 nicht alles kommt durch.",
11576
11542
  bewertung.status === "invalid" && "Aus dieser Fassung ist nichts zu \xFCbernehmen."
11577
11543
  ] }),
11578
- bewertung.proposals.length > 0 && /* @__PURE__ */ jsxs16(Fragment6, { children: [
11579
- /* @__PURE__ */ jsx16("h5", { children: "Verwertbar" }),
11580
- /* @__PURE__ */ jsx16("ul", { "data-testid": "rettung-verwertbar", children: bewertung.proposals.map((p) => /* @__PURE__ */ jsxs16("li", { "data-testid": `rettung-verwertbar-${p.type}`, children: [
11581
- /* @__PURE__ */ jsx16("strong", { children: p.type }),
11544
+ bewertung.proposals.length > 0 && /* @__PURE__ */ jsxs12(Fragment6, { children: [
11545
+ /* @__PURE__ */ jsx12("h5", { children: "Verwertbar" }),
11546
+ /* @__PURE__ */ jsx12("ul", { "data-testid": "rettung-verwertbar", children: bewertung.proposals.map((p) => /* @__PURE__ */ jsxs12("li", { "data-testid": `rettung-verwertbar-${p.type}`, children: [
11547
+ /* @__PURE__ */ jsx12("strong", { children: p.type }),
11582
11548
  " \u2014 ",
11583
11549
  p.status === "complete" ? "vollst\xE4ndig" : "teilweise; vor dem Ver\xF6ffentlichen zu erg\xE4nzen",
11584
- p.status === "partial" && p.gaps && p.gaps.length > 0 && /* @__PURE__ */ jsx16("ul", { children: p.gaps.map((l, i) => /* @__PURE__ */ jsxs16("li", { children: [
11585
- /* @__PURE__ */ jsx16("code", { children: l.pointer }),
11550
+ p.status === "partial" && p.gaps && p.gaps.length > 0 && /* @__PURE__ */ jsx12("ul", { children: p.gaps.map((l, i) => /* @__PURE__ */ jsxs12("li", { children: [
11551
+ /* @__PURE__ */ jsx12("code", { children: l.pointer }),
11586
11552
  ": ",
11587
11553
  l.reason
11588
11554
  ] }, i)) })
11589
11555
  ] }, p.type)) })
11590
11556
  ] }),
11591
- bewertung.rejected.length > 0 && /* @__PURE__ */ jsxs16(Fragment6, { children: [
11592
- /* @__PURE__ */ jsx16("h5", { children: "Nicht verwertbar" }),
11593
- /* @__PURE__ */ jsx16("ul", { "data-testid": "rettung-abgelehnt", children: bewertung.rejected.map((r) => /* @__PURE__ */ jsxs16("li", { "data-testid": `rettung-abgelehnt-${r.type}`, children: [
11594
- /* @__PURE__ */ jsx16("strong", { children: r.type }),
11595
- /* @__PURE__ */ jsx16(Diagnosen, { befunde: r.diagnostics, testId: `rettung-grund-${r.type}` })
11557
+ bewertung.rejected.length > 0 && /* @__PURE__ */ jsxs12(Fragment6, { children: [
11558
+ /* @__PURE__ */ jsx12("h5", { children: "Nicht verwertbar" }),
11559
+ /* @__PURE__ */ jsx12("ul", { "data-testid": "rettung-abgelehnt", children: bewertung.rejected.map((r) => /* @__PURE__ */ jsxs12("li", { "data-testid": `rettung-abgelehnt-${r.type}`, children: [
11560
+ /* @__PURE__ */ jsx12("strong", { children: r.type }),
11561
+ /* @__PURE__ */ jsx12(Diagnosen, { befunde: r.diagnostics, testId: `rettung-grund-${r.type}` })
11596
11562
  ] }, r.type)) })
11597
11563
  ] })
11598
11564
  ] });
@@ -11637,16 +11603,16 @@ var RecoveryPanel = ({ port, lauf }) => {
11637
11603
  setLaeuft(false);
11638
11604
  }
11639
11605
  }
11640
- return /* @__PURE__ */ jsxs16("section", { className: "szenen-rettung", "data-testid": "rettung", children: [
11641
- /* @__PURE__ */ jsx16("h4", { children: "Antwort retten" }),
11642
- /* @__PURE__ */ jsxs16("p", { className: "szenen-area__lead", children: [
11606
+ return /* @__PURE__ */ jsxs12("section", { className: "szenen-rettung", "data-testid": "rettung", children: [
11607
+ /* @__PURE__ */ jsx12("h4", { children: "Antwort retten" }),
11608
+ /* @__PURE__ */ jsxs12("p", { className: "szenen-area__lead", children: [
11643
11609
  "Der Lauf ist bezahlt und seine Antwort liegt vor. Sie l\xE4sst sich hier pr\xFCfen und korrigieren \u2014 ",
11644
- /* @__PURE__ */ jsx16("strong", { children: "ohne" }),
11610
+ /* @__PURE__ */ jsx12("strong", { children: "ohne" }),
11645
11611
  " einen weiteren Modellaufruf. Das Original bleibt unver\xE4ndert."
11646
11612
  ] }),
11647
- /* @__PURE__ */ jsxs16("label", { className: "szenen-field", children: [
11648
- /* @__PURE__ */ jsx16("span", { children: "Original der Modellantwort (unver\xE4nderlich)" }),
11649
- /* @__PURE__ */ jsx16(
11613
+ /* @__PURE__ */ jsxs12("label", { className: "szenen-field", children: [
11614
+ /* @__PURE__ */ jsx12("span", { children: "Original der Modellantwort (unver\xE4nderlich)" }),
11615
+ /* @__PURE__ */ jsx12(
11650
11616
  "textarea",
11651
11617
  {
11652
11618
  readOnly: true,
@@ -11657,12 +11623,12 @@ var RecoveryPanel = ({ port, lauf }) => {
11657
11623
  }
11658
11624
  )
11659
11625
  ] }),
11660
- /* @__PURE__ */ jsxs16("label", { className: "szenen-field", children: [
11661
- /* @__PURE__ */ jsxs16("span", { children: [
11626
+ /* @__PURE__ */ jsxs12("label", { className: "szenen-field", children: [
11627
+ /* @__PURE__ */ jsxs12("span", { children: [
11662
11628
  "Arbeitskopie",
11663
11629
  bearbeitet ? " (bearbeitet)" : ""
11664
11630
  ] }),
11665
- /* @__PURE__ */ jsx16(
11631
+ /* @__PURE__ */ jsx12(
11666
11632
  "textarea",
11667
11633
  {
11668
11634
  rows: 8,
@@ -11672,8 +11638,8 @@ var RecoveryPanel = ({ port, lauf }) => {
11672
11638
  }
11673
11639
  )
11674
11640
  ] }),
11675
- /* @__PURE__ */ jsxs16("div", { className: "szenen-rettung__aktionen", children: [
11676
- /* @__PURE__ */ jsx16(
11641
+ /* @__PURE__ */ jsxs12("div", { className: "szenen-rettung__aktionen", children: [
11642
+ /* @__PURE__ */ jsx12(
11677
11643
  "button",
11678
11644
  {
11679
11645
  type: "button",
@@ -11683,7 +11649,7 @@ var RecoveryPanel = ({ port, lauf }) => {
11683
11649
  children: "Arbeitskopie pr\xFCfen (kein Modellaufruf)"
11684
11650
  }
11685
11651
  ),
11686
- /* @__PURE__ */ jsx16(
11652
+ /* @__PURE__ */ jsx12(
11687
11653
  "button",
11688
11654
  {
11689
11655
  type: "button",
@@ -11693,7 +11659,7 @@ var RecoveryPanel = ({ port, lauf }) => {
11693
11659
  children: "Arbeitsfassung speichern"
11694
11660
  }
11695
11661
  ),
11696
- arbeitskopie !== null && /* @__PURE__ */ jsx16(
11662
+ arbeitskopie !== null && /* @__PURE__ */ jsx12(
11697
11663
  "button",
11698
11664
  {
11699
11665
  type: "button",
@@ -11708,15 +11674,15 @@ var RecoveryPanel = ({ port, lauf }) => {
11708
11674
  }
11709
11675
  )
11710
11676
  ] }),
11711
- meldung && /* @__PURE__ */ jsx16("p", { className: "szenen-error", role: "alert", "data-testid": "rettung-meldung", children: meldung }),
11712
- bewertung && /* @__PURE__ */ jsx16(Ausbeute, { bewertung }),
11713
- bewertung && bewertung.diagnostics.length > 0 && /* @__PURE__ */ jsxs16("div", { className: "szenen-diagnose", children: [
11714
- /* @__PURE__ */ jsx16("h5", { children: "Befunde an dieser Fassung" }),
11715
- /* @__PURE__ */ jsx16(Diagnosen, { befunde: bewertung.diagnostics, testId: "rettung-befunde" })
11677
+ meldung && /* @__PURE__ */ jsx12("p", { className: "szenen-error", role: "alert", "data-testid": "rettung-meldung", children: meldung }),
11678
+ bewertung && /* @__PURE__ */ jsx12(Ausbeute, { bewertung }),
11679
+ bewertung && bewertung.diagnostics.length > 0 && /* @__PURE__ */ jsxs12("div", { className: "szenen-diagnose", children: [
11680
+ /* @__PURE__ */ jsx12("h5", { children: "Befunde an dieser Fassung" }),
11681
+ /* @__PURE__ */ jsx12(Diagnosen, { befunde: bewertung.diagnostics, testId: "rettung-befunde" })
11716
11682
  ] }),
11717
- gesichert && /* @__PURE__ */ jsxs16("p", { "data-testid": "rettung-gesichert", children: [
11683
+ gesichert && /* @__PURE__ */ jsxs12("p", { "data-testid": "rettung-gesichert", children: [
11718
11684
  "Gespeichert als Arbeitsfassung ",
11719
- /* @__PURE__ */ jsx16("code", { children: gesichert.recovery_id }),
11685
+ /* @__PURE__ */ jsx12("code", { children: gesichert.recovery_id }),
11720
11686
  gesichert.edited ? " (bearbeitet)" : " (unver\xE4ndert)",
11721
11687
  ". Das Original des Laufs ist davon unber\xFChrt."
11722
11688
  ] })
@@ -11725,7 +11691,7 @@ var RecoveryPanel = ({ port, lauf }) => {
11725
11691
 
11726
11692
  // src/features/szenen/areas/ChainActions.tsx
11727
11693
  import { useState as useState15 } from "react";
11728
- import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
11694
+ import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
11729
11695
  var ChainActions = ({ port, runId, recoveryId }) => {
11730
11696
  const [graph, setGraph] = useState15(null);
11731
11697
  const [meldung, setMeldung] = useState15(null);
@@ -11751,14 +11717,14 @@ var ChainActions = ({ port, runId, recoveryId }) => {
11751
11717
  setLaeuft(false);
11752
11718
  }
11753
11719
  }
11754
- return /* @__PURE__ */ jsxs17("section", { className: "szenen-kette", "data-testid": "kette", children: [
11755
- /* @__PURE__ */ jsx17("h4", { children: "Draft-Kette" }),
11756
- /* @__PURE__ */ jsxs17("p", { className: "szenen-area__lead", children: [
11720
+ return /* @__PURE__ */ jsxs13("section", { className: "szenen-kette", "data-testid": "kette", children: [
11721
+ /* @__PURE__ */ jsx13("h4", { children: "Draft-Kette" }),
11722
+ /* @__PURE__ */ jsxs13("p", { className: "szenen-area__lead", children: [
11757
11723
  "Szene, Aufbau und Shot entstehen als zusammenh\xE4ngende Entw\xFCrfe. Daraus l\xE4sst sich sofort ein Prompt erzeugen \u2014 ",
11758
- /* @__PURE__ */ jsx17("strong", { children: "ohne" }),
11724
+ /* @__PURE__ */ jsx13("strong", { children: "ohne" }),
11759
11725
  " vorher etwas zu ver\xF6ffentlichen."
11760
11726
  ] }),
11761
- !graph && /* @__PURE__ */ jsx17(
11727
+ !graph && /* @__PURE__ */ jsx13(
11762
11728
  "button",
11763
11729
  {
11764
11730
  type: "button",
@@ -11768,34 +11734,34 @@ var ChainActions = ({ port, runId, recoveryId }) => {
11768
11734
  children: "Als Draft-Kette \xFCbernehmen"
11769
11735
  }
11770
11736
  ),
11771
- graph && /* @__PURE__ */ jsxs17("div", { "data-testid": "kette-ergebnis", children: [
11772
- /* @__PURE__ */ jsxs17("p", { children: [
11737
+ graph && /* @__PURE__ */ jsxs13("div", { "data-testid": "kette-ergebnis", children: [
11738
+ /* @__PURE__ */ jsxs13("p", { children: [
11773
11739
  "Kette ",
11774
- /* @__PURE__ */ jsx17("code", { children: graph.chainId }),
11740
+ /* @__PURE__ */ jsx13("code", { children: graph.chainId }),
11775
11741
  " angelegt. Kein Knoten ist ver\xF6ffentlicht."
11776
11742
  ] }),
11777
- /* @__PURE__ */ jsx17("ul", { "data-testid": "kette-knoten", children: graph.created.map((k) => /* @__PURE__ */ jsxs17("li", { "data-testid": `kette-knoten-${k.type}`, children: [
11778
- /* @__PURE__ */ jsx17("strong", { children: k.type }),
11743
+ /* @__PURE__ */ jsx13("ul", { "data-testid": "kette-knoten", children: graph.created.map((k) => /* @__PURE__ */ jsxs13("li", { "data-testid": `kette-knoten-${k.type}`, children: [
11744
+ /* @__PURE__ */ jsx13("strong", { children: k.type }),
11779
11745
  " \u2014 Element ",
11780
- /* @__PURE__ */ jsx17("code", { children: k.elementId }),
11746
+ /* @__PURE__ */ jsx13("code", { children: k.elementId }),
11781
11747
  ", Entwurf ",
11782
- /* @__PURE__ */ jsx17("code", { children: k.draftId }),
11748
+ /* @__PURE__ */ jsx13("code", { children: k.draftId }),
11783
11749
  " (Revision ",
11784
11750
  k.revision,
11785
11751
  ")"
11786
11752
  ] }, k.type)) }),
11787
- graph.missing.length > 0 && /* @__PURE__ */ jsxs17("div", { className: "szenen-diagnose", "data-testid": "kette-fehlend", children: [
11788
- /* @__PURE__ */ jsx17("h5", { children: "Unvollst\xE4ndig erzeugt" }),
11789
- /* @__PURE__ */ jsx17("ul", { children: graph.missing.map((m) => /* @__PURE__ */ jsxs17("li", { children: [
11790
- /* @__PURE__ */ jsx17("strong", { children: m.type }),
11753
+ graph.missing.length > 0 && /* @__PURE__ */ jsxs13("div", { className: "szenen-diagnose", "data-testid": "kette-fehlend", children: [
11754
+ /* @__PURE__ */ jsx13("h5", { children: "Unvollst\xE4ndig erzeugt" }),
11755
+ /* @__PURE__ */ jsx13("ul", { children: graph.missing.map((m) => /* @__PURE__ */ jsxs13("li", { children: [
11756
+ /* @__PURE__ */ jsx13("strong", { children: m.type }),
11791
11757
  ": ",
11792
11758
  m.reason
11793
11759
  ] }, m.type)) })
11794
11760
  ] })
11795
11761
  ] }),
11796
- shotKnoten && /* @__PURE__ */ jsxs17(Fragment7, { children: [
11797
- /* @__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".' }),
11798
- /* @__PURE__ */ jsx17(
11762
+ shotKnoten && /* @__PURE__ */ jsxs13(Fragment7, { children: [
11763
+ /* @__PURE__ */ jsx13("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".' }),
11764
+ /* @__PURE__ */ jsx13(
11799
11765
  PromptStartAction,
11800
11766
  {
11801
11767
  port,
@@ -11803,12 +11769,12 @@ var ChainActions = ({ port, runId, recoveryId }) => {
11803
11769
  }
11804
11770
  )
11805
11771
  ] }),
11806
- meldung && /* @__PURE__ */ jsx17("p", { className: "szenen-error", role: "alert", "data-testid": "kette-meldung", children: meldung })
11772
+ meldung && /* @__PURE__ */ jsx13("p", { className: "szenen-error", role: "alert", "data-testid": "kette-meldung", children: meldung })
11807
11773
  ] });
11808
11774
  };
11809
11775
 
11810
11776
  // src/features/szenen/areas/DeriveArea.tsx
11811
- import { Fragment as Fragment8, jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
11777
+ import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
11812
11778
  var MODUS_TEXT = {
11813
11779
  prompt: "Nur Prompt",
11814
11780
  image: "Nur Bild",
@@ -11826,15 +11792,15 @@ var BelegFeld = ({ titel, text, testId, offen }) => {
11826
11792
  setKopiert(false);
11827
11793
  }
11828
11794
  }
11829
- return /* @__PURE__ */ jsxs18("details", { open: offen, "data-testid": `belege-${testId}`, children: [
11830
- /* @__PURE__ */ jsxs18("summary", { children: [
11795
+ return /* @__PURE__ */ jsxs14("details", { open: offen, "data-testid": `belege-${testId}`, children: [
11796
+ /* @__PURE__ */ jsxs14("summary", { children: [
11831
11797
  titel,
11832
11798
  " (",
11833
11799
  text.length,
11834
11800
  " Zeichen)"
11835
11801
  ] }),
11836
- /* @__PURE__ */ jsxs18("div", { className: "szenen-beleg__kopf", children: [
11837
- /* @__PURE__ */ jsx18(
11802
+ /* @__PURE__ */ jsxs14("div", { className: "szenen-beleg__kopf", children: [
11803
+ /* @__PURE__ */ jsx14(
11838
11804
  "button",
11839
11805
  {
11840
11806
  type: "button",
@@ -11843,9 +11809,9 @@ var BelegFeld = ({ titel, text, testId, offen }) => {
11843
11809
  children: "Kopieren"
11844
11810
  }
11845
11811
  ),
11846
- kopiert && /* @__PURE__ */ jsx18("span", { "data-testid": `kopiert-${testId}`, children: "Kopiert." })
11812
+ kopiert && /* @__PURE__ */ jsx14("span", { "data-testid": `kopiert-${testId}`, children: "Kopiert." })
11847
11813
  ] }),
11848
- /* @__PURE__ */ jsx18(
11814
+ /* @__PURE__ */ jsx14(
11849
11815
  "textarea",
11850
11816
  {
11851
11817
  ref: feld,
@@ -11859,8 +11825,8 @@ var BelegFeld = ({ titel, text, testId, offen }) => {
11859
11825
  )
11860
11826
  ] });
11861
11827
  };
11862
- var Belege = ({ lauf }) => /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose", "data-testid": "belege", children: [
11863
- lauf.raw_output ? /* @__PURE__ */ jsx18(
11828
+ var Belege = ({ lauf }) => /* @__PURE__ */ jsxs14("div", { className: "szenen-diagnose", "data-testid": "belege", children: [
11829
+ lauf.raw_output ? /* @__PURE__ */ jsx14(
11864
11830
  BelegFeld,
11865
11831
  {
11866
11832
  titel: "Rohantwort des Modells",
@@ -11871,9 +11837,9 @@ var Belege = ({ lauf }) => /* @__PURE__ */ jsxs18("div", { className: "szenen-di
11871
11837
  ) : (
11872
11838
  /* Kein Text ist auch eine Auskunft: Der Provider hat nichts geliefert,
11873
11839
  das Modell hat also nicht „falsch geantwortet". */
11874
- /* @__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)." })
11840
+ /* @__PURE__ */ jsx14("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)." })
11875
11841
  ),
11876
- /* @__PURE__ */ jsx18(
11842
+ /* @__PURE__ */ jsx14(
11877
11843
  BelegFeld,
11878
11844
  {
11879
11845
  titel: "Systemprompt dieses Laufs",
@@ -11885,18 +11851,18 @@ var Belege = ({ lauf }) => /* @__PURE__ */ jsxs18("div", { className: "szenen-di
11885
11851
  ] });
11886
11852
  var Herkunft = ({ lauf }) => {
11887
11853
  if (!lauf.follows) return null;
11888
- return /* @__PURE__ */ jsxs18("p", { className: "szenen-run__herkunft", "data-testid": "folgt-auf", children: [
11854
+ return /* @__PURE__ */ jsxs14("p", { className: "szenen-run__herkunft", "data-testid": "folgt-auf", children: [
11889
11855
  "Folgt auf Lauf ",
11890
- /* @__PURE__ */ jsx18("code", { children: lauf.follows.run_id }),
11856
+ /* @__PURE__ */ jsx14("code", { children: lauf.follows.run_id }),
11891
11857
  ".",
11892
11858
  lauf.status === "succeeded" && " Im Folgelauf gelungen."
11893
11859
  ] });
11894
11860
  };
11895
11861
  var Widerspruch = ({ lauf }) => {
11896
11862
  if (!lauf.reply) return null;
11897
- return /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose szenen-diagnose--antwort", "data-testid": "modell-antwort", children: [
11898
- /* @__PURE__ */ jsx18("h4", { children: "Das Modell antwortet auf die Beanstandung" }),
11899
- /* @__PURE__ */ jsx18("p", { children: lauf.reply })
11863
+ return /* @__PURE__ */ jsxs14("div", { className: "szenen-diagnose szenen-diagnose--antwort", "data-testid": "modell-antwort", children: [
11864
+ /* @__PURE__ */ jsx14("h4", { children: "Das Modell antwortet auf die Beanstandung" }),
11865
+ /* @__PURE__ */ jsx14("p", { children: lauf.reply })
11900
11866
  ] });
11901
11867
  };
11902
11868
  function readAsBase642(datei) {
@@ -11915,7 +11881,7 @@ var ERSTE_KACHELN = 12;
11915
11881
  function useSichtbareKacheln(alle, wurzel) {
11916
11882
  const [gesehen, setGesehen] = useState16([]);
11917
11883
  const schluessel = alle.join(" ");
11918
- useEffect8(() => {
11884
+ useEffect9(() => {
11919
11885
  const ziel = wurzel.current;
11920
11886
  if (!ziel || typeof IntersectionObserver === "undefined") return void 0;
11921
11887
  const beobachter = new IntersectionObserver((eintraege) => {
@@ -11937,7 +11903,7 @@ function useVorschauen(port, mediaRefs) {
11937
11903
  const gehalten = useRef4(/* @__PURE__ */ new Map());
11938
11904
  const ohneBild = useRef4(/* @__PURE__ */ new Set());
11939
11905
  const schluessel = mediaRefs.join(" ");
11940
- useEffect8(() => {
11906
+ useEffect9(() => {
11941
11907
  const bestand = port.imageLibrary;
11942
11908
  if (!bestand?.loadPreview) return void 0;
11943
11909
  const refs = schluessel ? schluessel.split(" ") : [];
@@ -12003,10 +11969,10 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12003
11969
  if (item.images.length === 1) onWaehlen(deckbild);
12004
11970
  else setFokus(item.itemRef === fokus ? null : item.itemRef);
12005
11971
  }
12006
- return /* @__PURE__ */ jsxs18("div", { className: "szenen-bildwahl", "data-testid": "bildwahl", children: [
12007
- /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
12008
- /* @__PURE__ */ jsx18("span", { children: "Bild aus dem Bestand" }),
12009
- /* @__PURE__ */ jsx18(
11972
+ return /* @__PURE__ */ jsxs14("div", { className: "szenen-bildwahl", "data-testid": "bildwahl", children: [
11973
+ /* @__PURE__ */ jsxs14("label", { className: "szenen-field", children: [
11974
+ /* @__PURE__ */ jsx14("span", { children: "Bild aus dem Bestand" }),
11975
+ /* @__PURE__ */ jsx14(
12010
11976
  "input",
12011
11977
  {
12012
11978
  type: "search",
@@ -12020,23 +11986,23 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12020
11986
  }
12021
11987
  )
12022
11988
  ] }),
12023
- items.status === "loading" && /* @__PURE__ */ jsx18("p", { children: "Bilder werden geladen \u2026" }),
12024
- items.status === "error" && /* @__PURE__ */ jsxs18("p", { className: "szenen-error", role: "alert", children: [
11989
+ items.status === "loading" && /* @__PURE__ */ jsx14("p", { children: "Bilder werden geladen \u2026" }),
11990
+ items.status === "error" && /* @__PURE__ */ jsxs14("p", { className: "szenen-error", role: "alert", children: [
12025
11991
  "Der Bildbestand ist nicht lesbar: ",
12026
11992
  items.message
12027
11993
  ] }),
12028
- 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." }),
12029
- werke.length > 0 && /* @__PURE__ */ jsx18(
11994
+ items.status === "ready" && werke.length === 0 && /* @__PURE__ */ jsx14("p", { className: "szenen-empty", "data-testid": "bildwahl-leer", children: "Zu dieser Suche gibt es kein Bild. Ohne Treffer bleibt der Upload." }),
11995
+ werke.length > 0 && /* @__PURE__ */ jsx14(
12030
11996
  "div",
12031
11997
  {
12032
11998
  className: "szenen-bildwahl__browser",
12033
11999
  ref: browser,
12034
12000
  "data-testid": "bildwahl-werke",
12035
- children: /* @__PURE__ */ jsx18("ul", { className: "szenen-bildwahl__raster", children: werke.map((item) => {
12001
+ children: /* @__PURE__ */ jsx14("ul", { className: "szenen-bildwahl__raster", children: werke.map((item) => {
12036
12002
  const deckbild = item.images[0];
12037
12003
  if (!deckbild) return null;
12038
12004
  const fokussiert = item.itemRef === fokus;
12039
- return /* @__PURE__ */ jsx18("li", { "data-media-ref": deckbild.mediaRef, children: /* @__PURE__ */ jsxs18(
12005
+ return /* @__PURE__ */ jsx14("li", { "data-media-ref": deckbild.mediaRef, children: /* @__PURE__ */ jsxs14(
12040
12006
  "button",
12041
12007
  {
12042
12008
  type: "button",
@@ -12046,7 +12012,7 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12046
12012
  "data-testid": `item-waehlen-${item.itemRef}`,
12047
12013
  title: item.title,
12048
12014
  children: [
12049
- /* @__PURE__ */ jsx18(
12015
+ /* @__PURE__ */ jsx14(
12050
12016
  Kachel,
12051
12017
  {
12052
12018
  quelle: quelleVon(deckbild),
@@ -12054,7 +12020,7 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12054
12020
  ...gescheitert.has(deckbild.mediaRef) ? { leerText: "Vorschau fehlt" } : {}
12055
12021
  }
12056
12022
  ),
12057
- item.images.length > 1 && /* @__PURE__ */ jsxs18(
12023
+ item.images.length > 1 && /* @__PURE__ */ jsxs14(
12058
12024
  "span",
12059
12025
  {
12060
12026
  className: "szenen-bildwahl__anzahl",
@@ -12065,22 +12031,22 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12065
12031
  ]
12066
12032
  }
12067
12033
  ),
12068
- /* @__PURE__ */ jsx18("span", { className: "szenen-bildwahl__kacheltitel", children: item.title })
12034
+ /* @__PURE__ */ jsx14("span", { className: "szenen-bildwahl__kacheltitel", children: item.title })
12069
12035
  ]
12070
12036
  }
12071
12037
  ) }, item.itemRef);
12072
12038
  }) })
12073
12039
  }
12074
12040
  ),
12075
- werk && /* @__PURE__ */ jsxs18("section", { className: "szenen-bildwahl__inspector", "data-testid": "bildwahl-galerie", children: [
12076
- /* @__PURE__ */ jsxs18("header", { className: "szenen-bildwahl__inspektorkopf", children: [
12077
- /* @__PURE__ */ jsxs18("span", { className: "szenen-bildwahl__werktitel", "data-testid": "bildwahl-werktitel", children: [
12041
+ werk && /* @__PURE__ */ jsxs14("section", { className: "szenen-bildwahl__inspector", "data-testid": "bildwahl-galerie", children: [
12042
+ /* @__PURE__ */ jsxs14("header", { className: "szenen-bildwahl__inspektorkopf", children: [
12043
+ /* @__PURE__ */ jsxs14("span", { className: "szenen-bildwahl__werktitel", "data-testid": "bildwahl-werktitel", children: [
12078
12044
  werk.title,
12079
12045
  " \xB7 ",
12080
12046
  werk.images.length,
12081
12047
  " Bilder"
12082
12048
  ] }),
12083
- /* @__PURE__ */ jsx18(
12049
+ /* @__PURE__ */ jsx14(
12084
12050
  "button",
12085
12051
  {
12086
12052
  type: "button",
@@ -12091,7 +12057,7 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12091
12057
  }
12092
12058
  )
12093
12059
  ] }),
12094
- /* @__PURE__ */ jsx18("ul", { className: "szenen-bildwahl__streifen", children: werk.images.map((bild, position) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsxs18(
12060
+ /* @__PURE__ */ jsx14("ul", { className: "szenen-bildwahl__streifen", children: werk.images.map((bild, position) => /* @__PURE__ */ jsx14("li", { children: /* @__PURE__ */ jsxs14(
12095
12061
  "button",
12096
12062
  {
12097
12063
  type: "button",
@@ -12101,7 +12067,7 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12101
12067
  "data-testid": `bild-waehlen-${bild.mediaRef}`,
12102
12068
  title: bild.title,
12103
12069
  children: [
12104
- /* @__PURE__ */ jsx18(
12070
+ /* @__PURE__ */ jsx14(
12105
12071
  Kachel,
12106
12072
  {
12107
12073
  quelle: quelleVon(bild),
@@ -12109,7 +12075,7 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12109
12075
  ...gescheitert.has(bild.mediaRef) ? { leerText: "Vorschau fehlt" } : {}
12110
12076
  }
12111
12077
  ),
12112
- /* @__PURE__ */ jsxs18("span", { className: "szenen-bildwahl__nummer", children: [
12078
+ /* @__PURE__ */ jsxs14("span", { className: "szenen-bildwahl__nummer", children: [
12113
12079
  "#",
12114
12080
  position + 1
12115
12081
  ] })
@@ -12117,10 +12083,10 @@ var BildWaehler = ({ port, gewaehlt, onWaehlen, onEntfernen }) => {
12117
12083
  }
12118
12084
  ) }, bild.mediaRef)) })
12119
12085
  ] }),
12120
- gewaehlt.length > 0 && /* @__PURE__ */ jsx18("ul", { className: "szenen-bildwahl__gewaehlt", "data-testid": "bilder-gewaehlt", children: gewaehlt.map((bild) => /* @__PURE__ */ jsxs18("li", { children: [
12121
- /* @__PURE__ */ jsx18(Kachel, { quelle: quelleVon(bild), alt: bild.title }),
12122
- /* @__PURE__ */ jsx18("span", { className: "szenen-bildwahl__kacheltitel", children: bild.title }),
12123
- /* @__PURE__ */ jsx18(
12086
+ gewaehlt.length > 0 && /* @__PURE__ */ jsx14("ul", { className: "szenen-bildwahl__gewaehlt", "data-testid": "bilder-gewaehlt", children: gewaehlt.map((bild) => /* @__PURE__ */ jsxs14("li", { children: [
12087
+ /* @__PURE__ */ jsx14(Kachel, { quelle: quelleVon(bild), alt: bild.title }),
12088
+ /* @__PURE__ */ jsx14("span", { className: "szenen-bildwahl__kacheltitel", children: bild.title }),
12089
+ /* @__PURE__ */ jsx14(
12124
12090
  "button",
12125
12091
  {
12126
12092
  type: "button",
@@ -12156,6 +12122,15 @@ var DeriveArea = ({ port, contextId }) => {
12156
12122
  () => port.derivation.listPolicies(contextId),
12157
12123
  [port, contextId]
12158
12124
  );
12125
+ const sortiert = useMemo3(() => regeln.status === "ready" ? [...regeln.value].sort((a, b) => {
12126
+ const szeneZuerst = Number(b.produces.includes("scene")) - Number(a.produces.includes("scene"));
12127
+ return szeneZuerst !== 0 ? szeneZuerst : a.title.localeCompare(b.title, "de");
12128
+ }) : [], [regeln]);
12129
+ useEffect9(() => {
12130
+ if (policyVersionId) return;
12131
+ const fuerSzene = sortiert.find((r) => r.produces.includes("scene"));
12132
+ if (fuerSzene) setPolicyVersionId(fuerSzene.versionId);
12133
+ }, [sortiert, policyVersionId]);
12159
12134
  const gewaehlt = regeln.status === "ready" ? regeln.value.find((r) => r.versionId === policyVersionId) ?? null : null;
12160
12135
  async function starten(folgt) {
12161
12136
  if (!gewaehlt) {
@@ -12230,12 +12205,12 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12230
12205
  const text = beanstandung ?? vorgabeBeanstandung(satz);
12231
12206
  const bilderFehlen = satz.input.images.some((bild) => bild.kind !== "library");
12232
12207
  const bereit = Boolean(text.trim()) && !bilderFehlen && !laeuft;
12233
- return /* @__PURE__ */ jsxs18("div", { className: "szenen-folgelauf", "data-testid": "folgelauf", children: [
12234
- /* @__PURE__ */ jsx18("h4", { children: "Korrektur- oder Erg\xE4nzungslauf" }),
12235
- /* @__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." }),
12236
- /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
12237
- /* @__PURE__ */ jsx18("span", { children: "Beanstandung" }),
12238
- /* @__PURE__ */ jsx18(
12208
+ return /* @__PURE__ */ jsxs14("div", { className: "szenen-folgelauf", "data-testid": "folgelauf", children: [
12209
+ /* @__PURE__ */ jsx14("h4", { children: "Korrektur- oder Erg\xE4nzungslauf" }),
12210
+ /* @__PURE__ */ jsx14("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." }),
12211
+ /* @__PURE__ */ jsxs14("label", { className: "szenen-field", children: [
12212
+ /* @__PURE__ */ jsx14("span", { children: "Beanstandung" }),
12213
+ /* @__PURE__ */ jsx14(
12239
12214
  "textarea",
12240
12215
  {
12241
12216
  rows: 4,
@@ -12245,9 +12220,9 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12245
12220
  }
12246
12221
  )
12247
12222
  ] }),
12248
- /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
12249
- /* @__PURE__ */ jsx18("span", { children: "Zus\xE4tzliche Anweisung (optional)" }),
12250
- /* @__PURE__ */ jsx18(
12223
+ /* @__PURE__ */ jsxs14("label", { className: "szenen-field", children: [
12224
+ /* @__PURE__ */ jsx14("span", { children: "Zus\xE4tzliche Anweisung (optional)" }),
12225
+ /* @__PURE__ */ jsx14(
12251
12226
  "textarea",
12252
12227
  {
12253
12228
  rows: 2,
@@ -12258,8 +12233,8 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12258
12233
  }
12259
12234
  )
12260
12235
  ] }),
12261
- 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." }),
12262
- /* @__PURE__ */ jsx18(
12236
+ bilderFehlen && /* @__PURE__ */ jsx14("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." }),
12237
+ /* @__PURE__ */ jsx14(
12263
12238
  "button",
12264
12239
  {
12265
12240
  type: "button",
@@ -12299,19 +12274,19 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12299
12274
  setMeldung(ergebnis.message);
12300
12275
  }
12301
12276
  }
12302
- return /* @__PURE__ */ jsxs18("div", { className: "szenen-derive", "data-testid": "bereich-rekonstruktion", children: [
12303
- /* @__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." }),
12304
- regeln.status === "loading" && /* @__PURE__ */ jsx18("p", { children: "Regeln werden geladen \u2026" }),
12305
- regeln.status === "error" && /* @__PURE__ */ jsxs18("p", { className: "szenen-error", role: "alert", children: [
12277
+ return /* @__PURE__ */ jsxs14("div", { className: "szenen-derive", "data-testid": "bereich-rekonstruktion", children: [
12278
+ /* @__PURE__ */ jsx14("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." }),
12279
+ regeln.status === "loading" && /* @__PURE__ */ jsx14("p", { children: "Regeln werden geladen \u2026" }),
12280
+ regeln.status === "error" && /* @__PURE__ */ jsxs14("p", { className: "szenen-error", role: "alert", children: [
12306
12281
  "Die Regeln konnten nicht gelesen werden: ",
12307
12282
  regeln.message
12308
12283
  ] }),
12309
- regeln.status === "ready" && regeln.value.length === 0 && /* @__PURE__ */ jsxs18("p", { className: "szenen-empty", children: [
12284
+ regeln.status === "ready" && regeln.value.length === 0 && /* @__PURE__ */ jsxs14("p", { className: "szenen-empty", children: [
12310
12285
  "In diesem Kontext ist keine Rekonstruktionsregel (",
12311
- /* @__PURE__ */ jsx18("code", { children: "scene_derivation_policy" }),
12312
- ') 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.'
12286
+ /* @__PURE__ */ jsx14("code", { children: "scene_derivation_policy" }),
12287
+ ') ver\xF6ffentlicht. Ohne sie ist kein Lauf reproduzierbar \u2014 legen Sie eine unter \u201EErweitert" an, oder wechseln Sie in den Kontext, in dem Ihre Regel liegt. Regeln aus anderen Kontexten stehen hier bewusst nicht zur Auswahl.'
12313
12288
  ] }),
12314
- regeln.status === "ready" && regeln.value.length > 0 && /* @__PURE__ */ jsxs18(
12289
+ regeln.status === "ready" && regeln.value.length > 0 && /* @__PURE__ */ jsxs14(
12315
12290
  "form",
12316
12291
  {
12317
12292
  className: "szenen-form",
@@ -12320,17 +12295,17 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12320
12295
  void starten();
12321
12296
  },
12322
12297
  children: [
12323
- /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
12324
- /* @__PURE__ */ jsx18("span", { children: "Regel" }),
12325
- /* @__PURE__ */ jsxs18(
12298
+ /* @__PURE__ */ jsxs14("label", { className: "szenen-field", children: [
12299
+ /* @__PURE__ */ jsx14("span", { children: "Regel" }),
12300
+ /* @__PURE__ */ jsxs14(
12326
12301
  "select",
12327
12302
  {
12328
12303
  value: policyVersionId,
12329
12304
  onChange: (e) => setPolicyVersionId(e.target.value),
12330
12305
  "data-testid": "regel-auswahl",
12331
12306
  children: [
12332
- /* @__PURE__ */ jsx18("option", { value: "", children: "\u2014 bitte w\xE4hlen \u2014" }),
12333
- regeln.value.map((regel) => /* @__PURE__ */ jsxs18("option", { value: regel.versionId, children: [
12307
+ /* @__PURE__ */ jsx14("option", { value: "", children: "\u2014 bitte w\xE4hlen \u2014" }),
12308
+ sortiert.map((regel) => /* @__PURE__ */ jsxs14("option", { value: regel.versionId, children: [
12334
12309
  regel.title,
12335
12310
  " (",
12336
12311
  regel.produces.join(", "),
@@ -12340,21 +12315,21 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12340
12315
  }
12341
12316
  )
12342
12317
  ] }),
12343
- /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
12344
- /* @__PURE__ */ jsx18("span", { children: "Eingang" }),
12345
- /* @__PURE__ */ jsx18(
12318
+ /* @__PURE__ */ jsxs14("label", { className: "szenen-field", children: [
12319
+ /* @__PURE__ */ jsx14("span", { children: "Eingang" }),
12320
+ /* @__PURE__ */ jsx14(
12346
12321
  "select",
12347
12322
  {
12348
12323
  value: modus,
12349
12324
  onChange: (e) => setModus(e.target.value),
12350
12325
  "data-testid": "modus-auswahl",
12351
- children: (gewaehlt ? gewaehlt.inputModes : ["prompt", "image", "image_prompt"]).map((m) => /* @__PURE__ */ jsx18("option", { value: m, children: MODUS_TEXT[m] }, m))
12326
+ children: (gewaehlt ? gewaehlt.inputModes : ["prompt", "image", "image_prompt"]).map((m) => /* @__PURE__ */ jsx14("option", { value: m, children: MODUS_TEXT[m] }, m))
12352
12327
  }
12353
12328
  )
12354
12329
  ] }),
12355
- modus !== "image" && /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
12356
- /* @__PURE__ */ jsx18("span", { children: "Referenzprompt" }),
12357
- /* @__PURE__ */ jsx18(
12330
+ modus !== "image" && /* @__PURE__ */ jsxs14("label", { className: "szenen-field", children: [
12331
+ /* @__PURE__ */ jsx14("span", { children: "Referenzprompt" }),
12332
+ /* @__PURE__ */ jsx14(
12358
12333
  "textarea",
12359
12334
  {
12360
12335
  value: promptText,
@@ -12364,8 +12339,8 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12364
12339
  }
12365
12340
  )
12366
12341
  ] }),
12367
- modus !== "prompt" && /* @__PURE__ */ jsxs18(Fragment8, { children: [
12368
- port.imageLibrary && /* @__PURE__ */ jsx18(
12342
+ modus !== "prompt" && /* @__PURE__ */ jsxs14(Fragment8, { children: [
12343
+ port.imageLibrary && /* @__PURE__ */ jsx14(
12369
12344
  BildWaehler,
12370
12345
  {
12371
12346
  port,
@@ -12374,9 +12349,9 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12374
12349
  onEntfernen: (ref) => setBestandsbilder((v) => v.filter((b) => b.mediaRef !== ref))
12375
12350
  }
12376
12351
  ),
12377
- /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
12378
- /* @__PURE__ */ jsx18("span", { children: port.imageLibrary ? "Oder hochladen" : "Referenzbild" }),
12379
- /* @__PURE__ */ jsx18(
12352
+ /* @__PURE__ */ jsxs14("label", { className: "szenen-field", children: [
12353
+ /* @__PURE__ */ jsx14("span", { children: port.imageLibrary ? "Oder hochladen" : "Referenzbild" }),
12354
+ /* @__PURE__ */ jsx14(
12380
12355
  "input",
12381
12356
  {
12382
12357
  type: "file",
@@ -12386,40 +12361,40 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12386
12361
  "data-testid": "bild-eingabe"
12387
12362
  }
12388
12363
  ),
12389
- 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." })
12364
+ port.imageLibrary && /* @__PURE__ */ jsx14("small", { "data-testid": "upload-hinweis", children: "Hochgeladene Bilder werden im Bestand abgelegt \u2014 nur so ist sp\xE4ter ein Folgelauf damit m\xF6glich." })
12390
12365
  ] })
12391
12366
  ] }),
12392
- /* @__PURE__ */ jsx18("button", { type: "submit", disabled: !gewaehlt || laeuft, "data-testid": "lauf-starten", children: laeuft ? "Rekonstruiert \u2026" : "Rekonstruieren" })
12367
+ /* @__PURE__ */ jsx14("button", { type: "submit", disabled: !gewaehlt || laeuft, "data-testid": "lauf-starten", children: laeuft ? "Rekonstruiert \u2026" : "Rekonstruieren" })
12393
12368
  ]
12394
12369
  }
12395
12370
  ),
12396
- meldung && /* @__PURE__ */ jsx18("p", { className: "szenen-error", role: "alert", "data-testid": "derive-meldung", children: meldung }),
12397
- lauf && lauf.status === "failed" && /* @__PURE__ */ jsxs18("section", { className: "szenen-run szenen-run--failed", "data-testid": "lauf-fehler", children: [
12398
- /* @__PURE__ */ jsx18("h3", { children: "Der Lauf ist gescheitert" }),
12399
- /* @__PURE__ */ jsxs18("p", { children: [
12400
- /* @__PURE__ */ jsx18("strong", { children: lauf.failure?.class }),
12371
+ meldung && /* @__PURE__ */ jsx14("p", { className: "szenen-error", role: "alert", "data-testid": "derive-meldung", children: meldung }),
12372
+ lauf && lauf.status === "failed" && /* @__PURE__ */ jsxs14("section", { className: "szenen-run szenen-run--failed", "data-testid": "lauf-fehler", children: [
12373
+ /* @__PURE__ */ jsx14("h3", { children: "Der Lauf ist gescheitert" }),
12374
+ /* @__PURE__ */ jsxs14("p", { children: [
12375
+ /* @__PURE__ */ jsx14("strong", { children: lauf.failure?.class }),
12401
12376
  " \u2014 ",
12402
12377
  lauf.failure?.message
12403
12378
  ] }),
12404
- lauf.failure?.diagnostics && lauf.failure.diagnostics.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose", "data-testid": "lauf-diagnosen", children: [
12405
- /* @__PURE__ */ jsx18("h4", { children: "Befunde" }),
12406
- /* @__PURE__ */ jsx18(Diagnosen, { befunde: lauf.failure.diagnostics, testId: "lauf-befunde" })
12379
+ lauf.failure?.diagnostics && lauf.failure.diagnostics.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "szenen-diagnose", "data-testid": "lauf-diagnosen", children: [
12380
+ /* @__PURE__ */ jsx14("h4", { children: "Befunde" }),
12381
+ /* @__PURE__ */ jsx14(Diagnosen, { befunde: lauf.failure.diagnostics, testId: "lauf-befunde" })
12407
12382
  ] }),
12408
- /* @__PURE__ */ jsx18(Herkunft, { lauf }),
12409
- /* @__PURE__ */ jsx18(Widerspruch, { lauf }),
12410
- /* @__PURE__ */ jsx18(Belege, { lauf }),
12411
- /* @__PURE__ */ jsx18(RecoveryPanel, { port, lauf }),
12383
+ /* @__PURE__ */ jsx14(Herkunft, { lauf }),
12384
+ /* @__PURE__ */ jsx14(Widerspruch, { lauf }),
12385
+ /* @__PURE__ */ jsx14(Belege, { lauf }),
12386
+ /* @__PURE__ */ jsx14(RecoveryPanel, { port, lauf }),
12412
12387
  folgeblock(lauf)
12413
12388
  ] }),
12414
- lauf && lauf.status === "succeeded" && /* @__PURE__ */ jsxs18("section", { className: "szenen-run", "data-testid": "lauf-ergebnis", children: [
12415
- /* @__PURE__ */ jsx18("h3", { children: "Vorschlag" }),
12416
- /* @__PURE__ */ jsx18(Herkunft, { lauf }),
12417
- /* @__PURE__ */ jsx18(Widerspruch, { lauf }),
12418
- /* @__PURE__ */ jsx18("p", { className: "szenen-run__feedback", children: lauf.feedback }),
12419
- lauf.conflicts.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose szenen-diagnose--konflikt", "data-testid": "konflikte", children: [
12420
- /* @__PURE__ */ jsx18("h4", { children: "Widerspr\xFCche zwischen Bild und Prompt" }),
12421
- /* @__PURE__ */ jsx18("ul", { children: lauf.conflicts.map((k, i) => /* @__PURE__ */ jsxs18("li", { children: [
12422
- /* @__PURE__ */ jsx18("code", { children: k.field }),
12389
+ lauf && lauf.status === "succeeded" && /* @__PURE__ */ jsxs14("section", { className: "szenen-run", "data-testid": "lauf-ergebnis", children: [
12390
+ /* @__PURE__ */ jsx14("h3", { children: "Vorschlag" }),
12391
+ /* @__PURE__ */ jsx14(Herkunft, { lauf }),
12392
+ /* @__PURE__ */ jsx14(Widerspruch, { lauf }),
12393
+ /* @__PURE__ */ jsx14("p", { className: "szenen-run__feedback", children: lauf.feedback }),
12394
+ lauf.conflicts.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "szenen-diagnose szenen-diagnose--konflikt", "data-testid": "konflikte", children: [
12395
+ /* @__PURE__ */ jsx14("h4", { children: "Widerspr\xFCche zwischen Bild und Prompt" }),
12396
+ /* @__PURE__ */ jsx14("ul", { children: lauf.conflicts.map((k, i) => /* @__PURE__ */ jsxs14("li", { children: [
12397
+ /* @__PURE__ */ jsx14("code", { children: k.field }),
12423
12398
  ": Bild sagt \u201E",
12424
12399
  k.from_image,
12425
12400
  '", Prompt sagt \u201E',
@@ -12427,31 +12402,31 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12427
12402
  '". Nichts davon wurde \xFCbernommen.'
12428
12403
  ] }, i)) })
12429
12404
  ] }),
12430
- lauf.not_derivable.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose", "data-testid": "nicht-ableitbar", children: [
12431
- /* @__PURE__ */ jsx18("h4", { children: "Nicht ableitbar" }),
12432
- /* @__PURE__ */ jsx18("ul", { children: lauf.not_derivable.map((n, i) => /* @__PURE__ */ jsxs18("li", { children: [
12433
- /* @__PURE__ */ jsx18("code", { children: n.field }),
12405
+ lauf.not_derivable.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "szenen-diagnose", "data-testid": "nicht-ableitbar", children: [
12406
+ /* @__PURE__ */ jsx14("h4", { children: "Nicht ableitbar" }),
12407
+ /* @__PURE__ */ jsx14("ul", { children: lauf.not_derivable.map((n, i) => /* @__PURE__ */ jsxs14("li", { children: [
12408
+ /* @__PURE__ */ jsx14("code", { children: n.field }),
12434
12409
  ": ",
12435
12410
  n.reason
12436
12411
  ] }, i)) })
12437
12412
  ] }),
12438
- lauf.assumptions.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "szenen-diagnose", "data-testid": "annahmen", children: [
12439
- /* @__PURE__ */ jsx18("h4", { children: "Erschlossen, nicht belegt" }),
12440
- /* @__PURE__ */ jsx18("ul", { children: lauf.assumptions.map((a, i) => /* @__PURE__ */ jsx18("li", { children: a }, i)) })
12413
+ lauf.assumptions.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "szenen-diagnose", "data-testid": "annahmen", children: [
12414
+ /* @__PURE__ */ jsx14("h4", { children: "Erschlossen, nicht belegt" }),
12415
+ /* @__PURE__ */ jsx14("ul", { children: lauf.assumptions.map((a, i) => /* @__PURE__ */ jsx14("li", { children: a }, i)) })
12441
12416
  ] }),
12442
12417
  lauf.proposals.map((vorschlag) => {
12443
12418
  const bezug = REFERENCE_FIELD[vorschlag.type];
12444
12419
  const fertig = uebernommen[vorschlag.type];
12445
- return /* @__PURE__ */ jsxs18(
12420
+ return /* @__PURE__ */ jsxs14(
12446
12421
  "article",
12447
12422
  {
12448
12423
  className: "szenen-proposal",
12449
12424
  "data-testid": `vorschlag-${vorschlag.type}`,
12450
12425
  children: [
12451
- /* @__PURE__ */ jsx18("h4", { children: vorschlag.type }),
12452
- !fertig && /* @__PURE__ */ jsxs18("label", { className: "szenen-field", children: [
12453
- /* @__PURE__ */ jsx18("span", { children: "Titel" }),
12454
- /* @__PURE__ */ jsx18(
12426
+ /* @__PURE__ */ jsx14("h4", { children: vorschlag.type }),
12427
+ !fertig && /* @__PURE__ */ jsxs14("label", { className: "szenen-field", children: [
12428
+ /* @__PURE__ */ jsx14("span", { children: "Titel" }),
12429
+ /* @__PURE__ */ jsx14(
12455
12430
  "input",
12456
12431
  {
12457
12432
  type: "text",
@@ -12465,9 +12440,9 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12465
12440
  }
12466
12441
  )
12467
12442
  ] }),
12468
- /* @__PURE__ */ jsx18("pre", { className: "szenen-proposal__payload", children: JSON.stringify(vorschlag.payload, null, 2) }),
12469
- bezug && !fertig && /* @__PURE__ */ jsxs18(Fragment8, { children: [
12470
- /* @__PURE__ */ jsx18(
12443
+ /* @__PURE__ */ jsx14("pre", { className: "szenen-proposal__payload", children: JSON.stringify(vorschlag.payload, null, 2) }),
12444
+ bezug && !fertig && /* @__PURE__ */ jsxs14(Fragment8, { children: [
12445
+ /* @__PURE__ */ jsx14(
12471
12446
  ReferencePicker,
12472
12447
  {
12473
12448
  port,
@@ -12481,30 +12456,30 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12481
12456
  }))
12482
12457
  }
12483
12458
  ),
12484
- referenzen[vorschlag.type] ? /* @__PURE__ */ jsxs18("p", { "data-testid": `referenz-gewaehlt-${vorschlag.type}`, children: [
12459
+ referenzen[vorschlag.type] ? /* @__PURE__ */ jsxs14("p", { "data-testid": `referenz-gewaehlt-${vorschlag.type}`, children: [
12485
12460
  "Zeigt auf Version ",
12486
- /* @__PURE__ */ jsx18("code", { children: referenzen[vorschlag.type] }),
12461
+ /* @__PURE__ */ jsx14("code", { children: referenzen[vorschlag.type] }),
12487
12462
  "."
12488
12463
  ] }) : (
12489
12464
  /* Der Grund steht **vor** der Handlung. Den Nutzer erst
12490
12465
  auf einen Knopf drücken zu lassen, um ihm dann eine
12491
12466
  Ablehnung zu zeigen, ist keine Auskunft. */
12492
- /* @__PURE__ */ jsxs18("p", { "data-testid": `referenz-fehlt-${vorschlag.type}`, children: [
12467
+ /* @__PURE__ */ jsxs14("p", { "data-testid": `referenz-fehlt-${vorschlag.type}`, children: [
12493
12468
  "Diese ",
12494
- /* @__PURE__ */ jsx18("strong", { children: "Einzel\xFCbernahme" }),
12469
+ /* @__PURE__ */ jsx14("strong", { children: "Einzel\xFCbernahme" }),
12495
12470
  " braucht eine ver\xF6ffentlichte ",
12496
12471
  bezug.refersTo,
12497
12472
  "-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 ",
12498
- /* @__PURE__ */ jsx18("strong", { children: "Draft-Kette" }),
12473
+ /* @__PURE__ */ jsx14("strong", { children: "Draft-Kette" }),
12499
12474
  ": Dort entstehen Szene, Aufbau und Shot zusammenh\xE4ngend, und es muss nichts ver\xF6ffentlicht werden."
12500
12475
  ] })
12501
12476
  )
12502
12477
  ] }),
12503
- fertig ? /* @__PURE__ */ jsxs18("p", { className: "szenen-proposal__done", children: [
12478
+ fertig ? /* @__PURE__ */ jsxs14("p", { className: "szenen-proposal__done", children: [
12504
12479
  "Als Entwurf \xFCbernommen: ",
12505
- /* @__PURE__ */ jsx18("code", { children: fertig }),
12480
+ /* @__PURE__ */ jsx14("code", { children: fertig }),
12506
12481
  ". Er ist noch nicht ver\xF6ffentlicht."
12507
- ] }) : /* @__PURE__ */ jsx18(
12482
+ ] }) : /* @__PURE__ */ jsx14(
12508
12483
  "button",
12509
12484
  {
12510
12485
  type: "button",
@@ -12519,13 +12494,337 @@ ${teile.map((t) => `- ${t}`).join("\n")}`;
12519
12494
  vorschlag.type
12520
12495
  );
12521
12496
  }),
12522
- /* @__PURE__ */ jsx18(ChainActions, { port, runId: lauf.run_id }),
12523
- /* @__PURE__ */ jsx18(Belege, { lauf }),
12497
+ /* @__PURE__ */ jsx14(ChainActions, { port, runId: lauf.run_id }),
12498
+ /* @__PURE__ */ jsx14(Belege, { lauf }),
12524
12499
  folgeblock(lauf)
12525
12500
  ] })
12526
12501
  ] });
12527
12502
  };
12528
12503
 
12504
+ // src/features/szenen/areas/SceneArea.tsx
12505
+ import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
12506
+ var SceneArea = ({ port, contextId }) => {
12507
+ const kannAbleiten = capabilitiesOf(port).derivation;
12508
+ const [ableiten, setAbleiten] = useState17(false);
12509
+ const zeigeDerive = kannAbleiten && ableiten;
12510
+ return /* @__PURE__ */ jsxs15("div", { className: "szenen-scene", "data-testid": "bereich-szene", children: [
12511
+ /* @__PURE__ */ jsxs15("div", { className: "szenen-elements__toolbar", children: [
12512
+ /* @__PURE__ */ jsx15("p", { className: "szenen-area__lead", children: "Szenen dieses Kontexts. Auswahl \xF6ffnet die Bearbeitung der Nodes und Beziehungen und startet Prompt-L\xE4ufe." }),
12513
+ kannAbleiten && /* @__PURE__ */ jsx15(
12514
+ "button",
12515
+ {
12516
+ type: "button",
12517
+ className: "szenen-elements__new",
12518
+ "data-testid": "neu-aus-bild-text",
12519
+ "aria-expanded": ableiten,
12520
+ onClick: () => setAbleiten((offen) => !offen),
12521
+ children: ableiten ? "Zur\xFCck zu den Szenen" : "+ Neu aus Bild/Text"
12522
+ }
12523
+ )
12524
+ ] }),
12525
+ !kannAbleiten && /* @__PURE__ */ jsx15("p", { className: "szenen-view__capability-note", "data-testid": "hinweis-keine-rekonstruktion", children: "Aus Bild oder Text l\xE4sst sich in diesem Host keine Szene ableiten." }),
12526
+ zeigeDerive ? /* @__PURE__ */ jsx15(DeriveArea, { port, contextId }) : /* @__PURE__ */ jsx15(ElementsArea, { port, contextId, restrictToTypes: ["scene"] })
12527
+ ] });
12528
+ };
12529
+
12530
+ // src/features/szenen/areas/AdvancedArea.tsx
12531
+ import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
12532
+ var AdvancedArea = ({ port, contextId }) => /* @__PURE__ */ jsxs16("div", { className: "szenen-erweitert", "data-testid": "bereich-erweitert", children: [
12533
+ /* @__PURE__ */ jsx16("p", { className: "szenen-area__lead", children: "Optionale Pr\xE4zisierung: Bildaufbau und Shot, Kameras und Stile der Aufnahme, Zielmodelle, Rekonstruktionsregeln und Sequenzen. F\xFCr den normalen Weg von der Szene zum Bild wird hier nichts gebraucht." }),
12534
+ /* @__PURE__ */ jsx16(
12535
+ ElementsArea,
12536
+ {
12537
+ port,
12538
+ contextId,
12539
+ restrictToTypes: ERWEITERT_TYPES,
12540
+ allTypesLabel: "alle erweiterten Typen",
12541
+ listTitle: "Erweitert"
12542
+ }
12543
+ )
12544
+ ] });
12545
+
12546
+ // src/features/szenen/areas/PromptsArea.tsx
12547
+ import { useMemo as useMemo4, useState as useState18 } from "react";
12548
+ import { Fragment as Fragment9, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
12549
+ var HERKUNFT_TEXT2 = {
12550
+ published: "aus ver\xF6ffentlichtem Shot",
12551
+ draft_chain: "aus Draft-Kette",
12552
+ scene_direct: "direkt aus Szene",
12553
+ unresolved: "Herkunft unvollst\xE4ndig"
12554
+ };
12555
+ var PromptsArea = ({ port, contextId }) => {
12556
+ const faehig = capabilitiesOf(port);
12557
+ const [nachladen, setNachladen] = useState18(0);
12558
+ const [offen, setOffen] = useState18(null);
12559
+ const [alleKontexte, setAlleKontexte] = useState18(false);
12560
+ const [mitFehllaeufen, setMitFehllaeufen] = useState18(false);
12561
+ const [herkunft, setHerkunft] = useState18("alle");
12562
+ const [phase] = usePortQuery(
12563
+ () => port.runs.listAllRuns ? port.runs.listAllRuns({ status: "all" }) : Promise.resolve({
12564
+ kind: "ok",
12565
+ value: { runs: [], hiddenByStatus: 0, hiddenByContext: 0, withoutContext: 0 }
12566
+ }),
12567
+ [port, nachladen]
12568
+ );
12569
+ const alle = phase.status === "ready" ? phase.value.runs : [];
12570
+ const sicht = useMemo4(() => selectPromptRuns(alle, {
12571
+ status: mitFehllaeufen ? "all" : "succeeded",
12572
+ ...alleKontexte ? {} : { contextId }
12573
+ }), [alle, mitFehllaeufen, alleKontexte, contextId]);
12574
+ const titel = useLaufTitel(port, alle);
12575
+ const gezeigt = useMemo4(
12576
+ () => herkunft === "alle" ? sicht.runs : sicht.runs.filter((lauf) => groupOf(lauf).kind === herkunft),
12577
+ [sicht.runs, herkunft]
12578
+ );
12579
+ if (!faehig.promptOverview) {
12580
+ return /* @__PURE__ */ jsx17("div", { className: "szenen-prompts", "data-testid": "prompts-bereich", children: /* @__PURE__ */ jsx17("p", { "data-testid": "hinweis-keine-promptsicht", children: "Dieser Host bietet keine herkunfts\xFCbergreifende Prompt-Liste an. Prompt-L\xE4ufe bleiben im Detail ihrer Szene bzw. ihres Shots erreichbar \u2014 es ist kein Fehler und kein vor\xFCbergehender Zustand." }) });
12581
+ }
12582
+ return /* @__PURE__ */ jsxs17("div", { className: "szenen-prompts", "data-testid": "prompts-bereich", children: [
12583
+ /* @__PURE__ */ jsxs17("div", { className: "szenen-prompts__toolbar", children: [
12584
+ /* @__PURE__ */ jsx17("h3", { className: "szenen-prompts__heading", children: "Prompts" }),
12585
+ /* @__PURE__ */ jsxs17("label", { className: "szenen-prompts__filter", children: [
12586
+ "Herkunft",
12587
+ /* @__PURE__ */ jsxs17(
12588
+ "select",
12589
+ {
12590
+ "data-testid": "prompts-herkunft",
12591
+ value: herkunft,
12592
+ onChange: (e) => setHerkunft(e.target.value),
12593
+ children: [
12594
+ /* @__PURE__ */ jsx17("option", { value: "alle", children: "alle" }),
12595
+ /* @__PURE__ */ jsx17("option", { value: "published", children: HERKUNFT_TEXT2.published }),
12596
+ /* @__PURE__ */ jsx17("option", { value: "draft_chain", children: HERKUNFT_TEXT2.draft_chain }),
12597
+ /* @__PURE__ */ jsx17("option", { value: "scene_direct", children: HERKUNFT_TEXT2.scene_direct }),
12598
+ /* @__PURE__ */ jsx17("option", { value: "unresolved", children: HERKUNFT_TEXT2.unresolved })
12599
+ ]
12600
+ }
12601
+ )
12602
+ ] }),
12603
+ /* @__PURE__ */ jsxs17("label", { className: "szenen-prompts__filter", children: [
12604
+ /* @__PURE__ */ jsx17(
12605
+ "input",
12606
+ {
12607
+ type: "checkbox",
12608
+ "data-testid": "prompts-alle-kontexte",
12609
+ checked: alleKontexte,
12610
+ onChange: (e) => setAlleKontexte(e.target.checked)
12611
+ }
12612
+ ),
12613
+ "Alle Kontexte"
12614
+ ] }),
12615
+ /* @__PURE__ */ jsxs17("label", { className: "szenen-prompts__filter", children: [
12616
+ /* @__PURE__ */ jsx17(
12617
+ "input",
12618
+ {
12619
+ type: "checkbox",
12620
+ "data-testid": "prompts-mit-fehllaeufen",
12621
+ checked: mitFehllaeufen,
12622
+ onChange: (e) => setMitFehllaeufen(e.target.checked)
12623
+ }
12624
+ ),
12625
+ "Fehll\xE4ufe zeigen"
12626
+ ] })
12627
+ ] }),
12628
+ phase.status === "loading" && /* @__PURE__ */ jsx17("p", { "data-testid": "prompts-laden", children: "Prompts werden geladen \u2026" }),
12629
+ phase.status === "error" && /* @__PURE__ */ jsxs17("p", { "data-testid": "prompts-fehler", role: "alert", children: [
12630
+ "Prompts konnten nicht geladen werden: ",
12631
+ phase.message
12632
+ ] }),
12633
+ phase.status === "ready" && /* @__PURE__ */ jsxs17(Fragment9, { children: [
12634
+ gezeigt.length === 0 && /* @__PURE__ */ jsx17("p", { "data-testid": "keine-prompts", children: alle.length === 0 ? "Es gibt noch keinen Prompt-Lauf." : `Kein Prompt passt zu dieser Auswahl \u2014 von ${alle.length} vorhandenen L\xE4ufen bleibt keiner \xFCbrig.` }),
12635
+ /* @__PURE__ */ jsx17("ol", { "data-testid": "prompts-liste", children: gezeigt.map((lauf) => /* @__PURE__ */ jsx17(
12636
+ PromptEintrag,
12637
+ {
12638
+ port,
12639
+ lauf,
12640
+ alle,
12641
+ titel: titel.get(lauf.run_id) ?? null,
12642
+ offen: lauf.run_id === offen,
12643
+ onUmschalten: () => setOffen(
12644
+ lauf.run_id === offen ? null : lauf.run_id
12645
+ ),
12646
+ itemMoeglich: faehig.saveRunAsItem,
12647
+ onItemGespeichert: () => setNachladen((n) => n + 1)
12648
+ },
12649
+ lauf.run_id
12650
+ )) }),
12651
+ (sicht.hiddenByContext > 0 || sicht.withoutContext > 0 || sicht.hiddenByStatus > 0) && /* @__PURE__ */ jsxs17("p", { className: "szenen-prompts__ausgeblendet", "data-testid": "prompts-ausgeblendet", children: [
12652
+ sicht.hiddenByStatus > 0 && `${sicht.hiddenByStatus} Fehllauf/-l\xE4ufe ausgeblendet. `,
12653
+ sicht.hiddenByContext > 0 && `${sicht.hiddenByContext} Lauf/L\xE4ufe geh\xF6ren zu einem anderen Kontext. `,
12654
+ sicht.withoutContext > 0 && `${sicht.withoutContext} Lauf/L\xE4ufe nennen keinen Kontext und werden keinem zugeordnet \u2014 \u201EAlle Kontexte" zeigt sie. `
12655
+ ] })
12656
+ ] })
12657
+ ] });
12658
+ };
12659
+ var PromptEintrag = ({ port, lauf, alle, titel, offen, onUmschalten, itemMoeglich, onItemGespeichert }) => {
12660
+ const gruppe = groupOf(lauf);
12661
+ const runde = roundOfRun(lauf, siblingsOf(lauf, alle));
12662
+ return /* @__PURE__ */ jsxs17("li", { className: "szenen-prompts__eintrag", "data-testid": `prompt-${lauf.run_id}`, children: [
12663
+ /* @__PURE__ */ jsxs17("p", { className: "szenen-prompts__herkunft", "data-testid": `herkunft-${lauf.run_id}`, children: [
12664
+ /* @__PURE__ */ jsx17("span", { "data-herkunft": gruppe.kind, children: HERKUNFT_TEXT2[gruppe.kind] }),
12665
+ gruppe.kind === "unresolved" && // D-75: Was nicht belegbar ist, wird benannt und nicht
12666
+ // durch eine plausible Kennung ersetzt.
12667
+ /* @__PURE__ */ jsxs17("span", { className: "szenen-prompts__hinweis", children: [
12668
+ " \u2014 ",
12669
+ gruppe.reason
12670
+ ] })
12671
+ ] }),
12672
+ /* @__PURE__ */ jsx17("ol", { className: "szenen-prompts__lauf", children: /* @__PURE__ */ jsx17(
12673
+ RundenEintrag,
12674
+ {
12675
+ port,
12676
+ lauf,
12677
+ runde,
12678
+ titel,
12679
+ offen,
12680
+ onUmschalten,
12681
+ itemMoeglich,
12682
+ onItemGespeichert
12683
+ }
12684
+ ) })
12685
+ ] });
12686
+ };
12687
+
12688
+ // src/features/szenen/areas/MediaArea.tsx
12689
+ import { useState as useState19 } from "react";
12690
+ import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
12691
+ var leer = async () => ({ kind: "ok", value: [] });
12692
+ var MediaArea = ({ port }) => {
12693
+ const media = port.media;
12694
+ const [versionInput, setVersionInput] = useState19("");
12695
+ const [versionId, setVersionId] = useState19("");
12696
+ const [itemInput, setItemInput] = useState19("");
12697
+ const [itemId, setItemId] = useState19("");
12698
+ const [assetId, setAssetId] = useState19("");
12699
+ const [role, setRole] = useState19("reference");
12700
+ const [position, setPosition] = useState19("0");
12701
+ const [notiz, setNotiz] = useState19(null);
12702
+ const [busy, setBusy] = useState19(false);
12703
+ const [refresh, setRefresh] = useState19(0);
12704
+ const [versionPhase] = usePortQuery(
12705
+ () => versionId ? media.listVersionMedia(versionId) : leer(),
12706
+ [media, versionId, refresh]
12707
+ );
12708
+ const [itemPhase] = usePortQuery(
12709
+ () => itemId ? media.listItemMedia(itemId) : Promise.resolve({ kind: "ok", value: [] }),
12710
+ [media, itemId, refresh]
12711
+ );
12712
+ const zuordnen = async () => {
12713
+ if (!versionInput.trim() || !assetId.trim()) {
12714
+ setNotiz({ tone: "error", text: "Version-ID und Asset-ID sind erforderlich." });
12715
+ return;
12716
+ }
12717
+ const parsedPosition = Number(position);
12718
+ if (!Number.isInteger(parsedPosition) || parsedPosition < 0) {
12719
+ setNotiz({ tone: "error", text: `Position muss eine nicht-negative Ganzzahl sein, war ${JSON.stringify(position)}.` });
12720
+ return;
12721
+ }
12722
+ setBusy(true);
12723
+ const result = await media.attachVersionMedium({
12724
+ versionId: versionInput.trim(),
12725
+ assetId: assetId.trim(),
12726
+ role,
12727
+ position: parsedPosition
12728
+ });
12729
+ setNotiz(noticeFor(result, "Referenzmedium zuordnen"));
12730
+ if (result.kind === "ok") {
12731
+ setVersionId(versionInput.trim());
12732
+ setRefresh((value) => value + 1);
12733
+ }
12734
+ setBusy(false);
12735
+ };
12736
+ const entfernen = async (medium) => {
12737
+ setBusy(true);
12738
+ const result = await media.detachVersionMedium({
12739
+ versionId,
12740
+ assetId: medium.assetId,
12741
+ role: medium.role
12742
+ });
12743
+ setNotiz(noticeFor(result, "Referenzmedium entfernen"));
12744
+ if (result.kind === "ok") setRefresh((value) => value + 1);
12745
+ setBusy(false);
12746
+ };
12747
+ const versionMedien = versionPhase.status === "ready" ? versionPhase.value : [];
12748
+ const itemMedien = itemPhase.status === "ready" ? itemPhase.value : [];
12749
+ return /* @__PURE__ */ jsxs18("div", { className: "szenen-media", "data-testid": "bereich-medien", children: [
12750
+ /* @__PURE__ */ jsx18("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." }),
12751
+ /* @__PURE__ */ jsxs18("section", { children: [
12752
+ /* @__PURE__ */ jsx18("h3", { children: "Version" }),
12753
+ /* @__PURE__ */ jsxs18("div", { className: "szenen-media__lookup", children: [
12754
+ /* @__PURE__ */ jsxs18("label", { children: [
12755
+ "Version-ID",
12756
+ /* @__PURE__ */ jsx18("input", { value: versionInput, onChange: (event) => setVersionInput(event.target.value) })
12757
+ ] }),
12758
+ /* @__PURE__ */ jsx18("button", { type: "button", onClick: () => setVersionId(versionInput.trim()), children: "Medien laden" })
12759
+ ] }),
12760
+ /* @__PURE__ */ jsxs18("div", { className: "szenen-media__attach", children: [
12761
+ /* @__PURE__ */ jsxs18("label", { children: [
12762
+ "Asset-ID",
12763
+ /* @__PURE__ */ jsx18("input", { value: assetId, onChange: (event) => setAssetId(event.target.value) })
12764
+ ] }),
12765
+ /* @__PURE__ */ jsxs18("label", { children: [
12766
+ "Rolle",
12767
+ /* @__PURE__ */ jsxs18("select", { value: role, onChange: (event) => setRole(event.target.value), children: [
12768
+ /* @__PURE__ */ jsx18("option", { value: "reference", children: "reference" }),
12769
+ /* @__PURE__ */ jsx18("option", { value: "mask", children: "mask" }),
12770
+ /* @__PURE__ */ jsx18("option", { value: "palette", children: "palette" }),
12771
+ /* @__PURE__ */ jsx18("option", { value: "example", children: "example" })
12772
+ ] })
12773
+ ] }),
12774
+ /* @__PURE__ */ jsxs18("label", { children: [
12775
+ "Position",
12776
+ /* @__PURE__ */ jsx18("input", { type: "number", min: "0", value: position, onChange: (event) => setPosition(event.target.value) })
12777
+ ] }),
12778
+ /* @__PURE__ */ jsx18("button", { type: "button", disabled: busy, onClick: zuordnen, children: "zuordnen" })
12779
+ ] }),
12780
+ versionPhase.status === "loading" && versionId && /* @__PURE__ */ jsx18("p", { children: "Versionsmedien werden geladen \u2026" }),
12781
+ versionPhase.status === "error" && /* @__PURE__ */ jsxs18("p", { role: "alert", children: [
12782
+ "Versionsmedien konnten nicht geladen werden: ",
12783
+ versionPhase.message
12784
+ ] }),
12785
+ versionPhase.status === "ready" && versionId && versionMedien.length === 0 && /* @__PURE__ */ jsxs18("p", { children: [
12786
+ "Version ",
12787
+ versionId,
12788
+ " hat keine Medien."
12789
+ ] }),
12790
+ /* @__PURE__ */ jsx18("ul", { className: "szenen-media__list", children: versionMedien.map((medium) => /* @__PURE__ */ jsxs18("li", { children: [
12791
+ /* @__PURE__ */ jsx18("code", { children: medium.assetId }),
12792
+ /* @__PURE__ */ jsxs18("span", { children: [
12793
+ medium.role,
12794
+ " \xB7 Position ",
12795
+ medium.position
12796
+ ] }),
12797
+ medium.url && /* @__PURE__ */ jsx18("a", { href: medium.url, target: "_blank", rel: "noreferrer", children: "\xF6ffnen" }),
12798
+ /* @__PURE__ */ jsx18("button", { type: "button", disabled: busy, onClick: () => entfernen(medium), children: "entfernen" })
12799
+ ] }, `${medium.assetId}:${medium.role}`)) })
12800
+ ] }),
12801
+ /* @__PURE__ */ jsxs18("section", { children: [
12802
+ /* @__PURE__ */ jsx18("h3", { children: "Item-Medien" }),
12803
+ /* @__PURE__ */ jsxs18("div", { className: "szenen-media__lookup", children: [
12804
+ /* @__PURE__ */ jsxs18("label", { children: [
12805
+ "Item-ID",
12806
+ /* @__PURE__ */ jsx18("input", { value: itemInput, onChange: (event) => setItemInput(event.target.value) })
12807
+ ] }),
12808
+ /* @__PURE__ */ jsx18("button", { type: "button", onClick: () => setItemId(itemInput.trim()), children: "Item-Medien laden" })
12809
+ ] }),
12810
+ itemPhase.status === "error" && /* @__PURE__ */ jsxs18("p", { role: "alert", children: [
12811
+ "Item-Medien konnten nicht geladen werden: ",
12812
+ itemPhase.message
12813
+ ] }),
12814
+ /* @__PURE__ */ jsx18("ul", { className: "szenen-media__list", children: itemMedien.map((medium) => /* @__PURE__ */ jsxs18("li", { children: [
12815
+ /* @__PURE__ */ jsx18("code", { children: medium.assetId }),
12816
+ /* @__PURE__ */ jsxs18("span", { children: [
12817
+ medium.role,
12818
+ " \xB7 Position ",
12819
+ medium.position
12820
+ ] }),
12821
+ medium.url && /* @__PURE__ */ jsx18("a", { href: medium.url, target: "_blank", rel: "noreferrer", children: "\xF6ffnen" })
12822
+ ] }, `${medium.assetId}:${medium.role}:${medium.position}`)) })
12823
+ ] }),
12824
+ notiz && /* @__PURE__ */ jsx18("p", { role: notiz.tone === "error" ? "alert" : "status", "data-tone": notiz.tone, children: notiz.text })
12825
+ ] });
12826
+ };
12827
+
12529
12828
  // src/features/szenen/SzenenView.tsx
12530
12829
  import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
12531
12830
  var SzenenView = ({
@@ -12534,9 +12833,9 @@ var SzenenView = ({
12534
12833
  initialArea,
12535
12834
  onAreaChange
12536
12835
  }) => {
12537
- const bereiche = useMemo4(() => areasFor(port), [port]);
12538
- const faehig = useMemo4(() => capabilitiesOf(port), [port]);
12539
- const [aktiv, setAktiv] = useState17(() => resolveArea(port, initialArea));
12836
+ const bereiche = useMemo5(() => areasFor(port), [port]);
12837
+ const faehig = useMemo5(() => capabilitiesOf(port), [port]);
12838
+ const [aktiv, setAktiv] = useState20(() => resolveArea(port, initialArea));
12540
12839
  const wechsle = (id) => {
12541
12840
  setAktiv(id);
12542
12841
  onAreaChange?.(id);
@@ -12547,7 +12846,7 @@ var SzenenView = ({
12547
12846
  /* @__PURE__ */ jsxs19("div", { children: [
12548
12847
  /* @__PURE__ */ jsx19("p", { className: "szenen-view__eyebrow", children: "Vom Motiv zum Bild" }),
12549
12848
  /* @__PURE__ */ jsx19("h2", { children: "Bildprompt aus einer Szene" }),
12550
- /* @__PURE__ */ jsx19("p", { children: "Bausteine w\xE4hlen, Szene und Bildaufbau festlegen und daraus einen wiederholbaren Prompt erzeugen." })
12849
+ /* @__PURE__ */ jsx19("p", { children: 'Eine Szene anlegen oder aus Bild bzw. Text ableiten und daraus einen Prompt starten. Alle so entstandenen Prompts stehen mit ihren Bildern unter \u201EPrompts". Bausteine und Erweitertes pr\xE4zisieren den Weg, wenn er pr\xE4ziser werden soll.' })
12551
12850
  ] }),
12552
12851
  /* @__PURE__ */ jsx19("span", { className: "szenen-view__step", children: aktuellerBereich.title })
12553
12852
  ] }),
@@ -12566,7 +12865,8 @@ var SzenenView = ({
12566
12865
  bereich.id
12567
12866
  )) }),
12568
12867
  /* @__PURE__ */ jsxs19("section", { className: "szenen-view__area", "aria-label": aktuellerBereich.title, children: [
12569
- aktiv === "derive" && port.derivation && /* @__PURE__ */ jsx19(DeriveArea, { port, contextId }),
12868
+ aktiv === "scene" && /* @__PURE__ */ jsx19(SceneArea, { port, contextId }),
12869
+ aktiv === "prompts" && /* @__PURE__ */ jsx19(PromptsArea, { port, contextId }),
12570
12870
  aktiv === "elements" && /* @__PURE__ */ jsx19(
12571
12871
  ElementsArea,
12572
12872
  {
@@ -12577,9 +12877,7 @@ var SzenenView = ({
12577
12877
  listTitle: "Bausteine"
12578
12878
  }
12579
12879
  ),
12580
- aktiv === "scene" && /* @__PURE__ */ jsx19(SceneArea, { port, contextId }),
12581
- aktiv === "setup" && /* @__PURE__ */ jsx19(SetupArea, { port, contextId }),
12582
- aktiv === "shot" && /* @__PURE__ */ jsx19(ShotArea, { port, contextId }),
12880
+ aktiv === "advanced" && /* @__PURE__ */ jsx19(AdvancedArea, { port, contextId }),
12583
12881
  aktiv === "media" && port.media && /* @__PURE__ */ jsx19(MediaArea, { port, contextId })
12584
12882
  ] }),
12585
12883
  (!faehig.saveRunAsItem || !faehig.media) && /* @__PURE__ */ jsxs19("details", { className: "szenen-view__host-notes", children: [
@@ -15295,8 +15593,13 @@ function createEventLogRunPersistence(channel) {
15295
15593
  // Nur veroeffentlichte Laeufe. Ein Draft-Lauf hat eine **leere**
15296
15594
  // shot_version_id (D-98) und wuerde bei der Suche nach '' sonst
15297
15595
  // faelschlich mitkommen — eine stille Vermischung zweier Herkuenfte.
15596
+ //
15597
+ // Seit P1-B faellt die Entscheidung nicht mehr hier, sondern in
15598
+ // `groupKeyOf()`: dieselbe Regel, aus der auch die Geschwister und
15599
+ // damit die Rundennummer entstehen. Vorher stand sie hier **und**
15600
+ // — anders — in `domainService.getPromptRunWithSiblings()`.
15298
15601
  value: collectPromptRuns(events).filter(
15299
- (run) => sourceOf(run).kind === "published" && run.shot_version_id === shotVersionId
15602
+ (run) => groupKeyOf(run) === `published:${shotVersionId}`
15300
15603
  )
15301
15604
  };
15302
15605
  } catch (error) {
@@ -15318,10 +15621,9 @@ function createEventLogRunPersistence(channel) {
15318
15621
  const events = await channel.readEvents();
15319
15622
  return {
15320
15623
  kind: "ok",
15321
- value: collectPromptRuns(events).filter((run) => {
15322
- const quelle = sourceOf(run);
15323
- return quelle.kind === "draft_chain" && quelle.chain_id === chainId;
15324
- })
15624
+ value: collectPromptRuns(events).filter(
15625
+ (run) => groupKeyOf(run) === `chain:${chainId}`
15626
+ )
15325
15627
  };
15326
15628
  } catch (error) {
15327
15629
  return queryError(error, `Laeufe der Kette ${chainId} konnten nicht gelesen werden`);
@@ -15332,10 +15634,9 @@ function createEventLogRunPersistence(channel) {
15332
15634
  const events = await channel.readEvents();
15333
15635
  return {
15334
15636
  kind: "ok",
15335
- value: collectPromptRuns(events).filter((run) => {
15336
- const quelle = sourceOf(run);
15337
- return quelle.kind === "scene_direct" && quelle.scene.element_id === sceneElementId;
15338
- })
15637
+ value: collectPromptRuns(events).filter(
15638
+ (run) => groupKeyOf(run) === `scene:${sceneElementId}`
15639
+ )
15339
15640
  };
15340
15641
  } catch (error) {
15341
15642
  return queryError(
@@ -15344,6 +15645,16 @@ function createEventLogRunPersistence(channel) {
15344
15645
  );
15345
15646
  }
15346
15647
  },
15648
+ // P1-A: dieselbe Faltung, nur ohne Herkunftsfilter. Sie las schon bisher
15649
+ // in jedem der drei Fälle den **vollen** Log — hier fällt lediglich das
15650
+ // Aussieben weg.
15651
+ async listAll() {
15652
+ try {
15653
+ return { kind: "ok", value: collectPromptRuns(await channel.readEvents()) };
15654
+ } catch (error) {
15655
+ return queryError(error, "Die Prompt-Laeufe konnten nicht gelesen werden");
15656
+ }
15657
+ },
15347
15658
  async record(record) {
15348
15659
  try {
15349
15660
  await channel.appendEvent(SZENEN_EVENT_TYPES.promptRunRecorded, record);
@@ -15640,7 +15951,25 @@ function createClientRunPort(options) {
15640
15951
  `Laeufe der Szene ${sceneElementId} konnten nicht gelesen werden`
15641
15952
  );
15642
15953
  }
15643
- }
15954
+ },
15955
+ // ── Die gemeinsame Prompt-Sicht (P1-A) ────────────────────────────────
15956
+ //
15957
+ // Sie wird nur angeboten, wenn die **Persistenz** aufzählen kann. Ein
15958
+ // Host, dessen Speicher das nicht hergibt, bekommt hier keine Operation —
15959
+ // und die Ansicht nennt den Grund, statt eine leere Liste zu zeigen (§8).
15960
+ // Der Filter läuft über `selectPromptRuns()`, dieselbe Funktion, die auch
15961
+ // der Server benutzt; zwei Bezugsrahmen wären zwei Wahrheiten.
15962
+ ...typeof runs.listAll === "function" ? {
15963
+ async listAllRuns(filter) {
15964
+ try {
15965
+ const alle = await runs.listAll();
15966
+ if (alle.kind !== "ok") return alle;
15967
+ return { kind: "ok", value: selectPromptRuns(alle.value, filter) };
15968
+ } catch (error) {
15969
+ return queryError(error, "Die Prompt-Laeufe konnten nicht gelesen werden");
15970
+ }
15971
+ }
15972
+ } : {}
15644
15973
  };
15645
15974
  }
15646
15975
 
@@ -17021,22 +17350,29 @@ export {
17021
17350
  resolverFromQueries,
17022
17351
  isProjectionCurrent,
17023
17352
  isOk,
17024
- SZENEN_ITEM_PREFIX,
17025
- itemIdForRun,
17026
- isSzenenItemId,
17027
- checkSzenenBatchOrigin,
17028
- mergeSzenenBatchOrigin,
17029
- roundOfRun,
17030
- deriveLineage,
17031
- deriveItemFromRun,
17032
17353
  SZENEN_EVENT_PREFIX,
17033
17354
  SZENEN_EVENT_TYPES,
17034
17355
  reduceElementEvents,
17035
17356
  draftRevisionOf,
17036
17357
  logRevisionOf,
17037
17358
  preferredHeadRevisionOf,
17359
+ sourceOf,
17038
17360
  collectPromptRuns,
17039
17361
  findPromptRun,
17362
+ groupOf,
17363
+ groupKeyOf,
17364
+ siblingsOf,
17365
+ namingElementOf,
17366
+ contextOfRun,
17367
+ selectPromptRuns,
17368
+ SZENEN_ITEM_PREFIX,
17369
+ itemIdForRun,
17370
+ isSzenenItemId,
17371
+ checkSzenenBatchOrigin,
17372
+ mergeSzenenBatchOrigin,
17373
+ roundOfRun,
17374
+ deriveLineage,
17375
+ deriveItemFromRun,
17040
17376
  DEFAULT_SEED_VORLAGE,
17041
17377
  parseSeedListe,
17042
17378
  formatSeedListe,