@rslsp1/fa-app-tools 2.0.12 → 2.0.14

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
@@ -461,24 +461,14 @@ async function hfBootstrapFromLegacy(namespace, token, onProgress) {
461
461
  const ts = snapshot.meta.consolidatedAt;
462
462
  const stateFilename = `state-${new Date(ts).toISOString().replace(/:/g, "-").replace(".", "-")}.zip`;
463
463
  const repoPath = `${namespace}${stateFilename}`;
464
- let binary = "";
465
- zipBytes.forEach((b) => {
466
- binary += String.fromCharCode(b);
467
- });
468
- const b64 = btoa(binary);
469
464
  log("Lade state.zip hoch \u2026");
470
- const commitRes = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
471
- method: "POST",
472
- headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" },
473
- body: [
474
- JSON.stringify({ key: "header", value: { summary: `Bootstrap: initialer State aus Legacy-Daten`, description: "" } }),
475
- JSON.stringify({ key: "file", value: { path: repoPath, encoding: "base64", content: b64 } })
476
- ].join("\n")
465
+ await (0, import_hub.uploadFile)({
466
+ repo: { type: "dataset", name: HF_REPO },
467
+ credentials: { accessToken: token },
468
+ file: { path: repoPath, content: new Blob([zipBytes.buffer], { type: "application/zip" }) },
469
+ branch: "main",
470
+ commitTitle: `Bootstrap: initialer State aus Legacy-Daten`
477
471
  });
478
- if (!commitRes.ok) {
479
- const err = await commitRes.text().catch(() => "");
480
- throw new Error(`HF commit failed: ${commitRes.status} \u2014 ${err.slice(0, 300)}`);
481
- }
482
472
  log(`Fertig \u2014 ${stateFilename}`);
483
473
  }
484
474
  async function hfListProjects(token) {
@@ -509,65 +499,14 @@ async function hfUploadProject(zipBase64, name, token) {
509
499
  const binary = atob(zipBase64);
510
500
  const bytes = new Uint8Array(binary.length);
511
501
  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
512
- const hashBuffer = await crypto.subtle.digest("SHA-256", bytes);
513
- const oid = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
514
- const size = bytes.length;
515
- const sampleBytes = bytes.slice(0, 512);
516
- let sampleBinary = "";
517
- for (let i = 0; i < sampleBytes.length; i++) sampleBinary += String.fromCharCode(sampleBytes[i]);
518
- const sample = btoa(sampleBinary);
519
- const preRes = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/preupload/main`, {
520
- method: "POST",
521
- headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
522
- body: JSON.stringify({ files: [{ path: filename, size, sample }] })
502
+ await (0, import_hub.uploadFile)({
503
+ repo: { type: "dataset", name: HF_REPO },
504
+ credentials: { accessToken: token },
505
+ file: { path: filename, content: new Blob([bytes], { type: "application/zip" }) },
506
+ branch: "main",
507
+ commitTitle: `Upload ${filename}`
523
508
  });
524
- if (!preRes.ok) throw new Error(`HF preupload failed: ${preRes.status} ${preRes.statusText}`);
525
- const preData = await preRes.json();
526
- const fileInfo = preData.files?.[0];
527
- if (!fileInfo?.uploadMode) throw new Error(`HF preupload kein fileInfo: ${JSON.stringify(preData)}`);
528
- if (fileInfo.uploadMode === "lfs" && fileInfo.uploadUrl) {
529
- let uploadStatus = 0;
530
- try {
531
- const uploadRes = await fetch(fileInfo.uploadUrl, {
532
- method: "PUT",
533
- redirect: "follow",
534
- headers: { "Content-Type": "application/octet-stream", ...fileInfo.header || {} },
535
- body: bytes
536
- });
537
- uploadStatus = uploadRes.status;
538
- if (!uploadRes.ok) {
539
- const uploadErr = await uploadRes.text().catch(() => "");
540
- throw new Error(`HF LFS upload failed: ${uploadRes.status} \u2014 ${uploadErr.slice(0, 300)}`);
541
- }
542
- } catch (e) {
543
- if (uploadStatus === 0) throw new Error(`HF LFS upload network error (CORS/redirect?): ${e.message}`);
544
- throw e;
545
- }
546
- if (fileInfo.verifyUrl) {
547
- const verifyRes = await fetch(fileInfo.verifyUrl, {
548
- method: "POST",
549
- headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", ...fileInfo.verifyHeader || {} },
550
- body: JSON.stringify({ oid, size })
551
- });
552
- if (!verifyRes.ok) {
553
- const verifyErr = await verifyRes.text().catch(() => "");
554
- throw new Error(`HF LFS verify failed: ${verifyRes.status} \u2014 ${verifyErr.slice(0, 200)}`);
555
- }
556
- }
557
- }
558
- const commitRes = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
559
- method: "POST",
560
- headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" },
561
- body: [
562
- JSON.stringify({ key: "header", value: { summary: `Upload ${filename}`, description: "" } }),
563
- JSON.stringify({ key: "lfsFile", value: { path: filename, algo: "sha256", oid, size } })
564
- ].join("\n")
565
- });
566
- if (!commitRes.ok) {
567
- const err = await commitRes.text();
568
- throw new Error(`HF commit failed: ${commitRes.status} \u2014 ${err}`);
569
- }
570
- return { id: filename.replace(/\.zip$/, ""), name: filename.replace(/\.zip$/, ""), path: filename, size, isLfs: true };
509
+ return { id: filename.replace(/\.zip$/, ""), name: filename.replace(/\.zip$/, ""), path: filename, size: bytes.length, isLfs: true };
571
510
  }
572
511
  async function hfUploadProjectForm(_zipBase64, _name, _token) {
573
512
  throw new Error("hfUploadProjectForm is deprecated. Use hfUploadProject instead.");
@@ -618,32 +557,12 @@ async function hfUploadImage(base64, id, token, mimeType = "image/jpeg") {
618
557
  const binary = atob(base64);
619
558
  const bytes = new Uint8Array(binary.length);
620
559
  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
621
- const hashBuffer = await crypto.subtle.digest("SHA-256", bytes);
622
- const oid = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
623
- const size = bytes.length;
624
- const filename = `images/${id}.${ext}`;
625
- const preRes = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/preupload/main`, {
626
- method: "POST",
627
- headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
628
- body: JSON.stringify({ files: [{ path: filename, size }] })
629
- });
630
- if (!preRes.ok) throw new Error(`HF preupload failed: ${preRes.status}`);
631
- const preData = await preRes.json();
632
- const fileInfo = preData.files?.[0];
633
- if (fileInfo?.uploadUrl) {
634
- await fetch(fileInfo.uploadUrl, {
635
- method: "PUT",
636
- headers: { "Content-Type": mimeType, ...fileInfo.header || {} },
637
- body: bytes
638
- });
639
- }
640
- await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
641
- method: "POST",
642
- headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" },
643
- body: [
644
- JSON.stringify({ key: "header", value: { summary: `Add image ${id}`, description: "" } }),
645
- JSON.stringify({ key: "lfsFile", value: { path: filename, algo: "sha256", oid, size } })
646
- ].join("\n")
560
+ await (0, import_hub.uploadFile)({
561
+ repo: { type: "dataset", name: HF_REPO },
562
+ credentials: { accessToken: token },
563
+ file: { path: `images/${id}.${ext}`, content: new Blob([bytes], { type: mimeType }) },
564
+ branch: "main",
565
+ commitTitle: `Add image ${id}`
647
566
  });
648
567
  }
649
568
  async function hfLoadImageAsBase64(id, token) {
@@ -667,11 +586,12 @@ async function hfLoadImageAsBase64(id, token) {
667
586
  }
668
587
  return null;
669
588
  }
670
- var import_jszip2, HF_BASE, HF_REPO, HF_TOKEN_KEY, SESSION_CLIENT_ID;
589
+ var import_jszip2, import_hub, HF_BASE, HF_REPO, HF_TOKEN_KEY, SESSION_CLIENT_ID;
671
590
  var init_hfStateService = __esm({
672
591
  "src/lib/hfStateService.ts"() {
673
592
  "use strict";
674
593
  import_jszip2 = __toESM(require("jszip"));
594
+ import_hub = require("@huggingface/hub");
675
595
  init_hfEventTypes();
676
596
  HF_BASE = "https://huggingface.co";
677
597
  HF_REPO = "RolandSch/fa-app-state";
@@ -1537,7 +1457,7 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
1537
1457
  }
1538
1458
 
1539
1459
  // src/components/AvatarArchitectApp.tsx
1540
- var import_react22 = require("react");
1460
+ var import_react23 = require("react");
1541
1461
 
1542
1462
  // src/components/PromptTab.tsx
1543
1463
  var import_react12 = require("react");
@@ -2764,7 +2684,7 @@ function useHFState(token, namespace) {
2764
2684
  const id = setInterval(pollNew, POLL_INTERVAL_MS);
2765
2685
  return () => clearInterval(id);
2766
2686
  }, [token, namespace, pollNew]);
2767
- const writeEvent = (0, import_react14.useCallback)(async (type, payload) => {
2687
+ const writeEvent2 = (0, import_react14.useCallback)(async (type, payload) => {
2768
2688
  const prevTs = lastEventTs ? [lastEventTs] : [state?.meta.consolidatedAt ?? 0];
2769
2689
  console.log("[HF] writeEvent called:", { type, namespace, tokenOk: !!token, prevTs });
2770
2690
  await pollNew();
@@ -2799,7 +2719,7 @@ function useHFState(token, namespace) {
2799
2719
  pendingBufferCount,
2800
2720
  eventCount,
2801
2721
  forks,
2802
- writeEvent,
2722
+ writeEvent: writeEvent2,
2803
2723
  refresh: loadFull,
2804
2724
  lastEventTs,
2805
2725
  allEvents: allEventsRef.current,
@@ -3886,10 +3806,449 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
3886
3806
  ] });
3887
3807
  }
3888
3808
 
3889
- // src/components/AvatarArchitectApp.tsx
3809
+ // src/components/HFTestTab.tsx
3810
+ var import_react22 = require("react");
3890
3811
  var import_jsx_runtime20 = require("react/jsx-runtime");
3812
+ var HF_BASE2 = "https://huggingface.co";
3813
+ var HF_REPO2 = "RolandSch/fa-app-state";
3814
+ var TEST_DIR = "test";
3815
+ async function doFetch(label, url, init = {}) {
3816
+ const rawHeaders = init.headers || {};
3817
+ const sanitized = Object.fromEntries(
3818
+ Object.entries(rawHeaders).map(
3819
+ ([k, v]) => k.toLowerCase() === "authorization" ? [k, v.replace(/Bearer\s+\S+/, (m) => "Bearer " + m.slice(7, 14) + "***")] : [k, v]
3820
+ )
3821
+ );
3822
+ const s = {
3823
+ label,
3824
+ method: init.method || "GET",
3825
+ url,
3826
+ reqHeaders: sanitized,
3827
+ reqBody: init.body ? typeof init.body === "string" ? init.body.length > 800 ? init.body.slice(0, 800) + "\n\u2026[truncated]" : init.body : "[binary data]" : void 0
3828
+ };
3829
+ const t0 = Date.now();
3830
+ try {
3831
+ const r = await fetch(url, init);
3832
+ s.durationMs = Date.now() - t0;
3833
+ s.resStatus = r.status;
3834
+ s.resStatusText = r.statusText;
3835
+ const body = await r.text().catch(() => "");
3836
+ s.resBody = body.length > 3e3 ? body.slice(0, 3e3) + "\n\u2026[truncated]" : body;
3837
+ s.ok = r.ok;
3838
+ } catch (e) {
3839
+ s.durationMs = Date.now() - t0;
3840
+ s.error = String(e?.message ?? e);
3841
+ s.ok = false;
3842
+ }
3843
+ return s;
3844
+ }
3845
+ function toBase64(bytes) {
3846
+ let bin = "";
3847
+ bytes.forEach((b) => bin += String.fromCharCode(b));
3848
+ return btoa(bin);
3849
+ }
3850
+ async function sha256hex(bytes) {
3851
+ const buf = await crypto.subtle.digest("SHA-256", bytes);
3852
+ return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
3853
+ }
3854
+ function b64ToBytes(b64) {
3855
+ const raw = b64.includes(",") ? b64.split(",")[1] : b64;
3856
+ const bin = atob(raw);
3857
+ const bytes = new Uint8Array(bin.length);
3858
+ for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
3859
+ return bytes;
3860
+ }
3861
+ function rawB64(dataUrl) {
3862
+ return dataUrl.includes(",") ? dataUrl.split(",")[1] : dataUrl;
3863
+ }
3864
+ async function uploadDirect(token, path, b64content) {
3865
+ const ndjson = [
3866
+ JSON.stringify({ key: "header", value: { summary: `HF Test: upload ${path}`, description: "" } }),
3867
+ JSON.stringify({ key: "file", value: { path, encoding: "base64", content: b64content } })
3868
+ ].join("\n");
3869
+ return [await doFetch(
3870
+ "POST commit (direct, kein LFS)",
3871
+ `${HF_BASE2}/api/datasets/${HF_REPO2}/commit/main`,
3872
+ { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" }, body: ndjson }
3873
+ )];
3874
+ }
3875
+ async function uploadLFS(token, path, bytes) {
3876
+ const oid = await sha256hex(bytes);
3877
+ const size = bytes.length;
3878
+ const sample = toBase64(bytes.slice(0, 512));
3879
+ const steps = [];
3880
+ const pre = await doFetch("Preupload (LFS-URL anfordern)", `${HF_BASE2}/api/datasets/${HF_REPO2}/preupload/main`, {
3881
+ method: "POST",
3882
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
3883
+ body: JSON.stringify({ files: [{ path, size, sample }] })
3884
+ });
3885
+ steps.push(pre);
3886
+ if (!pre.ok) return steps;
3887
+ let fi;
3888
+ try {
3889
+ fi = JSON.parse(pre.resBody || "{}").files?.[0];
3890
+ } catch {
3891
+ }
3892
+ if (!fi) {
3893
+ steps.push({ label: "Parse", method: "-", url: "-", reqHeaders: {}, resBody: "Kein files[0] in preupload response", ok: false });
3894
+ return steps;
3895
+ }
3896
+ if (fi.uploadMode === "lfs" && fi.uploadUrl) {
3897
+ const up = await doFetch("PUT to LFS upload URL", fi.uploadUrl, {
3898
+ method: "PUT",
3899
+ headers: { "Content-Type": "application/octet-stream", ...fi.header || {} },
3900
+ body: bytes
3901
+ });
3902
+ steps.push(up);
3903
+ if (!up.ok) return steps;
3904
+ if (fi.verifyUrl) {
3905
+ const ver = await doFetch("POST LFS verify", fi.verifyUrl, {
3906
+ method: "POST",
3907
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", ...fi.verifyHeader || {} },
3908
+ body: JSON.stringify({ oid, size })
3909
+ });
3910
+ steps.push(ver);
3911
+ if (!ver.ok) return steps;
3912
+ }
3913
+ } else {
3914
+ steps.push({ label: "Info", method: "-", url: "-", reqHeaders: {}, resBody: `uploadMode="${fi.uploadMode}" \xB7 uploadUrl: ${fi.uploadUrl ? "ja" : "nein"} \u2192 ${!fi.uploadUrl ? "bereits in LFS (Deduplizierung)" : "kein LFS n\xF6tig"}`, ok: true });
3915
+ }
3916
+ const ndjson = [
3917
+ JSON.stringify({ key: "header", value: { summary: `HF Test: LFS commit ${path}`, description: "" } }),
3918
+ JSON.stringify({ key: "lfsFile", value: { path, algo: "sha256", oid, size } })
3919
+ ].join("\n");
3920
+ steps.push(await doFetch("Commit (lfsFile reference)", `${HF_BASE2}/api/datasets/${HF_REPO2}/commit/main`, {
3921
+ method: "POST",
3922
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" },
3923
+ body: ndjson
3924
+ }));
3925
+ return steps;
3926
+ }
3927
+ async function uploadViaHubLib(token, path, bytes, mimeType) {
3928
+ const s = { label: "uploadFile() via @huggingface/hub", method: "import()+call", url: "@huggingface/hub", reqHeaders: {} };
3929
+ const t0 = Date.now();
3930
+ try {
3931
+ const { uploadFile: uploadFile2 } = await import(
3932
+ /* @vite-ignore */
3933
+ "@huggingface/hub"
3934
+ );
3935
+ await uploadFile2({
3936
+ repo: { type: "dataset", name: HF_REPO2 },
3937
+ credentials: { accessToken: token },
3938
+ file: { path, content: new Blob([bytes], { type: mimeType }) },
3939
+ branch: "main",
3940
+ commitTitle: `HF Test: hub lib upload ${path}`
3941
+ });
3942
+ s.durationMs = Date.now() - t0;
3943
+ s.resBody = "SUCCESS";
3944
+ s.ok = true;
3945
+ } catch (e) {
3946
+ s.durationMs = Date.now() - t0;
3947
+ s.error = String(e?.message ?? e);
3948
+ s.ok = false;
3949
+ }
3950
+ return [s];
3951
+ }
3952
+ async function uploadViaCdnLib(token, path, bytes, mimeType) {
3953
+ const s = { label: "uploadFile() via esm.sh/@huggingface/hub", method: "import()+call", url: "https://esm.sh/@huggingface/hub", reqHeaders: {} };
3954
+ const t0 = Date.now();
3955
+ try {
3956
+ const { uploadFile: uploadFile2 } = await import(
3957
+ /* @vite-ignore */
3958
+ "https://esm.sh/@huggingface/hub"
3959
+ );
3960
+ await uploadFile2({
3961
+ repo: { type: "dataset", name: HF_REPO2 },
3962
+ credentials: { accessToken: token },
3963
+ file: { path, content: new Blob([bytes], { type: mimeType }) },
3964
+ branch: "main",
3965
+ commitTitle: `HF Test: CDN hub lib upload ${path}`
3966
+ });
3967
+ s.durationMs = Date.now() - t0;
3968
+ s.resBody = "SUCCESS";
3969
+ s.ok = true;
3970
+ } catch (e) {
3971
+ s.durationMs = Date.now() - t0;
3972
+ s.error = String(e?.message ?? e);
3973
+ s.ok = false;
3974
+ }
3975
+ return [s];
3976
+ }
3977
+ async function writeEvent(token, namespace) {
3978
+ const ns = namespace.endsWith("/") ? namespace : namespace ? namespace + "/" : "";
3979
+ const ts = Date.now();
3980
+ const uuid = crypto.randomUUID().slice(0, 8);
3981
+ const isoTs = new Date(ts).toISOString().replace(/:/g, "-").replace(".", "-");
3982
+ const eventPath = `${ns}${TEST_DIR}/events/${isoTs}_${uuid}.json`;
3983
+ const event = JSON.stringify({ v: { major: 1, minor: 0 }, type: "probe", ts, prevTs: [], clientId: "hf-test-tab", payload: { test: true } }, null, 2);
3984
+ const b64 = toBase64(new TextEncoder().encode(event));
3985
+ const ndjson = [
3986
+ JSON.stringify({ key: "header", value: { summary: "HF Test: write event", description: "" } }),
3987
+ JSON.stringify({ key: "file", value: { path: eventPath, encoding: "base64", content: b64 } })
3988
+ ].join("\n");
3989
+ return [await doFetch(
3990
+ `Event \u2192 ${eventPath}`,
3991
+ `${HF_BASE2}/api/datasets/${HF_REPO2}/commit/main`,
3992
+ { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" }, body: ndjson }
3993
+ )];
3994
+ }
3995
+ function tryFmt(s) {
3996
+ try {
3997
+ return JSON.stringify(JSON.parse(s), null, 2);
3998
+ } catch {
3999
+ return s;
4000
+ }
4001
+ }
4002
+ function CopyBtn({ text }) {
4003
+ const [done, setDone] = (0, import_react22.useState)(false);
4004
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4005
+ "button",
4006
+ {
4007
+ onClick: () => {
4008
+ navigator.clipboard?.writeText(text).catch(() => {
4009
+ });
4010
+ setDone(true);
4011
+ setTimeout(() => setDone(false), 1500);
4012
+ },
4013
+ style: { background: "none", border: "1px solid rgba(255,255,255,0.15)", borderRadius: 5, color: done ? "#4ade80" : "rgba(255,255,255,0.45)", fontSize: 10, padding: "3px 8px", cursor: "pointer", fontFamily: "inherit", display: "flex", alignItems: "center", gap: 3 },
4014
+ children: [
4015
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: done ? "check" : "content_copy" }),
4016
+ done ? "Kopiert" : "Copy"
4017
+ ]
4018
+ }
4019
+ );
4020
+ }
4021
+ function StepView({ step }) {
4022
+ const isSpecial = step.method === "-" || step.method === "import()" || step.method === "import()+call";
4023
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 6, background: "rgba(0,0,0,0.3)", borderRadius: 7, padding: "7px 9px", border: `1px solid ${step.ok === false ? "rgba(248,113,113,0.2)" : "rgba(255,255,255,0.05)"}` }, children: [
4024
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }, children: [
4025
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: step.ok === false ? "#f87171" : "#4ade80" }, children: step.ok === false ? "\u2717" : "\u2713" }),
4026
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 11, fontWeight: 600, color: "rgba(255,255,255,0.7)", flex: 1 }, children: step.label }),
4027
+ step.durationMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4028
+ step.durationMs,
4029
+ "ms"
4030
+ ] }),
4031
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CopyBtn, { text: JSON.stringify(step, null, 2) })
4032
+ ] }),
4033
+ !isSpecial && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 5 }, children: [
4034
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginBottom: 2 }, children: [
4035
+ "\u2192 ",
4036
+ step.method,
4037
+ " ",
4038
+ step.url
4039
+ ] }),
4040
+ Object.keys(step.reqHeaders).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.35)", margin: "2px 0", padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 60, overflow: "auto" }, children: Object.entries(step.reqHeaders).map(([k, v]) => `${k}: ${v}`).join("\n") }),
4041
+ step.reqBody && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.35)", margin: "2px 0", padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 80, overflow: "auto" }, children: step.reqBody })
4042
+ ] }),
4043
+ step.error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { style: { fontSize: 11, color: "#f87171", margin: 0, padding: "3px 5px", background: "rgba(248,113,113,0.05)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all" }, children: step.error }),
4044
+ !step.error && (step.resStatus !== void 0 || step.resBody) && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
4045
+ step.resStatus !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 11, fontWeight: 700, color: (step.resStatus || 0) < 300 ? "#4ade80" : "#f87171", marginBottom: 3 }, children: [
4046
+ "\u2190 ",
4047
+ step.resStatus,
4048
+ " ",
4049
+ step.resStatusText
4050
+ ] }),
4051
+ step.resBody && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { style: { fontSize: 9, color: "rgba(255,255,255,0.55)", margin: 0, padding: "3px 5px", background: "rgba(255,255,255,0.03)", borderRadius: 3, whiteSpace: "pre-wrap", wordBreak: "break-all", maxHeight: 180, overflow: "auto" }, children: tryFmt(step.resBody) })
4052
+ ] })
4053
+ ] });
4054
+ }
4055
+ function TestCard({
4056
+ id,
4057
+ label,
4058
+ icon,
4059
+ desc,
4060
+ disabled,
4061
+ state,
4062
+ onRun,
4063
+ expanded,
4064
+ onToggle
4065
+ }) {
4066
+ const hasResult = state && state.status !== "idle";
4067
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 8, background: "rgba(255,255,255,0.03)", borderRadius: 10, border: `1px solid ${state?.status === "ok" ? "rgba(74,222,128,0.15)" : state?.status === "error" ? "rgba(248,113,113,0.15)" : "rgba(255,255,255,0.07)"}`, overflow: "hidden" }, children: [
4068
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "9px 10px" }, children: [
4069
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18, color: state?.status === "ok" ? "#4ade80" : state?.status === "error" ? "#f87171" : state?.status === "running" ? "#60a5fa" : "rgba(255,255,255,0.35)", flexShrink: 0 }, children: state?.status === "ok" ? "check_circle" : state?.status === "error" ? "error" : state?.status === "running" ? "hourglass_top" : icon }),
4070
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4071
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 13, fontWeight: 700, color: "#fff" }, children: label }),
4072
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: desc })
4073
+ ] }),
4074
+ hasResult && state?.status !== "running" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: onToggle, style: { background: "none", border: "none", color: "rgba(255,255,255,0.3)", cursor: "pointer", padding: 2, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: expanded ? "expand_less" : "expand_more" }) }),
4075
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4076
+ "button",
4077
+ {
4078
+ onClick: onRun,
4079
+ disabled,
4080
+ style: { background: disabled ? "transparent" : "#0284c7", border: "1px solid rgba(255,255,255,0.1)", borderRadius: 6, color: "#fff", fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.05em", padding: "5px 10px", cursor: disabled ? "default" : "pointer", opacity: disabled ? 0.35 : 1, fontFamily: "inherit", flexShrink: 0 },
4081
+ children: state?.status === "running" ? "\u2026" : "Run"
4082
+ }
4083
+ )
4084
+ ] }),
4085
+ hasResult && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { borderTop: "1px solid rgba(255,255,255,0.05)" }, children: [
4086
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { padding: "4px 10px 5px", display: "flex", alignItems: "center", gap: 8 }, children: [
4087
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 11, fontWeight: 700, color: state.status === "ok" ? "#4ade80" : "#f87171" }, children: state.status === "ok" ? "\u2713 OK" : state.status === "running" ? "\u2026" : "\u2717 Fehler" }),
4088
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
4089
+ state.totalMs,
4090
+ "ms \xB7 ",
4091
+ state.steps.length,
4092
+ " Step",
4093
+ state.steps.length !== 1 ? "s" : ""
4094
+ ] }),
4095
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1 } }),
4096
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CopyBtn, { text: JSON.stringify(state, null, 2) })
4097
+ ] }),
4098
+ expanded && state.steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { padding: "0 10px 4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StepView, { step }) }, i))
4099
+ ] })
4100
+ ] });
4101
+ }
4102
+ function HFTestTab({ token, namespace, galleryItems }) {
4103
+ const [selected, setSelected] = (0, import_react22.useState)(null);
4104
+ const [results, setResults] = (0, import_react22.useState)({});
4105
+ const [expanded, setExpanded] = (0, import_react22.useState)({});
4106
+ const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
4107
+ const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
4108
+ const setDone = (id, steps, t0) => {
4109
+ const ok = steps.length > 0 && steps.every((s) => s.ok !== false);
4110
+ setResults((r) => ({ ...r, [id]: { status: ok ? "ok" : "error", steps, totalMs: Date.now() - t0 } }));
4111
+ setExpanded((e) => ({ ...e, [id]: true }));
4112
+ };
4113
+ const run = async (id) => {
4114
+ const isImgTest = id !== "event";
4115
+ if (isImgTest && !selected?.base64) return;
4116
+ setRunning(id);
4117
+ const t0 = Date.now();
4118
+ let steps = [];
4119
+ try {
4120
+ if (isImgTest) {
4121
+ const bytes = b64ToBytes(selected.base64);
4122
+ const imgPath = `${TEST_DIR}/${selected.id}.jpg`;
4123
+ switch (id) {
4124
+ case "img-direct":
4125
+ steps = await uploadDirect(token, imgPath, rawB64(selected.base64));
4126
+ break;
4127
+ case "img-lfs":
4128
+ steps = await uploadLFS(token, imgPath, bytes);
4129
+ break;
4130
+ case "img-hub":
4131
+ steps = await uploadViaHubLib(token, imgPath, bytes, "image/jpeg");
4132
+ break;
4133
+ case "img-cdn":
4134
+ steps = await uploadViaCdnLib(token, imgPath, bytes, "image/jpeg");
4135
+ break;
4136
+ }
4137
+ } else {
4138
+ steps = await writeEvent(token, namespace);
4139
+ }
4140
+ } catch (e) {
4141
+ steps = [{ label: "Unexpected error", method: "-", url: "-", reqHeaders: {}, error: String(e?.message ?? e), ok: false }];
4142
+ }
4143
+ setDone(id, steps, t0);
4144
+ };
4145
+ const noToken = !token;
4146
+ const noImg = !selected;
4147
+ const imgTests = [
4148
+ { id: "img-direct", label: "Upload Direct", icon: "upload_file", desc: "POST commit + file+base64 (kein LFS)" },
4149
+ { id: "img-lfs", label: "Upload LFS", icon: "cloud_upload", desc: "preupload \u2192 PUT LFS \u2192 verify \u2192 commit" },
4150
+ { id: "img-hub", label: "Upload hub lib", icon: "package_2", desc: "uploadFile() via @huggingface/hub" },
4151
+ { id: "img-cdn", label: "Upload CDN lib", icon: "language", desc: "uploadFile() via esm.sh hub lib" }
4152
+ ];
4153
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflowY: "auto", padding: "12px 10px 80px", boxSizing: "border-box", fontFamily: "inherit" }, children: [
4154
+ noToken && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginBottom: 10, padding: "8px 12px", background: "rgba(248,113,113,0.08)", borderRadius: 8, border: "1px solid rgba(248,113,113,0.2)", fontSize: 12, color: "#f87171" }, children: "Kein HF-Token geladen \u2014 bitte zuerst Token im Sync-Tab eingeben." }),
4155
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 14 }, children: [
4156
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 8 }, children: [
4157
+ "Bild ausw\xE4hlen (",
4158
+ withResults.length,
4159
+ " verf\xFCgbar)"
4160
+ ] }),
4161
+ withResults.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 12, color: "rgba(255,255,255,0.3)", fontStyle: "italic" }, children: "Noch keine Bilder in der Galerie. Generiere zuerst ein Bild oder lade von HF." }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 6 }, children: withResults.slice(0, 12).map((g) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4162
+ "button",
4163
+ {
4164
+ onClick: () => setSelected(g),
4165
+ style: { padding: 0, border: `2px solid ${selected?.id === g.id ? "#0284c7" : "transparent"}`, borderRadius: 6, cursor: "pointer", overflow: "hidden", background: "none", lineHeight: 0 },
4166
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4167
+ "img",
4168
+ {
4169
+ src: g.base64,
4170
+ alt: g.prompt || g.id,
4171
+ style: { width: "100%", aspectRatio: "1", objectFit: "cover", display: "block", borderRadius: 4 }
4172
+ }
4173
+ )
4174
+ },
4175
+ g.id
4176
+ )) }),
4177
+ selected && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginTop: 10, display: "flex", gap: 10, alignItems: "flex-start" }, children: [
4178
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4179
+ "img",
4180
+ {
4181
+ src: selected.base64,
4182
+ style: { width: 80, height: 80, objectFit: "cover", borderRadius: 8, border: "1px solid rgba(255,255,255,0.1)", flexShrink: 0 }
4183
+ }
4184
+ ),
4185
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
4186
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 11, fontWeight: 700, color: "rgba(255,255,255,0.7)", marginBottom: 2 }, children: "Ausgew\xE4hlt" }),
4187
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", wordBreak: "break-all" }, children: [
4188
+ "ID: ",
4189
+ selected.id
4190
+ ] }),
4191
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginTop: 2 }, children: [
4192
+ "Ziel: test/",
4193
+ selected.id,
4194
+ ".jpg"
4195
+ ] }),
4196
+ selected.prompt && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginTop: 2, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selected.prompt })
4197
+ ] })
4198
+ ] })
4199
+ ] }),
4200
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { marginBottom: 18 }, children: [
4201
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.1em", marginBottom: 8, borderBottom: "1px solid rgba(255,255,255,0.06)", paddingBottom: 4 }, children: [
4202
+ "Bild hochladen \u2192 test/",
4203
+ "{",
4204
+ "id",
4205
+ "}",
4206
+ ".jpg"
4207
+ ] }),
4208
+ imgTests.map((t) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4209
+ TestCard,
4210
+ {
4211
+ id: t.id,
4212
+ label: t.label,
4213
+ icon: t.icon,
4214
+ desc: t.desc,
4215
+ disabled: noToken || noImg || results[t.id]?.status === "running",
4216
+ state: results[t.id],
4217
+ onRun: () => run(t.id),
4218
+ expanded: !!expanded[t.id],
4219
+ onToggle: () => setExpanded((e) => ({ ...e, [t.id]: !e[t.id] }))
4220
+ },
4221
+ t.id
4222
+ ))
4223
+ ] }),
4224
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
4225
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.1em", marginBottom: 8, borderBottom: "1px solid rgba(255,255,255,0.06)", paddingBottom: 4 }, children: [
4226
+ "Event schreiben \u2192 ",
4227
+ namespace || "(kein namespace)",
4228
+ "test/events/"
4229
+ ] }),
4230
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4231
+ TestCard,
4232
+ {
4233
+ id: "event",
4234
+ label: "Write Event",
4235
+ icon: "bolt",
4236
+ desc: "Kleines JSON-Event hochladen (direct commit)",
4237
+ disabled: noToken || results["event"]?.status === "running",
4238
+ state: results["event"],
4239
+ onRun: () => run("event"),
4240
+ expanded: !!expanded["event"],
4241
+ onToggle: () => setExpanded((e) => ({ ...e, event: !e.event }))
4242
+ }
4243
+ )
4244
+ ] })
4245
+ ] });
4246
+ }
4247
+
4248
+ // src/components/AvatarArchitectApp.tsx
4249
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3891
4250
  function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
3892
- (0, import_react22.useEffect)(() => {
4251
+ (0, import_react23.useEffect)(() => {
3893
4252
  const id = "flow-styles";
3894
4253
  if (!document.getElementById(id)) {
3895
4254
  const style = document.createElement("style");
@@ -3898,19 +4257,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3898
4257
  document.head.appendChild(style);
3899
4258
  }
3900
4259
  }, []);
3901
- const [showStart, setShowStart] = (0, import_react22.useState)(true);
3902
- const [layoutChoice, setLayoutChoice] = (0, import_react22.useState)(() => {
4260
+ const [showStart, setShowStart] = (0, import_react23.useState)(true);
4261
+ const [layoutChoice, setLayoutChoice] = (0, import_react23.useState)(() => {
3903
4262
  try {
3904
4263
  return localStorage.getItem("aa-layout") || null;
3905
4264
  } catch {
3906
4265
  return null;
3907
4266
  }
3908
4267
  });
3909
- const [projectLoaded, setProjectLoaded] = (0, import_react22.useState)(false);
3910
- const [hfToken, setHfToken] = (0, import_react22.useState)(initialHfToken || "");
3911
- const [hfTokenInput, setHfTokenInput] = (0, import_react22.useState)(initialHfToken || "");
3912
- const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react22.useState)(false);
3913
- const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react22.useState)(() => {
4268
+ const [projectLoaded, setProjectLoaded] = (0, import_react23.useState)(false);
4269
+ const [hfToken, setHfToken] = (0, import_react23.useState)(initialHfToken || "");
4270
+ const [hfTokenInput, setHfTokenInput] = (0, import_react23.useState)(initialHfToken || "");
4271
+ const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react23.useState)(false);
4272
+ const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react23.useState)(() => {
3914
4273
  try {
3915
4274
  const stored = localStorage.getItem("aa-hf-namespace");
3916
4275
  if (stored !== null) return stored;
@@ -3919,8 +4278,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3919
4278
  return "";
3920
4279
  }
3921
4280
  });
3922
- const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react22.useState)(null);
3923
- (0, import_react22.useEffect)(() => {
4281
+ const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react23.useState)(null);
4282
+ (0, import_react23.useEffect)(() => {
3924
4283
  if (hfNamespace !== void 0) return;
3925
4284
  const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
3926
4285
  if (!backendUrl) return;
@@ -3939,27 +4298,27 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3939
4298
  refresh: refreshHF,
3940
4299
  hasStateZip
3941
4300
  } = useHFState(hfToken, effectiveNamespace);
3942
- const [bootstrapLog, setBootstrapLog] = (0, import_react22.useState)([]);
3943
- const [isBootstrapping, setIsBootstrapping] = (0, import_react22.useState)(false);
3944
- const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3945
- pendingBufferCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
4301
+ const [bootstrapLog, setBootstrapLog] = (0, import_react23.useState)([]);
4302
+ const [isBootstrapping, setIsBootstrapping] = (0, import_react23.useState)(false);
4303
+ const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
4304
+ pendingBufferCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
3946
4305
  pendingBufferCount,
3947
4306
  " \xC4nderung",
3948
4307
  pendingBufferCount > 1 ? "en" : "",
3949
4308
  " lokal \u2014 bei Flow-Reload verloren wenn nicht synchronisiert"
3950
4309
  ] }),
3951
- eventCount > 100 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
4310
+ eventCount > 100 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
3952
4311
  "\u26A0 ",
3953
4312
  eventCount,
3954
4313
  " Events nicht konsolidiert \u2014 Konsolidierung dringend empfohlen"
3955
4314
  ] }),
3956
- eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
4315
+ eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
3957
4316
  eventCount,
3958
4317
  " Events seit letzter Konsolidierung \u2014 Konsolidierung empfohlen"
3959
4318
  ] }),
3960
- hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
3961
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { fontSize: 12, color: "#a8a29e", marginBottom: 6 }, children: effectiveNamespace ? `Kein State-Snapshot in HF (${effectiveNamespace}) \u2014 aus Legacy-Daten (tags.json + metadata.json) migrieren?` : "Namespace wird geladen\u2026" }),
3962
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4319
+ hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
4320
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 12, color: "#a8a29e", marginBottom: 6 }, children: effectiveNamespace ? `Kein State-Snapshot in HF (${effectiveNamespace}) \u2014 aus Legacy-Daten (tags.json + metadata.json) migrieren?` : "Namespace wird geladen\u2026" }),
4321
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3963
4322
  "button",
3964
4323
  {
3965
4324
  disabled: isBootstrapping || !effectiveNamespace,
@@ -3980,10 +4339,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3980
4339
  children: isBootstrapping ? "Migriere\u2026" : "Legacy-Migration starten"
3981
4340
  }
3982
4341
  ),
3983
- bootstrapLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { children: l }, i)) })
4342
+ bootstrapLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: l }, i)) })
3984
4343
  ] })
3985
4344
  ] });
3986
- const wsInputRef = (0, import_react22.useRef)(null);
4345
+ const wsInputRef = (0, import_react23.useRef)(null);
3987
4346
  const startApp = (choice) => {
3988
4347
  try {
3989
4348
  localStorage.setItem("aa-layout", choice);
@@ -3992,16 +4351,16 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3992
4351
  setLayoutChoice(choice);
3993
4352
  setShowStart(false);
3994
4353
  };
3995
- const [nodes, setNodes] = (0, import_react22.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
3996
- const [edges, setEdges] = (0, import_react22.useState)([]);
3997
- const [history, setHistory] = (0, import_react22.useState)([]);
3998
- const [galleryItems, setGalleryItems] = (0, import_react22.useState)([]);
3999
- const galleryItemsRef = (0, import_react22.useRef)([]);
4000
- (0, import_react22.useEffect)(() => {
4354
+ const [nodes, setNodes] = (0, import_react23.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
4355
+ const [edges, setEdges] = (0, import_react23.useState)([]);
4356
+ const [history, setHistory] = (0, import_react23.useState)([]);
4357
+ const [galleryItems, setGalleryItems] = (0, import_react23.useState)([]);
4358
+ const galleryItemsRef = (0, import_react23.useRef)([]);
4359
+ (0, import_react23.useEffect)(() => {
4001
4360
  galleryItemsRef.current = galleryItems;
4002
4361
  }, [galleryItems]);
4003
- const hfImageNotFoundRef = (0, import_react22.useRef)(/* @__PURE__ */ new Set());
4004
- (0, import_react22.useEffect)(() => {
4362
+ const hfImageNotFoundRef = (0, import_react23.useRef)(/* @__PURE__ */ new Set());
4363
+ (0, import_react23.useEffect)(() => {
4005
4364
  if (!hfState) return;
4006
4365
  if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
4007
4366
  const hfIds = new Set(hfState.metadata.map((m) => m.id));
@@ -4040,62 +4399,62 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4040
4399
  });
4041
4400
  }
4042
4401
  }, [hfState]);
4043
- const [activePrompt, setActivePrompt] = (0, import_react22.useState)("");
4044
- const [isSynthesizing, setIsSynthesizing] = (0, import_react22.useState)(false);
4045
- const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react22.useState)(0);
4046
- const [currentResult, setCurrentResult] = (0, import_react22.useState)(null);
4047
- const [focusedNodeId, setFocusedNodeId] = (0, import_react22.useState)(null);
4048
- const [leftTab, setLeftTab] = (0, import_react22.useState)("prompt");
4049
- const [promptFeedback, setPromptFeedback] = (0, import_react22.useState)(null);
4050
- const [lastPromptPayload, setLastPromptPayload] = (0, import_react22.useState)(null);
4051
- const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react22.useState)(false);
4052
- const [activeTab, setActiveTab] = (0, import_react22.useState)("history");
4053
- const [mobileTab, setMobileTab] = (0, import_react22.useState)("stage");
4054
- const [middlePanel, setMiddlePanel] = (0, import_react22.useState)("stage");
4055
- const [recentLabItems, setRecentLabItems] = (0, import_react22.useState)([]);
4056
- const [aspectRatio, setAspectRatio] = (0, import_react22.useState)("1:1");
4057
- const [selectedModel, setSelectedModel] = (0, import_react22.useState)("\u{1F34C} Nano Banana Pro");
4058
- const [seed, setSeed] = (0, import_react22.useState)(Math.floor(Math.random() * 1e6));
4059
- const [seedMode, setSeedMode] = (0, import_react22.useState)("random");
4060
- const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react22.useState)(false);
4061
- const [isRightCollapsed, setIsRightCollapsed] = (0, import_react22.useState)(false);
4062
- const [leftPanelWidth, setLeftPanelWidth] = (0, import_react22.useState)(() => {
4402
+ const [activePrompt, setActivePrompt] = (0, import_react23.useState)("");
4403
+ const [isSynthesizing, setIsSynthesizing] = (0, import_react23.useState)(false);
4404
+ const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react23.useState)(0);
4405
+ const [currentResult, setCurrentResult] = (0, import_react23.useState)(null);
4406
+ const [focusedNodeId, setFocusedNodeId] = (0, import_react23.useState)(null);
4407
+ const [leftTab, setLeftTab] = (0, import_react23.useState)("prompt");
4408
+ const [promptFeedback, setPromptFeedback] = (0, import_react23.useState)(null);
4409
+ const [lastPromptPayload, setLastPromptPayload] = (0, import_react23.useState)(null);
4410
+ const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react23.useState)(false);
4411
+ const [activeTab, setActiveTab] = (0, import_react23.useState)("history");
4412
+ const [mobileTab, setMobileTab] = (0, import_react23.useState)("stage");
4413
+ const [middlePanel, setMiddlePanel] = (0, import_react23.useState)("stage");
4414
+ const [recentLabItems, setRecentLabItems] = (0, import_react23.useState)([]);
4415
+ const [aspectRatio, setAspectRatio] = (0, import_react23.useState)("1:1");
4416
+ const [selectedModel, setSelectedModel] = (0, import_react23.useState)("\u{1F34C} Nano Banana Pro");
4417
+ const [seed, setSeed] = (0, import_react23.useState)(Math.floor(Math.random() * 1e6));
4418
+ const [seedMode, setSeedMode] = (0, import_react23.useState)("random");
4419
+ const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react23.useState)(false);
4420
+ const [isRightCollapsed, setIsRightCollapsed] = (0, import_react23.useState)(false);
4421
+ const [leftPanelWidth, setLeftPanelWidth] = (0, import_react23.useState)(() => {
4063
4422
  try {
4064
4423
  return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
4065
4424
  } catch {
4066
4425
  return 260;
4067
4426
  }
4068
4427
  });
4069
- const [rightPanelWidth, setRightPanelWidth] = (0, import_react22.useState)(() => {
4428
+ const [rightPanelWidth, setRightPanelWidth] = (0, import_react23.useState)(() => {
4070
4429
  try {
4071
4430
  return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
4072
4431
  } catch {
4073
4432
  return 320;
4074
4433
  }
4075
4434
  });
4076
- const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react22.useState)(false);
4077
- const [projectActionState, setProjectActionState] = (0, import_react22.useState)("idle");
4078
- const syncServerDataRef = (0, import_react22.useRef)(null);
4079
- const [workspaceTags, setWorkspaceTags] = (0, import_react22.useState)(null);
4080
- const [serverProjects, setServerProjects] = (0, import_react22.useState)([]);
4081
- const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react22.useState)(false);
4082
- const [highContrast, setHighContrast] = (0, import_react22.useState)(() => {
4435
+ const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react23.useState)(false);
4436
+ const [projectActionState, setProjectActionState] = (0, import_react23.useState)("idle");
4437
+ const syncServerDataRef = (0, import_react23.useRef)(null);
4438
+ const [workspaceTags, setWorkspaceTags] = (0, import_react23.useState)(null);
4439
+ const [serverProjects, setServerProjects] = (0, import_react23.useState)([]);
4440
+ const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react23.useState)(false);
4441
+ const [highContrast, setHighContrast] = (0, import_react23.useState)(() => {
4083
4442
  try {
4084
4443
  return localStorage.getItem("aa-contrast") === "high";
4085
4444
  } catch {
4086
4445
  return false;
4087
4446
  }
4088
4447
  });
4089
- const [activeReferenceId, setActiveReferenceId] = (0, import_react22.useState)(null);
4090
- const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react22.useState)(null);
4091
- const [isScanningImage, setIsScanningImage] = (0, import_react22.useState)(false);
4092
- const [touchStartX, setTouchStartX] = (0, import_react22.useState)(null);
4093
- const [isFullscreen, setIsFullscreen] = (0, import_react22.useState)(false);
4094
- const [zoomScale, setZoomScale] = (0, import_react22.useState)(1);
4095
- const [zoomOffset, setZoomOffset] = (0, import_react22.useState)({ x: 0, y: 0 });
4096
- const lastPinchDist = (0, import_react22.useRef)(null);
4097
- const lastTapTime = (0, import_react22.useRef)(0);
4098
- const dragStart = (0, import_react22.useRef)(null);
4448
+ const [activeReferenceId, setActiveReferenceId] = (0, import_react23.useState)(null);
4449
+ const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react23.useState)(null);
4450
+ const [isScanningImage, setIsScanningImage] = (0, import_react23.useState)(false);
4451
+ const [touchStartX, setTouchStartX] = (0, import_react23.useState)(null);
4452
+ const [isFullscreen, setIsFullscreen] = (0, import_react23.useState)(false);
4453
+ const [zoomScale, setZoomScale] = (0, import_react23.useState)(1);
4454
+ const [zoomOffset, setZoomOffset] = (0, import_react23.useState)({ x: 0, y: 0 });
4455
+ const lastPinchDist = (0, import_react23.useRef)(null);
4456
+ const lastTapTime = (0, import_react23.useRef)(0);
4457
+ const dragStart = (0, import_react23.useRef)(null);
4099
4458
  const openFullscreen = () => {
4100
4459
  setIsFullscreen(true);
4101
4460
  setZoomScale(1);
@@ -4158,7 +4517,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4158
4517
  setActiveReferenceId(null);
4159
4518
  setActiveReferenceThumbnail(null);
4160
4519
  };
4161
- const labServices = (0, import_react22.useMemo)(() => {
4520
+ const labServices = (0, import_react23.useMemo)(() => {
4162
4521
  const available = groupGenerationsToLabItems([...galleryItems, ...history]);
4163
4522
  return {
4164
4523
  availableItems: available,
@@ -4238,17 +4597,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4238
4597
  setIsScanningImage(false);
4239
4598
  }
4240
4599
  };
4241
- const currentIndex = (0, import_react22.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
4242
- const goToPrev = (0, import_react22.useCallback)(() => {
4600
+ const currentIndex = (0, import_react23.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
4601
+ const goToPrev = (0, import_react23.useCallback)(() => {
4243
4602
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
4244
4603
  }, [currentIndex, history]);
4245
- const goToNext = (0, import_react22.useCallback)(() => {
4604
+ const goToNext = (0, import_react23.useCallback)(() => {
4246
4605
  if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
4247
4606
  }, [currentIndex, history]);
4248
4607
  const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
4249
4608
  const isGenerating = activeGenerationsCount > 0;
4250
4609
  useKeyboardNavigation(history, currentResult, setCurrentResult);
4251
- const getSubtreeFormat = (0, import_react22.useCallback)((nodeId, depth = 0) => {
4610
+ const getSubtreeFormat = (0, import_react23.useCallback)((nodeId, depth = 0) => {
4252
4611
  const node = nodes.find((n) => n.id === nodeId);
4253
4612
  if (!node) return "";
4254
4613
  const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
@@ -4256,7 +4615,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4256
4615
  return `${indent}- ${node.data.label || "(unbenannt)"}
4257
4616
  ` + childrenIds.map((id) => getSubtreeFormat(id, depth + 1)).join("");
4258
4617
  }, [nodes, edges]);
4259
- const activePath = (0, import_react22.useMemo)(() => {
4618
+ const activePath = (0, import_react23.useMemo)(() => {
4260
4619
  if (!focusedNodeId) return /* @__PURE__ */ new Set();
4261
4620
  const path = /* @__PURE__ */ new Set([focusedNodeId]);
4262
4621
  let currId = focusedNodeId;
@@ -4600,7 +4959,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4600
4959
  setTimeout(() => setProjectActionState("idle"), 4e3);
4601
4960
  }
4602
4961
  };
4603
- (0, import_react22.useEffect)(() => {
4962
+ (0, import_react23.useEffect)(() => {
4604
4963
  if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
4605
4964
  }, [activeTab]);
4606
4965
  const mergeWorkspaceTags = (local, remote) => {
@@ -4624,7 +4983,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4624
4983
  };
4625
4984
  if (isFullscreen && currentResult?.base64) {
4626
4985
  const fsBase64 = currentResult.base64.startsWith("data:") ? currentResult.base64 : `data:image/png;base64,${currentResult.base64}`;
4627
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4986
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4628
4987
  "div",
4629
4988
  {
4630
4989
  className: "fixed inset-0 bg-black z-50 flex items-center justify-center overflow-hidden touch-none",
@@ -4632,7 +4991,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4632
4991
  onTouchMove: handleFsTouchMove,
4633
4992
  onTouchEnd: handleFsTouchEnd,
4634
4993
  children: [
4635
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4994
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4636
4995
  "img",
4637
4996
  {
4638
4997
  src: fsBase64,
@@ -4649,77 +5008,77 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4649
5008
  }
4650
5009
  }
4651
5010
  ),
4652
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: closeFullscreen, className: "absolute top-4 right-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "close" }) }),
4653
- zoomScale > 1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => {
5011
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: closeFullscreen, className: "absolute top-4 right-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "close" }) }),
5012
+ zoomScale > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => {
4654
5013
  setZoomScale(1);
4655
5014
  setZoomOffset({ x: 0, y: 0 });
4656
- }, className: "absolute top-4 left-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
4657
- history.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4658
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => {
5015
+ }, className: "absolute top-4 left-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
5016
+ history.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5017
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => {
4659
5018
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
4660
- }, 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", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
4661
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => {
5019
+ }, 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", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
5020
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => {
4662
5021
  if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
4663
- }, 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", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
4664
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "absolute bottom-6 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
5022
+ }, 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", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
5023
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "absolute bottom-6 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
4665
5024
  currentIndex + 1,
4666
5025
  " / ",
4667
5026
  history.length
4668
5027
  ] })
4669
5028
  ] }),
4670
- zoomScale === 1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "absolute bottom-6 right-4 text-[9px] text-white/20 font-mono", children: "Pinch zum Zoomen \xB7 Doppeltipp 2.5\xD7" })
5029
+ zoomScale === 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute bottom-6 right-4 text-[9px] text-white/20 font-mono", children: "Pinch zum Zoomen \xB7 Doppeltipp 2.5\xD7" })
4671
5030
  ]
4672
5031
  }
4673
5032
  );
4674
5033
  }
4675
5034
  if (showStart) {
4676
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
4677
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { ref: wsInputRef, type: "file", accept: ".zip", className: "hidden", onChange: (e) => {
5035
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
5036
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { ref: wsInputRef, type: "file", accept: ".zip", className: "hidden", onChange: (e) => {
4678
5037
  const f = e.target.files?.[0];
4679
5038
  if (f) handleProjectImport(f);
4680
5039
  e.target.value = "";
4681
5040
  } }),
4682
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
4683
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
4684
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
4685
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "text-white text-[13px] font-mono", children: [
5041
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
5042
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
5043
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
5044
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-white text-[13px] font-mono", children: [
4686
5045
  "v",
4687
5046
  LIB_VERSION
4688
5047
  ] })
4689
5048
  ] }),
4690
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5049
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4691
5050
  "button",
4692
5051
  {
4693
5052
  onClick: toggleContrast,
4694
5053
  className: "flex items-center gap-3 px-5 py-3 rounded-2xl border transition-colors",
4695
5054
  style: { borderColor: highContrast ? "rgba(255,255,255,0.3)" : "rgba(255,255,255,0.08)", background: highContrast ? "rgba(255,255,255,0.08)" : "transparent" },
4696
5055
  children: [
4697
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[22px]", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.35)" }, children: highContrast ? "light_mode" : "dark_mode" }),
4698
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-start", children: [
4699
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[13px] font-bold", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.5)" }, children: highContrast ? "Hoher Kontrast" : "Normaler Kontrast" }),
4700
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
5056
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.35)" }, children: highContrast ? "light_mode" : "dark_mode" }),
5057
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-start", children: [
5058
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[13px] font-bold", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.5)" }, children: highContrast ? "Hoher Kontrast" : "Normaler Kontrast" }),
5059
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
4701
5060
  ] })
4702
5061
  ]
4703
5062
  }
4704
5063
  ),
4705
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
4706
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5064
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5065
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4707
5066
  "button",
4708
5067
  {
4709
5068
  onClick: () => wsInputRef.current?.click(),
4710
5069
  className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform",
4711
5070
  style: { height: 56, background: projectLoaded ? "#16a34a" : "#0284c7" },
4712
5071
  children: [
4713
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: projectLoaded ? "check_circle" : "folder_zip" }),
5072
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: projectLoaded ? "check_circle" : "folder_zip" }),
4714
5073
  projectLoaded ? "Projekt geladen \u2713" : "Projekt laden (.zip)"
4715
5074
  ]
4716
5075
  }
4717
5076
  ),
4718
- !projectLoaded && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Baum, Bilder und Einstellungen wiederherstellen" })
5077
+ !projectLoaded && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Baum, Bilder und Einstellungen wiederherstellen" })
4719
5078
  ] }),
4720
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
4721
- !initialHfToken && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-2 w-full", children: [
4722
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5079
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5080
+ !initialHfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-2 w-full", children: [
5081
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4723
5082
  "input",
4724
5083
  {
4725
5084
  type: "password",
@@ -4735,7 +5094,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4735
5094
  style: { height: 44, background: "rgba(255,255,255,0.05)", border: "1px solid rgba(255,255,255,0.1)", color: "rgba(255,255,255,0.7)" }
4736
5095
  }
4737
5096
  ),
4738
- hfTokenInput.trim() && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5097
+ hfTokenInput.trim() && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4739
5098
  "button",
4740
5099
  {
4741
5100
  type: "button",
@@ -4746,7 +5105,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4746
5105
  }
4747
5106
  )
4748
5107
  ] }),
4749
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5108
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4750
5109
  "button",
4751
5110
  {
4752
5111
  disabled: isLoadingFromHF,
@@ -4768,15 +5127,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4768
5127
  className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform disabled:opacity-50",
4769
5128
  style: { height: 56, background: "#f59e0b" },
4770
5129
  children: [
4771
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromHF ? " animate-spin" : ""}`, children: isLoadingFromHF ? "sync" : "cloud_download" }),
5130
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromHF ? " animate-spin" : ""}`, children: isLoadingFromHF ? "sync" : "cloud_download" }),
4772
5131
  isLoadingFromHF ? "Laden\u2026" : "Von HF laden"
4773
5132
  ]
4774
5133
  }
4775
5134
  ),
4776
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand von Hugging Face laden" })
5135
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand von Hugging Face laden" })
4777
5136
  ] }),
4778
- onFetchServerProjects && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
4779
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5137
+ onFetchServerProjects && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5138
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4780
5139
  "button",
4781
5140
  {
4782
5141
  disabled: isLoadingFromServer,
@@ -4797,39 +5156,39 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4797
5156
  className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform disabled:opacity-50",
4798
5157
  style: { height: 56, background: "#7c3aed" },
4799
5158
  children: [
4800
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromServer ? " animate-spin" : ""}`, children: isLoadingFromServer ? "sync" : "cloud_download" }),
5159
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromServer ? " animate-spin" : ""}`, children: isLoadingFromServer ? "sync" : "cloud_download" }),
4801
5160
  isLoadingFromServer ? "Laden\u2026" : "Vom Server laden"
4802
5161
  ]
4803
5162
  }
4804
5163
  ),
4805
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand vom Server wiederherstellen" })
5164
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand vom Server wiederherstellen" })
4806
5165
  ] }),
4807
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
4808
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
4809
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
5166
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
5167
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
5168
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
4810
5169
  { id: "mobile", icon: "smartphone", label: "Mobile" },
4811
5170
  { id: "mobile-desktop", icon: "phonelink", label: "Mobile+" },
4812
5171
  { id: "desktop", icon: "desktop_windows", label: "Desktop" },
4813
5172
  { id: "tablet-landscape", icon: "tablet", label: "Landscape" }
4814
- ].map((opt) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5173
+ ].map((opt) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4815
5174
  "button",
4816
5175
  {
4817
5176
  onClick: () => startApp(opt.id),
4818
5177
  className: "flex flex-col items-center gap-2 py-4 rounded-2xl border transition-colors",
4819
5178
  style: { borderColor: layoutChoice === opt.id ? "rgba(255,255,255,0.35)" : "rgba(255,255,255,0.08)", background: layoutChoice === opt.id ? "rgba(255,255,255,0.07)" : "transparent" },
4820
5179
  children: [
4821
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[24px]", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.icon }),
4822
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[11px] font-bold", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.label })
5180
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[24px]", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.icon }),
5181
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[11px] font-bold", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.label })
4823
5182
  ]
4824
5183
  },
4825
5184
  opt.id
4826
5185
  )) }),
4827
- layoutChoice === "mobile-desktop" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
4828
- layoutChoice === "tablet-landscape" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
5186
+ layoutChoice === "mobile-desktop" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
5187
+ layoutChoice === "tablet-landscape" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
4829
5188
  ] }),
4830
- !hfNamespace && !hfNamespaceFromServer && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-3 w-full max-w-[280px]", children: [
4831
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "State:" }),
4832
- ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5189
+ !hfNamespace && !hfNamespaceFromServer && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3 w-full max-w-[280px]", children: [
5190
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "State:" }),
5191
+ ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4833
5192
  "button",
4834
5193
  {
4835
5194
  onClick: () => {
@@ -4856,21 +5215,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4856
5215
  const mdScale = mdMode ? window.innerWidth / 430 : 1;
4857
5216
  const mdW = mdMode ? 430 : void 0;
4858
5217
  const mdH = mdMode ? Math.ceil(window.innerHeight / mdScale) : void 0;
4859
- const mobileRoot = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
5218
+ const mobileRoot = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
4860
5219
  width: mdMode ? mdW : "100vw",
4861
5220
  height: mdMode ? mdH : "100dvh",
4862
5221
  transform: mdMode ? `scale(${mdScale})` : void 0,
4863
5222
  transformOrigin: mdMode ? "top left" : void 0,
4864
5223
  ...hcStyle || {}
4865
5224
  }, children: [
4866
- mobileTab === "labs" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LabsTab, { services: labServices, onResult: (item) => {
5225
+ mobileTab === "labs" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LabsTab, { services: labServices, onResult: (item) => {
4867
5226
  const frame = item.frames[0];
4868
5227
  if (frame?.base64) {
4869
5228
  setCurrentResult(frameToGeneration(frame, item));
4870
5229
  setMobileTab("stage");
4871
5230
  }
4872
5231
  } }) }),
4873
- mobileTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5232
+ mobileTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4874
5233
  TagManagerPanel,
4875
5234
  {
4876
5235
  workspaceTags,
@@ -4881,21 +5240,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4881
5240
  onTagMove: handleTagMove
4882
5241
  }
4883
5242
  ) }),
4884
- mobileTab === "stage" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
4885
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
4886
- /* @__PURE__ */ (0, import_jsx_runtime20.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" }] }),
4887
- /* @__PURE__ */ (0, import_jsx_runtime20.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" }] }),
4888
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1" }),
4889
- activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime20.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: [
4890
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
4891
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
4892
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
4893
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
4894
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
4895
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
5243
+ mobileTab === "stage" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
5244
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
5245
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" }] }),
5246
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" }] }),
5247
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1" }),
5248
+ activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5249
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
5250
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
5251
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5252
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
5253
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
5254
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
4896
5255
  ] }),
4897
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: `relative rounded-xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
4898
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5256
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `relative rounded-xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
5257
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4899
5258
  "textarea",
4900
5259
  {
4901
5260
  value: activePrompt,
@@ -4905,26 +5264,26 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4905
5264
  placeholder: "Prompt eingeben..."
4906
5265
  }
4907
5266
  ),
4908
- activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime20.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_runtime20.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
5267
+ activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
4909
5268
  ] }) }),
4910
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5269
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4911
5270
  "button",
4912
5271
  {
4913
5272
  onClick: () => handleGenerateImage(),
4914
5273
  disabled: !activePrompt.trim() || isGenerating,
4915
5274
  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",
4916
5275
  style: { height: 48, background: activePrompt.trim() && !isGenerating ? "#0284c7" : void 0, border: "1px solid rgba(255,255,255,0.1)" },
4917
- children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4918
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-4 h-4 border-t-2 border-white rounded-full animate-spin" }),
4919
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Generiere..." })
4920
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4921
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
4922
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Generieren" })
5276
+ children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5277
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-4 h-4 border-t-2 border-white rounded-full animate-spin" }),
5278
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Generiere..." })
5279
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5280
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
5281
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Generieren" })
4923
5282
  ] })
4924
5283
  }
4925
5284
  ) }),
4926
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
4927
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5285
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
5286
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4928
5287
  "div",
4929
5288
  {
4930
5289
  className: "w-full rounded-2xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center",
@@ -4938,25 +5297,25 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4938
5297
  setTouchStartX(null);
4939
5298
  },
4940
5299
  children: [
4941
- currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
4942
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
4943
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[11px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
5300
+ currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
5301
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
5302
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[11px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
4944
5303
  ] }),
4945
- currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
4946
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
4947
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
4948
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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" })
5304
+ currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
5305
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
5306
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
5307
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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" })
4949
5308
  ] }),
4950
- currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
4951
- !currentResult && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
4952
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
4953
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
5309
+ currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
5310
+ !currentResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
5311
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
5312
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
4954
5313
  ] }),
4955
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
4956
- history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4957
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
4958
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
4959
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "absolute bottom-2 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
5314
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
5315
+ history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5316
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
5317
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
5318
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "absolute bottom-2 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
4960
5319
  currentIndex + 1,
4961
5320
  " / ",
4962
5321
  history.length
@@ -4965,33 +5324,33 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4965
5324
  ]
4966
5325
  }
4967
5326
  ),
4968
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex gap-2 mt-3", children: [
4969
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("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: [
4970
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
4971
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[12px] text-white/60", children: "Prompt" })
5327
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex gap-2 mt-3", children: [
5328
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("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: [
5329
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
5330
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[12px] text-white/60", children: "Prompt" })
4972
5331
  ] }),
4973
- /* @__PURE__ */ (0, import_jsx_runtime20.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: [
4974
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
4975
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
5332
+ /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5333
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
5334
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
4976
5335
  ] }),
4977
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: handleDownloadSingle, 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: [
4978
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
4979
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[12px] text-white/60", children: "Laden" })
5336
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: handleDownloadSingle, 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: [
5337
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
5338
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[12px] text-white/60", children: "Laden" })
4980
5339
  ] })
4981
5340
  ] })
4982
5341
  ] })
4983
5342
  ] }),
4984
- mobileTab === "browse" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
4985
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
4986
- ["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setActiveTab(tab), className: `flex-1 flex items-center justify-center gap-1.5 transition-colors text-[11px] font-bold uppercase tracking-wide ${activeTab === tab ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
4987
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime20.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_runtime20.jsx)("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
5343
+ mobileTab === "browse" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col flex-1 min-h-0", children: [
5344
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
5345
+ ["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActiveTab(tab), className: `flex-1 flex items-center justify-center gap-1.5 transition-colors text-[11px] font-bold uppercase tracking-wide ${activeTab === tab ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
5346
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
4988
5347
  ] }),
4989
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
4990
- activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: (g) => {
5348
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5349
+ activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: (g) => {
4991
5350
  setCurrentResult(g);
4992
5351
  setMobileTab("stage");
4993
5352
  }, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
4994
- activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5353
+ activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4995
5354
  MediaLibrary,
4996
5355
  {
4997
5356
  items: galleryItems,
@@ -5011,39 +5370,43 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5011
5370
  }
5012
5371
  }
5013
5372
  ),
5014
- activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InspectPanel, { currentResult, history, onSelect: (g) => {
5373
+ activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectPanel, { currentResult, history, onSelect: (g) => {
5015
5374
  setCurrentResult(g);
5016
5375
  } })
5017
5376
  ] })
5018
5377
  ] }),
5019
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
5020
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
5021
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: () => {
5378
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
5379
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
5380
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => {
5022
5381
  setLeftTab("prompt");
5023
5382
  if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
5024
5383
  }, className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5025
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
5384
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
5026
5385
  "Prompt"
5027
5386
  ] }),
5028
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: () => {
5387
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => {
5029
5388
  setLeftTab("hierarchy");
5030
5389
  if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
5031
5390
  }, className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5032
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
5391
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
5033
5392
  "Hierarchie"
5034
5393
  ] }),
5035
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: () => setActiveTab("setup"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "setup" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5036
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
5394
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setActiveTab("setup"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "setup" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5395
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
5037
5396
  "Setup"
5038
5397
  ] }),
5039
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: () => setActiveTab("sync"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "sync" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5040
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
5398
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setActiveTab("sync"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "sync" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5399
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
5041
5400
  "Sync"
5042
5401
  ] }),
5043
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
5402
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setActiveTab("hftest"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "hftest" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: [
5403
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
5404
+ "HF"
5405
+ ] }),
5406
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
5044
5407
  ] }),
5045
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5046
- leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5408
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5409
+ leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5047
5410
  ListView,
5048
5411
  {
5049
5412
  nodes,
@@ -5074,12 +5437,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5074
5437
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
5075
5438
  }
5076
5439
  ) }),
5077
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
5440
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
5078
5441
  handleGenerateImage(prompt);
5079
5442
  setMobileTab("stage");
5080
5443
  }, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
5081
- activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
5082
- activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5444
+ activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
5445
+ activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5083
5446
  ProjectSyncTab,
5084
5447
  {
5085
5448
  topSlot: syncTopSlot,
@@ -5103,7 +5466,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5103
5466
  onHfInitialSync: hfToken ? handleHfInitialSync : void 0
5104
5467
  }
5105
5468
  ),
5106
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5469
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5107
5470
  TagManagerPanel,
5108
5471
  {
5109
5472
  workspaceTags,
@@ -5113,22 +5476,23 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5113
5476
  onTagReorder: handleTagReorder,
5114
5477
  onTagMove: handleTagMove
5115
5478
  }
5116
- )
5479
+ ),
5480
+ activeTab === "hftest" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(HFTestTab, { token: hfToken, namespace: effectiveNamespace, galleryItems }) })
5117
5481
  ] })
5118
5482
  ] }),
5119
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
5483
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
5120
5484
  { id: "tools", icon: "auto_fix_high", label: "Prompt" },
5121
5485
  { id: "stage", icon: "palette", label: "Stage" },
5122
5486
  { id: "labs", icon: "science", label: "Labs" },
5123
5487
  ...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
5124
5488
  { id: "browse", icon: "photo_library", label: "Galerie" }
5125
- ].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: () => setMobileTab(tab.id), className: `flex-1 flex flex-col items-center justify-center gap-0.5 transition-colors ${mobileTab === tab.id ? "text-white" : "text-white/30"}`, children: [
5126
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
5127
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
5489
+ ].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setMobileTab(tab.id), className: `flex-1 flex flex-col items-center justify-center gap-0.5 transition-colors ${mobileTab === tab.id ? "text-white" : "text-white/30"}`, children: [
5490
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
5491
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
5128
5492
  ] }, tab.id)) })
5129
5493
  ] });
5130
5494
  if (mdMode) {
5131
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
5495
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
5132
5496
  }
5133
5497
  return mobileRoot;
5134
5498
  }
@@ -5136,17 +5500,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5136
5500
  const tlScale = Math.min(window.innerWidth / 920, window.innerHeight / 520);
5137
5501
  const tlW = 920;
5138
5502
  const tlH = 520;
5139
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { position: "fixed", inset: 0, background: "#0e0e0e", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", ...hcStyle || {} }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { width: tlW, height: tlH, transform: `scale(${tlScale})`, transformOrigin: "center center", display: "flex", flexDirection: "row", color: "#fff", overflow: "hidden", borderRadius: 0 }, children: [
5140
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { width: 320, height: tlH, display: "flex", flexDirection: "column", borderRight: "1px solid rgba(255,255,255,0.05)", background: "#000", flexShrink: 0 }, children: [
5141
- /* @__PURE__ */ (0, import_jsx_runtime20.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: [
5142
- /* @__PURE__ */ (0, import_jsx_runtime20.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" }] }),
5143
- /* @__PURE__ */ (0, import_jsx_runtime20.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" }] }),
5144
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1 } }),
5145
- /* @__PURE__ */ (0, import_jsx_runtime20.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_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
5146
- /* @__PURE__ */ (0, import_jsx_runtime20.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_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
5503
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { position: "fixed", inset: 0, background: "#0e0e0e", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", ...hcStyle || {} }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { width: tlW, height: tlH, transform: `scale(${tlScale})`, transformOrigin: "center center", display: "flex", flexDirection: "row", color: "#fff", overflow: "hidden", borderRadius: 0 }, children: [
5504
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { width: 320, height: tlH, display: "flex", flexDirection: "column", borderRight: "1px solid rgba(255,255,255,0.05)", background: "#000", flexShrink: 0 }, children: [
5505
+ /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5506
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" }] }),
5507
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" }] }),
5508
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { flex: 1 } }),
5509
+ /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
5510
+ /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
5147
5511
  ] }),
5148
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { padding: "12px 12px 8px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "relative", borderRadius: 12, border: `1px solid ${isSynthesizing ? "rgba(255,255,255,0.2)" : "rgba(255,255,255,0.1)"}`, background: "rgba(255,255,255,0.05)" }, children: [
5149
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5512
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { padding: "12px 12px 8px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { position: "relative", borderRadius: 12, border: `1px solid ${isSynthesizing ? "rgba(255,255,255,0.2)" : "rgba(255,255,255,0.1)"}`, background: "rgba(255,255,255,0.05)" }, children: [
5513
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5150
5514
  "textarea",
5151
5515
  {
5152
5516
  value: activePrompt,
@@ -5155,27 +5519,27 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5155
5519
  placeholder: "Prompt eingeben..."
5156
5520
  }
5157
5521
  ),
5158
- activePrompt && /* @__PURE__ */ (0, import_jsx_runtime20.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_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
5522
+ activePrompt && /* @__PURE__ */ (0, import_jsx_runtime21.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_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
5159
5523
  ] }) }),
5160
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5524
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5161
5525
  "button",
5162
5526
  {
5163
5527
  onClick: () => handleGenerateImage(),
5164
5528
  disabled: !activePrompt.trim() || isGenerating,
5165
5529
  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" },
5166
- children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
5167
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { width: 14, height: 14, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
5168
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Generiere..." })
5169
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
5170
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
5171
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Generieren" })
5530
+ children: isGenerating ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5531
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { width: 14, height: 14, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
5532
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Generiere..." })
5533
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5534
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
5535
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Generieren" })
5172
5536
  ] })
5173
5537
  }
5174
5538
  ) }),
5175
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }) })
5539
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }) })
5176
5540
  ] }),
5177
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
5178
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5541
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
5542
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5179
5543
  "div",
5180
5544
  {
5181
5545
  style: { flex: 1, padding: 16, display: "flex", alignItems: "center", justifyContent: "center", position: "relative" },
@@ -5187,26 +5551,26 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5187
5551
  else if (dx > 50) goToPrev();
5188
5552
  setTouchStartX(null);
5189
5553
  },
5190
- children: /* @__PURE__ */ (0, import_jsx_runtime20.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: [
5191
- currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
5192
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { width: 36, height: 36, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
5193
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.4)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
5554
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5555
+ currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
5556
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { width: 36, height: 36, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
5557
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.4)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
5194
5558
  ] }),
5195
- currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
5196
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
5197
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
5198
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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" })
5559
+ currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
5560
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
5561
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
5562
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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" })
5199
5563
  ] }),
5200
- currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
5201
- !currentResult && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
5202
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
5203
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
5564
+ currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
5565
+ !currentResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
5566
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
5567
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
5204
5568
  ] }),
5205
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
5206
- history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
5207
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
5208
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
5209
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "absolute", bottom: 8, left: "50%", transform: "translateX(-50%)", background: "rgba(0,0,0,0.6)", borderRadius: 999, padding: "2px 12px", fontSize: 10, color: "rgba(255,255,255,0.4)", fontFamily: "monospace" }, children: [
5569
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
5570
+ history.length > 1 && currentResult && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5571
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
5572
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
5573
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { position: "absolute", bottom: 8, left: "50%", transform: "translateX(-50%)", background: "rgba(0,0,0,0.6)", borderRadius: 999, padding: "2px 12px", fontSize: 10, color: "rgba(255,255,255,0.4)", fontFamily: "monospace" }, children: [
5210
5574
  currentIndex + 1,
5211
5575
  " / ",
5212
5576
  history.length
@@ -5215,42 +5579,42 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5215
5579
  ] })
5216
5580
  }
5217
5581
  ),
5218
- currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
5219
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("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: [
5220
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
5221
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Prompt" })
5582
+ currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
5583
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("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: [
5584
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
5585
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Prompt" })
5222
5586
  ] }),
5223
- /* @__PURE__ */ (0, import_jsx_runtime20.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: [
5224
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
5225
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Referenz" })
5587
+ /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5588
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
5589
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Referenz" })
5226
5590
  ] }),
5227
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: handleDownloadSingle, 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: [
5228
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
5229
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Laden" })
5591
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: handleDownloadSingle, 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: [
5592
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
5593
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Laden" })
5230
5594
  ] })
5231
5595
  ] })
5232
5596
  ] })
5233
5597
  ] }) });
5234
5598
  }
5235
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
5236
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
5237
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col border-r border-white/5 overflow-hidden relative bg-black/10 shrink-0", style: { width: isLeftCollapsed ? 48 : leftPanelWidth, transition: "none" }, children: [
5238
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
5239
- !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-1 gap-1", children: [
5240
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: () => setLeftTab("prompt"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "prompt" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
5241
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
5599
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
5600
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
5601
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col border-r border-white/5 overflow-hidden relative bg-black/10 shrink-0", style: { width: isLeftCollapsed ? 48 : leftPanelWidth, transition: "none" }, children: [
5602
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
5603
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-1 gap-1", children: [
5604
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setLeftTab("prompt"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "prompt" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
5605
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
5242
5606
  "Prompt"
5243
5607
  ] }),
5244
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: () => setLeftTab("hierarchy"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "hierarchy" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
5245
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
5608
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: () => setLeftTab("hierarchy"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "hierarchy" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
5609
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
5246
5610
  "Hierarchie"
5247
5611
  ] }),
5248
- workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
5612
+ workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
5249
5613
  ] }),
5250
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setIsLeftCollapsed(!isLeftCollapsed), className: "material-symbols-outlined text-[18px] text-white/40 hover:text-white transition-all w-10 flex items-center justify-center", children: isLeftCollapsed ? "chevron_right" : "chevron_left" })
5614
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setIsLeftCollapsed(!isLeftCollapsed), className: "material-symbols-outlined text-[18px] text-white/40 hover:text-white transition-all w-10 flex items-center justify-center", children: isLeftCollapsed ? "chevron_right" : "chevron_left" })
5251
5615
  ] }),
5252
- !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5253
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5616
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5617
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5254
5618
  TagManagerPanel,
5255
5619
  {
5256
5620
  workspaceTags,
@@ -5261,11 +5625,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5261
5625
  onTagMove: handleTagMove
5262
5626
  }
5263
5627
  ),
5264
- activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
5265
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
5266
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
5628
+ activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
5629
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
5630
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
5267
5631
  ] }) }),
5268
- leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5632
+ leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5269
5633
  ListView,
5270
5634
  {
5271
5635
  nodes,
@@ -5290,18 +5654,18 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5290
5654
  isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
5291
5655
  }
5292
5656
  ) }),
5293
- leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime20.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 })
5657
+ leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime21.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 })
5294
5658
  ] })
5295
5659
  ] }),
5296
- !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime20.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" } }),
5297
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
5298
- /* @__PURE__ */ (0, import_jsx_runtime20.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: [
5299
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5", children: [
5300
- /* @__PURE__ */ (0, import_jsx_runtime20.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" }] }),
5301
- /* @__PURE__ */ (0, import_jsx_runtime20.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" }] })
5660
+ !isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.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" } }),
5661
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
5662
+ /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5663
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1.5", children: [
5664
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" }] }),
5665
+ /* @__PURE__ */ (0, import_jsx_runtime21.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" }] })
5302
5666
  ] }),
5303
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1 mx-auto", children: [
5304
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5667
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1 mx-auto", children: [
5668
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5305
5669
  "button",
5306
5670
  {
5307
5671
  onClick: () => setMiddlePanel("stage"),
@@ -5309,7 +5673,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5309
5673
  children: "Stage"
5310
5674
  }
5311
5675
  ),
5312
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5676
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5313
5677
  "button",
5314
5678
  {
5315
5679
  onClick: () => setMiddlePanel("labs"),
@@ -5318,68 +5682,68 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5318
5682
  }
5319
5683
  )
5320
5684
  ] }),
5321
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2", children: [
5322
- activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
5323
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
5324
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
5325
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5326
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("button", { onClick: handleSelectReference, className: "flex items-center gap-1 h-7 px-2 rounded-lg border border-white/10 text-white/30 hover:text-white/60 hover:border-white/20 transition-colors text-[10px] font-bold uppercase tracking-wide", children: [
5327
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
5328
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Ref" })
5685
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
5686
+ activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
5687
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
5688
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
5689
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5690
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick: handleSelectReference, className: "flex items-center gap-1 h-7 px-2 rounded-lg border border-white/10 text-white/30 hover:text-white/60 hover:border-white/20 transition-colors text-[10px] font-bold uppercase tracking-wide", children: [
5691
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
5692
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Ref" })
5329
5693
  ] }),
5330
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
5331
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PillButton, { variant: "solid", icon: "bolt", loading: isGenerating, disabled: !activePrompt.trim(), onClick: () => handleGenerateImage(), children: "Generieren" })
5694
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
5695
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "solid", icon: "bolt", loading: isGenerating, disabled: !activePrompt.trim(), onClick: () => handleGenerateImage(), children: "Generieren" })
5332
5696
  ] })
5333
5697
  ] }),
5334
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
5335
- !isPromptCollapsed && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "px-6 py-4 border-b border-white/5 bg-black/10 overflow-hidden shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: `relative min-h-[60px] p-4 rounded-2xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
5336
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("textarea", { value: activePrompt, onChange: (e) => setActivePrompt(e.target.value), className: "w-full bg-transparent border-none outline-none text-[12px] leading-relaxed text-white/80 resize-none h-20 dark-scrollbar", placeholder: "W\xE4hle einen Knoten oder tippe einen Prompt..." }),
5337
- activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setActivePrompt(""), className: "absolute top-2 right-2 w-6 h-6 rounded-full bg-white/5 hover:bg-white/10 flex items-center justify-center transition-colors text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5698
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
5699
+ !isPromptCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "px-6 py-4 border-b border-white/5 bg-black/10 overflow-hidden shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: `relative min-h-[60px] p-4 rounded-2xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
5700
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("textarea", { value: activePrompt, onChange: (e) => setActivePrompt(e.target.value), className: "w-full bg-transparent border-none outline-none text-[12px] leading-relaxed text-white/80 resize-none h-20 dark-scrollbar", placeholder: "W\xE4hle einen Knoten oder tippe einen Prompt..." }),
5701
+ activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setActivePrompt(""), className: "absolute top-2 right-2 w-6 h-6 rounded-full bg-white/5 hover:bg-white/10 flex items-center justify-center transition-colors text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
5338
5702
  ] }) }),
5339
- middlePanel === "labs" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LabsTab, { services: labServices, onResult: (item) => {
5703
+ middlePanel === "labs" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LabsTab, { services: labServices, onResult: (item) => {
5340
5704
  const frame = item.frames[0];
5341
5705
  if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
5342
- } }) }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime20.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: [
5343
- isGenerating && currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime20.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: [
5344
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
5345
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
5706
+ } }) }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5707
+ isGenerating && currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5708
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
5709
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
5346
5710
  ] }),
5347
- currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
5348
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
5349
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
5350
- ] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
5351
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
5352
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col gap-2", children: [
5353
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
5354
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
5711
+ currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
5712
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
5713
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
5714
+ ] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
5715
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
5716
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col gap-2", children: [
5717
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
5718
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
5355
5719
  ] }),
5356
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
5357
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
5358
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("img", { src: currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
5359
- /* @__PURE__ */ (0, import_jsx_runtime20.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: [
5360
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
5361
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
5362
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
5720
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
5721
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
5722
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
5723
+ /* @__PURE__ */ (0, import_jsx_runtime21.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: [
5724
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
5725
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
5726
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
5363
5727
  ] })
5364
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
5365
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
5366
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
5728
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
5729
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
5730
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
5367
5731
  ] })
5368
5732
  ] }) })
5369
5733
  ] })
5370
5734
  ] }),
5371
- !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
5372
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
5373
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
5374
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-1", children: ["history", "gallery", "inspect", "setup", "sync", "tags"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => {
5735
+ !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
5736
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
5737
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
5738
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex flex-1", children: ["history", "gallery", "inspect", "setup", "sync", "tags"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => {
5375
5739
  setActiveTab(tab);
5376
5740
  setIsRightCollapsed(false);
5377
- }, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : tab === "inspect" ? "info" : tab === "setup" ? "settings" : tab === "sync" ? "cloud_sync" : "label" }) }, tab)) }),
5378
- hfToken && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-10 flex items-center justify-center text-white/20 hover:text-white/60 transition-colors disabled:opacity-30", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
5379
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
5741
+ }, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : tab === "inspect" ? "info" : tab === "setup" ? "settings" : tab === "sync" ? "cloud_sync" : "label" }) }, tab)) }),
5742
+ hfToken && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-10 flex items-center justify-center text-white/20 hover:text-white/60 transition-colors disabled:opacity-30", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
5743
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
5380
5744
  ] }),
5381
- !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5382
- activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5745
+ !isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
5746
+ activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5383
5747
  TagManagerPanel,
5384
5748
  {
5385
5749
  workspaceTags,
@@ -5390,12 +5754,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5390
5754
  onTagMove: handleTagMove
5391
5755
  }
5392
5756
  ),
5393
- activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
5394
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
5395
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
5757
+ activeTab === "tags" && !workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
5758
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
5759
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
5396
5760
  ] }) }),
5397
- activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
5398
- activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5761
+ activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
5762
+ activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5399
5763
  MediaLibrary,
5400
5764
  {
5401
5765
  items: galleryItems,
@@ -5409,9 +5773,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5409
5773
  onGenerateReference: (item) => handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true })
5410
5774
  }
5411
5775
  ),
5412
- activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
5413
- activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
5414
- activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5776
+ activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
5777
+ activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
5778
+ activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5415
5779
  ProjectSyncTab,
5416
5780
  {
5417
5781
  topSlot: syncTopSlot,
@@ -5441,8 +5805,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5441
5805
  }
5442
5806
 
5443
5807
  // src/components/FaApp.tsx
5444
- var import_react23 = require("react");
5445
- var import_jsx_runtime21 = require("react/jsx-runtime");
5808
+ var import_react24 = require("react");
5809
+ var import_jsx_runtime22 = require("react/jsx-runtime");
5446
5810
  function FaApp({
5447
5811
  onGenerateImage,
5448
5812
  onGeneratePrompt,
@@ -5461,8 +5825,8 @@ function FaApp({
5461
5825
  onServerDelete,
5462
5826
  buildInfo
5463
5827
  }) {
5464
- const [hfNamespace, setHfNamespace] = (0, import_react23.useState)(void 0);
5465
- (0, import_react23.useEffect)(() => {
5828
+ const [hfNamespace, setHfNamespace] = (0, import_react24.useState)(void 0);
5829
+ (0, import_react24.useEffect)(() => {
5466
5830
  if (!serverBaseUrl) return;
5467
5831
  fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
5468
5832
  if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
@@ -5473,7 +5837,7 @@ function FaApp({
5473
5837
  const result = await onGeneratePrompt(text, options);
5474
5838
  return result.text;
5475
5839
  };
5476
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5840
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5477
5841
  AvatarArchitectApp,
5478
5842
  {
5479
5843
  onGenerateImage,
@@ -5495,7 +5859,7 @@ function FaApp({
5495
5859
  // src/index.ts
5496
5860
  init_hfStateService();
5497
5861
  init_hfStateService();
5498
- var LIB_VERSION = "2.0.12";
5862
+ var LIB_VERSION = "2.0.14";
5499
5863
  // Annotate the CommonJS export names for ESM import in node:
5500
5864
  0 && (module.exports = {
5501
5865
  AvatarArchitectApp,