@rslsp1/fa-app-tools 10.3.4 → 10.3.6

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
@@ -22,7 +22,7 @@ require('./chunk-FTLEDU6C.js');
22
22
  require('./chunk-DDH2SGZM.js');
23
23
 
24
24
  // package.json
25
- var version = "10.3.4";
25
+ var version = "10.3.6";
26
26
 
27
27
  // src/hooks/useOnClickOutside.ts
28
28
  var _react = require('react'); var _react2 = _interopRequireDefault(_react);
@@ -5465,7 +5465,7 @@ function ServerTab({ serverBaseUrl }) {
5465
5465
  function FlowWorkspacePicker({
5466
5466
  tagBase,
5467
5467
  selectedUserId,
5468
- message: message2,
5468
+ message: message3,
5469
5469
  onSelectUser,
5470
5470
  onSelectContext
5471
5471
  }) {
@@ -5489,7 +5489,7 @@ function FlowWorkspacePicker({
5489
5489
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "strong", { children: "FineArt Flow" }),
5490
5490
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "small", { children: step === "user" ? "Benutzer w\xE4hlen" : `Kontext f\xFCr ${_nullishCoalesce(_optionalChain([selectedUser, 'optionalAccess', _153 => _153.username]), () => ( `User ${selectedUserId}`))}` })
5491
5491
  ] }),
5492
- message2 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "flow-workspace-picker__warning", children: message2 }),
5492
+ message3 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "flow-workspace-picker__warning", children: message3 }),
5493
5493
  step === "user" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flow-workspace-picker__choices", "aria-label": "Benutzer w\xE4hlen", children: [
5494
5494
  tagBase.users.map((user) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { type: "button", onClick: () => chooseUser(user.id), children: [
5495
5495
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: user.username }),
@@ -5538,6 +5538,7 @@ var FLOW_BRIDGE_REQUEST_EVENT = "fine-art-flow-bridge:request:v1";
5538
5538
  var FLOW_BRIDGE_RESPONSE_EVENT = "fine-art-flow-bridge:response:v1";
5539
5539
  var FLOW_BRIDGE_HELLO_TIMEOUT_MS = 1500;
5540
5540
  var FLOW_BRIDGE_REQUEST_TIMEOUT_MS = 15e3;
5541
+ var FLOW_BRIDGE_PROXY_TIMEOUT_MS = 75e3;
5541
5542
  function isRecord(value) {
5542
5543
  return value !== null && typeof value === "object" && !Array.isArray(value);
5543
5544
  }
@@ -5604,13 +5605,32 @@ function createFlowBridgeClient({
5604
5605
  }
5605
5606
  return { available: true, name: bridge.name, version: bridge.version, protocol: bridge.protocol, roundTripMs };
5606
5607
  },
5607
- async request(request) {
5608
+ async proxy({ env, tokenSuffix, method, path }) {
5609
+ const started = clock();
5610
+ const reply = await exchange({ op: "proxy", env, tokenSuffix, method, path }, FLOW_BRIDGE_PROXY_TIMEOUT_MS);
5611
+ const roundTripMs = Math.round(clock() - started);
5612
+ if (!reply) {
5613
+ return { ok: false, transport: null, status: null, data: null, latencyMs: null, roundTripMs, error: noBridge(FLOW_BRIDGE_PROXY_TIMEOUT_MS) };
5614
+ }
5615
+ const ok = reply.ok === true;
5616
+ const body = isRecord(reply.body) && reply.body.encoding === "text" && typeof reply.body.data === "string" ? reply.body.data : null;
5617
+ return {
5618
+ ok,
5619
+ transport: typeof reply.transport === "string" ? reply.transport : null,
5620
+ status: nullableNumber(reply.status),
5621
+ data: ok ? body : null,
5622
+ latencyMs: nullableNumber(reply.latencyMs),
5623
+ roundTripMs,
5624
+ error: ok ? null : readError(reply.error)
5625
+ };
5626
+ },
5627
+ async request(request, { timeoutMs = requestTimeoutMs } = {}) {
5608
5628
  const started = clock();
5609
5629
  const tokenSuffix = "tokenSuffix" in request && request.tokenSuffix !== void 0 ? { tokenSuffix: request.tokenSuffix } : {};
5610
- const reply = await exchange({ op: "request", target: request.target, method: request.method, path: request.path, ...tokenSuffix }, requestTimeoutMs);
5630
+ const reply = await exchange({ op: "request", target: request.target, method: request.method, path: request.path, ...tokenSuffix }, timeoutMs);
5611
5631
  const roundTripMs = Math.round(clock() - started);
5612
5632
  if (!reply) {
5613
- return { ok: false, transport: null, status: null, data: null, latencyMs: null, roundTripMs, error: noBridge(requestTimeoutMs) };
5633
+ return { ok: false, transport: null, status: null, data: null, latencyMs: null, roundTripMs, error: noBridge(timeoutMs) };
5614
5634
  }
5615
5635
  const ok = reply.ok === true;
5616
5636
  return {
@@ -5852,6 +5872,239 @@ var FlowBridgePanel = ({ appVersion, client, hfToken }) => {
5852
5872
  ] });
5853
5873
  };
5854
5874
 
5875
+ // src/components/FlowFineArtApp.tsx
5876
+
5877
+
5878
+ // src/lib/flowAppLoader.ts
5879
+ var FLOW_APP_TARGETS = {
5880
+ dev: { bridgeTarget: "devMcp", backendUrl: "https://dev-app.art-by-rolands.de" },
5881
+ prod: { bridgeTarget: "prodMcp", backendUrl: "https://app.art-by-rolands.de" }
5882
+ };
5883
+ var FLOW_APP_FILES = ["react-runtime.js", "master.css", "app.js"];
5884
+ var FLOW_APP_REQUEST_TIMEOUT_MS = 75e3;
5885
+ var FLOW_APP_SCRIPT_TIMEOUT_MS = 15e3;
5886
+ var CSP_SETTLE_MS2 = 100;
5887
+ function isRecord3(value) {
5888
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5889
+ }
5890
+ function readFlowAppFile(data, file) {
5891
+ if (!isRecord3(data)) return null;
5892
+ const { sha256, source } = data;
5893
+ if (data.file !== file) return null;
5894
+ if (typeof sha256 !== "string" || !/^[0-9a-f]{64}$/.test(sha256)) return null;
5895
+ if (typeof source !== "string" || source.length === 0) return null;
5896
+ return { file, sha256, source };
5897
+ }
5898
+ async function sha256Hex2(text) {
5899
+ if (!_optionalChain([globalThis, 'access', _182 => _182.crypto, 'optionalAccess', _183 => _183.subtle])) throw new Error("crypto.subtle ist in diesem Kontext nicht verfuegbar.");
5900
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
5901
+ return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
5902
+ }
5903
+ var message2 = (error) => error instanceof Error ? error.message : String(error);
5904
+ var wait2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5905
+ async function runScriptBlob(source, doc, timeoutMs, step) {
5906
+ const onViolation = (event) => {
5907
+ const violation = event;
5908
+ step.cspViolations.push(`${violation.effectiveDirective || violation.violatedDirective}: ${violation.blockedURI || "unbekannt"}`);
5909
+ };
5910
+ doc.addEventListener("securitypolicyviolation", onViolation);
5911
+ let url = null;
5912
+ let script = null;
5913
+ try {
5914
+ url = URL.createObjectURL(new Blob([source], { type: "text/javascript" }));
5915
+ const element = doc.createElement("script");
5916
+ script = element;
5917
+ step.scriptEvent = await new Promise((resolve) => {
5918
+ const timer = setTimeout(() => resolve("timeout"), timeoutMs);
5919
+ element.addEventListener("load", () => {
5920
+ clearTimeout(timer);
5921
+ resolve("load");
5922
+ });
5923
+ element.addEventListener("error", () => {
5924
+ clearTimeout(timer);
5925
+ resolve("error");
5926
+ });
5927
+ element.src = url;
5928
+ (_nullishCoalesce(doc.head, () => ( doc.documentElement))).appendChild(element);
5929
+ });
5930
+ } catch (error) {
5931
+ step.error = `Skript nicht einfuegbar: ${message2(error)}`;
5932
+ }
5933
+ if (step.scriptEvent !== "load") await wait2(CSP_SETTLE_MS2);
5934
+ doc.removeEventListener("securitypolicyviolation", onViolation);
5935
+ _optionalChain([script, 'optionalAccess', _184 => _184.remove, 'call', _185 => _185()]);
5936
+ if (url) URL.revokeObjectURL(url);
5937
+ }
5938
+ function scriptFailure(step, expectation) {
5939
+ if (step.error) return step.error;
5940
+ if (step.scriptEvent === "load") return `script.onload, aber ${expectation} \u2014 Ausfuehrung nicht belegt.`;
5941
+ if (step.scriptEvent === "error") return "script.onerror \u2014 Skript nicht geladen oder blockiert.";
5942
+ return "Kein Skript-Ereignis innerhalb der Wartezeit.";
5943
+ }
5944
+ async function loadFlowApp({
5945
+ bridge,
5946
+ environment,
5947
+ tokenSuffix,
5948
+ win = window,
5949
+ doc = document,
5950
+ digest = sha256Hex2,
5951
+ scriptTimeoutMs = FLOW_APP_SCRIPT_TIMEOUT_MS,
5952
+ onStep
5953
+ }) {
5954
+ const target = FLOW_APP_TARGETS[environment];
5955
+ const globals = win;
5956
+ const steps = [];
5957
+ const report = () => _optionalChain([onStep, 'optionalCall', _186 => _186(steps.map((step) => ({ ...step, cspViolations: [...step.cspViolations] })))]);
5958
+ const fail3 = (step, error) => {
5959
+ step.error = error;
5960
+ report();
5961
+ return { ok: false, steps, error: `${step.file}: ${error}` };
5962
+ };
5963
+ let css = "";
5964
+ for (const file of FLOW_APP_FILES) {
5965
+ const step = { file, response: null, chars: null, hash: null, scriptEvent: null, cspViolations: [], error: null };
5966
+ steps.push(step);
5967
+ report();
5968
+ step.response = await bridge.request(
5969
+ { target: target.bridgeTarget, method: "GET", path: `/flow-app/bundle/${file}`, tokenSuffix },
5970
+ { timeoutMs: FLOW_APP_REQUEST_TIMEOUT_MS }
5971
+ );
5972
+ if (!step.response.ok) {
5973
+ const status = step.response.status !== null ? `HTTP ${step.response.status} \xB7 ` : "";
5974
+ return fail3(step, `${status}${_optionalChain([step, 'access', _187 => _187.response, 'access', _188 => _188.error, 'optionalAccess', _189 => _189.code])}: ${_optionalChain([step, 'access', _190 => _190.response, 'access', _191 => _191.error, 'optionalAccess', _192 => _192.message])}`);
5975
+ }
5976
+ const loaded = readFlowAppFile(step.response.data, file);
5977
+ if (!loaded) return fail3(step, "Antwort ohne gueltige Datei.");
5978
+ step.chars = loaded.source.length;
5979
+ try {
5980
+ step.hash = await digest(loaded.source) === loaded.sha256 ? "ok" : "mismatch";
5981
+ } catch (e21) {
5982
+ step.hash = "unavailable";
5983
+ }
5984
+ if (step.hash === "mismatch") return fail3(step, "SHA-256 des empfangenen Quelltexts weicht ab \u2014 nicht ausgefuehrt.");
5985
+ if (file === "master.css") {
5986
+ css = loaded.source;
5987
+ report();
5988
+ continue;
5989
+ }
5990
+ if (file === "app.js") delete globals.FineArtApp;
5991
+ await runScriptBlob(loaded.source, doc, scriptTimeoutMs, step);
5992
+ if (file === "react-runtime.js") {
5993
+ const ReactDOM = globals.ReactDOM;
5994
+ if (!isRecord3(globals.React) || typeof _optionalChain([ReactDOM, 'optionalAccess', _193 => _193.createRoot]) !== "function") {
5995
+ return fail3(step, scriptFailure(step, "window.React/window.ReactDOM.createRoot fehlen"));
5996
+ }
5997
+ } else if (typeof globals.FineArtApp !== "function") {
5998
+ return fail3(step, scriptFailure(step, "window.FineArtApp fehlt"));
5999
+ }
6000
+ report();
6001
+ }
6002
+ return {
6003
+ ok: true,
6004
+ steps,
6005
+ css,
6006
+ runtime: {
6007
+ React: globals.React,
6008
+ ReactDOM: globals.ReactDOM,
6009
+ FineArtApp: globals.FineArtApp
6010
+ },
6011
+ backendUrl: target.backendUrl
6012
+ };
6013
+ }
6014
+
6015
+ // src/components/FlowFineArtApp.tsx
6016
+
6017
+ var FLOW_APP_STYLE_ID = "fa-flow-app-master-css";
6018
+ var BAR_HEIGHT = 32;
6019
+ function stepText(step) {
6020
+ const parts = [step.file];
6021
+ if (step.response) {
6022
+ parts.push(step.response.status !== null ? `HTTP ${step.response.status}` : "kein HTTP-Status");
6023
+ parts.push(`${_nullishCoalesce(step.response.transport, () => ( "kein Transport"))} \xB7 ${step.response.roundTripMs} ms`);
6024
+ } else {
6025
+ parts.push("l\xE4dt\u2026");
6026
+ }
6027
+ if (step.chars !== null) parts.push(`${step.chars} Zeichen`);
6028
+ if (step.hash === "ok") parts.push("Hash gepr\xFCft");
6029
+ if (step.hash === "unavailable") parts.push("Hash nicht pr\xFCfbar");
6030
+ if (step.scriptEvent) parts.push(`Skript ${step.scriptEvent}`);
6031
+ if (step.cspViolations.length > 0) parts.push(`CSP: ${step.cspViolations.join("; ")}`);
6032
+ if (step.error) parts.push(`FEHLER: ${step.error}`);
6033
+ return parts.join(" \xB7 ");
6034
+ }
6035
+ var FlowFineArtApp = ({ environment, hfToken, appVersion, client, onClose }) => {
6036
+ const bridge = _react.useMemo.call(void 0, () => _nullishCoalesce(client, () => ( createFlowBridgeClient({ appVersion }))), [client, appVersion]);
6037
+ const [access, setAccess] = _react.useState.call(void 0, null);
6038
+ const [steps, setSteps] = _react.useState.call(void 0, []);
6039
+ const [load, setLoad] = _react.useState.call(void 0, null);
6040
+ const [renderError, setRenderError] = _react.useState.call(void 0, null);
6041
+ const appRootRef = _react.useRef.call(void 0, null);
6042
+ const tokenSuffix = hfTokenSuffix(hfToken);
6043
+ const target = FLOW_APP_TARGETS[environment];
6044
+ _react.useEffect.call(void 0, () => {
6045
+ if (!tokenSuffix) return void 0;
6046
+ let active = true;
6047
+ void (async () => {
6048
+ const checked = bridge.proxy ? await bridge.proxy({ env: environment, tokenSuffix, method: "GET", path: "/api/status" }) : { ok: false, transport: null, status: null, data: null, latencyMs: null, roundTripMs: 0, error: { code: "no-bridge", message: "Bridge-Client ohne proxy." } };
6049
+ if (!active) return;
6050
+ setAccess(checked);
6051
+ if (!checked.ok || checked.status !== 200) return;
6052
+ const result = await loadFlowApp({ bridge, environment, tokenSuffix, onStep: (next) => {
6053
+ if (active) setSteps(next);
6054
+ } });
6055
+ if (active) setLoad(result);
6056
+ })();
6057
+ return () => {
6058
+ active = false;
6059
+ };
6060
+ }, [bridge, environment, tokenSuffix]);
6061
+ _react.useEffect.call(void 0, () => {
6062
+ const container = appRootRef.current;
6063
+ if (!_optionalChain([load, 'optionalAccess', _194 => _194.ok]) || !container) return void 0;
6064
+ const style = document.createElement("style");
6065
+ style.id = FLOW_APP_STYLE_ID;
6066
+ style.textContent = load.css;
6067
+ document.head.appendChild(style);
6068
+ let root = null;
6069
+ try {
6070
+ root = load.runtime.ReactDOM.createRoot(container);
6071
+ root.render(load.runtime.React.createElement(load.runtime.FineArtApp, {
6072
+ customTabs: [],
6073
+ apiKey: null,
6074
+ backendUrl: load.backendUrl,
6075
+ transport: "flow-bridge",
6076
+ bridgeEnv: environment,
6077
+ bridgeTokenSuffix: tokenSuffix
6078
+ }));
6079
+ } catch (error) {
6080
+ setRenderError(error instanceof Error ? error.message : String(error));
6081
+ }
6082
+ return () => {
6083
+ _optionalChain([root, 'optionalAccess', _195 => _195.unmount, 'call', _196 => _196()]);
6084
+ style.remove();
6085
+ };
6086
+ }, [load, environment, tokenSuffix]);
6087
+ const accessFailed = access !== null && (!access.ok || access.status !== 200);
6088
+ const failed = !tokenSuffix || accessFailed || load !== null && !load.ok || renderError !== null;
6089
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col", "data-testid": "flow-fine-art-app", children: [
6090
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3 px-3 text-[11px] font-mono text-white/60", style: { height: BAR_HEIGHT, borderBottom: "1px solid rgba(255,255,255,0.08)" }, children: [
6091
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { type: "button", onClick: onClose, className: "font-bold text-white/80", children: "\u2190 FlowFA" }),
6092
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: `Fine-Art App \xB7 ${environment.toUpperCase()} \xB7 ${target.backendUrl}` })
6093
+ ] }),
6094
+ !_optionalChain([load, 'optionalAccess', _197 => _197.ok]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1 p-4 text-[11px] font-mono break-all", "data-testid": "flow-fine-art-app-steps", children: [
6095
+ !tokenSuffix && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { role: "alert", style: { color: "#f87171" }, children: "Kein HF-Token in FlowFA gesetzt \u2014 ohne ihn kein Zugang zum MCP-Host." }),
6096
+ tokenSuffix && !access && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { "data-testid": "flow-fine-art-app-access", className: "text-white/60", children: `Datenzugang ${environment.toUpperCase()} wird gepr\xFCft \u2026` }),
6097
+ access && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { "data-testid": "flow-fine-art-app-access", style: { color: accessFailed ? "#f87171" : "rgba(255,255,255,0.6)" }, children: access.ok ? `Datenzugang: GET /api/status \u2192 HTTP ${access.status} \xB7 ${_nullishCoalesce(access.transport, () => ( "kein Transport"))} \xB7 ${access.roundTripMs} ms` : `Datenzugang: ${_optionalChain([access, 'access', _198 => _198.error, 'optionalAccess', _199 => _199.code])}: ${_optionalChain([access, 'access', _200 => _200.error, 'optionalAccess', _201 => _201.message])}` }),
6098
+ _optionalChain([access, 'optionalAccess', _202 => _202.error, 'optionalAccess', _203 => _203.code]) === "not-approved" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { color: "#fbbf24" }, children: `Extension-Popup \u201EFine-Art Flow Bridge\u201C \u2192 Fine-Art App: Datenzugang \u2192 ${environment.toUpperCase()} einschalten, dann neu starten.` }),
6099
+ accessFailed && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { role: "alert", className: "font-bold", style: { color: "#f87171" }, children: "App nicht gestartet \u2014 ohne Datenzugang erreicht sie ihren Server nicht." }),
6100
+ steps.map((step) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { color: step.error ? "#f87171" : "rgba(255,255,255,0.6)" }, children: stepText(step) }, step.file)),
6101
+ load && !load.ok && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { role: "alert", className: "font-bold", style: { color: "#f87171" }, children: `App nicht gestartet \u2014 ${load.error}` })
6102
+ ] }),
6103
+ renderError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { role: "alert", className: "p-4 text-[11px] font-mono", style: { color: "#f87171" }, children: `App nicht gerendert \u2014 ${renderError}` }),
6104
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: appRootRef, className: "flex-1 overflow-auto", style: { display: _optionalChain([load, 'optionalAccess', _204 => _204.ok]) && !failed ? "block" : "none" } })
6105
+ ] });
6106
+ };
6107
+
5855
6108
  // src/lib/flowBootstrapTarget.ts
5856
6109
  var PROD_NAMESPACE = "app.art-by-rolands.de/";
5857
6110
  var DEV_NAMESPACE = "dev-app.art-by-rolands.de/";
@@ -5902,6 +6155,10 @@ function resolveBootstrapTarget(input) {
5902
6155
  environment: environmentForNamespace(namespace)
5903
6156
  };
5904
6157
  }
6158
+ function flowAppEnvironment(target, isDialogTarget, selectedNamespace) {
6159
+ if (isDialogTarget) return environmentForNamespace(normalizeSelectableNamespace(selectedNamespace));
6160
+ return target.ready ? target.environment : null;
6161
+ }
5905
6162
 
5906
6163
  // src/components/AvatarArchitectApp.tsx
5907
6164
 
@@ -5919,16 +6176,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5919
6176
  const [layoutChoice, setLayoutChoice] = _react.useState.call(void 0, () => {
5920
6177
  try {
5921
6178
  return localStorage.getItem("aa-layout") || null;
5922
- } catch (e21) {
6179
+ } catch (e22) {
5923
6180
  return null;
5924
6181
  }
5925
6182
  });
5926
6183
  const [hfToken, setHfToken] = _react.useState.call(void 0, initialHfToken || "");
6184
+ const [serverAppEnvironment, setServerAppEnvironment] = _react.useState.call(void 0, null);
5927
6185
  const [hfTokenInput, setHfTokenInput] = _react.useState.call(void 0, initialHfToken || "");
5928
6186
  const [hfNamespaceLocal, setHfNamespaceLocal] = _react.useState.call(void 0, () => {
5929
6187
  try {
5930
6188
  return normalizeSelectableNamespace(localStorage.getItem("aa-hf-namespace"));
5931
- } catch (e22) {
6189
+ } catch (e23) {
5932
6190
  return DEFAULT_NAMESPACE;
5933
6191
  }
5934
6192
  });
@@ -6031,7 +6289,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6031
6289
  const startApp = (choice) => {
6032
6290
  try {
6033
6291
  localStorage.setItem("aa-layout", choice);
6034
- } catch (e23) {
6292
+ } catch (e24) {
6035
6293
  }
6036
6294
  setLayoutChoice(choice);
6037
6295
  setTargetConfirmed(true);
@@ -6052,7 +6310,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6052
6310
  const loadThumbnailsForEntries = _react.useCallback.call(void 0, async (entries) => {
6053
6311
  await loadThumbnailsSequentially(entries, {
6054
6312
  inFlight: hfInFlightRef.current,
6055
- isAlreadyLoaded: (entry) => !!_optionalChain([galleryItemsRef, 'access', _182 => _182.current, 'access', _183 => _183.find, 'call', _184 => _184((g) => g.id === entry.id), 'optionalAccess', _185 => _185.base64]),
6313
+ isAlreadyLoaded: (entry) => !!_optionalChain([galleryItemsRef, 'access', _205 => _205.current, 'access', _206 => _206.find, 'call', _207 => _207((g) => g.id === entry.id), 'optionalAccess', _208 => _208.base64]),
6056
6314
  isKnownMissing: (entry) => hfImageNotFoundRef.current.has(entry.id),
6057
6315
  loadImage: (entry) => _chunkVSHSZEGVjs.hfLoadImageAsBase64.call(void 0, entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb),
6058
6316
  onLoaded: (entry, b64) => {
@@ -6071,7 +6329,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6071
6329
  }, [hfToken, effectiveNamespace]);
6072
6330
  _react.useEffect.call(void 0, () => {
6073
6331
  if (!hfState) return;
6074
- if (_optionalChain([hfState, 'access', _186 => _186.tags, 'optionalAccess', _187 => _187.by_category])) setWorkspaceTags(hfState.tags);
6332
+ if (_optionalChain([hfState, 'access', _209 => _209.tags, 'optionalAccess', _210 => _210.by_category])) setWorkspaceTags(hfState.tags);
6075
6333
  const hfIds = new Set(hfState.metadata.map((m) => m.id));
6076
6334
  const skeletons = hfState.metadata.map((m) => ({
6077
6335
  id: m.id,
@@ -6117,7 +6375,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6117
6375
  try {
6118
6376
  const v = parseInt(localStorage.getItem("aa-image-count") || "", 10);
6119
6377
  return v >= 1 && v <= 8 ? v : 4;
6120
- } catch (e24) {
6378
+ } catch (e25) {
6121
6379
  return 4;
6122
6380
  }
6123
6381
  });
@@ -6126,7 +6384,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6126
6384
  setImageCount(n);
6127
6385
  try {
6128
6386
  localStorage.setItem("aa-image-count", String(n));
6129
- } catch (e25) {
6387
+ } catch (e26) {
6130
6388
  }
6131
6389
  };
6132
6390
  const imageCountOptions = [
@@ -6140,14 +6398,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6140
6398
  const [leftPanelWidth, setLeftPanelWidth] = _react.useState.call(void 0, () => {
6141
6399
  try {
6142
6400
  return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
6143
- } catch (e26) {
6401
+ } catch (e27) {
6144
6402
  return 260;
6145
6403
  }
6146
6404
  });
6147
6405
  const [rightPanelWidth, setRightPanelWidth] = _react.useState.call(void 0, () => {
6148
6406
  try {
6149
6407
  return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
6150
- } catch (e27) {
6408
+ } catch (e28) {
6151
6409
  return 320;
6152
6410
  }
6153
6411
  });
@@ -6156,7 +6414,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6156
6414
  const [highContrast, setHighContrast] = _react.useState.call(void 0, () => {
6157
6415
  try {
6158
6416
  return localStorage.getItem("aa-contrast") === "high";
6159
- } catch (e28) {
6417
+ } catch (e29) {
6160
6418
  return false;
6161
6419
  }
6162
6420
  });
@@ -6169,14 +6427,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6169
6427
  const [zoomOffset, setZoomOffset] = _react.useState.call(void 0, { x: 0, y: 0 });
6170
6428
  const { historyVisible, galleryVisible } = computePrefetchVisibility({
6171
6429
  layoutChoice,
6172
- appShellVisible: !showStart && !requireWorkspaceSelection && !(isFullscreen && !!_optionalChain([currentResult, 'optionalAccess', _188 => _188.base64])),
6430
+ appShellVisible: !showStart && !requireWorkspaceSelection && !(isFullscreen && !!_optionalChain([currentResult, 'optionalAccess', _211 => _211.base64])),
6173
6431
  mobileTab,
6174
6432
  middlePanel,
6175
6433
  activeTab,
6176
6434
  isRightCollapsed
6177
6435
  });
6178
6436
  useThumbnailPrefetch({
6179
- metadata: _optionalChain([hfState, 'optionalAccess', _189 => _189.metadata]),
6437
+ metadata: _optionalChain([hfState, 'optionalAccess', _212 => _212.metadata]),
6180
6438
  historyVisible,
6181
6439
  galleryVisible,
6182
6440
  historyVisibleCount,
@@ -6232,12 +6490,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6232
6490
  setHighContrast(next);
6233
6491
  try {
6234
6492
  localStorage.setItem("aa-contrast", next ? "high" : "low");
6235
- } catch (e29) {
6493
+ } catch (e30) {
6236
6494
  }
6237
6495
  };
6238
6496
  const handleSelectReference = async () => {
6239
6497
  const media = await onSelectMedia();
6240
- if (!_optionalChain([media, 'optionalAccess', _190 => _190.length])) return;
6498
+ if (!_optionalChain([media, 'optionalAccess', _213 => _213.length])) return;
6241
6499
  const first = media[0];
6242
6500
  if (first.mediaId) {
6243
6501
  setActiveReferenceId(first.mediaId);
@@ -6260,7 +6518,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6260
6518
  generateImage: onGenerateImage,
6261
6519
  saveResult: async (item) => {
6262
6520
  const frame = item.frames[0];
6263
- if (_optionalChain([frame, 'optionalAccess', _191 => _191.base64])) {
6521
+ if (_optionalChain([frame, 'optionalAccess', _214 => _214.base64])) {
6264
6522
  const gen = frameToGeneration(frame, item);
6265
6523
  setGalleryItems((prev) => [gen, ...prev]);
6266
6524
  setHistory((prev) => [gen, ...prev]);
@@ -6278,7 +6536,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6278
6536
  setLeftPanelWidth(w);
6279
6537
  try {
6280
6538
  localStorage.setItem("aa-left-width", String(w));
6281
- } catch (e30) {
6539
+ } catch (e31) {
6282
6540
  }
6283
6541
  };
6284
6542
  const onUp = () => {
@@ -6297,7 +6555,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6297
6555
  setRightPanelWidth(w);
6298
6556
  try {
6299
6557
  localStorage.setItem("aa-right-width", String(w));
6300
- } catch (e31) {
6558
+ } catch (e32) {
6301
6559
  }
6302
6560
  };
6303
6561
  const onUp = () => {
@@ -6328,7 +6586,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6328
6586
  setIsScanningImage(false);
6329
6587
  }
6330
6588
  };
6331
- const currentIndex = _react.useMemo.call(void 0, () => history.findIndex((h) => h.id === _optionalChain([currentResult, 'optionalAccess', _192 => _192.id])), [history, currentResult]);
6589
+ const currentIndex = _react.useMemo.call(void 0, () => history.findIndex((h) => h.id === _optionalChain([currentResult, 'optionalAccess', _215 => _215.id])), [history, currentResult]);
6332
6590
  const goToPrev = _react.useCallback.call(void 0, () => {
6333
6591
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
6334
6592
  }, [currentIndex, history]);
@@ -6342,7 +6600,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6342
6600
  _chunkVSHSZEGVjs.hfLoadImageAsBase64.call(void 0, g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
6343
6601
  if (!b64) return;
6344
6602
  const full = `data:${g.mimeType || "image/jpeg"};base64,${b64}`;
6345
- setCurrentResult((prev) => _optionalChain([prev, 'optionalAccess', _193 => _193.id]) === g.id ? { ...prev, fullBase64: full } : prev);
6603
+ setCurrentResult((prev) => _optionalChain([prev, 'optionalAccess', _216 => _216.id]) === g.id ? { ...prev, fullBase64: full } : prev);
6346
6604
  setGalleryItems((prev) => prev.map((item) => item.id === g.id ? { ...item, fullBase64: full } : item));
6347
6605
  }).catch(() => {
6348
6606
  });
@@ -6358,13 +6616,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6358
6616
  }
6359
6617
  }, [hfToken, effectiveNamespace, hfWriteEvent]);
6360
6618
  const currentGroup = _react.useMemo.call(void 0, () => {
6361
- if (!_optionalChain([currentResult, 'optionalAccess', _194 => _194.prompt])) return [];
6619
+ if (!_optionalChain([currentResult, 'optionalAccess', _217 => _217.prompt])) return [];
6362
6620
  const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
6363
6621
  const group = groups.find((gr) => gr.prompt === currentResult.prompt);
6364
6622
  return group ? group.items : [];
6365
- }, [galleryItems, _optionalChain([currentResult, 'optionalAccess', _195 => _195.prompt])]);
6623
+ }, [galleryItems, _optionalChain([currentResult, 'optionalAccess', _218 => _218.prompt])]);
6366
6624
  _react.useEffect.call(void 0, () => {
6367
- if (!_optionalChain([currentResult, 'optionalAccess', _196 => _196.prompt]) || !hfToken || !effectiveNamespace || !hfState) return;
6625
+ if (!_optionalChain([currentResult, 'optionalAccess', _219 => _219.prompt]) || !hfToken || !effectiveNamespace || !hfState) return;
6368
6626
  const siblings = galleryItemsRef.current.filter(
6369
6627
  (g) => g.prompt === currentResult.prompt && !g.base64 && !hfImageNotFoundRef.current.has(g.id)
6370
6628
  );
@@ -6382,12 +6640,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6382
6640
  const prefix = `data:${meta.mimeType || "image/jpeg"};base64,`;
6383
6641
  setGalleryItems((prev) => prev.map((g) => g.id === sib.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
6384
6642
  setHistory((prev) => prev.map((g) => g.id === sib.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
6385
- } catch (e32) {
6643
+ } catch (e33) {
6386
6644
  hfImageNotFoundRef.current.set(sib.id, Date.now());
6387
6645
  }
6388
6646
  }
6389
6647
  })();
6390
- }, [_optionalChain([currentResult, 'optionalAccess', _197 => _197.id]), _optionalChain([currentResult, 'optionalAccess', _198 => _198.prompt])]);
6648
+ }, [_optionalChain([currentResult, 'optionalAccess', _220 => _220.id]), _optionalChain([currentResult, 'optionalAccess', _221 => _221.prompt])]);
6391
6649
  const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
6392
6650
  const runningBadge = activeGenerationsCount > 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6393
6651
  "div",
@@ -6468,7 +6726,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6468
6726
  const errorGen = { ...newGen, status: "error", error: { message: err.message || "Unbekannter Fehler", details: err.toString() } };
6469
6727
  setHistory((prev) => prev.map((g) => g.id === genId ? errorGen : g));
6470
6728
  setGalleryItems((prev) => prev.filter((g) => g.id !== genId));
6471
- if (!options.silent || _optionalChain([currentResult, 'optionalAccess', _199 => _199.id]) === genId) setCurrentResult(errorGen);
6729
+ if (!options.silent || _optionalChain([currentResult, 'optionalAccess', _222 => _222.id]) === genId) setCurrentResult(errorGen);
6472
6730
  } finally {
6473
6731
  setActiveGenerationsCount((prev) => Math.max(0, prev - 1));
6474
6732
  }
@@ -6524,7 +6782,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6524
6782
  setActivePrompt(prompt);
6525
6783
  setFocusedNodeId(nodeId);
6526
6784
  if (autoGenerate) handleGenerateImage(prompt, void 0, nodeId);
6527
- } catch (e33) {
6785
+ } catch (e34) {
6528
6786
  setActivePrompt("Synthese-Fehler");
6529
6787
  } finally {
6530
6788
  setIsSynthesizing(false);
@@ -6597,14 +6855,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6597
6855
  const { prompt, feedback } = parsePromptResponse(raw);
6598
6856
  setActivePrompt(prompt);
6599
6857
  setPromptFeedback(feedback);
6600
- } catch (e34) {
6858
+ } catch (e35) {
6601
6859
  setActivePrompt("Synthese-Fehler");
6602
6860
  } finally {
6603
6861
  setIsPromptTabGenerating(false);
6604
6862
  }
6605
6863
  };
6606
6864
  const handleDownloadSingle = async () => {
6607
- if (!_optionalChain([currentResult, 'optionalAccess', _200 => _200.base64])) return;
6865
+ if (!_optionalChain([currentResult, 'optionalAccess', _223 => _223.base64])) return;
6608
6866
  try {
6609
6867
  const downloadSrc = currentResult.fullBase64 || currentResult.base64;
6610
6868
  const base64Data = downloadSrc.split(",")[1];
@@ -6620,9 +6878,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6620
6878
  const reader = new FileReader();
6621
6879
  reader.onload = (ev) => {
6622
6880
  try {
6623
- const root = JSON.parse(_optionalChain([ev, 'access', _201 => _201.target, 'optionalAccess', _202 => _202.result]));
6881
+ const root = JSON.parse(_optionalChain([ev, 'access', _224 => _224.target, 'optionalAccess', _225 => _225.result]));
6624
6882
  const rawTags = root.tags || root;
6625
- if (!_optionalChain([rawTags, 'optionalAccess', _203 => _203.by_category])) return;
6883
+ if (!_optionalChain([rawTags, 'optionalAccess', _226 => _226.by_category])) return;
6626
6884
  const filtered = {};
6627
6885
  const EXCLUDED2 = ["pdf-export", "book.micro-edit-rules"];
6628
6886
  Object.entries(rawTags.by_category).forEach(([cat, items]) => {
@@ -6639,7 +6897,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6639
6897
  };
6640
6898
  const handleHfInitialSync = async (onProgress) => {
6641
6899
  if (!hfToken || !effectiveNamespace) return;
6642
- const existingIds = new Set((_optionalChain([hfState, 'optionalAccess', _204 => _204.metadata]) || []).map((m) => m.id));
6900
+ const existingIds = new Set((_optionalChain([hfState, 'optionalAccess', _227 => _227.metadata]) || []).map((m) => m.id));
6643
6901
  const gens = galleryItems.filter((g) => g.base64 && g.status === "done" && !existingIds.has(g.id));
6644
6902
  const total = gens.length;
6645
6903
  onProgress(0, total);
@@ -6665,7 +6923,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6665
6923
  }
6666
6924
  };
6667
6925
  const mergeWorkspaceTags = (local, remote) => {
6668
- if (!_optionalChain([remote, 'optionalAccess', _205 => _205.by_category])) return local;
6926
+ if (!_optionalChain([remote, 'optionalAccess', _228 => _228.by_category])) return local;
6669
6927
  const merged = {};
6670
6928
  const allCategories = /* @__PURE__ */ new Set([...Object.keys(local.by_category), ...Object.keys(remote.by_category)]);
6671
6929
  for (const cat of allCategories) {
@@ -6675,7 +6933,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6675
6933
  const localValues = new Set(localTags.map((t) => t.value));
6676
6934
  const mergedLocal = localTags.map((t) => {
6677
6935
  const remote2 = remoteMap.get(t.value);
6678
- return _optionalChain([remote2, 'optionalAccess', _206 => _206.is_deleted]) ? { ...t, is_deleted: true } : t;
6936
+ return _optionalChain([remote2, 'optionalAccess', _229 => _229.is_deleted]) ? { ...t, is_deleted: true } : t;
6679
6937
  });
6680
6938
  const onlyInRemote = remoteTags.filter((t) => !localValues.has(t.value));
6681
6939
  merged[cat] = [...mergedLocal, ...onlyInRemote];
@@ -6683,7 +6941,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6683
6941
  const all = Object.entries(merged).flatMap(([cat, tags]) => tags.map((t) => ({ ...t, category: cat })));
6684
6942
  return { by_category: merged, all };
6685
6943
  };
6686
- if (isFullscreen && _optionalChain([currentResult, 'optionalAccess', _207 => _207.base64])) {
6944
+ if (isFullscreen && _optionalChain([currentResult, 'optionalAccess', _230 => _230.base64])) {
6687
6945
  const fsRaw = currentResult.fullBase64 || currentResult.base64;
6688
6946
  const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
6689
6947
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
@@ -6734,7 +6992,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6734
6992
  }
6735
6993
  );
6736
6994
  }
6995
+ if (serverAppEnvironment) {
6996
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FlowFineArtApp, { environment: serverAppEnvironment, hfToken, appVersion: version, onClose: () => setServerAppEnvironment(null) });
6997
+ }
6737
6998
  if (showStart) {
6999
+ const serverAppTarget = flowAppEnvironment(bootstrapTarget, isDialogTarget, hfNamespaceLocal);
6738
7000
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
6739
7001
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-1", children: [
6740
7002
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
@@ -6797,7 +7059,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6797
7059
  setHfNamespaceLocal(ns);
6798
7060
  try {
6799
7061
  localStorage.setItem("aa-hf-namespace", ns);
6800
- } catch (e35) {
7062
+ } catch (e36) {
6801
7063
  }
6802
7064
  },
6803
7065
  className: "px-3 py-1 rounded-lg text-[11px] font-bold transition-colors",
@@ -6834,6 +7096,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6834
7096
  layoutChoice === "mobile-desktop" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
6835
7097
  layoutChoice === "tablet-landscape" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
6836
7098
  ] }),
7099
+ serverAppTarget && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
7100
+ "button",
7101
+ {
7102
+ type: "button",
7103
+ onClick: () => setServerAppEnvironment(serverAppTarget),
7104
+ className: "flex items-center justify-center gap-2 w-full max-w-[280px] py-3 rounded-2xl border text-[11px] font-bold",
7105
+ style: { borderColor: "rgba(255,255,255,0.08)", color: "rgba(255,255,255,0.6)" },
7106
+ children: [
7107
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[20px]", children: "web" }),
7108
+ `Fine-Art App (Server) \xB7 ${serverAppTarget.toUpperCase()}`
7109
+ ]
7110
+ }
7111
+ ),
6837
7112
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FlowBridgePanel, { appVersion: version, hfToken })
6838
7113
  ] });
6839
7114
  }
@@ -6898,7 +7173,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6898
7173
  }, children: [
6899
7174
  mobileTab === "labs" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LabsTab, { services: labServices, onResult: (item) => {
6900
7175
  const frame = item.frames[0];
6901
- if (_optionalChain([frame, 'optionalAccess', _208 => _208.base64])) {
7176
+ if (_optionalChain([frame, 'optionalAccess', _231 => _231.base64])) {
6902
7177
  setCurrentResult(frameToGeneration(frame, item));
6903
7178
  setMobileTab("stage");
6904
7179
  }
@@ -6922,7 +7197,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6922
7197
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 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" }] }),
6923
7198
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
6924
7199
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1" }),
6925
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _209 => _209.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7200
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _232 => _232.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
6926
7201
  runningBadge,
6927
7202
  activeReferenceThumbnail ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
6928
7203
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
@@ -6973,21 +7248,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6973
7248
  setTouchStartX(null);
6974
7249
  },
6975
7250
  children: [
6976
- _optionalChain([currentResult, 'optionalAccess', _210 => _210.status]) === "processing" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
7251
+ _optionalChain([currentResult, 'optionalAccess', _233 => _233.status]) === "processing" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
6977
7252
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
6978
7253
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[11px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
6979
7254
  ] }),
6980
- _optionalChain([currentResult, 'optionalAccess', _211 => _211.status]) === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
7255
+ _optionalChain([currentResult, 'optionalAccess', _234 => _234.status]) === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
6981
7256
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
6982
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-white/50 text-[13px]", children: _optionalChain([currentResult, 'access', _212 => _212.error, 'optionalAccess', _213 => _213.message]) }),
7257
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-white/50 text-[13px]", children: _optionalChain([currentResult, 'access', _235 => _235.error, 'optionalAccess', _236 => _236.message]) }),
6983
7258
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => handleGenerateImage(currentResult.prompt), className: "px-4 py-2 rounded-lg border border-white/20 text-[13px] text-white/70 active:bg-white/10", children: "Erneut versuchen" })
6984
7259
  ] }),
6985
- _optionalChain([currentResult, 'optionalAccess', _214 => _214.status]) === "done" && currentResult.base64 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
7260
+ _optionalChain([currentResult, 'optionalAccess', _237 => _237.status]) === "done" && currentResult.base64 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
6986
7261
  !currentResult && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
6987
7262
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
6988
7263
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
6989
7264
  ] }),
6990
- _optionalChain([currentResult, 'optionalAccess', _215 => _215.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: openFullscreen, className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center rounded-full bg-black/60 border border-white/10 z-10", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
7265
+ _optionalChain([currentResult, 'optionalAccess', _238 => _238.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: openFullscreen, className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center rounded-full bg-black/60 border border-white/10 z-10", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
6991
7266
  history.length > 1 && currentResult && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
6992
7267
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: goToPrev, disabled: currentIndex <= 0, className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
6993
7268
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, className: "absolute right-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
@@ -7000,7 +7275,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7000
7275
  ]
7001
7276
  }
7002
7277
  ),
7003
- _optionalChain([currentResult, 'optionalAccess', _216 => _216.status]) === "done" && currentGroup.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { position: "relative", flexShrink: 0 }, children: [
7278
+ _optionalChain([currentResult, 'optionalAccess', _239 => _239.status]) === "done" && currentGroup.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { position: "relative", flexShrink: 0 }, children: [
7004
7279
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7005
7280
  "div",
7006
7281
  {
@@ -7043,7 +7318,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7043
7318
  }
7044
7319
  )
7045
7320
  ] }, item.id)) }),
7046
- _optionalChain([currentResult, 'optionalAccess', _217 => _217.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2 mt-3", children: [
7321
+ _optionalChain([currentResult, 'optionalAccess', _240 => _240.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2 mt-3", children: [
7047
7322
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { onClick: () => setActivePrompt(currentResult.prompt || ""), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl border border-white/10 bg-white/5 active:bg-white/10 transition-colors", style: { height: 44 }, children: [
7048
7323
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
7049
7324
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[12px] text-white/60", children: "Prompt" })
@@ -7065,14 +7340,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7065
7340
  hfToken && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "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__ */ _jsxruntime.jsx.call(void 0, "span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
7066
7341
  ] }),
7067
7342
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 overflow-hidden relative", children: [
7068
- activeTab === "history" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _218 => _218.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
7343
+ activeTab === "history" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _241 => _241.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
7069
7344
  activeTab === "gallery" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7070
7345
  MediaLibrary,
7071
7346
  {
7072
7347
  items: galleryItems,
7073
7348
  onImport: async () => {
7074
7349
  const media = await onSelectMedia();
7075
- if (!_optionalChain([media, 'optionalAccess', _219 => _219.length])) return;
7350
+ if (!_optionalChain([media, 'optionalAccess', _242 => _242.length])) return;
7076
7351
  setGalleryItems((prev) => [...media.map((m) => ({ id: crypto.randomUUID(), nodeId: "1", base64: `data:${m.mimeType};base64,${m.base64}`, mediaId: m.mediaId, prompt: m.name || "Importiert", timestamp: Date.now(), status: "done", tags: [], type: "import" })), ...prev]);
7077
7352
  },
7078
7353
  onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
@@ -7220,7 +7495,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7220
7495
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, 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" }] }),
7221
7496
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
7222
7497
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { flex: 1 } }),
7223
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _220 => _220.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7498
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _243 => _243.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7224
7499
  runningBadge,
7225
7500
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
7226
7501
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
@@ -7249,7 +7524,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7249
7524
  ]
7250
7525
  }
7251
7526
  ) }),
7252
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _221 => _221.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }) })
7527
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _244 => _244.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }) })
7253
7528
  ] }),
7254
7529
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
7255
7530
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -7265,21 +7540,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7265
7540
  setTouchStartX(null);
7266
7541
  },
7267
7542
  children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "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: [
7268
- _optionalChain([currentResult, 'optionalAccess', _222 => _222.status]) === "processing" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
7543
+ _optionalChain([currentResult, 'optionalAccess', _245 => _245.status]) === "processing" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
7269
7544
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 36 }, children: "hourglass_top" }),
7270
7545
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 10, color: "rgba(255,255,255,0.6)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
7271
7546
  ] }),
7272
- _optionalChain([currentResult, 'optionalAccess', _223 => _223.status]) === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
7547
+ _optionalChain([currentResult, 'optionalAccess', _246 => _246.status]) === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
7273
7548
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
7274
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: _optionalChain([currentResult, 'access', _224 => _224.error, 'optionalAccess', _225 => _225.message]) }),
7549
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: _optionalChain([currentResult, 'access', _247 => _247.error, 'optionalAccess', _248 => _248.message]) }),
7275
7550
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => handleGenerateImage(currentResult.prompt), style: { padding: "8px 16px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.2)", fontSize: 11, color: "rgba(255,255,255,0.7)", background: "none", cursor: "pointer", fontFamily: "inherit" }, children: "Erneut versuchen" })
7276
7551
  ] }),
7277
- _optionalChain([currentResult, 'optionalAccess', _226 => _226.status]) === "done" && currentResult.base64 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
7552
+ _optionalChain([currentResult, 'optionalAccess', _249 => _249.status]) === "done" && currentResult.base64 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
7278
7553
  !currentResult && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
7279
7554
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
7280
7555
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
7281
7556
  ] }),
7282
- _optionalChain([currentResult, 'optionalAccess', _227 => _227.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: openFullscreen, style: { position: "absolute", top: 8, right: 8, width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
7557
+ _optionalChain([currentResult, 'optionalAccess', _250 => _250.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: openFullscreen, style: { position: "absolute", top: 8, right: 8, width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
7283
7558
  history.length > 1 && currentResult && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
7284
7559
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: goToPrev, disabled: currentIndex <= 0, style: { position: "absolute", left: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex <= 0 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
7285
7560
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, style: { position: "absolute", right: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex >= history.length - 1 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
@@ -7292,7 +7567,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7292
7567
  ] })
7293
7568
  }
7294
7569
  ),
7295
- _optionalChain([currentResult, 'optionalAccess', _228 => _228.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
7570
+ _optionalChain([currentResult, 'optionalAccess', _251 => _251.status]) === "done" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
7296
7571
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { onClick: () => setActivePrompt(currentResult.prompt || ""), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "1px solid rgba(255,255,255,0.1)", background: "rgba(255,255,255,0.05)", color: "rgba(255,255,255,0.6)", fontSize: 11, cursor: "pointer", fontFamily: "inherit" }, children: [
7297
7572
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
7298
7573
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Prompt" })
@@ -7414,7 +7689,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7414
7689
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Ref" })
7415
7690
  ] }),
7416
7691
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
7417
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _229 => _229.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7692
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TaskExecutor, { openTasks: _optionalChain([hfState, 'optionalAccess', _252 => _252.openTasks]) || {}, onExecute: handleExecuteTask, onTaskCompleted: handleTaskCompleted }),
7418
7693
  runningBadge,
7419
7694
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PillButton, { variant: "solid", icon: "bolt", disabled: !activePrompt.trim(), onClick: () => handleGenerateBatch(), children: "Generieren" })
7420
7695
  ] })
@@ -7426,7 +7701,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7426
7701
  ] }) }),
7427
7702
  middlePanel === "szenen" ? szenenPane : middlePanel === "labs" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LabsTab, { services: labServices, onResult: (item) => {
7428
7703
  const frame = item.frames[0];
7429
- if (_optionalChain([frame, 'optionalAccess', _230 => _230.base64])) setCurrentResult(frameToGeneration(frame, item));
7704
+ if (_optionalChain([frame, 'optionalAccess', _253 => _253.base64])) setCurrentResult(frameToGeneration(frame, item));
7430
7705
  } }) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1 overflow-hidden flex flex-col", children: [
7431
7706
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "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__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center gap-4 opacity-40", children: [
7432
7707
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
@@ -7435,7 +7710,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7435
7710
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
7436
7711
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
7437
7712
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
7438
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-white/60 text-[12px] leading-relaxed", children: _optionalChain([currentResult, 'access', _231 => _231.error, 'optionalAccess', _232 => _232.message]) })
7713
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-white/60 text-[12px] leading-relaxed", children: _optionalChain([currentResult, 'access', _254 => _254.error, 'optionalAccess', _255 => _255.message]) })
7439
7714
  ] }),
7440
7715
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
7441
7716
  ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "h-full w-full relative flex items-center justify-center", children: [
@@ -7449,7 +7724,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7449
7724
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
7450
7725
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
7451
7726
  ] }) }) }),
7452
- _optionalChain([currentResult, 'optionalAccess', _233 => _233.status]) === "done" && currentGroup.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { position: "relative", flexShrink: 0 }, children: [
7727
+ _optionalChain([currentResult, 'optionalAccess', _256 => _256.status]) === "done" && currentGroup.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { position: "relative", flexShrink: 0 }, children: [
7453
7728
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7454
7729
  "div",
7455
7730
  {
@@ -7530,14 +7805,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
7530
7805
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
7531
7806
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
7532
7807
  ] }) }),
7533
- activeTab === "history" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _234 => _234.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
7808
+ activeTab === "history" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HistoryPanel, { history, currentResultId: _optionalChain([currentResult, 'optionalAccess', _257 => _257.id]) || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
7534
7809
  activeTab === "gallery" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7535
7810
  MediaLibrary,
7536
7811
  {
7537
7812
  items: galleryItems,
7538
7813
  onImport: async () => {
7539
7814
  const media = await onSelectMedia();
7540
- if (!_optionalChain([media, 'optionalAccess', _235 => _235.length])) return;
7815
+ if (!_optionalChain([media, 'optionalAccess', _258 => _258.length])) return;
7541
7816
  setGalleryItems((prev) => [...media.map((m) => ({ id: crypto.randomUUID(), nodeId: "1", base64: `data:${m.mimeType};base64,${m.base64}`, mediaId: m.mediaId, prompt: m.name || "Importiert", timestamp: Date.now(), status: "done", tags: [], type: "import" })), ...prev]);
7542
7817
  },
7543
7818
  onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
@@ -7693,7 +7968,7 @@ function createFaStore({ contracts, descriptors, persistence, workspaceId }) {
7693
7968
  };
7694
7969
  };
7695
7970
  const applyWriteResult = (sliceId, result, savedData, signal) => {
7696
- if (_optionalChain([signal, 'optionalAccess', _236 => _236.aborted])) {
7971
+ if (_optionalChain([signal, 'optionalAccess', _259 => _259.aborted])) {
7697
7972
  patchMeta(sliceId, { saveState: "idle" });
7698
7973
  return result;
7699
7974
  }
@@ -7721,8 +7996,8 @@ function createFaStore({ contracts, descriptors, persistence, workspaceId }) {
7721
7996
  const requestId = _nullishCoalesce(externalRequestId, () => ( nextRequestId()));
7722
7997
  patchMeta(sliceId, { loadRequestId: requestId, saveState: "restoring" });
7723
7998
  const result = await persistence.load(workspaceId, descriptor, _nullishCoalesce(signal, () => ( new AbortController().signal)));
7724
- if (_optionalChain([signal, 'optionalAccess', _237 => _237.aborted]) || _optionalChain([get, 'call', _238 => _238(), 'access', _239 => _239.meta, 'access', _240 => _240[sliceId], 'optionalAccess', _241 => _241.loadRequestId]) !== requestId) {
7725
- if (_optionalChain([signal, 'optionalAccess', _242 => _242.aborted]) && _optionalChain([get, 'call', _243 => _243(), 'access', _244 => _244.meta, 'access', _245 => _245[sliceId], 'optionalAccess', _246 => _246.loadRequestId]) === requestId) {
7999
+ if (_optionalChain([signal, 'optionalAccess', _260 => _260.aborted]) || _optionalChain([get, 'call', _261 => _261(), 'access', _262 => _262.meta, 'access', _263 => _263[sliceId], 'optionalAccess', _264 => _264.loadRequestId]) !== requestId) {
8000
+ if (_optionalChain([signal, 'optionalAccess', _265 => _265.aborted]) && _optionalChain([get, 'call', _266 => _266(), 'access', _267 => _267.meta, 'access', _268 => _268[sliceId], 'optionalAccess', _269 => _269.loadRequestId]) === requestId) {
7726
8001
  patchMeta(sliceId, { saveState: "idle", loadRequestId: null });
7727
8002
  }
7728
8003
  return result;
@@ -7757,7 +8032,7 @@ function createFaStore({ contracts, descriptors, persistence, workspaceId }) {
7757
8032
  },
7758
8033
  async resetSlice(sliceId, signal, options) {
7759
8034
  const contract = requireContract(sliceId);
7760
- if (get().meta[sliceId].dirty && !_optionalChain([options, 'optionalAccess', _247 => _247.confirmed])) {
8035
+ if (get().meta[sliceId].dirty && !_optionalChain([options, 'optionalAccess', _270 => _270.confirmed])) {
7761
8036
  throw new Error(`Reset for slice ${sliceId} requires confirmation while unsaved changes exist`);
7762
8037
  }
7763
8038
  const defaultData = contract.createDefault();
@@ -7810,7 +8085,7 @@ function createInMemoryWorkspacePersistence(now = () => Date.now()) {
7810
8085
  }
7811
8086
  const saved = {
7812
8087
  ...clone(slice),
7813
- revision: (_nullishCoalesce(_optionalChain([current, 'optionalAccess', _248 => _248.revision]), () => ( 0))) + 1,
8088
+ revision: (_nullishCoalesce(_optionalChain([current, 'optionalAccess', _271 => _271.revision]), () => ( 0))) + 1,
7814
8089
  updatedAt: now(),
7815
8090
  ...resetAt !== void 0 ? { resetAt } : {}
7816
8091
  };
@@ -7891,7 +8166,7 @@ function createPersistenceCoordinator({
7891
8166
  if (disposed) return;
7892
8167
  const runtime = runtimeOf(sliceId);
7893
8168
  const meta = store.getState().meta[sliceId];
7894
- if (!_optionalChain([meta, 'optionalAccess', _249 => _249.dirty])) return;
8169
+ if (!_optionalChain([meta, 'optionalAccess', _272 => _272.dirty])) return;
7895
8170
  if (meta.saveState === "restoring" || meta.saveState === "saving") {
7896
8171
  runtime.pendingSave = true;
7897
8172
  return;
@@ -7919,7 +8194,7 @@ function createPersistenceCoordinator({
7919
8194
  return {
7920
8195
  async load(sliceId) {
7921
8196
  const runtime = runtimeOf(sliceId);
7922
- _optionalChain([runtime, 'access', _250 => _250.loadController, 'optionalAccess', _251 => _251.abort, 'call', _252 => _252()]);
8197
+ _optionalChain([runtime, 'access', _273 => _273.loadController, 'optionalAccess', _274 => _274.abort, 'call', _275 => _275()]);
7923
8198
  runtime.loadController = new AbortController();
7924
8199
  const controller = runtime.loadController;
7925
8200
  try {
@@ -7947,8 +8222,8 @@ function createPersistenceCoordinator({
7947
8222
  disposed = true;
7948
8223
  for (const runtime of runtimes.values()) {
7949
8224
  clearTimer(runtime);
7950
- _optionalChain([runtime, 'access', _253 => _253.loadController, 'optionalAccess', _254 => _254.abort, 'call', _255 => _255()]);
7951
- _optionalChain([runtime, 'access', _256 => _256.saveController, 'optionalAccess', _257 => _257.abort, 'call', _258 => _258()]);
8225
+ _optionalChain([runtime, 'access', _276 => _276.loadController, 'optionalAccess', _277 => _277.abort, 'call', _278 => _278()]);
8226
+ _optionalChain([runtime, 'access', _279 => _279.saveController, 'optionalAccess', _280 => _280.abort, 'call', _281 => _281()]);
7952
8227
  runtime.pendingSave = false;
7953
8228
  }
7954
8229
  runtimes.clear();
@@ -8052,7 +8327,7 @@ function parseLegacyLibraryFilters(source, knownTagIds) {
8052
8327
  return null;
8053
8328
  }).filter((id) => id !== null && knownTagIds.has(id));
8054
8329
  }
8055
- } catch (e36) {
8330
+ } catch (e37) {
8056
8331
  tagIds = [];
8057
8332
  }
8058
8333
  }
@@ -8063,7 +8338,7 @@ function parseLegacyLibraryFilters(source, knownTagIds) {
8063
8338
  if (Array.isArray(parsed)) {
8064
8339
  recentFilterTagIds = parsed.filter((entry) => typeof entry === "string" || typeof entry === "number").map((entry) => String(entry)).filter((id) => knownTagIds.has(id)).slice(0, 5);
8065
8340
  }
8066
- } catch (e37) {
8341
+ } catch (e38) {
8067
8342
  recentFilterTagIds = [];
8068
8343
  }
8069
8344
  }
@@ -8102,9 +8377,9 @@ function hatNavigationsziele(zugehoerigkeit) {
8102
8377
  var kennung = (wert) => typeof wert === "string" && wert.trim().length > 0;
8103
8378
  var kurz = (id) => id.slice(0, 8);
8104
8379
  function zugehoerigkeitOf(item) {
8105
- const runId = _optionalChain([item, 'optionalAccess', _259 => _259.szenen, 'optionalAccess', _260 => _260.prompt_run_id]);
8380
+ const runId = _optionalChain([item, 'optionalAccess', _282 => _282.szenen, 'optionalAccess', _283 => _283.prompt_run_id]);
8106
8381
  if (!kennung(runId)) return null;
8107
- const links = _nullishCoalesce(_optionalChain([item, 'optionalAccess', _261 => _261.szenen_links]), () => ( null));
8382
+ const links = _nullishCoalesce(_optionalChain([item, 'optionalAccess', _284 => _284.szenen_links]), () => ( null));
8108
8383
  if (!links || links.prompt_run_id !== runId) {
8109
8384
  return {
8110
8385
  run: null,
@@ -8135,15 +8410,15 @@ function zugehoerigkeitOf(item) {
8135
8410
  return { run, scene, hinweis: null };
8136
8411
  }
8137
8412
  function zugehoerigkeitenOf(item) {
8138
- const szenen = _optionalChain([item, 'optionalAccess', _262 => _262.szenen]);
8413
+ const szenen = _optionalChain([item, 'optionalAccess', _285 => _285.szenen]);
8139
8414
  if (!szenen) return [];
8140
8415
  const laeufe = [];
8141
8416
  const merken = (id) => {
8142
8417
  if (kennung(id) && !laeufe.includes(id)) laeufe.push(id);
8143
8418
  };
8144
8419
  merken(szenen.prompt_run_id);
8145
- for (const run of _nullishCoalesce(szenen.runs, () => ( []))) merken(_optionalChain([run, 'optionalAccess', _263 => _263.prompt_run_id]));
8146
- const linkFuer = (runId) => _nullishCoalesce((_nullishCoalesce(_optionalChain([item, 'optionalAccess', _264 => _264.szenen_run_links]), () => ( []))).find((l) => l.prompt_run_id === runId), () => ( (_optionalChain([item, 'optionalAccess', _265 => _265.szenen_links]) && item.szenen_links.prompt_run_id === runId ? item.szenen_links : null)));
8420
+ for (const run of _nullishCoalesce(szenen.runs, () => ( []))) merken(_optionalChain([run, 'optionalAccess', _286 => _286.prompt_run_id]));
8421
+ const linkFuer = (runId) => _nullishCoalesce((_nullishCoalesce(_optionalChain([item, 'optionalAccess', _287 => _287.szenen_run_links]), () => ( []))).find((l) => l.prompt_run_id === runId), () => ( (_optionalChain([item, 'optionalAccess', _288 => _288.szenen_links]) && item.szenen_links.prompt_run_id === runId ? item.szenen_links : null)));
8147
8422
  const ergebnis = [];
8148
8423
  for (const runId of laeufe) {
8149
8424
  const z = zugehoerigkeitOf({ szenen: { prompt_run_id: runId }, szenen_links: linkFuer(runId) });
@@ -8289,7 +8564,7 @@ function parseLegacyRecentTags(raw) {
8289
8564
  }
8290
8565
  return null;
8291
8566
  }).filter((entry) => entry !== null).slice(0, 10);
8292
- } catch (e38) {
8567
+ } catch (e39) {
8293
8568
  return [];
8294
8569
  }
8295
8570
  }