@rslsp1/fa-app-tools 2.0.57 → 2.0.61

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.
package/dist/index.js CHANGED
@@ -1033,10 +1033,8 @@ var CompactDropdown = ({
1033
1033
  };
1034
1034
 
1035
1035
  // src/components/HistoryPanel.tsx
1036
- var import_react4 = require("react");
1037
- var import_react5 = require("motion/react");
1036
+ var import_react4 = require("motion/react");
1038
1037
  var import_jsx_runtime5 = require("react/jsx-runtime");
1039
- var PAGE_SIZE = 20;
1040
1038
  var formatFriendlyTimestamp = (timestamp) => {
1041
1039
  const date = new Date(timestamp);
1042
1040
  const now = /* @__PURE__ */ new Date();
@@ -1048,8 +1046,7 @@ var formatFriendlyTimestamp = (timestamp) => {
1048
1046
  if (date.toDateString() === yesterday.toDateString()) return `Gestern, ${timeStr}`;
1049
1047
  return `${date.toLocaleDateString([], { day: "2-digit", month: "2-digit" })}, ${timeStr}`;
1050
1048
  };
1051
- var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
1052
- const [visibleCount, setVisibleCount] = (0, import_react4.useState)(PAGE_SIZE);
1049
+ var HistoryPanel = ({ history, currentResultId, onSelect, onDelete, visibleCount, onLoadMore }) => {
1053
1050
  const visibleHistory = history.slice(0, visibleCount);
1054
1051
  if (history.length === 0) {
1055
1052
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-col items-center justify-center py-20 text-center gap-4 opacity-10", children: [
@@ -1057,7 +1054,7 @@ var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
1057
1054
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[10px] font-bold uppercase tracking-widest", children: "Keine Historie" })
1058
1055
  ] });
1059
1056
  }
1060
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react5.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-4 flex flex-col gap-3 overflow-y-auto dark-scrollbar", children: [
1057
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react4.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-4 flex flex-col gap-3 overflow-y-auto dark-scrollbar", children: [
1061
1058
  visibleHistory.map((gen) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1062
1059
  "div",
1063
1060
  {
@@ -1093,7 +1090,7 @@ var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
1093
1090
  },
1094
1091
  gen.id
1095
1092
  )),
1096
- visibleCount < history.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", onClick: () => setVisibleCount((c) => c + PAGE_SIZE), className: "w-full py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-xl text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
1093
+ visibleCount < history.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", onClick: onLoadMore, className: "w-full py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-xl text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
1097
1094
  history.length - visibleCount,
1098
1095
  " weitere laden"
1099
1096
  ] })
@@ -1101,11 +1098,11 @@ var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
1101
1098
  };
1102
1099
 
1103
1100
  // src/components/InspectPanel.tsx
1104
- var import_react6 = require("react");
1105
- var import_react7 = require("motion/react");
1101
+ var import_react5 = require("react");
1102
+ var import_react6 = require("motion/react");
1106
1103
  var import_jsx_runtime6 = require("react/jsx-runtime");
1107
1104
  var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagToggle }) => {
1108
- const currentIndex = (0, import_react6.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
1105
+ const currentIndex = (0, import_react5.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
1109
1106
  if (!currentResult) {
1110
1107
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col items-center justify-center py-20 text-center gap-4 opacity-10", children: [
1111
1108
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "info" }),
@@ -1113,7 +1110,7 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
1113
1110
  ] });
1114
1111
  }
1115
1112
  const fullDateStr = new Date(currentResult.timestamp).toLocaleString([], { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit" });
1116
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react7.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 flex flex-col overflow-hidden", children: [
1113
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react6.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 flex flex-col overflow-hidden", children: [
1117
1114
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex-shrink-0 border-b border-white/5 bg-black/20 py-3 px-4", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex gap-2 overflow-x-auto no-scrollbar pb-1", children: history.map((gen) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => onSelect(gen), className: `w-10 h-10 rounded-lg overflow-hidden border shrink-0 transition-all ${currentResult.id === gen.id ? "border-white scale-105 shadow-lg" : "border-white/5 opacity-40 hover:opacity-100"}`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: gen.base64 ? gen.base64.startsWith("data:") ? gen.base64 : `data:image/png;base64,${gen.base64}` : "", className: "w-full h-full object-cover", alt: "Thumbnail" }) }, gen.id)) }) }),
1118
1115
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex-1 overflow-y-auto p-4 flex flex-col gap-6 dark-scrollbar pb-10", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col gap-4", children: [
1119
1116
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "Vorschau" }),
@@ -1166,8 +1163,8 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
1166
1163
  };
1167
1164
 
1168
1165
  // src/components/SetupPanel.tsx
1169
- var import_react8 = require("react");
1170
- var import_react9 = require("motion/react");
1166
+ var import_react7 = require("react");
1167
+ var import_react8 = require("motion/react");
1171
1168
  var import_jsx_runtime7 = require("react/jsx-runtime");
1172
1169
  var PRESET_URLS = [
1173
1170
  "https://jsonplaceholder.typicode.com/todos/1",
@@ -1175,12 +1172,12 @@ var PRESET_URLS = [
1175
1172
  "https://esm.sh/@rslsp1/fa-app-tools@latest"
1176
1173
  ];
1177
1174
  var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
1178
- const workspaceInputRef = (0, import_react8.useRef)(null);
1179
- const [urlInput, setUrlInput] = (0, import_react8.useState)("");
1180
- const [tokenInput, setTokenInput] = (0, import_react8.useState)("");
1181
- const [testStatus, setTestStatus] = (0, import_react8.useState)("idle");
1182
- const [result, setResult] = (0, import_react8.useState)(null);
1183
- const [fetchError, setFetchError] = (0, import_react8.useState)(null);
1175
+ const workspaceInputRef = (0, import_react7.useRef)(null);
1176
+ const [urlInput, setUrlInput] = (0, import_react7.useState)("");
1177
+ const [tokenInput, setTokenInput] = (0, import_react7.useState)("");
1178
+ const [testStatus, setTestStatus] = (0, import_react7.useState)("idle");
1179
+ const [result, setResult] = (0, import_react7.useState)(null);
1180
+ const [fetchError, setFetchError] = (0, import_react7.useState)(null);
1184
1181
  const runTest = async (url) => {
1185
1182
  if (!url.trim()) return;
1186
1183
  setTestStatus("loading");
@@ -1220,7 +1217,7 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
1220
1217
  setTestStatus("error");
1221
1218
  }
1222
1219
  };
1223
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react9.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-6 flex flex-col gap-10 overflow-y-auto", children: [
1220
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react8.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-6 flex flex-col gap-10 overflow-y-auto", children: [
1224
1221
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-4", children: [
1225
1222
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-1", children: [
1226
1223
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionLabel, { children: "Workspace Management" }),
@@ -1343,8 +1340,7 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
1343
1340
  };
1344
1341
 
1345
1342
  // src/components/MediaLibrary.tsx
1346
- var import_react10 = require("react");
1347
- var import_react11 = require("motion/react");
1343
+ var import_react9 = require("motion/react");
1348
1344
 
1349
1345
  // src/lib/grouping.ts
1350
1346
  function groupByPrompt(items) {
@@ -1369,9 +1365,7 @@ function groupByPrompt(items) {
1369
1365
 
1370
1366
  // src/components/MediaLibrary.tsx
1371
1367
  var import_jsx_runtime8 = require("react/jsx-runtime");
1372
- var PAGE_SIZE2 = 20;
1373
- var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, onBatchDownload, onGenerateReference }) => {
1374
- const [visibleCount, setVisibleCount] = (0, import_react10.useState)(PAGE_SIZE2);
1368
+ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, onBatchDownload, onGenerateReference, visibleCount, onLoadMore }) => {
1375
1369
  const selectedCount = items.filter((i) => i.selectedForExport).length;
1376
1370
  const groups = groupByPrompt(items);
1377
1371
  const visibleGroups = groups.slice(0, visibleCount);
@@ -1392,7 +1386,7 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
1392
1386
  "Laden"
1393
1387
  ] })
1394
1388
  ] }),
1395
- selectedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react11.motion.div, { initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, className: "flex items-center justify-between bg-blue-500/10 border border-blue-500/20 p-2 rounded-xl", children: [
1389
+ selectedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react9.motion.div, { initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, className: "flex items-center justify-between bg-blue-500/10 border border-blue-500/20 p-2 rounded-xl", children: [
1396
1390
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "text-[9px] font-bold uppercase text-blue-400 ml-1", children: [
1397
1391
  selectedCount,
1398
1392
  " ausgew\xE4hlt"
@@ -1413,7 +1407,7 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
1413
1407
  visibleGroups.map((group) => {
1414
1408
  const rep = group.representative;
1415
1409
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1416
- import_react11.motion.div,
1410
+ import_react9.motion.div,
1417
1411
  {
1418
1412
  initial: { opacity: 0, scale: 0.9 },
1419
1413
  animate: { opacity: 1, scale: 1 },
@@ -1444,7 +1438,7 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
1444
1438
  rep.id
1445
1439
  );
1446
1440
  }),
1447
- visibleCount < groups.length && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "col-span-2 flex justify-center pt-2 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", onClick: () => setVisibleCount((c) => c + PAGE_SIZE2), className: "px-4 py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-lg text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
1441
+ visibleCount < groups.length && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "col-span-2 flex justify-center pt-2 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", onClick: onLoadMore, className: "px-4 py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-lg text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
1448
1442
  groups.length - visibleCount,
1449
1443
  " weitere laden"
1450
1444
  ] }) })
@@ -1453,10 +1447,10 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
1453
1447
  };
1454
1448
 
1455
1449
  // src/components/ListView.tsx
1456
- var import_react12 = require("react");
1450
+ var import_react10 = require("react");
1457
1451
  var import_jsx_runtime9 = require("react/jsx-runtime");
1458
1452
  var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, isActive, isInPath, onFocus, onGenerate, onGenerateBranch, onGenerateSubtree, isGenerating, isCollapsed, toggleCollapse, renderNode, children }) => {
1459
- const inputRef = (0, import_react12.useRef)(null);
1453
+ const inputRef = (0, import_react10.useRef)(null);
1460
1454
  const hasChildren = children && children.length > 0;
1461
1455
  const handleKeyDown = (e) => {
1462
1456
  if (e.key === "Tab") {
@@ -1484,7 +1478,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
1484
1478
  onMoveNode(node.id, "down");
1485
1479
  }
1486
1480
  };
1487
- (0, import_react12.useEffect)(() => {
1481
+ (0, import_react10.useEffect)(() => {
1488
1482
  if (isActive && inputRef.current) inputRef.current.focus();
1489
1483
  }, [isActive]);
1490
1484
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col w-full", children: [
@@ -1518,7 +1512,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
1518
1512
  ] });
1519
1513
  };
1520
1514
  function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, focusedNodeId, onFocus, activePath, onGenerate, onGenerateBranch, onGenerateSubtree, isGeneratingNodeId }) {
1521
- const [collapsed, setCollapsed] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
1515
+ const [collapsed, setCollapsed] = (0, import_react10.useState)(/* @__PURE__ */ new Set());
1522
1516
  const toggleCollapse = (id) => {
1523
1517
  setCollapsed((prev) => {
1524
1518
  const next = new Set(prev);
@@ -1546,13 +1540,13 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
1546
1540
  }
1547
1541
 
1548
1542
  // src/components/AvatarArchitectApp.tsx
1549
- var import_react27 = require("react");
1543
+ var import_react25 = require("react");
1550
1544
 
1551
1545
  // src/components/PromptTab.tsx
1552
- var import_react14 = require("react");
1546
+ var import_react12 = require("react");
1553
1547
 
1554
1548
  // src/components/CollapsibleCard.tsx
1555
- var import_react13 = require("react");
1549
+ var import_react11 = require("react");
1556
1550
  var import_jsx_runtime10 = require("react/jsx-runtime");
1557
1551
  var CollapsibleCard = ({
1558
1552
  title,
@@ -1563,7 +1557,7 @@ var CollapsibleCard = ({
1563
1557
  collapsible = true,
1564
1558
  className = ""
1565
1559
  }) => {
1566
- const [isOpen, setIsOpen] = (0, import_react13.useState)(defaultOpen);
1560
+ const [isOpen, setIsOpen] = (0, import_react11.useState)(defaultOpen);
1567
1561
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `border border-neutral-800 rounded-lg ${className}`, children: [
1568
1562
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1569
1563
  "div",
@@ -1610,20 +1604,20 @@ var PromptTab = ({
1610
1604
  onTagUpdate,
1611
1605
  onTagDelete
1612
1606
  }) => {
1613
- const [selectedLabels, setSelectedLabels] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
1614
- const [instructions, setInstructions] = (0, import_react14.useState)("");
1615
- const [rules, setRules] = (0, import_react14.useState)("");
1616
- const [activeCategory, setActiveCategory] = (0, import_react14.useState)(null);
1617
- const [copied, setCopied] = (0, import_react14.useState)(false);
1618
- const imgInputRef = (0, import_react14.useRef)(null);
1619
- const [addingInCat, setAddingInCat] = (0, import_react14.useState)(null);
1620
- const [newLabel, setNewLabel] = (0, import_react14.useState)("");
1621
- const [newValue, setNewValue] = (0, import_react14.useState)("");
1622
- const [editingTag, setEditingTag] = (0, import_react14.useState)(null);
1623
- const [editLabel, setEditLabel] = (0, import_react14.useState)("");
1624
- const [editValue, setEditValue] = (0, import_react14.useState)("");
1625
- const longPressTimer = (0, import_react14.useRef)(null);
1626
- const longPressActivated = (0, import_react14.useRef)(false);
1607
+ const [selectedLabels, setSelectedLabels] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
1608
+ const [instructions, setInstructions] = (0, import_react12.useState)("");
1609
+ const [rules, setRules] = (0, import_react12.useState)("");
1610
+ const [activeCategory, setActiveCategory] = (0, import_react12.useState)(null);
1611
+ const [copied, setCopied] = (0, import_react12.useState)(false);
1612
+ const imgInputRef = (0, import_react12.useRef)(null);
1613
+ const [addingInCat, setAddingInCat] = (0, import_react12.useState)(null);
1614
+ const [newLabel, setNewLabel] = (0, import_react12.useState)("");
1615
+ const [newValue, setNewValue] = (0, import_react12.useState)("");
1616
+ const [editingTag, setEditingTag] = (0, import_react12.useState)(null);
1617
+ const [editLabel, setEditLabel] = (0, import_react12.useState)("");
1618
+ const [editValue, setEditValue] = (0, import_react12.useState)("");
1619
+ const longPressTimer = (0, import_react12.useRef)(null);
1620
+ const longPressActivated = (0, import_react12.useRef)(false);
1627
1621
  const toggleTag = (label) => {
1628
1622
  setSelectedLabels((prev) => {
1629
1623
  const next = new Set(prev);
@@ -2070,7 +2064,7 @@ var PromptTab = ({
2070
2064
  };
2071
2065
 
2072
2066
  // src/components/ProjectSyncTab.tsx
2073
- var import_react15 = require("react");
2067
+ var import_react13 = require("react");
2074
2068
  init_hfStateService();
2075
2069
  var import_jsx_runtime12 = require("react/jsx-runtime");
2076
2070
  var ProjectSyncTab = ({
@@ -2091,14 +2085,14 @@ var ProjectSyncTab = ({
2091
2085
  onProjectExportBase64,
2092
2086
  onHfInitialSync
2093
2087
  }) => {
2094
- const projectInputRef = (0, import_react15.useRef)(null);
2095
- const workspaceInputRef = (0, import_react15.useRef)(null);
2096
- const [saveName, setSaveName] = (0, import_react15.useState)("");
2097
- const [isSaving, setIsSaving] = (0, import_react15.useState)(false);
2098
- const [isExporting, setIsExporting] = (0, import_react15.useState)(false);
2099
- const [syncState, setSyncState] = (0, import_react15.useState)("idle");
2100
- const [syncDiff, setSyncDiff] = (0, import_react15.useState)(null);
2101
- const [selectedLocalIds, setSelectedLocalIds] = (0, import_react15.useState)(/* @__PURE__ */ new Set());
2088
+ const projectInputRef = (0, import_react13.useRef)(null);
2089
+ const workspaceInputRef = (0, import_react13.useRef)(null);
2090
+ const [saveName, setSaveName] = (0, import_react13.useState)("");
2091
+ const [isSaving, setIsSaving] = (0, import_react13.useState)(false);
2092
+ const [isExporting, setIsExporting] = (0, import_react13.useState)(false);
2093
+ const [syncState, setSyncState] = (0, import_react13.useState)("idle");
2094
+ const [syncDiff, setSyncDiff] = (0, import_react13.useState)(null);
2095
+ const [selectedLocalIds, setSelectedLocalIds] = (0, import_react13.useState)(/* @__PURE__ */ new Set());
2102
2096
  const handleExport = async () => {
2103
2097
  if (!onProjectExport) return;
2104
2098
  setIsExporting(true);
@@ -2144,13 +2138,13 @@ var ProjectSyncTab = ({
2144
2138
  });
2145
2139
  };
2146
2140
  const isWorking = projectActionState === "working" || projectActionState === "working-full";
2147
- const [hfProjects, setHfProjects] = (0, import_react15.useState)([]);
2148
- const [hfLoading, setHfLoading] = (0, import_react15.useState)(false);
2149
- const [hfSaving, setHfSaving] = (0, import_react15.useState)(false);
2150
- const [hfError, setHfError] = (0, import_react15.useState)(null);
2151
- const [hfSaveName, setHfSaveName] = (0, import_react15.useState)("");
2152
- const [hfSyncProgress, setHfSyncProgress] = (0, import_react15.useState)(null);
2153
- const [hfSyncing, setHfSyncing] = (0, import_react15.useState)(false);
2141
+ const [hfProjects, setHfProjects] = (0, import_react13.useState)([]);
2142
+ const [hfLoading, setHfLoading] = (0, import_react13.useState)(false);
2143
+ const [hfSaving, setHfSaving] = (0, import_react13.useState)(false);
2144
+ const [hfError, setHfError] = (0, import_react13.useState)(null);
2145
+ const [hfSaveName, setHfSaveName] = (0, import_react13.useState)("");
2146
+ const [hfSyncProgress, setHfSyncProgress] = (0, import_react13.useState)(null);
2147
+ const [hfSyncing, setHfSyncing] = (0, import_react13.useState)(false);
2154
2148
  const loadHfProjects = async (token) => {
2155
2149
  setHfLoading(true);
2156
2150
  setHfError(null);
@@ -2162,7 +2156,7 @@ var ProjectSyncTab = ({
2162
2156
  setHfLoading(false);
2163
2157
  }
2164
2158
  };
2165
- (0, import_react15.useEffect)(() => {
2159
+ (0, import_react13.useEffect)(() => {
2166
2160
  if (hfToken) loadHfProjects(hfToken);
2167
2161
  }, [hfToken]);
2168
2162
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "absolute inset-0 overflow-y-auto dark-scrollbar", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "p-6 flex flex-col gap-8", children: [
@@ -2576,7 +2570,7 @@ function toPromptImages(images) {
2576
2570
  init_hfStateService();
2577
2571
 
2578
2572
  // src/hooks/useHFState.ts
2579
- var import_react16 = require("react");
2573
+ var import_react14 = require("react");
2580
2574
  init_hfStateService();
2581
2575
 
2582
2576
  // src/lib/hfReducer.ts
@@ -2709,19 +2703,19 @@ function writeOfflineBuffer(events) {
2709
2703
  }
2710
2704
  }
2711
2705
  function useHFState(token, namespace) {
2712
- const [state, setState] = (0, import_react16.useState)(null);
2713
- const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
2714
- const [error, setError] = (0, import_react16.useState)(null);
2715
- const [eventCount, setEventCount] = (0, import_react16.useState)(0);
2716
- const [localOnlyCount, setLocalOnlyCount] = (0, import_react16.useState)(0);
2717
- const [forks, setForks] = (0, import_react16.useState)([]);
2718
- const [pendingBufferCount, setPendingBufferCount] = (0, import_react16.useState)(readOfflineBuffer().length);
2719
- const [lastEventTs, setLastEventTs] = (0, import_react16.useState)(0);
2720
- const [hasStateZip, setHasStateZip] = (0, import_react16.useState)(false);
2721
- const knownEventPaths = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
2722
- const knownFilePaths = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
2723
- const allEventsRef = (0, import_react16.useRef)([]);
2724
- const applyNewEvents = (0, import_react16.useCallback)((snapshot, newEvents) => {
2706
+ const [state, setState] = (0, import_react14.useState)(null);
2707
+ const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
2708
+ const [error, setError] = (0, import_react14.useState)(null);
2709
+ const [eventCount, setEventCount] = (0, import_react14.useState)(0);
2710
+ const [localOnlyCount, setLocalOnlyCount] = (0, import_react14.useState)(0);
2711
+ const [forks, setForks] = (0, import_react14.useState)([]);
2712
+ const [pendingBufferCount, setPendingBufferCount] = (0, import_react14.useState)(readOfflineBuffer().length);
2713
+ const [lastEventTs, setLastEventTs] = (0, import_react14.useState)(0);
2714
+ const [hasStateZip, setHasStateZip] = (0, import_react14.useState)(false);
2715
+ const knownEventPaths = (0, import_react14.useRef)(/* @__PURE__ */ new Set());
2716
+ const knownFilePaths = (0, import_react14.useRef)(/* @__PURE__ */ new Set());
2717
+ const allEventsRef = (0, import_react14.useRef)([]);
2718
+ const applyNewEvents = (0, import_react14.useCallback)((snapshot, newEvents) => {
2725
2719
  if (!newEvents.length && allEventsRef.current.length === 0) {
2726
2720
  setEventCount(0);
2727
2721
  return snapshot;
@@ -2735,7 +2729,7 @@ function useHFState(token, namespace) {
2735
2729
  if (afterConsolidation.length) setLastEventTs(Math.max(...afterConsolidation.map((e) => e.ts)));
2736
2730
  return applyEvents(snapshot, afterConsolidation);
2737
2731
  }, []);
2738
- const loadFull = (0, import_react16.useCallback)(async () => {
2732
+ const loadFull = (0, import_react14.useCallback)(async () => {
2739
2733
  if (!token || !namespace) return;
2740
2734
  setIsLoading(true);
2741
2735
  setError(null);
@@ -2783,7 +2777,7 @@ function useHFState(token, namespace) {
2783
2777
  setIsLoading(false);
2784
2778
  }
2785
2779
  }, [token, namespace, applyNewEvents]);
2786
- const pollNew = (0, import_react16.useCallback)(async () => {
2780
+ const pollNew = (0, import_react14.useCallback)(async () => {
2787
2781
  if (!token || !namespace || !state) return;
2788
2782
  try {
2789
2783
  const events = await loadPendingEvents(namespace, token, state.meta.consolidatedAt, knownFilePaths.current);
@@ -2797,15 +2791,15 @@ function useHFState(token, namespace) {
2797
2791
  } catch {
2798
2792
  }
2799
2793
  }, [token, namespace, state, applyNewEvents]);
2800
- (0, import_react16.useEffect)(() => {
2794
+ (0, import_react14.useEffect)(() => {
2801
2795
  if (token && namespace) loadFull();
2802
2796
  }, [token, namespace]);
2803
- (0, import_react16.useEffect)(() => {
2797
+ (0, import_react14.useEffect)(() => {
2804
2798
  if (!token || !namespace) return;
2805
2799
  const id = setInterval(pollNew, POLL_INTERVAL_MS);
2806
2800
  return () => clearInterval(id);
2807
2801
  }, [token, namespace, pollNew]);
2808
- const writeEvent = (0, import_react16.useCallback)(async (type, payload) => {
2802
+ const writeEvent = (0, import_react14.useCallback)(async (type, payload) => {
2809
2803
  const prevTs = lastEventTs ? [lastEventTs] : [state?.meta.consolidatedAt ?? 0];
2810
2804
  console.log("[HF] writeEvent called:", { type, namespace, tokenOk: !!token, prevTs });
2811
2805
  await pollNew();
@@ -2855,13 +2849,13 @@ function useHFState(token, namespace) {
2855
2849
  }
2856
2850
 
2857
2851
  // src/components/labs/LabsTab.tsx
2858
- var import_react23 = require("react");
2852
+ var import_react21 = require("react");
2859
2853
 
2860
2854
  // src/components/labs/LabRemix.tsx
2861
- var import_react18 = require("react");
2855
+ var import_react16 = require("react");
2862
2856
 
2863
2857
  // src/components/labs/LabImagePicker.tsx
2864
- var import_react17 = require("react");
2858
+ var import_react15 = require("react");
2865
2859
  var import_jsx_runtime13 = require("react/jsx-runtime");
2866
2860
  var LabImagePicker = ({
2867
2861
  availableItems,
@@ -2870,8 +2864,8 @@ var LabImagePicker = ({
2870
2864
  onClose,
2871
2865
  title = "Bild w\xE4hlen"
2872
2866
  }) => {
2873
- const [search, setSearch] = (0, import_react17.useState)("");
2874
- const [drillItem, setDrillItem] = (0, import_react17.useState)(null);
2867
+ const [search, setSearch] = (0, import_react15.useState)("");
2868
+ const [drillItem, setDrillItem] = (0, import_react15.useState)(null);
2875
2869
  const filtered = availableItems.filter(
2876
2870
  (item) => !search || item.prompt.toLowerCase().includes(search.toLowerCase())
2877
2871
  );
@@ -2973,13 +2967,13 @@ var LabImagePicker = ({
2973
2967
  // src/components/labs/LabRemix.tsx
2974
2968
  var import_jsx_runtime14 = require("react/jsx-runtime");
2975
2969
  var LabRemix = ({ services, onResult }) => {
2976
- const [showPicker, setShowPicker] = (0, import_react18.useState)(false);
2977
- const [selected, setSelected] = (0, import_react18.useState)(null);
2978
- const [instruction, setInstruction] = (0, import_react18.useState)("");
2979
- const [generatedPrompt, setGeneratedPrompt] = (0, import_react18.useState)("");
2980
- const [resultImage, setResultImage] = (0, import_react18.useState)(null);
2981
- const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react18.useState)(false);
2982
- const [isGeneratingImage, setIsGeneratingImage] = (0, import_react18.useState)(false);
2970
+ const [showPicker, setShowPicker] = (0, import_react16.useState)(false);
2971
+ const [selected, setSelected] = (0, import_react16.useState)(null);
2972
+ const [instruction, setInstruction] = (0, import_react16.useState)("");
2973
+ const [generatedPrompt, setGeneratedPrompt] = (0, import_react16.useState)("");
2974
+ const [resultImage, setResultImage] = (0, import_react16.useState)(null);
2975
+ const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react16.useState)(false);
2976
+ const [isGeneratingImage, setIsGeneratingImage] = (0, import_react16.useState)(false);
2983
2977
  const handleSelectImage = (item, frame) => {
2984
2978
  services.onItemUsed(item);
2985
2979
  setSelected({
@@ -3162,16 +3156,16 @@ var LabRemix = ({ services, onResult }) => {
3162
3156
  };
3163
3157
 
3164
3158
  // src/components/labs/LabBlend.tsx
3165
- var import_react19 = require("react");
3159
+ var import_react17 = require("react");
3166
3160
  var import_jsx_runtime15 = require("react/jsx-runtime");
3167
3161
  var LabBlend = ({ services, onResult }) => {
3168
- const [showPickerFor, setShowPickerFor] = (0, import_react19.useState)(null);
3169
- const [selectedImages, setSelectedImages] = (0, import_react19.useState)([]);
3170
- const [instruction, setInstruction] = (0, import_react19.useState)("");
3171
- const [generatedPrompt, setGeneratedPrompt] = (0, import_react19.useState)("");
3172
- const [resultImage, setResultImage] = (0, import_react19.useState)(null);
3173
- const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react19.useState)(false);
3174
- const [isGeneratingImage, setIsGeneratingImage] = (0, import_react19.useState)(false);
3162
+ const [showPickerFor, setShowPickerFor] = (0, import_react17.useState)(null);
3163
+ const [selectedImages, setSelectedImages] = (0, import_react17.useState)([]);
3164
+ const [instruction, setInstruction] = (0, import_react17.useState)("");
3165
+ const [generatedPrompt, setGeneratedPrompt] = (0, import_react17.useState)("");
3166
+ const [resultImage, setResultImage] = (0, import_react17.useState)(null);
3167
+ const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react17.useState)(false);
3168
+ const [isGeneratingImage, setIsGeneratingImage] = (0, import_react17.useState)(false);
3175
3169
  const handleSelectImage = (index, item, frame) => {
3176
3170
  services.onItemUsed(item);
3177
3171
  const newImg = {
@@ -3358,17 +3352,17 @@ var LabBlend = ({ services, onResult }) => {
3358
3352
  };
3359
3353
 
3360
3354
  // src/components/labs/LabCompare.tsx
3361
- var import_react20 = require("react");
3355
+ var import_react18 = require("react");
3362
3356
  var import_jsx_runtime16 = require("react/jsx-runtime");
3363
3357
  var LabCompare = ({ services, onResult }) => {
3364
- const [showPickerFor, setShowPickerFor] = (0, import_react20.useState)(null);
3365
- const [selectedImages, setSelectedImages] = (0, import_react20.useState)([]);
3366
- const [instruction, setInstruction] = (0, import_react20.useState)("");
3367
- const [analysis, setAnalysis] = (0, import_react20.useState)("");
3368
- const [generatedPrompt, setGeneratedPrompt] = (0, import_react20.useState)("");
3369
- const [resultImage, setResultImage] = (0, import_react20.useState)(null);
3370
- const [isAnalyzing, setIsAnalyzing] = (0, import_react20.useState)(false);
3371
- const [isGeneratingImage, setIsGeneratingImage] = (0, import_react20.useState)(false);
3358
+ const [showPickerFor, setShowPickerFor] = (0, import_react18.useState)(null);
3359
+ const [selectedImages, setSelectedImages] = (0, import_react18.useState)([]);
3360
+ const [instruction, setInstruction] = (0, import_react18.useState)("");
3361
+ const [analysis, setAnalysis] = (0, import_react18.useState)("");
3362
+ const [generatedPrompt, setGeneratedPrompt] = (0, import_react18.useState)("");
3363
+ const [resultImage, setResultImage] = (0, import_react18.useState)(null);
3364
+ const [isAnalyzing, setIsAnalyzing] = (0, import_react18.useState)(false);
3365
+ const [isGeneratingImage, setIsGeneratingImage] = (0, import_react18.useState)(false);
3372
3366
  const handleSelectImage = (index, item, frame) => {
3373
3367
  services.onItemUsed(item);
3374
3368
  const newImg = {
@@ -3531,14 +3525,14 @@ var LabCompare = ({ services, onResult }) => {
3531
3525
  };
3532
3526
 
3533
3527
  // src/components/labs/LabLoop.tsx
3534
- var import_react21 = require("react");
3528
+ var import_react19 = require("react");
3535
3529
  var import_jsx_runtime17 = require("react/jsx-runtime");
3536
3530
  var LabLoop = ({ services, onResult }) => {
3537
- const [rounds, setRounds] = (0, import_react21.useState)([]);
3538
- const [currentInstruction, setCurrentInstruction] = (0, import_react21.useState)("");
3539
- const [showPickerForRound, setShowPickerForRound] = (0, import_react21.useState)(null);
3540
- const [pendingImages, setPendingImages] = (0, import_react21.useState)([]);
3541
- const [isGenerating, setIsGenerating] = (0, import_react21.useState)(false);
3531
+ const [rounds, setRounds] = (0, import_react19.useState)([]);
3532
+ const [currentInstruction, setCurrentInstruction] = (0, import_react19.useState)("");
3533
+ const [showPickerForRound, setShowPickerForRound] = (0, import_react19.useState)(null);
3534
+ const [pendingImages, setPendingImages] = (0, import_react19.useState)([]);
3535
+ const [isGenerating, setIsGenerating] = (0, import_react19.useState)(false);
3542
3536
  const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
3543
3537
  const handleAddImage = (item, frame) => {
3544
3538
  services.onItemUsed(item);
@@ -3694,7 +3688,7 @@ var LabLoop = ({ services, onResult }) => {
3694
3688
  };
3695
3689
 
3696
3690
  // src/components/labs/LabFrameExtractor.tsx
3697
- var import_react22 = require("react");
3691
+ var import_react20 = require("react");
3698
3692
  var import_jsx_runtime18 = require("react/jsx-runtime");
3699
3693
  var formatTime = (s) => {
3700
3694
  const m = Math.floor(s / 60);
@@ -3708,15 +3702,15 @@ var LabFrameExtractor = ({
3708
3702
  onResult,
3709
3703
  resolveVideoUrl
3710
3704
  }) => {
3711
- const videoRef = (0, import_react22.useRef)(null);
3712
- const canvasRef = (0, import_react22.useRef)(null);
3713
- const cancelledRef = (0, import_react22.useRef)(false);
3714
- const [selectedItem, setSelectedItem] = (0, import_react22.useState)(null);
3715
- const [videoSrc, setVideoSrc] = (0, import_react22.useState)(null);
3716
- const [videoReady, setVideoReady] = (0, import_react22.useState)(false);
3717
- const [frames, setFrames] = (0, import_react22.useState)([]);
3718
- const [isExtracting, setIsExtracting] = (0, import_react22.useState)(false);
3719
- const [intervalSec, setIntervalSec] = (0, import_react22.useState)("1");
3705
+ const videoRef = (0, import_react20.useRef)(null);
3706
+ const canvasRef = (0, import_react20.useRef)(null);
3707
+ const cancelledRef = (0, import_react20.useRef)(false);
3708
+ const [selectedItem, setSelectedItem] = (0, import_react20.useState)(null);
3709
+ const [videoSrc, setVideoSrc] = (0, import_react20.useState)(null);
3710
+ const [videoReady, setVideoReady] = (0, import_react20.useState)(false);
3711
+ const [frames, setFrames] = (0, import_react20.useState)([]);
3712
+ const [isExtracting, setIsExtracting] = (0, import_react20.useState)(false);
3713
+ const [intervalSec, setIntervalSec] = (0, import_react20.useState)("1");
3720
3714
  const handleVideoSelect = (item) => {
3721
3715
  const mediaId = item.frames[0]?.mediaId;
3722
3716
  if (!mediaId) return;
@@ -3726,7 +3720,7 @@ var LabFrameExtractor = ({
3726
3720
  setVideoReady(false);
3727
3721
  cancelledRef.current = false;
3728
3722
  };
3729
- const captureAt = (0, import_react22.useCallback)(
3723
+ const captureAt = (0, import_react20.useCallback)(
3730
3724
  (t, label) => new Promise((resolve) => {
3731
3725
  const video = videoRef.current;
3732
3726
  const canvas = canvasRef.current;
@@ -3953,7 +3947,7 @@ var BASE_TABS = [
3953
3947
  ];
3954
3948
  var FRAMES_TAB = { key: "frames", label: "Frames", icon: "crop_original" };
3955
3949
  var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
3956
- const [activeTab, setActiveTab] = (0, import_react23.useState)("remix");
3950
+ const [activeTab, setActiveTab] = (0, import_react21.useState)("remix");
3957
3951
  const showFrames = !!(videoItems && resolveVideoUrl);
3958
3952
  const tabs = showFrames ? [...BASE_TABS, FRAMES_TAB] : BASE_TABS;
3959
3953
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
@@ -3987,19 +3981,19 @@ var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
3987
3981
  };
3988
3982
 
3989
3983
  // src/components/TagManagerPanel.tsx
3990
- var import_react24 = require("react");
3984
+ var import_react22 = require("react");
3991
3985
  var import_jsx_runtime20 = require("react/jsx-runtime");
3992
3986
  function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
3993
3987
  const categories = Object.keys(workspaceTags.by_category).filter(
3994
3988
  (cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
3995
3989
  );
3996
- const [selectedCategory, setSelectedCategory] = (0, import_react24.useState)(categories[0] || "");
3990
+ const [selectedCategory, setSelectedCategory] = (0, import_react22.useState)(categories[0] || "");
3997
3991
  const effectiveCategory = categories.includes(selectedCategory) ? selectedCategory : categories[0] || "";
3998
- const [editingLabel, setEditingLabel] = (0, import_react24.useState)(null);
3999
- const [editState, setEditState] = (0, import_react24.useState)({ label: "", value: "" });
4000
- const [newTag, setNewTag] = (0, import_react24.useState)({ label: "", value: "" });
4001
- const [movingLabel, setMovingLabel] = (0, import_react24.useState)(null);
4002
- const [moveTarget, setMoveTarget] = (0, import_react24.useState)("");
3992
+ const [editingLabel, setEditingLabel] = (0, import_react22.useState)(null);
3993
+ const [editState, setEditState] = (0, import_react22.useState)({ label: "", value: "" });
3994
+ const [newTag, setNewTag] = (0, import_react22.useState)({ label: "", value: "" });
3995
+ const [movingLabel, setMovingLabel] = (0, import_react22.useState)(null);
3996
+ const [moveTarget, setMoveTarget] = (0, import_react22.useState)("");
4003
3997
  const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
4004
3998
  const otherCategories = categories.filter((c) => c !== effectiveCategory);
4005
3999
  const startEdit = (tag) => {
@@ -4195,7 +4189,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
4195
4189
  }
4196
4190
 
4197
4191
  // src/components/HFTestTab.tsx
4198
- var import_react25 = require("react");
4192
+ var import_react23 = require("react");
4199
4193
  var import_jsx_runtime21 = require("react/jsx-runtime");
4200
4194
  var HF_BASE2 = "https://huggingface.co";
4201
4195
  var HF_REPO2 = "RolandSch/fa-app-state";
@@ -4388,7 +4382,7 @@ function tryFmt(s) {
4388
4382
  }
4389
4383
  }
4390
4384
  function CopyBtn({ text }) {
4391
- const [done, setDone] = (0, import_react25.useState)(false);
4385
+ const [done, setDone] = (0, import_react23.useState)(false);
4392
4386
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4393
4387
  "button",
4394
4388
  {
@@ -4560,9 +4554,9 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
4560
4554
  ] });
4561
4555
  }
4562
4556
  function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map(), missingImages = [] }) {
4563
- const [selected, setSelected] = (0, import_react25.useState)(null);
4564
- const [results, setResults] = (0, import_react25.useState)({});
4565
- const [expanded, setExpanded] = (0, import_react25.useState)({});
4557
+ const [selected, setSelected] = (0, import_react23.useState)(null);
4558
+ const [results, setResults] = (0, import_react23.useState)({});
4559
+ const [expanded, setExpanded] = (0, import_react23.useState)({});
4566
4560
  const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
4567
4561
  const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
4568
4562
  const setDone = (id, steps, t0) => {
@@ -4760,7 +4754,7 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
4760
4754
  }
4761
4755
 
4762
4756
  // src/components/ServerTab.tsx
4763
- var import_react26 = require("react");
4757
+ var import_react24 = require("react");
4764
4758
  var import_jsx_runtime22 = require("react/jsx-runtime");
4765
4759
  function StarRating({ rating = 0 }) {
4766
4760
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex gap-[2px]", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: `material-symbols-outlined text-[12px] ${i <= rating ? "text-yellow-400" : "text-white/15"}`, children: "star" }, i)) });
@@ -4773,21 +4767,21 @@ async function serverGet(baseUrl, path) {
4773
4767
  return json && typeof json === "object" && "data" in json ? json.data : json;
4774
4768
  }
4775
4769
  function ServerTab({ serverBaseUrl }) {
4776
- const [step, setStep] = (0, import_react26.useState)("user");
4777
- const [users, setUsers] = (0, import_react26.useState)([]);
4778
- const [usersLoading, setUsersLoading] = (0, import_react26.useState)(false);
4779
- const [usersError, setUsersError] = (0, import_react26.useState)(null);
4780
- const [selectedUser, setSelectedUser] = (0, import_react26.useState)(null);
4781
- const [contexts, setContexts] = (0, import_react26.useState)([]);
4782
- const [contextsLoading, setContextsLoading] = (0, import_react26.useState)(false);
4783
- const [selectedContext, setSelectedContext] = (0, import_react26.useState)(null);
4784
- const [tags, setTags] = (0, import_react26.useState)([]);
4785
- const [items, setItems] = (0, import_react26.useState)([]);
4786
- const [libLoading, setLibLoading] = (0, import_react26.useState)(false);
4787
- const [libError, setLibError] = (0, import_react26.useState)(null);
4788
- const [activeTag, setActiveTag] = (0, import_react26.useState)(null);
4789
- const [preview, setPreview] = (0, import_react26.useState)(null);
4790
- (0, import_react26.useEffect)(() => {
4770
+ const [step, setStep] = (0, import_react24.useState)("user");
4771
+ const [users, setUsers] = (0, import_react24.useState)([]);
4772
+ const [usersLoading, setUsersLoading] = (0, import_react24.useState)(false);
4773
+ const [usersError, setUsersError] = (0, import_react24.useState)(null);
4774
+ const [selectedUser, setSelectedUser] = (0, import_react24.useState)(null);
4775
+ const [contexts, setContexts] = (0, import_react24.useState)([]);
4776
+ const [contextsLoading, setContextsLoading] = (0, import_react24.useState)(false);
4777
+ const [selectedContext, setSelectedContext] = (0, import_react24.useState)(null);
4778
+ const [tags, setTags] = (0, import_react24.useState)([]);
4779
+ const [items, setItems] = (0, import_react24.useState)([]);
4780
+ const [libLoading, setLibLoading] = (0, import_react24.useState)(false);
4781
+ const [libError, setLibError] = (0, import_react24.useState)(null);
4782
+ const [activeTag, setActiveTag] = (0, import_react24.useState)(null);
4783
+ const [preview, setPreview] = (0, import_react24.useState)(null);
4784
+ (0, import_react24.useEffect)(() => {
4791
4785
  if (!serverBaseUrl) return;
4792
4786
  setUsersLoading(true);
4793
4787
  setUsersError(null);
@@ -4940,7 +4934,7 @@ function ServerTab({ serverBaseUrl }) {
4940
4934
  // src/components/AvatarArchitectApp.tsx
4941
4935
  var import_jsx_runtime23 = require("react/jsx-runtime");
4942
4936
  function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, serverBaseUrl, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
4943
- (0, import_react27.useEffect)(() => {
4937
+ (0, import_react25.useEffect)(() => {
4944
4938
  const id = "flow-styles";
4945
4939
  if (!document.getElementById(id)) {
4946
4940
  const style = document.createElement("style");
@@ -4949,19 +4943,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4949
4943
  document.head.appendChild(style);
4950
4944
  }
4951
4945
  }, []);
4952
- const [showStart, setShowStart] = (0, import_react27.useState)(true);
4953
- const [layoutChoice, setLayoutChoice] = (0, import_react27.useState)(() => {
4946
+ const [showStart, setShowStart] = (0, import_react25.useState)(true);
4947
+ const [layoutChoice, setLayoutChoice] = (0, import_react25.useState)(() => {
4954
4948
  try {
4955
4949
  return localStorage.getItem("aa-layout") || null;
4956
4950
  } catch {
4957
4951
  return null;
4958
4952
  }
4959
4953
  });
4960
- const [projectLoaded, setProjectLoaded] = (0, import_react27.useState)(false);
4961
- const [hfToken, setHfToken] = (0, import_react27.useState)(initialHfToken || "");
4962
- const [hfTokenInput, setHfTokenInput] = (0, import_react27.useState)(initialHfToken || "");
4963
- const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react27.useState)(false);
4964
- const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react27.useState)(() => {
4954
+ const [projectLoaded, setProjectLoaded] = (0, import_react25.useState)(false);
4955
+ const [hfToken, setHfToken] = (0, import_react25.useState)(initialHfToken || "");
4956
+ const [hfTokenInput, setHfTokenInput] = (0, import_react25.useState)(initialHfToken || "");
4957
+ const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react25.useState)(false);
4958
+ const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react25.useState)(() => {
4965
4959
  const KNOWN = ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"];
4966
4960
  const DEFAULT = "app.art-by-rolands.de/";
4967
4961
  try {
@@ -4973,8 +4967,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4973
4967
  return DEFAULT;
4974
4968
  }
4975
4969
  });
4976
- const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react27.useState)(null);
4977
- (0, import_react27.useEffect)(() => {
4970
+ const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react25.useState)(null);
4971
+ (0, import_react25.useEffect)(() => {
4978
4972
  if (hfNamespace !== void 0) return;
4979
4973
  const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
4980
4974
  if (!backendUrl) return;
@@ -4996,10 +4990,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4996
4990
  refresh: refreshHF,
4997
4991
  hasStateZip
4998
4992
  } = useHFState(hfToken, effectiveNamespace);
4999
- const [imageUploadStatus, setImageUploadStatus] = (0, import_react27.useState)(/* @__PURE__ */ new Map());
5000
- const [bootstrapLog, setBootstrapLog] = (0, import_react27.useState)([]);
5001
- const [isBootstrapping, setIsBootstrapping] = (0, import_react27.useState)(false);
5002
- const [hfMissingImages, setHfMissingImages] = (0, import_react27.useState)([]);
4993
+ const [imageUploadStatus, setImageUploadStatus] = (0, import_react25.useState)(/* @__PURE__ */ new Map());
4994
+ const [bootstrapLog, setBootstrapLog] = (0, import_react25.useState)([]);
4995
+ const [isBootstrapping, setIsBootstrapping] = (0, import_react25.useState)(false);
4996
+ const [hfMissingImages, setHfMissingImages] = (0, import_react25.useState)([]);
5003
4997
  const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5004
4998
  localOnlyCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { background: "rgba(234,179,8,0.15)", border: "1px solid rgba(234,179,8,0.3)", padding: "4px 10px", fontSize: 11, color: "#fbbf24", borderRadius: 4, marginBottom: 4 }, children: [
5005
4999
  "\u26A0 ",
@@ -5049,7 +5043,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5049
5043
  bootstrapLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: l }, i)) })
5050
5044
  ] })
5051
5045
  ] });
5052
- const wsInputRef = (0, import_react27.useRef)(null);
5046
+ const wsInputRef = (0, import_react25.useRef)(null);
5053
5047
  const startApp = (choice) => {
5054
5048
  try {
5055
5049
  localStorage.setItem("aa-layout", choice);
@@ -5058,16 +5052,37 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5058
5052
  setLayoutChoice(choice);
5059
5053
  setShowStart(false);
5060
5054
  };
5061
- const [nodes, setNodes] = (0, import_react27.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
5062
- const [edges, setEdges] = (0, import_react27.useState)([]);
5063
- const [history, setHistory] = (0, import_react27.useState)([]);
5064
- const [galleryItems, setGalleryItems] = (0, import_react27.useState)([]);
5065
- const galleryItemsRef = (0, import_react27.useRef)([]);
5066
- (0, import_react27.useEffect)(() => {
5055
+ const [nodes, setNodes] = (0, import_react25.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
5056
+ const [edges, setEdges] = (0, import_react25.useState)([]);
5057
+ const [history, setHistory] = (0, import_react25.useState)([]);
5058
+ const [galleryItems, setGalleryItems] = (0, import_react25.useState)([]);
5059
+ const galleryItemsRef = (0, import_react25.useRef)([]);
5060
+ (0, import_react25.useEffect)(() => {
5067
5061
  galleryItemsRef.current = galleryItems;
5068
5062
  }, [galleryItems]);
5069
- const hfImageNotFoundRef = (0, import_react27.useRef)(/* @__PURE__ */ new Map());
5070
- (0, import_react27.useEffect)(() => {
5063
+ const hfImageNotFoundRef = (0, import_react25.useRef)(/* @__PURE__ */ new Map());
5064
+ const [galleryVisibleCount, setGalleryVisibleCount] = (0, import_react25.useState)(20);
5065
+ const [historyVisibleCount, setHistoryVisibleCount] = (0, import_react25.useState)(20);
5066
+ const loadThumbnailsForEntries = (0, import_react25.useCallback)(async (entries) => {
5067
+ for (const entry of entries) {
5068
+ if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
5069
+ if (hfImageNotFoundRef.current.has(entry.id)) continue;
5070
+ try {
5071
+ const b64 = await hfLoadImageAsBase64(entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb);
5072
+ if (!b64) {
5073
+ hfImageNotFoundRef.current.set(entry.id, Date.now());
5074
+ setHfMissingImages((prev) => prev.find((e) => e.id === entry.id) ? prev : [...prev, { id: entry.id, filename: entry.filename, mimeType: entry.mimeType ?? "image/jpeg", timestamp: entry.timestamp ?? 0 }]);
5075
+ continue;
5076
+ }
5077
+ const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
5078
+ setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
5079
+ setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
5080
+ } catch {
5081
+ hfImageNotFoundRef.current.set(entry.id, Date.now());
5082
+ }
5083
+ }
5084
+ }, [hfToken, effectiveNamespace]);
5085
+ (0, import_react25.useEffect)(() => {
5071
5086
  if (!hfState) return;
5072
5087
  if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
5073
5088
  const hfIds = new Set(hfState.metadata.map((m) => m.id));
@@ -5093,90 +5108,97 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5093
5108
  const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
5094
5109
  return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
5095
5110
  });
5096
- const sortedEntries = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
5097
- const galleryRepIds = new Set(groupByPrompt(skeletons).slice(0, 20).map((g) => g.representative.id));
5098
- const historyIds = new Set(sortedEntries.slice(0, 20).map((e) => e.id));
5099
- const initialIds = /* @__PURE__ */ new Set([...galleryRepIds, ...historyIds]);
5100
- const toLoad = sortedEntries.filter((e) => initialIds.has(e.id));
5101
- (async () => {
5102
- for (const entry of toLoad) {
5103
- if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
5104
- if (hfImageNotFoundRef.current.has(entry.id)) continue;
5105
- try {
5106
- const b64 = await hfLoadImageAsBase64(entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb);
5107
- if (!b64) {
5108
- hfImageNotFoundRef.current.set(entry.id, Date.now());
5109
- setHfMissingImages((prev) => {
5110
- if (prev.find((e) => e.id === entry.id)) return prev;
5111
- return [...prev, { id: entry.id, filename: entry.filename, mimeType: entry.mimeType, timestamp: entry.timestamp }];
5112
- });
5113
- continue;
5114
- }
5115
- const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
5116
- setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
5117
- setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
5118
- } catch {
5119
- hfImageNotFoundRef.current.set(entry.id, Date.now());
5120
- }
5121
- }
5122
- })();
5123
5111
  }, [hfState]);
5124
- const [activePrompt, setActivePrompt] = (0, import_react27.useState)("");
5125
- const [isSynthesizing, setIsSynthesizing] = (0, import_react27.useState)(false);
5126
- const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react27.useState)(0);
5127
- const [currentResult, setCurrentResult] = (0, import_react27.useState)(null);
5128
- const [focusedNodeId, setFocusedNodeId] = (0, import_react27.useState)(null);
5129
- const [leftTab, setLeftTab] = (0, import_react27.useState)("prompt");
5130
- const [promptFeedback, setPromptFeedback] = (0, import_react27.useState)(null);
5131
- const [lastPromptPayload, setLastPromptPayload] = (0, import_react27.useState)(null);
5132
- const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react27.useState)(false);
5133
- const [activeTab, setActiveTab] = (0, import_react27.useState)("history");
5134
- const [mobileTab, setMobileTab] = (0, import_react27.useState)("stage");
5135
- const [middlePanel, setMiddlePanel] = (0, import_react27.useState)("stage");
5136
- const [recentLabItems, setRecentLabItems] = (0, import_react27.useState)([]);
5137
- const [aspectRatio, setAspectRatio] = (0, import_react27.useState)("1:1");
5138
- const [selectedModel, setSelectedModel] = (0, import_react27.useState)("\u{1F34C} Nano Banana Pro");
5139
- const [seed, setSeed] = (0, import_react27.useState)(Math.floor(Math.random() * 1e6));
5140
- const [seedMode, setSeedMode] = (0, import_react27.useState)("random");
5141
- const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react27.useState)(false);
5142
- const [isRightCollapsed, setIsRightCollapsed] = (0, import_react27.useState)(false);
5143
- const [leftPanelWidth, setLeftPanelWidth] = (0, import_react27.useState)(() => {
5112
+ (0, import_react25.useEffect)(() => {
5113
+ if (!hfState) return;
5114
+ const sortedMeta = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
5115
+ const skeletons = sortedMeta.map((m) => ({ id: m.id, prompt: m.prompt, timestamp: m.timestamp, status: "done", nodeId: m.id, tags: m.tags || [] }));
5116
+ const repIds = new Set(groupByPrompt(skeletons).slice(0, galleryVisibleCount).map((g) => g.representative.id));
5117
+ loadThumbnailsForEntries(sortedMeta.filter((e) => repIds.has(e.id)));
5118
+ }, [hfState, galleryVisibleCount, loadThumbnailsForEntries]);
5119
+ (0, import_react25.useEffect)(() => {
5120
+ if (!hfState) return;
5121
+ const sortedMeta = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
5122
+ loadThumbnailsForEntries(sortedMeta.slice(0, historyVisibleCount));
5123
+ }, [hfState, historyVisibleCount, loadThumbnailsForEntries]);
5124
+ const [activePrompt, setActivePrompt] = (0, import_react25.useState)("");
5125
+ const [isSynthesizing, setIsSynthesizing] = (0, import_react25.useState)(false);
5126
+ const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react25.useState)(0);
5127
+ const [currentResult, setCurrentResult] = (0, import_react25.useState)(null);
5128
+ const [focusedNodeId, setFocusedNodeId] = (0, import_react25.useState)(null);
5129
+ const [leftTab, setLeftTab] = (0, import_react25.useState)("prompt");
5130
+ const [promptFeedback, setPromptFeedback] = (0, import_react25.useState)(null);
5131
+ const [lastPromptPayload, setLastPromptPayload] = (0, import_react25.useState)(null);
5132
+ const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react25.useState)(false);
5133
+ const [activeTab, setActiveTab] = (0, import_react25.useState)("history");
5134
+ const [mobileTab, setMobileTab] = (0, import_react25.useState)("stage");
5135
+ const [middlePanel, setMiddlePanel] = (0, import_react25.useState)("stage");
5136
+ const [recentLabItems, setRecentLabItems] = (0, import_react25.useState)([]);
5137
+ const [aspectRatio, setAspectRatio] = (0, import_react25.useState)("1:1");
5138
+ const [selectedModel, setSelectedModel] = (0, import_react25.useState)("\u{1F34C} Nano Banana Pro");
5139
+ const [seed, setSeed] = (0, import_react25.useState)(Math.floor(Math.random() * 1e6));
5140
+ const [seedMode, setSeedMode] = (0, import_react25.useState)("random");
5141
+ const [imageCount, setImageCount] = (0, import_react25.useState)(() => {
5142
+ try {
5143
+ const v = parseInt(localStorage.getItem("aa-image-count") || "", 10);
5144
+ return v >= 1 && v <= 8 ? v : 4;
5145
+ } catch {
5146
+ return 4;
5147
+ }
5148
+ });
5149
+ const updateImageCount = (val) => {
5150
+ const n = Math.max(1, Math.min(8, parseInt(val, 10) || 4));
5151
+ setImageCount(n);
5152
+ try {
5153
+ localStorage.setItem("aa-image-count", String(n));
5154
+ } catch {
5155
+ }
5156
+ };
5157
+ const imageCountOptions = [
5158
+ { label: "1 Bild", value: "1" },
5159
+ { label: "2 Bilder", value: "2" },
5160
+ { label: "4 Bilder", value: "4" },
5161
+ { label: "8 Bilder", value: "8" }
5162
+ ];
5163
+ const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react25.useState)(false);
5164
+ const [isRightCollapsed, setIsRightCollapsed] = (0, import_react25.useState)(false);
5165
+ const [leftPanelWidth, setLeftPanelWidth] = (0, import_react25.useState)(() => {
5144
5166
  try {
5145
5167
  return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
5146
5168
  } catch {
5147
5169
  return 260;
5148
5170
  }
5149
5171
  });
5150
- const [rightPanelWidth, setRightPanelWidth] = (0, import_react27.useState)(() => {
5172
+ const [rightPanelWidth, setRightPanelWidth] = (0, import_react25.useState)(() => {
5151
5173
  try {
5152
5174
  return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
5153
5175
  } catch {
5154
5176
  return 320;
5155
5177
  }
5156
5178
  });
5157
- const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react27.useState)(false);
5158
- const [projectActionState, setProjectActionState] = (0, import_react27.useState)("idle");
5159
- const syncServerDataRef = (0, import_react27.useRef)(null);
5160
- const [workspaceTags, setWorkspaceTags] = (0, import_react27.useState)(null);
5161
- const [serverProjects, setServerProjects] = (0, import_react27.useState)([]);
5162
- const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react27.useState)(false);
5163
- const [highContrast, setHighContrast] = (0, import_react27.useState)(() => {
5179
+ const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react25.useState)(false);
5180
+ const [projectActionState, setProjectActionState] = (0, import_react25.useState)("idle");
5181
+ const syncServerDataRef = (0, import_react25.useRef)(null);
5182
+ const [workspaceTags, setWorkspaceTags] = (0, import_react25.useState)(null);
5183
+ const [serverProjects, setServerProjects] = (0, import_react25.useState)([]);
5184
+ const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react25.useState)(false);
5185
+ const [highContrast, setHighContrast] = (0, import_react25.useState)(() => {
5164
5186
  try {
5165
5187
  return localStorage.getItem("aa-contrast") === "high";
5166
5188
  } catch {
5167
5189
  return false;
5168
5190
  }
5169
5191
  });
5170
- const [activeReferenceId, setActiveReferenceId] = (0, import_react27.useState)(null);
5171
- const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react27.useState)(null);
5172
- const [isScanningImage, setIsScanningImage] = (0, import_react27.useState)(false);
5173
- const [touchStartX, setTouchStartX] = (0, import_react27.useState)(null);
5174
- const [isFullscreen, setIsFullscreen] = (0, import_react27.useState)(false);
5175
- const [zoomScale, setZoomScale] = (0, import_react27.useState)(1);
5176
- const [zoomOffset, setZoomOffset] = (0, import_react27.useState)({ x: 0, y: 0 });
5177
- const lastPinchDist = (0, import_react27.useRef)(null);
5178
- const lastTapTime = (0, import_react27.useRef)(0);
5179
- const dragStart = (0, import_react27.useRef)(null);
5192
+ const [activeReferenceId, setActiveReferenceId] = (0, import_react25.useState)(null);
5193
+ const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react25.useState)(null);
5194
+ const [isScanningImage, setIsScanningImage] = (0, import_react25.useState)(false);
5195
+ const [touchStartX, setTouchStartX] = (0, import_react25.useState)(null);
5196
+ const [isFullscreen, setIsFullscreen] = (0, import_react25.useState)(false);
5197
+ const [zoomScale, setZoomScale] = (0, import_react25.useState)(1);
5198
+ const [zoomOffset, setZoomOffset] = (0, import_react25.useState)({ x: 0, y: 0 });
5199
+ const lastPinchDist = (0, import_react25.useRef)(null);
5200
+ const lastTapTime = (0, import_react25.useRef)(0);
5201
+ const dragStart = (0, import_react25.useRef)(null);
5180
5202
  const openFullscreen = () => {
5181
5203
  setIsFullscreen(true);
5182
5204
  setZoomScale(1);
@@ -5239,7 +5261,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5239
5261
  setActiveReferenceId(null);
5240
5262
  setActiveReferenceThumbnail(null);
5241
5263
  };
5242
- const labServices = (0, import_react27.useMemo)(() => {
5264
+ const labServices = (0, import_react25.useMemo)(() => {
5243
5265
  const available = groupGenerationsToLabItems([...galleryItems, ...history]);
5244
5266
  return {
5245
5267
  availableItems: available,
@@ -5319,17 +5341,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5319
5341
  setIsScanningImage(false);
5320
5342
  }
5321
5343
  };
5322
- const currentIndex = (0, import_react27.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
5323
- const goToPrev = (0, import_react27.useCallback)(() => {
5344
+ const currentIndex = (0, import_react25.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
5345
+ const goToPrev = (0, import_react25.useCallback)(() => {
5324
5346
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
5325
5347
  }, [currentIndex, history]);
5326
- const goToNext = (0, import_react27.useCallback)(() => {
5348
+ const goToNext = (0, import_react25.useCallback)(() => {
5327
5349
  if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
5328
5350
  }, [currentIndex, history]);
5329
- const handleGallerySelect = (0, import_react27.useCallback)((g) => {
5351
+ const handleGallerySelect = (0, import_react25.useCallback)((g) => {
5330
5352
  setCurrentResult(g);
5331
5353
  setMobileTab("stage");
5332
- if (g.filename && hfToken && !g.fullBase64) {
5354
+ if (g.hasThumb && g.filename && hfToken && !g.fullBase64) {
5333
5355
  hfLoadImageAsBase64(g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
5334
5356
  if (!b64) return;
5335
5357
  const full = `data:${g.mimeType || "image/jpeg"};base64,${b64}`;
@@ -5339,7 +5361,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5339
5361
  });
5340
5362
  }
5341
5363
  }, [hfToken, effectiveNamespace]);
5342
- const handleTitleSet = (0, import_react27.useCallback)((id) => {
5364
+ const handleTitleSet = (0, import_react25.useCallback)((id) => {
5343
5365
  const ts = Date.now();
5344
5366
  setGalleryItems((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
5345
5367
  setHistory((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
@@ -5348,13 +5370,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5348
5370
  });
5349
5371
  }
5350
5372
  }, [hfToken, effectiveNamespace, hfWriteEvent]);
5351
- const currentGroup = (0, import_react27.useMemo)(() => {
5373
+ const currentGroup = (0, import_react25.useMemo)(() => {
5352
5374
  if (!currentResult?.prompt) return [];
5353
5375
  const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
5354
5376
  const group = groups.find((gr) => gr.prompt === currentResult.prompt);
5355
5377
  return group ? group.items : [];
5356
5378
  }, [galleryItems, currentResult?.prompt]);
5357
- (0, import_react27.useEffect)(() => {
5379
+ (0, import_react25.useEffect)(() => {
5358
5380
  if (!currentResult?.prompt || !hfToken || !effectiveNamespace || !hfState) return;
5359
5381
  const siblings = galleryItemsRef.current.filter(
5360
5382
  (g) => g.prompt === currentResult.prompt && !g.base64 && !hfImageNotFoundRef.current.has(g.id)
@@ -5380,9 +5402,20 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5380
5402
  })();
5381
5403
  }, [currentResult?.id, currentResult?.prompt]);
5382
5404
  const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
5383
- const isGenerating = activeGenerationsCount > 0;
5405
+ const runningBadge = activeGenerationsCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5406
+ "div",
5407
+ {
5408
+ className: "flex items-center gap-1 rounded-full bg-sky-500/15 border border-sky-400/30 px-2 shrink-0",
5409
+ style: { height: 24 },
5410
+ title: `${activeGenerationsCount} Generierung${activeGenerationsCount === 1 ? "" : "en"} l\xE4uft gerade`,
5411
+ children: [
5412
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-sky-300", style: { fontSize: 14, lineHeight: 1 }, children: "autorenew" }),
5413
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] font-bold text-sky-300 tabular-nums", children: activeGenerationsCount })
5414
+ ]
5415
+ }
5416
+ ) : null;
5384
5417
  useKeyboardNavigation(history, currentResult, setCurrentResult);
5385
- const getSubtreeFormat = (0, import_react27.useCallback)((nodeId, depth = 0) => {
5418
+ const getSubtreeFormat = (0, import_react25.useCallback)((nodeId, depth = 0) => {
5386
5419
  const node = nodes.find((n) => n.id === nodeId);
5387
5420
  if (!node) return "";
5388
5421
  const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
@@ -5390,7 +5423,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5390
5423
  return `${indent}- ${node.data.label || "(unbenannt)"}
5391
5424
  ` + childrenIds.map((id) => getSubtreeFormat(id, depth + 1)).join("");
5392
5425
  }, [nodes, edges]);
5393
- const activePath = (0, import_react27.useMemo)(() => {
5426
+ const activePath = (0, import_react25.useMemo)(() => {
5394
5427
  if (!focusedNodeId) return /* @__PURE__ */ new Set();
5395
5428
  const path = /* @__PURE__ */ new Set([focusedNodeId]);
5396
5429
  let currId = focusedNodeId;
@@ -5453,6 +5486,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5453
5486
  setActiveGenerationsCount((prev) => Math.max(0, prev - 1));
5454
5487
  }
5455
5488
  };
5489
+ const handleGenerateBatch = (customPrompt, useReferenceId, overrideNodeId, options = { silent: false }) => {
5490
+ const count = Math.max(1, Math.min(8, imageCount));
5491
+ return Promise.all(
5492
+ Array.from(
5493
+ { length: count },
5494
+ (_, i) => handleGenerateImage(customPrompt, useReferenceId, overrideNodeId, { silent: options.silent || i > 0 })
5495
+ )
5496
+ );
5497
+ };
5456
5498
  const handleSynthesizePrompt = async (nodeId, autoGenerate = false) => {
5457
5499
  setIsSynthesizing(true);
5458
5500
  try {
@@ -5739,7 +5781,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5739
5781
  setTimeout(() => setProjectActionState("idle"), 4e3);
5740
5782
  }
5741
5783
  };
5742
- (0, import_react27.useEffect)(() => {
5784
+ (0, import_react25.useEffect)(() => {
5743
5785
  if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
5744
5786
  }, [activeTab]);
5745
5787
  const mergeWorkspaceTags = (local, remote) => {
@@ -6026,7 +6068,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6026
6068
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
6027
6069
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
6028
6070
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
6071
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6029
6072
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1" }),
6073
+ runningBadge,
6030
6074
  activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
6031
6075
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
6032
6076
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
@@ -6048,20 +6092,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6048
6092
  ),
6049
6093
  activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActivePrompt(""), className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center text-white/20 active:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
6050
6094
  ] }) }),
6051
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6095
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6052
6096
  "button",
6053
6097
  {
6054
- onClick: () => handleGenerateImage(),
6055
- disabled: !activePrompt.trim() || isGenerating,
6098
+ onClick: () => handleGenerateBatch(),
6099
+ disabled: !activePrompt.trim(),
6056
6100
  className: "w-full flex items-center justify-center gap-2 rounded-xl font-bold text-[14px] uppercase tracking-wide transition-all disabled:opacity-30 active:scale-95",
6057
- style: { height: 48, background: activePrompt.trim() && !isGenerating ? "#0284c7" : void 0, border: "1px solid rgba(255,255,255,0.1)" },
6058
- children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6059
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-4 h-4 border-t-2 border-white rounded-full animate-spin" }),
6060
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generiere..." })
6061
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6101
+ style: { height: 48, background: activePrompt.trim() ? "#0284c7" : void 0, border: "1px solid rgba(255,255,255,0.1)" },
6102
+ children: [
6062
6103
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
6063
6104
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generieren" })
6064
- ] })
6105
+ ]
6065
6106
  }
6066
6107
  ) }),
6067
6108
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
@@ -6079,9 +6120,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6079
6120
  setTouchStartX(null);
6080
6121
  },
6081
6122
  children: [
6082
- currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
6083
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
6084
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6123
+ currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
6124
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6125
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6085
6126
  ] }),
6086
6127
  currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
6087
6128
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
@@ -6154,7 +6195,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6154
6195
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
6155
6196
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/60", children: "Prompt" })
6156
6197
  ] }),
6157
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl bg-white/10 active:bg-white/15 transition-colors", style: { height: 44 }, children: [
6198
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl bg-white/10 active:bg-white/15 transition-colors", style: { height: 44 }, children: [
6158
6199
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
6159
6200
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
6160
6201
  ] }),
@@ -6171,7 +6212,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6171
6212
  hfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-12 flex items-center justify-center text-white/20 active:text-white transition-colors disabled:opacity-30", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
6172
6213
  ] }),
6173
6214
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
6174
- activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
6215
+ activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
6175
6216
  activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6176
6217
  MediaLibrary,
6177
6218
  {
@@ -6184,9 +6225,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6184
6225
  onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
6185
6226
  onSelect: handleGallerySelect,
6186
6227
  onGenerateReference: (item) => {
6187
- handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true });
6228
+ handleGenerateBatch(item.prompt || activePrompt, item.mediaId, void 0, { silent: true });
6188
6229
  setMobileTab("stage");
6189
- }
6230
+ },
6231
+ visibleCount: galleryVisibleCount,
6232
+ onLoadMore: () => setGalleryVisibleCount((c) => c + 20)
6190
6233
  }
6191
6234
  ),
6192
6235
  activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectPanel, { currentResult, history, onSelect: (g) => {
@@ -6258,7 +6301,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6258
6301
  }
6259
6302
  ) }),
6260
6303
  workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
6261
- handleGenerateImage(prompt);
6304
+ handleGenerateBatch(prompt);
6262
6305
  setMobileTab("stage");
6263
6306
  }, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
6264
6307
  activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
@@ -6338,7 +6381,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6338
6381
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { height: 52, borderBottom: "1px solid rgba(255,255,255,0.05)", display: "flex", alignItems: "center", gap: 8, padding: "0 12px", flexShrink: 0 }, children: [
6339
6382
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
6340
6383
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
6384
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6341
6385
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1 } }),
6386
+ runningBadge,
6342
6387
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
6343
6388
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
6344
6389
  ] }),
@@ -6354,22 +6399,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6354
6399
  ),
6355
6400
  activePrompt && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActivePrompt(""), style: { position: "absolute", top: 6, right: 6, width: 22, height: 22, display: "flex", alignItems: "center", justifyContent: "center", color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
6356
6401
  ] }) }),
6357
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6402
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
6358
6403
  "button",
6359
6404
  {
6360
- onClick: () => handleGenerateImage(),
6361
- disabled: !activePrompt.trim() || isGenerating,
6362
- style: { width: "100%", height: 42, display: "flex", alignItems: "center", justifyContent: "center", gap: 8, borderRadius: 10, fontWeight: "bold", fontSize: 13, textTransform: "uppercase", letterSpacing: "0.05em", border: "1px solid rgba(255,255,255,0.1)", background: activePrompt.trim() && !isGenerating ? "#0284c7" : "transparent", color: "#fff", cursor: activePrompt.trim() && !isGenerating ? "pointer" : "default", opacity: !activePrompt.trim() || isGenerating ? 0.3 : 1, fontFamily: "inherit", transition: "background 0.2s" },
6363
- children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6364
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { width: 14, height: 14, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
6365
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generiere..." })
6366
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
6405
+ onClick: () => handleGenerateBatch(),
6406
+ disabled: !activePrompt.trim(),
6407
+ style: { width: "100%", height: 42, display: "flex", alignItems: "center", justifyContent: "center", gap: 8, borderRadius: 10, fontWeight: "bold", fontSize: 13, textTransform: "uppercase", letterSpacing: "0.05em", border: "1px solid rgba(255,255,255,0.1)", background: activePrompt.trim() ? "#0284c7" : "transparent", color: "#fff", cursor: activePrompt.trim() ? "pointer" : "default", opacity: !activePrompt.trim() ? 0.3 : 1, fontFamily: "inherit", transition: "background 0.2s" },
6408
+ children: [
6367
6409
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
6368
6410
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generieren" })
6369
- ] })
6411
+ ]
6370
6412
  }
6371
6413
  ) }),
6372
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }) })
6414
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }) })
6373
6415
  ] }),
6374
6416
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
6375
6417
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
@@ -6385,9 +6427,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6385
6427
  setTouchStartX(null);
6386
6428
  },
6387
6429
  children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { height: "100%", width: "100%", borderRadius: 20, border: "1px solid rgba(255,255,255,0.05)", background: "rgba(0,0,0,0.4)", position: "relative", overflow: "hidden", display: "flex", alignItems: "center", justifyContent: "center" }, children: [
6388
- currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
6389
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { width: 36, height: 36, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
6390
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.4)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
6430
+ currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
6431
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 36 }, children: "hourglass_top" }),
6432
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.6)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
6391
6433
  ] }),
6392
6434
  currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
6393
6435
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
@@ -6417,7 +6459,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6417
6459
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
6418
6460
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Prompt" })
6419
6461
  ] }),
6420
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "none", background: "rgba(255,255,255,0.1)", color: "rgba(255,255,255,0.8)", fontSize: 11, fontWeight: "bold", cursor: "pointer", fontFamily: "inherit" }, children: [
6462
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "none", background: "rgba(255,255,255,0.1)", color: "rgba(255,255,255,0.8)", fontSize: 11, fontWeight: "bold", cursor: "pointer", fontFamily: "inherit" }, children: [
6421
6463
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
6422
6464
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Referenz" })
6423
6465
  ] }),
@@ -6487,7 +6529,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6487
6529
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
6488
6530
  }
6489
6531
  ) }),
6490
- leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateImage(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
6532
+ leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateBatch(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
6491
6533
  ] })
6492
6534
  ] }),
6493
6535
  !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
@@ -6495,7 +6537,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6495
6537
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
6496
6538
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1.5", children: [
6497
6539
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
6498
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] })
6540
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
6541
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions })
6499
6542
  ] }),
6500
6543
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1 mx-auto", children: [
6501
6544
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
@@ -6525,7 +6568,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6525
6568
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Ref" })
6526
6569
  ] }),
6527
6570
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
6528
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "bolt", loading: isGenerating, disabled: !activePrompt.trim(), onClick: () => handleGenerateImage(), children: "Generieren" })
6571
+ runningBadge,
6572
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "bolt", disabled: !activePrompt.trim(), onClick: () => handleGenerateBatch(), children: "Generieren" })
6529
6573
  ] })
6530
6574
  ] }),
6531
6575
  /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
@@ -6537,33 +6581,27 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6537
6581
  const frame = item.frames[0];
6538
6582
  if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
6539
6583
  } }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
6540
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full max-w-4xl aspect-square rounded-3xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center group shadow-2xl", children: [
6541
- isGenerating && currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute top-6 right-6 z-30 bg-black/60 backdrop-blur-md px-4 py-2 rounded-full border border-white/10 flex items-center gap-3", children: [
6542
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
6543
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
6584
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-full w-full max-w-4xl aspect-square rounded-3xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center group shadow-2xl", children: currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-4 opacity-40", children: [
6585
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6586
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6587
+ ] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
6588
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
6589
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2", children: [
6590
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
6591
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
6544
6592
  ] }),
6545
- currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
6546
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
6547
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6548
- ] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
6549
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
6550
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2", children: [
6551
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
6552
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
6553
- ] }),
6554
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
6555
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
6556
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
6557
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute bottom-6 flex gap-2 opacity-0 group-hover:opacity-100 transition-all translate-y-4 group-hover:translate-y-0 z-20", children: [
6558
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
6559
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
6560
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
6561
- ] })
6562
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6563
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
6564
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6593
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
6594
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
6595
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
6596
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute bottom-6 flex gap-2 opacity-0 group-hover:opacity-100 transition-all translate-y-4 group-hover:translate-y-0 z-20", children: [
6597
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
6598
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
6599
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
6565
6600
  ] })
6566
- ] }) }),
6601
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6602
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
6603
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6604
+ ] }) }) }),
6567
6605
  currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
6568
6606
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6569
6607
  "div",
@@ -6645,7 +6683,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6645
6683
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
6646
6684
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
6647
6685
  ] }) }),
6648
- activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
6686
+ activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
6649
6687
  activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
6650
6688
  MediaLibrary,
6651
6689
  {
@@ -6657,7 +6695,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6657
6695
  },
6658
6696
  onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
6659
6697
  onSelect: handleGallerySelect,
6660
- onGenerateReference: (item) => handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true })
6698
+ onGenerateReference: (item) => handleGenerateBatch(item.prompt || activePrompt, item.mediaId, void 0, { silent: true }),
6699
+ visibleCount: galleryVisibleCount,
6700
+ onLoadMore: () => setGalleryVisibleCount((c) => c + 20)
6661
6701
  }
6662
6702
  ),
6663
6703
  activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
@@ -6693,7 +6733,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6693
6733
  }
6694
6734
 
6695
6735
  // src/components/FaApp.tsx
6696
- var import_react28 = require("react");
6736
+ var import_react26 = require("react");
6697
6737
  var import_jsx_runtime24 = require("react/jsx-runtime");
6698
6738
  function FaApp({
6699
6739
  onGenerateImage,
@@ -6713,8 +6753,8 @@ function FaApp({
6713
6753
  onServerDelete,
6714
6754
  buildInfo
6715
6755
  }) {
6716
- const [hfNamespace, setHfNamespace] = (0, import_react28.useState)(void 0);
6717
- (0, import_react28.useEffect)(() => {
6756
+ const [hfNamespace, setHfNamespace] = (0, import_react26.useState)(void 0);
6757
+ (0, import_react26.useEffect)(() => {
6718
6758
  if (!serverBaseUrl) return;
6719
6759
  fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
6720
6760
  if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
@@ -6748,7 +6788,7 @@ function FaApp({
6748
6788
  // src/index.ts
6749
6789
  init_hfStateService();
6750
6790
  init_hfStateService();
6751
- var LIB_VERSION = "2.0.57";
6791
+ var LIB_VERSION = "2.0.61";
6752
6792
  // Annotate the CommonJS export names for ESM import in node:
6753
6793
  0 && (module.exports = {
6754
6794
  AvatarArchitectApp,