@rslsp1/fa-app-tools 1.3.18 → 2.0.13
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/chunk-WCFXXLKN.mjs +409 -0
- package/dist/hfStateService-6YYT6ATO.mjs +54 -0
- package/dist/index.d.mts +103 -9
- package/dist/index.d.ts +103 -9
- package/dist/index.js +1514 -557
- package/dist/index.mjs +1277 -511
- package/package.json +5 -4
- package/dist/chunk-X6S5BP36.mjs +0 -232
- package/dist/hfStateService-B62RV5K3.mjs +0 -32
package/dist/index.mjs
CHANGED
|
@@ -5,18 +5,23 @@ import {
|
|
|
5
5
|
} from "./chunk-UFXDXENC.mjs";
|
|
6
6
|
import {
|
|
7
7
|
getHFToken,
|
|
8
|
+
getSessionClientId,
|
|
9
|
+
hfBatchArchive,
|
|
10
|
+
hfBootstrapFromLegacy,
|
|
8
11
|
hfDeleteProject,
|
|
9
12
|
hfDownloadProject,
|
|
13
|
+
hfListDir,
|
|
10
14
|
hfListProjects,
|
|
11
15
|
hfLoadImageAsBase64,
|
|
12
|
-
hfLoadMetadata,
|
|
13
|
-
hfLoadTags,
|
|
14
|
-
hfSaveMetadata,
|
|
15
|
-
hfSaveTags,
|
|
16
16
|
hfUploadImage,
|
|
17
17
|
hfUploadProjectForm,
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
hfUploadSmallFile,
|
|
19
|
+
loadHFState,
|
|
20
|
+
loadPendingEvents,
|
|
21
|
+
setHFToken,
|
|
22
|
+
tsFromEventPath,
|
|
23
|
+
writeHFEvent
|
|
24
|
+
} from "./chunk-WCFXXLKN.mjs";
|
|
20
25
|
|
|
21
26
|
// src/hooks/useOnClickOutside.ts
|
|
22
27
|
import { useEffect } from "react";
|
|
@@ -793,7 +798,7 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
|
|
|
793
798
|
}
|
|
794
799
|
|
|
795
800
|
// src/components/AvatarArchitectApp.tsx
|
|
796
|
-
import { useState as
|
|
801
|
+
import { useState as useState16, useCallback as useCallback2, useMemo as useMemo2, useEffect as useEffect6, useRef as useRef7 } from "react";
|
|
797
802
|
|
|
798
803
|
// src/components/PromptTab.tsx
|
|
799
804
|
import { useRef as useRef4, useState as useState5 } from "react";
|
|
@@ -1320,6 +1325,7 @@ var PromptTab = ({
|
|
|
1320
1325
|
import { useRef as useRef5, useState as useState6, useEffect as useEffect4 } from "react";
|
|
1321
1326
|
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1322
1327
|
var ProjectSyncTab = ({
|
|
1328
|
+
topSlot,
|
|
1323
1329
|
onProjectExport,
|
|
1324
1330
|
onProjectImport,
|
|
1325
1331
|
onWorkspaceImport,
|
|
@@ -1411,6 +1417,7 @@ var ProjectSyncTab = ({
|
|
|
1411
1417
|
if (hfToken) loadHfProjects(hfToken);
|
|
1412
1418
|
}, [hfToken]);
|
|
1413
1419
|
return /* @__PURE__ */ jsx12("div", { className: "absolute inset-0 overflow-y-auto dark-scrollbar", children: /* @__PURE__ */ jsxs10("div", { className: "p-6 flex flex-col gap-8", children: [
|
|
1420
|
+
topSlot && /* @__PURE__ */ jsx12("div", { children: topSlot }),
|
|
1414
1421
|
(onProjectExport || onProjectImport || onWorkspaceImport) && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-4", children: [
|
|
1415
1422
|
/* @__PURE__ */ jsx12(SectionLabel, { children: "Projekt-ZIP" }),
|
|
1416
1423
|
/* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2", children: [
|
|
@@ -1591,7 +1598,7 @@ var ProjectSyncTab = ({
|
|
|
1591
1598
|
{
|
|
1592
1599
|
onClick: async () => {
|
|
1593
1600
|
try {
|
|
1594
|
-
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
1601
|
+
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-6YYT6ATO.mjs");
|
|
1595
1602
|
const file = await hfDownloadProject2(p.path, hfToken);
|
|
1596
1603
|
onHfLoad(file);
|
|
1597
1604
|
} catch (e) {
|
|
@@ -1812,14 +1819,254 @@ function toPromptImages(images) {
|
|
|
1812
1819
|
});
|
|
1813
1820
|
}
|
|
1814
1821
|
|
|
1822
|
+
// src/hooks/useHFState.ts
|
|
1823
|
+
import { useState as useState7, useEffect as useEffect5, useRef as useRef6, useCallback } from "react";
|
|
1824
|
+
|
|
1825
|
+
// src/lib/hfReducer.ts
|
|
1826
|
+
function applyEvent(state, event) {
|
|
1827
|
+
if (event.v.major > 1) return state;
|
|
1828
|
+
switch (event.type) {
|
|
1829
|
+
case "image_added": {
|
|
1830
|
+
const p = event.payload;
|
|
1831
|
+
if (state.metadata.some((m) => m.id === p.id)) return state;
|
|
1832
|
+
return { ...state, metadata: [...state.metadata, p] };
|
|
1833
|
+
}
|
|
1834
|
+
case "tag_upserted": {
|
|
1835
|
+
const p = event.payload;
|
|
1836
|
+
const tags = state.tags;
|
|
1837
|
+
const cat = tags.by_category[p.category] || [];
|
|
1838
|
+
const existing = cat.find((t) => t.value === p.value);
|
|
1839
|
+
const updated = { label: p.label, value: p.value, is_user_created: p.is_user_created, is_deleted: p.is_deleted };
|
|
1840
|
+
const newCat = existing ? cat.map((t) => t.value === p.value ? { ...t, ...updated } : t) : [...cat, updated];
|
|
1841
|
+
const newAll = tags.all.some((t) => t.value === p.value && t.category === p.category) ? tags.all.map((t) => t.value === p.value && t.category === p.category ? { ...t, ...updated, category: p.category } : t) : [...tags.all, { ...updated, category: p.category }];
|
|
1842
|
+
return { ...state, tags: { by_category: { ...tags.by_category, [p.category]: newCat }, all: newAll } };
|
|
1843
|
+
}
|
|
1844
|
+
case "metadata_updated": {
|
|
1845
|
+
const p = event.payload;
|
|
1846
|
+
return {
|
|
1847
|
+
...state,
|
|
1848
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, ...p.delta } : m)
|
|
1849
|
+
};
|
|
1850
|
+
}
|
|
1851
|
+
default:
|
|
1852
|
+
return state;
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
function applyEvents(state, events) {
|
|
1856
|
+
return events.reduce(applyEvent, state);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// src/lib/hfDag.ts
|
|
1860
|
+
function buildDag(events) {
|
|
1861
|
+
const dag = /* @__PURE__ */ new Map();
|
|
1862
|
+
for (const event of events) {
|
|
1863
|
+
dag.set(event.ts, { event, children: [] });
|
|
1864
|
+
}
|
|
1865
|
+
for (const event of events) {
|
|
1866
|
+
for (const parent of event.prevTs) {
|
|
1867
|
+
const node = dag.get(parent);
|
|
1868
|
+
if (node && !node.children.includes(event.ts)) {
|
|
1869
|
+
node.children.push(event.ts);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
return dag;
|
|
1874
|
+
}
|
|
1875
|
+
function findTips(dag) {
|
|
1876
|
+
return [...dag.values()].filter((n) => n.children.length === 0).map((n) => n.event.ts);
|
|
1877
|
+
}
|
|
1878
|
+
function findForks(dag) {
|
|
1879
|
+
const forks = [];
|
|
1880
|
+
for (const [ts, node] of dag) {
|
|
1881
|
+
if (node.children.length > 1) {
|
|
1882
|
+
forks.push({ parentTs: ts, childTs: node.children });
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
return forks;
|
|
1886
|
+
}
|
|
1887
|
+
function topoSort(events) {
|
|
1888
|
+
if (!events.length) return [];
|
|
1889
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
1890
|
+
const children = /* @__PURE__ */ new Map();
|
|
1891
|
+
const tsSet = new Set(events.map((e) => e.ts));
|
|
1892
|
+
for (const e of events) {
|
|
1893
|
+
inDegree.set(e.ts, 0);
|
|
1894
|
+
children.set(e.ts, []);
|
|
1895
|
+
}
|
|
1896
|
+
for (const e of events) {
|
|
1897
|
+
for (const p of e.prevTs) {
|
|
1898
|
+
if (tsSet.has(p)) {
|
|
1899
|
+
children.get(p).push(e.ts);
|
|
1900
|
+
inDegree.set(e.ts, (inDegree.get(e.ts) || 0) + 1);
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
const queue = events.filter((e) => (inDegree.get(e.ts) || 0) === 0).sort((a, b) => a.ts - b.ts);
|
|
1905
|
+
const result = [];
|
|
1906
|
+
const byTs = new Map(events.map((e) => [e.ts, e]));
|
|
1907
|
+
while (queue.length) {
|
|
1908
|
+
const node = queue.shift();
|
|
1909
|
+
result.push(node);
|
|
1910
|
+
for (const childTs of children.get(node.ts) || []) {
|
|
1911
|
+
const newDeg = (inDegree.get(childTs) || 0) - 1;
|
|
1912
|
+
inDegree.set(childTs, newDeg);
|
|
1913
|
+
if (newDeg === 0) {
|
|
1914
|
+
const child = byTs.get(childTs);
|
|
1915
|
+
const insertAt = queue.findIndex((q) => q.ts > child.ts);
|
|
1916
|
+
if (insertAt === -1) queue.push(child);
|
|
1917
|
+
else queue.splice(insertAt, 0, child);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
return result;
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
// src/hooks/useHFState.ts
|
|
1925
|
+
var OFFLINE_BUFFER_KEY = "hf-offline-buffer";
|
|
1926
|
+
var POLL_INTERVAL_MS = 3e4;
|
|
1927
|
+
function readOfflineBuffer() {
|
|
1928
|
+
try {
|
|
1929
|
+
return JSON.parse(localStorage.getItem(OFFLINE_BUFFER_KEY) || "[]");
|
|
1930
|
+
} catch {
|
|
1931
|
+
return [];
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
function writeOfflineBuffer(events) {
|
|
1935
|
+
try {
|
|
1936
|
+
localStorage.setItem(OFFLINE_BUFFER_KEY, JSON.stringify(events));
|
|
1937
|
+
} catch {
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
function useHFState(token, namespace) {
|
|
1941
|
+
const [state, setState] = useState7(null);
|
|
1942
|
+
const [isLoading, setIsLoading] = useState7(false);
|
|
1943
|
+
const [error, setError] = useState7(null);
|
|
1944
|
+
const [eventCount, setEventCount] = useState7(0);
|
|
1945
|
+
const [forks, setForks] = useState7([]);
|
|
1946
|
+
const [pendingBufferCount, setPendingBufferCount] = useState7(readOfflineBuffer().length);
|
|
1947
|
+
const [lastEventTs, setLastEventTs] = useState7(0);
|
|
1948
|
+
const [hasStateZip, setHasStateZip] = useState7(false);
|
|
1949
|
+
const knownEventPaths = useRef6(/* @__PURE__ */ new Set());
|
|
1950
|
+
const allEventsRef = useRef6([]);
|
|
1951
|
+
const applyNewEvents = useCallback((snapshot, newEvents) => {
|
|
1952
|
+
if (!newEvents.length && allEventsRef.current.length === 0) {
|
|
1953
|
+
setEventCount(0);
|
|
1954
|
+
return snapshot;
|
|
1955
|
+
}
|
|
1956
|
+
const sorted = topoSort([...allEventsRef.current, ...newEvents]);
|
|
1957
|
+
allEventsRef.current = sorted;
|
|
1958
|
+
const afterConsolidation = sorted.filter((e) => e.ts > snapshot.meta.consolidatedAt);
|
|
1959
|
+
const dag = buildDag(afterConsolidation);
|
|
1960
|
+
setForks(findForks(dag));
|
|
1961
|
+
setEventCount(afterConsolidation.length);
|
|
1962
|
+
if (afterConsolidation.length) setLastEventTs(Math.max(...afterConsolidation.map((e) => e.ts)));
|
|
1963
|
+
return applyEvents(snapshot, afterConsolidation);
|
|
1964
|
+
}, []);
|
|
1965
|
+
const loadFull = useCallback(async () => {
|
|
1966
|
+
if (!token || !namespace) return;
|
|
1967
|
+
setIsLoading(true);
|
|
1968
|
+
setError(null);
|
|
1969
|
+
try {
|
|
1970
|
+
const snapshot = await loadHFState(namespace, token);
|
|
1971
|
+
setHasStateZip(snapshot !== null);
|
|
1972
|
+
const base = snapshot ?? {
|
|
1973
|
+
metadata: [],
|
|
1974
|
+
tags: { by_category: {}, all: [] },
|
|
1975
|
+
meta: { consolidatedAt: 0, version: 1 }
|
|
1976
|
+
};
|
|
1977
|
+
const events = await loadPendingEvents(namespace, token, base.meta.consolidatedAt);
|
|
1978
|
+
events.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
|
|
1979
|
+
allEventsRef.current = [];
|
|
1980
|
+
const finalState = applyNewEvents(base, events);
|
|
1981
|
+
setState(finalState);
|
|
1982
|
+
const buffer = readOfflineBuffer();
|
|
1983
|
+
if (buffer.length) {
|
|
1984
|
+
for (const evt of buffer) {
|
|
1985
|
+
await writeHFEvent(namespace, token, evt.type, evt.payload, evt.prevTs).catch(() => {
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
writeOfflineBuffer([]);
|
|
1989
|
+
setPendingBufferCount(0);
|
|
1990
|
+
const freshEvents = await loadPendingEvents(namespace, token, base.meta.consolidatedAt);
|
|
1991
|
+
freshEvents.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
|
|
1992
|
+
setState((prev) => prev ? applyNewEvents(base, freshEvents) : prev);
|
|
1993
|
+
}
|
|
1994
|
+
} catch (e) {
|
|
1995
|
+
setError(e.message);
|
|
1996
|
+
} finally {
|
|
1997
|
+
setIsLoading(false);
|
|
1998
|
+
}
|
|
1999
|
+
}, [token, namespace, applyNewEvents]);
|
|
2000
|
+
const pollNew = useCallback(async () => {
|
|
2001
|
+
if (!token || !namespace || !state) return;
|
|
2002
|
+
try {
|
|
2003
|
+
const events = await loadPendingEvents(namespace, token, state.meta.consolidatedAt);
|
|
2004
|
+
const newEvents = events.filter((e) => !knownEventPaths.current.has(`${e.ts}_${e.clientId}`));
|
|
2005
|
+
if (!newEvents.length) return;
|
|
2006
|
+
newEvents.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
|
|
2007
|
+
setState((prev) => prev ? applyNewEvents(prev, newEvents) : prev);
|
|
2008
|
+
} catch {
|
|
2009
|
+
}
|
|
2010
|
+
}, [token, namespace, state, applyNewEvents]);
|
|
2011
|
+
useEffect5(() => {
|
|
2012
|
+
if (token && namespace) loadFull();
|
|
2013
|
+
}, [token, namespace]);
|
|
2014
|
+
useEffect5(() => {
|
|
2015
|
+
if (!token || !namespace) return;
|
|
2016
|
+
const id = setInterval(pollNew, POLL_INTERVAL_MS);
|
|
2017
|
+
return () => clearInterval(id);
|
|
2018
|
+
}, [token, namespace, pollNew]);
|
|
2019
|
+
const writeEvent2 = useCallback(async (type, payload) => {
|
|
2020
|
+
const prevTs = lastEventTs ? [lastEventTs] : [state?.meta.consolidatedAt ?? 0];
|
|
2021
|
+
console.log("[HF] writeEvent called:", { type, namespace, tokenOk: !!token, prevTs });
|
|
2022
|
+
await pollNew();
|
|
2023
|
+
try {
|
|
2024
|
+
console.log("[HF] writeHFEvent start, path will be:", `${namespace}events/...`);
|
|
2025
|
+
const event = await writeHFEvent(namespace, token, type, payload, prevTs);
|
|
2026
|
+
console.log("[HF] writeHFEvent success:", event.ts);
|
|
2027
|
+
knownEventPaths.current.add(`${event.ts}_${event.clientId}`);
|
|
2028
|
+
setState((prev) => prev ? applyNewEvents(prev, [event]) : prev);
|
|
2029
|
+
setLastEventTs(event.ts);
|
|
2030
|
+
await pollNew();
|
|
2031
|
+
} catch (e) {
|
|
2032
|
+
console.error("[HF] writeHFEvent FAILED, going to offline buffer:", e);
|
|
2033
|
+
const buffer = readOfflineBuffer();
|
|
2034
|
+
const offline = {
|
|
2035
|
+
v: { major: 1, minor: 0 },
|
|
2036
|
+
type,
|
|
2037
|
+
ts: Date.now(),
|
|
2038
|
+
prevTs,
|
|
2039
|
+
clientId: getSessionClientId(),
|
|
2040
|
+
payload
|
|
2041
|
+
};
|
|
2042
|
+
writeOfflineBuffer([...buffer, offline]);
|
|
2043
|
+
setPendingBufferCount(buffer.length + 1);
|
|
2044
|
+
setState((prev) => prev ? applyNewEvents(prev, [offline]) : prev);
|
|
2045
|
+
}
|
|
2046
|
+
}, [namespace, token, lastEventTs, state, pollNew, applyNewEvents]);
|
|
2047
|
+
return {
|
|
2048
|
+
state,
|
|
2049
|
+
isLoading,
|
|
2050
|
+
error,
|
|
2051
|
+
pendingBufferCount,
|
|
2052
|
+
eventCount,
|
|
2053
|
+
forks,
|
|
2054
|
+
writeEvent: writeEvent2,
|
|
2055
|
+
refresh: loadFull,
|
|
2056
|
+
lastEventTs,
|
|
2057
|
+
allEvents: allEventsRef.current,
|
|
2058
|
+
hasStateZip
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
|
|
1815
2062
|
// src/components/labs/LabsTab.tsx
|
|
1816
|
-
import { useState as
|
|
2063
|
+
import { useState as useState13 } from "react";
|
|
1817
2064
|
|
|
1818
2065
|
// src/components/labs/LabRemix.tsx
|
|
1819
|
-
import { useState as
|
|
2066
|
+
import { useState as useState9 } from "react";
|
|
1820
2067
|
|
|
1821
2068
|
// src/components/labs/LabImagePicker.tsx
|
|
1822
|
-
import { useState as
|
|
2069
|
+
import { useState as useState8 } from "react";
|
|
1823
2070
|
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1824
2071
|
var LabImagePicker = ({
|
|
1825
2072
|
availableItems,
|
|
@@ -1828,8 +2075,8 @@ var LabImagePicker = ({
|
|
|
1828
2075
|
onClose,
|
|
1829
2076
|
title = "Bild w\xE4hlen"
|
|
1830
2077
|
}) => {
|
|
1831
|
-
const [search, setSearch] =
|
|
1832
|
-
const [drillItem, setDrillItem] =
|
|
2078
|
+
const [search, setSearch] = useState8("");
|
|
2079
|
+
const [drillItem, setDrillItem] = useState8(null);
|
|
1833
2080
|
const filtered = availableItems.filter(
|
|
1834
2081
|
(item) => !search || item.prompt.toLowerCase().includes(search.toLowerCase())
|
|
1835
2082
|
);
|
|
@@ -1931,13 +2178,13 @@ var LabImagePicker = ({
|
|
|
1931
2178
|
// src/components/labs/LabRemix.tsx
|
|
1932
2179
|
import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1933
2180
|
var LabRemix = ({ services, onResult }) => {
|
|
1934
|
-
const [showPicker, setShowPicker] =
|
|
1935
|
-
const [selected, setSelected] =
|
|
1936
|
-
const [instruction, setInstruction] =
|
|
1937
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
1938
|
-
const [resultImage, setResultImage] =
|
|
1939
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] =
|
|
1940
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2181
|
+
const [showPicker, setShowPicker] = useState9(false);
|
|
2182
|
+
const [selected, setSelected] = useState9(null);
|
|
2183
|
+
const [instruction, setInstruction] = useState9("");
|
|
2184
|
+
const [generatedPrompt, setGeneratedPrompt] = useState9("");
|
|
2185
|
+
const [resultImage, setResultImage] = useState9(null);
|
|
2186
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = useState9(false);
|
|
2187
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState9(false);
|
|
1941
2188
|
const handleSelectImage = (item, frame) => {
|
|
1942
2189
|
services.onItemUsed(item);
|
|
1943
2190
|
setSelected({
|
|
@@ -2120,16 +2367,16 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
2120
2367
|
};
|
|
2121
2368
|
|
|
2122
2369
|
// src/components/labs/LabBlend.tsx
|
|
2123
|
-
import { useState as
|
|
2370
|
+
import { useState as useState10 } from "react";
|
|
2124
2371
|
import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2125
2372
|
var LabBlend = ({ services, onResult }) => {
|
|
2126
|
-
const [showPickerFor, setShowPickerFor] =
|
|
2127
|
-
const [selectedImages, setSelectedImages] =
|
|
2128
|
-
const [instruction, setInstruction] =
|
|
2129
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
2130
|
-
const [resultImage, setResultImage] =
|
|
2131
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] =
|
|
2132
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2373
|
+
const [showPickerFor, setShowPickerFor] = useState10(null);
|
|
2374
|
+
const [selectedImages, setSelectedImages] = useState10([]);
|
|
2375
|
+
const [instruction, setInstruction] = useState10("");
|
|
2376
|
+
const [generatedPrompt, setGeneratedPrompt] = useState10("");
|
|
2377
|
+
const [resultImage, setResultImage] = useState10(null);
|
|
2378
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = useState10(false);
|
|
2379
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState10(false);
|
|
2133
2380
|
const handleSelectImage = (index, item, frame) => {
|
|
2134
2381
|
services.onItemUsed(item);
|
|
2135
2382
|
const newImg = {
|
|
@@ -2316,17 +2563,17 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
2316
2563
|
};
|
|
2317
2564
|
|
|
2318
2565
|
// src/components/labs/LabCompare.tsx
|
|
2319
|
-
import { useState as
|
|
2566
|
+
import { useState as useState11 } from "react";
|
|
2320
2567
|
import { Fragment as Fragment7, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2321
2568
|
var LabCompare = ({ services, onResult }) => {
|
|
2322
|
-
const [showPickerFor, setShowPickerFor] =
|
|
2323
|
-
const [selectedImages, setSelectedImages] =
|
|
2324
|
-
const [instruction, setInstruction] =
|
|
2325
|
-
const [analysis, setAnalysis] =
|
|
2326
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
2327
|
-
const [resultImage, setResultImage] =
|
|
2328
|
-
const [isAnalyzing, setIsAnalyzing] =
|
|
2329
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2569
|
+
const [showPickerFor, setShowPickerFor] = useState11(null);
|
|
2570
|
+
const [selectedImages, setSelectedImages] = useState11([]);
|
|
2571
|
+
const [instruction, setInstruction] = useState11("");
|
|
2572
|
+
const [analysis, setAnalysis] = useState11("");
|
|
2573
|
+
const [generatedPrompt, setGeneratedPrompt] = useState11("");
|
|
2574
|
+
const [resultImage, setResultImage] = useState11(null);
|
|
2575
|
+
const [isAnalyzing, setIsAnalyzing] = useState11(false);
|
|
2576
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState11(false);
|
|
2330
2577
|
const handleSelectImage = (index, item, frame) => {
|
|
2331
2578
|
services.onItemUsed(item);
|
|
2332
2579
|
const newImg = {
|
|
@@ -2489,14 +2736,14 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
2489
2736
|
};
|
|
2490
2737
|
|
|
2491
2738
|
// src/components/labs/LabLoop.tsx
|
|
2492
|
-
import { useState as
|
|
2739
|
+
import { useState as useState12 } from "react";
|
|
2493
2740
|
import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2494
2741
|
var LabLoop = ({ services, onResult }) => {
|
|
2495
|
-
const [rounds, setRounds] =
|
|
2496
|
-
const [currentInstruction, setCurrentInstruction] =
|
|
2497
|
-
const [showPickerForRound, setShowPickerForRound] =
|
|
2498
|
-
const [pendingImages, setPendingImages] =
|
|
2499
|
-
const [isGenerating, setIsGenerating] =
|
|
2742
|
+
const [rounds, setRounds] = useState12([]);
|
|
2743
|
+
const [currentInstruction, setCurrentInstruction] = useState12("");
|
|
2744
|
+
const [showPickerForRound, setShowPickerForRound] = useState12(null);
|
|
2745
|
+
const [pendingImages, setPendingImages] = useState12([]);
|
|
2746
|
+
const [isGenerating, setIsGenerating] = useState12(false);
|
|
2500
2747
|
const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
|
|
2501
2748
|
const handleAddImage = (item, frame) => {
|
|
2502
2749
|
services.onItemUsed(item);
|
|
@@ -2660,7 +2907,7 @@ var TABS = [
|
|
|
2660
2907
|
{ key: "loop", label: "Loop", icon: "loop" }
|
|
2661
2908
|
];
|
|
2662
2909
|
var LabsTab = ({ services, onResult }) => {
|
|
2663
|
-
const [activeTab, setActiveTab] =
|
|
2910
|
+
const [activeTab, setActiveTab] = useState13("remix");
|
|
2664
2911
|
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
2665
2912
|
/* @__PURE__ */ jsx18("div", { className: "flex border-b border-white/5 shrink-0", children: TABS.map((tab) => /* @__PURE__ */ jsxs16(
|
|
2666
2913
|
"button",
|
|
@@ -2684,19 +2931,19 @@ var LabsTab = ({ services, onResult }) => {
|
|
|
2684
2931
|
};
|
|
2685
2932
|
|
|
2686
2933
|
// src/components/TagManagerPanel.tsx
|
|
2687
|
-
import { useState as
|
|
2934
|
+
import { useState as useState14 } from "react";
|
|
2688
2935
|
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2689
2936
|
function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
|
|
2690
2937
|
const categories = Object.keys(workspaceTags.by_category).filter(
|
|
2691
2938
|
(cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
|
|
2692
2939
|
);
|
|
2693
|
-
const [selectedCategory, setSelectedCategory] =
|
|
2940
|
+
const [selectedCategory, setSelectedCategory] = useState14(categories[0] || "");
|
|
2694
2941
|
const effectiveCategory = categories.includes(selectedCategory) ? selectedCategory : categories[0] || "";
|
|
2695
|
-
const [editingLabel, setEditingLabel] =
|
|
2696
|
-
const [editState, setEditState] =
|
|
2697
|
-
const [newTag, setNewTag] =
|
|
2698
|
-
const [movingLabel, setMovingLabel] =
|
|
2699
|
-
const [moveTarget, setMoveTarget] =
|
|
2942
|
+
const [editingLabel, setEditingLabel] = useState14(null);
|
|
2943
|
+
const [editState, setEditState] = useState14({ label: "", value: "" });
|
|
2944
|
+
const [newTag, setNewTag] = useState14({ label: "", value: "" });
|
|
2945
|
+
const [movingLabel, setMovingLabel] = useState14(null);
|
|
2946
|
+
const [moveTarget, setMoveTarget] = useState14("");
|
|
2700
2947
|
const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
|
|
2701
2948
|
const otherCategories = categories.filter((c) => c !== effectiveCategory);
|
|
2702
2949
|
const startEdit = (tag) => {
|
|
@@ -2891,10 +3138,449 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
|
|
|
2891
3138
|
] });
|
|
2892
3139
|
}
|
|
2893
3140
|
|
|
3141
|
+
// src/components/HFTestTab.tsx
|
|
3142
|
+
import { useState as useState15 } from "react";
|
|
3143
|
+
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3144
|
+
var HF_BASE = "https://huggingface.co";
|
|
3145
|
+
var HF_REPO = "RolandSch/fa-app-state";
|
|
3146
|
+
var TEST_DIR = "test";
|
|
3147
|
+
async function doFetch(label, url, init = {}) {
|
|
3148
|
+
const rawHeaders = init.headers || {};
|
|
3149
|
+
const sanitized = Object.fromEntries(
|
|
3150
|
+
Object.entries(rawHeaders).map(
|
|
3151
|
+
([k, v]) => k.toLowerCase() === "authorization" ? [k, v.replace(/Bearer\s+\S+/, (m) => "Bearer " + m.slice(7, 14) + "***")] : [k, v]
|
|
3152
|
+
)
|
|
3153
|
+
);
|
|
3154
|
+
const s = {
|
|
3155
|
+
label,
|
|
3156
|
+
method: init.method || "GET",
|
|
3157
|
+
url,
|
|
3158
|
+
reqHeaders: sanitized,
|
|
3159
|
+
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
|
|
3160
|
+
};
|
|
3161
|
+
const t0 = Date.now();
|
|
3162
|
+
try {
|
|
3163
|
+
const r = await fetch(url, init);
|
|
3164
|
+
s.durationMs = Date.now() - t0;
|
|
3165
|
+
s.resStatus = r.status;
|
|
3166
|
+
s.resStatusText = r.statusText;
|
|
3167
|
+
const body = await r.text().catch(() => "");
|
|
3168
|
+
s.resBody = body.length > 3e3 ? body.slice(0, 3e3) + "\n\u2026[truncated]" : body;
|
|
3169
|
+
s.ok = r.ok;
|
|
3170
|
+
} catch (e) {
|
|
3171
|
+
s.durationMs = Date.now() - t0;
|
|
3172
|
+
s.error = String(e?.message ?? e);
|
|
3173
|
+
s.ok = false;
|
|
3174
|
+
}
|
|
3175
|
+
return s;
|
|
3176
|
+
}
|
|
3177
|
+
function toBase64(bytes) {
|
|
3178
|
+
let bin = "";
|
|
3179
|
+
bytes.forEach((b) => bin += String.fromCharCode(b));
|
|
3180
|
+
return btoa(bin);
|
|
3181
|
+
}
|
|
3182
|
+
async function sha256hex(bytes) {
|
|
3183
|
+
const buf = await crypto.subtle.digest("SHA-256", bytes);
|
|
3184
|
+
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3185
|
+
}
|
|
3186
|
+
function b64ToBytes(b64) {
|
|
3187
|
+
const raw = b64.includes(",") ? b64.split(",")[1] : b64;
|
|
3188
|
+
const bin = atob(raw);
|
|
3189
|
+
const bytes = new Uint8Array(bin.length);
|
|
3190
|
+
for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
|
|
3191
|
+
return bytes;
|
|
3192
|
+
}
|
|
3193
|
+
function rawB64(dataUrl) {
|
|
3194
|
+
return dataUrl.includes(",") ? dataUrl.split(",")[1] : dataUrl;
|
|
3195
|
+
}
|
|
3196
|
+
async function uploadDirect(token, path, b64content) {
|
|
3197
|
+
const ndjson = [
|
|
3198
|
+
JSON.stringify({ key: "header", value: { summary: `HF Test: upload ${path}`, description: "" } }),
|
|
3199
|
+
JSON.stringify({ key: "file", value: { path, encoding: "base64", content: b64content } })
|
|
3200
|
+
].join("\n");
|
|
3201
|
+
return [await doFetch(
|
|
3202
|
+
"POST commit (direct, kein LFS)",
|
|
3203
|
+
`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`,
|
|
3204
|
+
{ method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" }, body: ndjson }
|
|
3205
|
+
)];
|
|
3206
|
+
}
|
|
3207
|
+
async function uploadLFS(token, path, bytes) {
|
|
3208
|
+
const oid = await sha256hex(bytes);
|
|
3209
|
+
const size = bytes.length;
|
|
3210
|
+
const sample = toBase64(bytes.slice(0, 512));
|
|
3211
|
+
const steps = [];
|
|
3212
|
+
const pre = await doFetch("Preupload (LFS-URL anfordern)", `${HF_BASE}/api/datasets/${HF_REPO}/preupload/main`, {
|
|
3213
|
+
method: "POST",
|
|
3214
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
3215
|
+
body: JSON.stringify({ files: [{ path, size, sample }] })
|
|
3216
|
+
});
|
|
3217
|
+
steps.push(pre);
|
|
3218
|
+
if (!pre.ok) return steps;
|
|
3219
|
+
let fi;
|
|
3220
|
+
try {
|
|
3221
|
+
fi = JSON.parse(pre.resBody || "{}").files?.[0];
|
|
3222
|
+
} catch {
|
|
3223
|
+
}
|
|
3224
|
+
if (!fi) {
|
|
3225
|
+
steps.push({ label: "Parse", method: "-", url: "-", reqHeaders: {}, resBody: "Kein files[0] in preupload response", ok: false });
|
|
3226
|
+
return steps;
|
|
3227
|
+
}
|
|
3228
|
+
if (fi.uploadMode === "lfs" && fi.uploadUrl) {
|
|
3229
|
+
const up = await doFetch("PUT to LFS upload URL", fi.uploadUrl, {
|
|
3230
|
+
method: "PUT",
|
|
3231
|
+
headers: { "Content-Type": "application/octet-stream", ...fi.header || {} },
|
|
3232
|
+
body: bytes
|
|
3233
|
+
});
|
|
3234
|
+
steps.push(up);
|
|
3235
|
+
if (!up.ok) return steps;
|
|
3236
|
+
if (fi.verifyUrl) {
|
|
3237
|
+
const ver = await doFetch("POST LFS verify", fi.verifyUrl, {
|
|
3238
|
+
method: "POST",
|
|
3239
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", ...fi.verifyHeader || {} },
|
|
3240
|
+
body: JSON.stringify({ oid, size })
|
|
3241
|
+
});
|
|
3242
|
+
steps.push(ver);
|
|
3243
|
+
if (!ver.ok) return steps;
|
|
3244
|
+
}
|
|
3245
|
+
} else {
|
|
3246
|
+
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 });
|
|
3247
|
+
}
|
|
3248
|
+
const ndjson = [
|
|
3249
|
+
JSON.stringify({ key: "header", value: { summary: `HF Test: LFS commit ${path}`, description: "" } }),
|
|
3250
|
+
JSON.stringify({ key: "lfsFile", value: { path, algo: "sha256", oid, size } })
|
|
3251
|
+
].join("\n");
|
|
3252
|
+
steps.push(await doFetch("Commit (lfsFile reference)", `${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
|
|
3253
|
+
method: "POST",
|
|
3254
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" },
|
|
3255
|
+
body: ndjson
|
|
3256
|
+
}));
|
|
3257
|
+
return steps;
|
|
3258
|
+
}
|
|
3259
|
+
async function uploadViaHubLib(token, path, bytes, mimeType) {
|
|
3260
|
+
const s = { label: "uploadFile() via @huggingface/hub", method: "import()+call", url: "@huggingface/hub", reqHeaders: {} };
|
|
3261
|
+
const t0 = Date.now();
|
|
3262
|
+
try {
|
|
3263
|
+
const { uploadFile } = await import(
|
|
3264
|
+
/* @vite-ignore */
|
|
3265
|
+
"@huggingface/hub"
|
|
3266
|
+
);
|
|
3267
|
+
await uploadFile({
|
|
3268
|
+
repo: { type: "dataset", name: HF_REPO },
|
|
3269
|
+
credentials: { accessToken: token },
|
|
3270
|
+
file: { path, content: new Blob([bytes], { type: mimeType }) },
|
|
3271
|
+
branch: "main",
|
|
3272
|
+
commitTitle: `HF Test: hub lib upload ${path}`
|
|
3273
|
+
});
|
|
3274
|
+
s.durationMs = Date.now() - t0;
|
|
3275
|
+
s.resBody = "SUCCESS";
|
|
3276
|
+
s.ok = true;
|
|
3277
|
+
} catch (e) {
|
|
3278
|
+
s.durationMs = Date.now() - t0;
|
|
3279
|
+
s.error = String(e?.message ?? e);
|
|
3280
|
+
s.ok = false;
|
|
3281
|
+
}
|
|
3282
|
+
return [s];
|
|
3283
|
+
}
|
|
3284
|
+
async function uploadViaCdnLib(token, path, bytes, mimeType) {
|
|
3285
|
+
const s = { label: "uploadFile() via esm.sh/@huggingface/hub", method: "import()+call", url: "https://esm.sh/@huggingface/hub", reqHeaders: {} };
|
|
3286
|
+
const t0 = Date.now();
|
|
3287
|
+
try {
|
|
3288
|
+
const { uploadFile } = await import(
|
|
3289
|
+
/* @vite-ignore */
|
|
3290
|
+
"https://esm.sh/@huggingface/hub"
|
|
3291
|
+
);
|
|
3292
|
+
await uploadFile({
|
|
3293
|
+
repo: { type: "dataset", name: HF_REPO },
|
|
3294
|
+
credentials: { accessToken: token },
|
|
3295
|
+
file: { path, content: new Blob([bytes], { type: mimeType }) },
|
|
3296
|
+
branch: "main",
|
|
3297
|
+
commitTitle: `HF Test: CDN hub lib upload ${path}`
|
|
3298
|
+
});
|
|
3299
|
+
s.durationMs = Date.now() - t0;
|
|
3300
|
+
s.resBody = "SUCCESS";
|
|
3301
|
+
s.ok = true;
|
|
3302
|
+
} catch (e) {
|
|
3303
|
+
s.durationMs = Date.now() - t0;
|
|
3304
|
+
s.error = String(e?.message ?? e);
|
|
3305
|
+
s.ok = false;
|
|
3306
|
+
}
|
|
3307
|
+
return [s];
|
|
3308
|
+
}
|
|
3309
|
+
async function writeEvent(token, namespace) {
|
|
3310
|
+
const ns = namespace.endsWith("/") ? namespace : namespace ? namespace + "/" : "";
|
|
3311
|
+
const ts = Date.now();
|
|
3312
|
+
const uuid = crypto.randomUUID().slice(0, 8);
|
|
3313
|
+
const isoTs = new Date(ts).toISOString().replace(/:/g, "-").replace(".", "-");
|
|
3314
|
+
const eventPath = `${ns}${TEST_DIR}/events/${isoTs}_${uuid}.json`;
|
|
3315
|
+
const event = JSON.stringify({ v: { major: 1, minor: 0 }, type: "probe", ts, prevTs: [], clientId: "hf-test-tab", payload: { test: true } }, null, 2);
|
|
3316
|
+
const b64 = toBase64(new TextEncoder().encode(event));
|
|
3317
|
+
const ndjson = [
|
|
3318
|
+
JSON.stringify({ key: "header", value: { summary: "HF Test: write event", description: "" } }),
|
|
3319
|
+
JSON.stringify({ key: "file", value: { path: eventPath, encoding: "base64", content: b64 } })
|
|
3320
|
+
].join("\n");
|
|
3321
|
+
return [await doFetch(
|
|
3322
|
+
`Event \u2192 ${eventPath}`,
|
|
3323
|
+
`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`,
|
|
3324
|
+
{ method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" }, body: ndjson }
|
|
3325
|
+
)];
|
|
3326
|
+
}
|
|
3327
|
+
function tryFmt(s) {
|
|
3328
|
+
try {
|
|
3329
|
+
return JSON.stringify(JSON.parse(s), null, 2);
|
|
3330
|
+
} catch {
|
|
3331
|
+
return s;
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
function CopyBtn({ text }) {
|
|
3335
|
+
const [done, setDone] = useState15(false);
|
|
3336
|
+
return /* @__PURE__ */ jsxs18(
|
|
3337
|
+
"button",
|
|
3338
|
+
{
|
|
3339
|
+
onClick: () => {
|
|
3340
|
+
navigator.clipboard?.writeText(text).catch(() => {
|
|
3341
|
+
});
|
|
3342
|
+
setDone(true);
|
|
3343
|
+
setTimeout(() => setDone(false), 1500);
|
|
3344
|
+
},
|
|
3345
|
+
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 },
|
|
3346
|
+
children: [
|
|
3347
|
+
/* @__PURE__ */ jsx20("span", { className: "material-symbols-outlined", style: { fontSize: 11 }, children: done ? "check" : "content_copy" }),
|
|
3348
|
+
done ? "Kopiert" : "Copy"
|
|
3349
|
+
]
|
|
3350
|
+
}
|
|
3351
|
+
);
|
|
3352
|
+
}
|
|
3353
|
+
function StepView({ step }) {
|
|
3354
|
+
const isSpecial = step.method === "-" || step.method === "import()" || step.method === "import()+call";
|
|
3355
|
+
return /* @__PURE__ */ jsxs18("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: [
|
|
3356
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 4 }, children: [
|
|
3357
|
+
/* @__PURE__ */ jsx20("span", { style: { fontSize: 11, fontWeight: 700, color: step.ok === false ? "#f87171" : "#4ade80" }, children: step.ok === false ? "\u2717" : "\u2713" }),
|
|
3358
|
+
/* @__PURE__ */ jsx20("span", { style: { fontSize: 11, fontWeight: 600, color: "rgba(255,255,255,0.7)", flex: 1 }, children: step.label }),
|
|
3359
|
+
step.durationMs !== void 0 && /* @__PURE__ */ jsxs18("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
|
|
3360
|
+
step.durationMs,
|
|
3361
|
+
"ms"
|
|
3362
|
+
] }),
|
|
3363
|
+
/* @__PURE__ */ jsx20(CopyBtn, { text: JSON.stringify(step, null, 2) })
|
|
3364
|
+
] }),
|
|
3365
|
+
!isSpecial && /* @__PURE__ */ jsxs18("div", { style: { marginBottom: 5 }, children: [
|
|
3366
|
+
/* @__PURE__ */ jsxs18("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginBottom: 2 }, children: [
|
|
3367
|
+
"\u2192 ",
|
|
3368
|
+
step.method,
|
|
3369
|
+
" ",
|
|
3370
|
+
step.url
|
|
3371
|
+
] }),
|
|
3372
|
+
Object.keys(step.reqHeaders).length > 0 && /* @__PURE__ */ jsx20("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") }),
|
|
3373
|
+
step.reqBody && /* @__PURE__ */ jsx20("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 })
|
|
3374
|
+
] }),
|
|
3375
|
+
step.error && /* @__PURE__ */ jsx20("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 }),
|
|
3376
|
+
!step.error && (step.resStatus !== void 0 || step.resBody) && /* @__PURE__ */ jsxs18("div", { children: [
|
|
3377
|
+
step.resStatus !== void 0 && /* @__PURE__ */ jsxs18("div", { style: { fontSize: 11, fontWeight: 700, color: (step.resStatus || 0) < 300 ? "#4ade80" : "#f87171", marginBottom: 3 }, children: [
|
|
3378
|
+
"\u2190 ",
|
|
3379
|
+
step.resStatus,
|
|
3380
|
+
" ",
|
|
3381
|
+
step.resStatusText
|
|
3382
|
+
] }),
|
|
3383
|
+
step.resBody && /* @__PURE__ */ jsx20("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) })
|
|
3384
|
+
] })
|
|
3385
|
+
] });
|
|
3386
|
+
}
|
|
3387
|
+
function TestCard({
|
|
3388
|
+
id,
|
|
3389
|
+
label,
|
|
3390
|
+
icon,
|
|
3391
|
+
desc,
|
|
3392
|
+
disabled,
|
|
3393
|
+
state,
|
|
3394
|
+
onRun,
|
|
3395
|
+
expanded,
|
|
3396
|
+
onToggle
|
|
3397
|
+
}) {
|
|
3398
|
+
const hasResult = state && state.status !== "idle";
|
|
3399
|
+
return /* @__PURE__ */ jsxs18("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: [
|
|
3400
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "9px 10px" }, children: [
|
|
3401
|
+
/* @__PURE__ */ jsx20("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 }),
|
|
3402
|
+
/* @__PURE__ */ jsxs18("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
3403
|
+
/* @__PURE__ */ jsx20("div", { style: { fontSize: 13, fontWeight: 700, color: "#fff" }, children: label }),
|
|
3404
|
+
/* @__PURE__ */ jsx20("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: desc })
|
|
3405
|
+
] }),
|
|
3406
|
+
hasResult && state?.status !== "running" && /* @__PURE__ */ jsx20("button", { onClick: onToggle, style: { background: "none", border: "none", color: "rgba(255,255,255,0.3)", cursor: "pointer", padding: 2, lineHeight: 0 }, children: /* @__PURE__ */ jsx20("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: expanded ? "expand_less" : "expand_more" }) }),
|
|
3407
|
+
/* @__PURE__ */ jsx20(
|
|
3408
|
+
"button",
|
|
3409
|
+
{
|
|
3410
|
+
onClick: onRun,
|
|
3411
|
+
disabled,
|
|
3412
|
+
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 },
|
|
3413
|
+
children: state?.status === "running" ? "\u2026" : "Run"
|
|
3414
|
+
}
|
|
3415
|
+
)
|
|
3416
|
+
] }),
|
|
3417
|
+
hasResult && /* @__PURE__ */ jsxs18("div", { style: { borderTop: "1px solid rgba(255,255,255,0.05)" }, children: [
|
|
3418
|
+
/* @__PURE__ */ jsxs18("div", { style: { padding: "4px 10px 5px", display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
3419
|
+
/* @__PURE__ */ jsx20("span", { style: { fontSize: 11, fontWeight: 700, color: state.status === "ok" ? "#4ade80" : "#f87171" }, children: state.status === "ok" ? "\u2713 OK" : state.status === "running" ? "\u2026" : "\u2717 Fehler" }),
|
|
3420
|
+
/* @__PURE__ */ jsxs18("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)" }, children: [
|
|
3421
|
+
state.totalMs,
|
|
3422
|
+
"ms \xB7 ",
|
|
3423
|
+
state.steps.length,
|
|
3424
|
+
" Step",
|
|
3425
|
+
state.steps.length !== 1 ? "s" : ""
|
|
3426
|
+
] }),
|
|
3427
|
+
/* @__PURE__ */ jsx20("div", { style: { flex: 1 } }),
|
|
3428
|
+
/* @__PURE__ */ jsx20(CopyBtn, { text: JSON.stringify(state, null, 2) })
|
|
3429
|
+
] }),
|
|
3430
|
+
expanded && state.steps.map((step, i) => /* @__PURE__ */ jsx20("div", { style: { padding: "0 10px 4px" }, children: /* @__PURE__ */ jsx20(StepView, { step }) }, i))
|
|
3431
|
+
] })
|
|
3432
|
+
] });
|
|
3433
|
+
}
|
|
3434
|
+
function HFTestTab({ token, namespace, galleryItems }) {
|
|
3435
|
+
const [selected, setSelected] = useState15(null);
|
|
3436
|
+
const [results, setResults] = useState15({});
|
|
3437
|
+
const [expanded, setExpanded] = useState15({});
|
|
3438
|
+
const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
|
|
3439
|
+
const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
|
|
3440
|
+
const setDone = (id, steps, t0) => {
|
|
3441
|
+
const ok = steps.length > 0 && steps.every((s) => s.ok !== false);
|
|
3442
|
+
setResults((r) => ({ ...r, [id]: { status: ok ? "ok" : "error", steps, totalMs: Date.now() - t0 } }));
|
|
3443
|
+
setExpanded((e) => ({ ...e, [id]: true }));
|
|
3444
|
+
};
|
|
3445
|
+
const run = async (id) => {
|
|
3446
|
+
const isImgTest = id !== "event";
|
|
3447
|
+
if (isImgTest && !selected?.base64) return;
|
|
3448
|
+
setRunning(id);
|
|
3449
|
+
const t0 = Date.now();
|
|
3450
|
+
let steps = [];
|
|
3451
|
+
try {
|
|
3452
|
+
if (isImgTest) {
|
|
3453
|
+
const bytes = b64ToBytes(selected.base64);
|
|
3454
|
+
const imgPath = `${TEST_DIR}/${selected.id}.jpg`;
|
|
3455
|
+
switch (id) {
|
|
3456
|
+
case "img-direct":
|
|
3457
|
+
steps = await uploadDirect(token, imgPath, rawB64(selected.base64));
|
|
3458
|
+
break;
|
|
3459
|
+
case "img-lfs":
|
|
3460
|
+
steps = await uploadLFS(token, imgPath, bytes);
|
|
3461
|
+
break;
|
|
3462
|
+
case "img-hub":
|
|
3463
|
+
steps = await uploadViaHubLib(token, imgPath, bytes, "image/jpeg");
|
|
3464
|
+
break;
|
|
3465
|
+
case "img-cdn":
|
|
3466
|
+
steps = await uploadViaCdnLib(token, imgPath, bytes, "image/jpeg");
|
|
3467
|
+
break;
|
|
3468
|
+
}
|
|
3469
|
+
} else {
|
|
3470
|
+
steps = await writeEvent(token, namespace);
|
|
3471
|
+
}
|
|
3472
|
+
} catch (e) {
|
|
3473
|
+
steps = [{ label: "Unexpected error", method: "-", url: "-", reqHeaders: {}, error: String(e?.message ?? e), ok: false }];
|
|
3474
|
+
}
|
|
3475
|
+
setDone(id, steps, t0);
|
|
3476
|
+
};
|
|
3477
|
+
const noToken = !token;
|
|
3478
|
+
const noImg = !selected;
|
|
3479
|
+
const imgTests = [
|
|
3480
|
+
{ id: "img-direct", label: "Upload Direct", icon: "upload_file", desc: "POST commit + file+base64 (kein LFS)" },
|
|
3481
|
+
{ id: "img-lfs", label: "Upload LFS", icon: "cloud_upload", desc: "preupload \u2192 PUT LFS \u2192 verify \u2192 commit" },
|
|
3482
|
+
{ id: "img-hub", label: "Upload hub lib", icon: "package_2", desc: "uploadFile() via @huggingface/hub" },
|
|
3483
|
+
{ id: "img-cdn", label: "Upload CDN lib", icon: "language", desc: "uploadFile() via esm.sh hub lib" }
|
|
3484
|
+
];
|
|
3485
|
+
return /* @__PURE__ */ jsxs18("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflowY: "auto", padding: "12px 10px 80px", boxSizing: "border-box", fontFamily: "inherit" }, children: [
|
|
3486
|
+
noToken && /* @__PURE__ */ jsx20("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." }),
|
|
3487
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginBottom: 14 }, children: [
|
|
3488
|
+
/* @__PURE__ */ jsxs18("div", { style: { fontSize: 10, fontWeight: 700, color: "rgba(255,255,255,0.3)", textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 8 }, children: [
|
|
3489
|
+
"Bild ausw\xE4hlen (",
|
|
3490
|
+
withResults.length,
|
|
3491
|
+
" verf\xFCgbar)"
|
|
3492
|
+
] }),
|
|
3493
|
+
withResults.length === 0 ? /* @__PURE__ */ jsx20("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__ */ jsx20("div", { style: { display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 6 }, children: withResults.slice(0, 12).map((g) => /* @__PURE__ */ jsx20(
|
|
3494
|
+
"button",
|
|
3495
|
+
{
|
|
3496
|
+
onClick: () => setSelected(g),
|
|
3497
|
+
style: { padding: 0, border: `2px solid ${selected?.id === g.id ? "#0284c7" : "transparent"}`, borderRadius: 6, cursor: "pointer", overflow: "hidden", background: "none", lineHeight: 0 },
|
|
3498
|
+
children: /* @__PURE__ */ jsx20(
|
|
3499
|
+
"img",
|
|
3500
|
+
{
|
|
3501
|
+
src: g.base64,
|
|
3502
|
+
alt: g.prompt || g.id,
|
|
3503
|
+
style: { width: "100%", aspectRatio: "1", objectFit: "cover", display: "block", borderRadius: 4 }
|
|
3504
|
+
}
|
|
3505
|
+
)
|
|
3506
|
+
},
|
|
3507
|
+
g.id
|
|
3508
|
+
)) }),
|
|
3509
|
+
selected && /* @__PURE__ */ jsxs18("div", { style: { marginTop: 10, display: "flex", gap: 10, alignItems: "flex-start" }, children: [
|
|
3510
|
+
/* @__PURE__ */ jsx20(
|
|
3511
|
+
"img",
|
|
3512
|
+
{
|
|
3513
|
+
src: selected.base64,
|
|
3514
|
+
style: { width: 80, height: 80, objectFit: "cover", borderRadius: 8, border: "1px solid rgba(255,255,255,0.1)", flexShrink: 0 }
|
|
3515
|
+
}
|
|
3516
|
+
),
|
|
3517
|
+
/* @__PURE__ */ jsxs18("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
3518
|
+
/* @__PURE__ */ jsx20("div", { style: { fontSize: 11, fontWeight: 700, color: "rgba(255,255,255,0.7)", marginBottom: 2 }, children: "Ausgew\xE4hlt" }),
|
|
3519
|
+
/* @__PURE__ */ jsxs18("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", wordBreak: "break-all" }, children: [
|
|
3520
|
+
"ID: ",
|
|
3521
|
+
selected.id
|
|
3522
|
+
] }),
|
|
3523
|
+
/* @__PURE__ */ jsxs18("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.3)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginTop: 2 }, children: [
|
|
3524
|
+
"Ziel: test/",
|
|
3525
|
+
selected.id,
|
|
3526
|
+
".jpg"
|
|
3527
|
+
] }),
|
|
3528
|
+
selected.prompt && /* @__PURE__ */ jsx20("div", { style: { fontSize: 10, color: "rgba(255,255,255,0.25)", marginTop: 2, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selected.prompt })
|
|
3529
|
+
] })
|
|
3530
|
+
] })
|
|
3531
|
+
] }),
|
|
3532
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginBottom: 18 }, children: [
|
|
3533
|
+
/* @__PURE__ */ jsxs18("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: [
|
|
3534
|
+
"Bild hochladen \u2192 test/",
|
|
3535
|
+
"{",
|
|
3536
|
+
"id",
|
|
3537
|
+
"}",
|
|
3538
|
+
".jpg"
|
|
3539
|
+
] }),
|
|
3540
|
+
imgTests.map((t) => /* @__PURE__ */ jsx20(
|
|
3541
|
+
TestCard,
|
|
3542
|
+
{
|
|
3543
|
+
id: t.id,
|
|
3544
|
+
label: t.label,
|
|
3545
|
+
icon: t.icon,
|
|
3546
|
+
desc: t.desc,
|
|
3547
|
+
disabled: noToken || noImg || results[t.id]?.status === "running",
|
|
3548
|
+
state: results[t.id],
|
|
3549
|
+
onRun: () => run(t.id),
|
|
3550
|
+
expanded: !!expanded[t.id],
|
|
3551
|
+
onToggle: () => setExpanded((e) => ({ ...e, [t.id]: !e[t.id] }))
|
|
3552
|
+
},
|
|
3553
|
+
t.id
|
|
3554
|
+
))
|
|
3555
|
+
] }),
|
|
3556
|
+
/* @__PURE__ */ jsxs18("div", { children: [
|
|
3557
|
+
/* @__PURE__ */ jsxs18("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: [
|
|
3558
|
+
"Event schreiben \u2192 ",
|
|
3559
|
+
namespace || "(kein namespace)",
|
|
3560
|
+
"test/events/"
|
|
3561
|
+
] }),
|
|
3562
|
+
/* @__PURE__ */ jsx20(
|
|
3563
|
+
TestCard,
|
|
3564
|
+
{
|
|
3565
|
+
id: "event",
|
|
3566
|
+
label: "Write Event",
|
|
3567
|
+
icon: "bolt",
|
|
3568
|
+
desc: "Kleines JSON-Event hochladen (direct commit)",
|
|
3569
|
+
disabled: noToken || results["event"]?.status === "running",
|
|
3570
|
+
state: results["event"],
|
|
3571
|
+
onRun: () => run("event"),
|
|
3572
|
+
expanded: !!expanded["event"],
|
|
3573
|
+
onToggle: () => setExpanded((e) => ({ ...e, event: !e.event }))
|
|
3574
|
+
}
|
|
3575
|
+
)
|
|
3576
|
+
] })
|
|
3577
|
+
] });
|
|
3578
|
+
}
|
|
3579
|
+
|
|
2894
3580
|
// src/components/AvatarArchitectApp.tsx
|
|
2895
|
-
import { Fragment as Fragment9, jsx as
|
|
2896
|
-
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
2897
|
-
|
|
3581
|
+
import { Fragment as Fragment9, jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3582
|
+
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
3583
|
+
useEffect6(() => {
|
|
2898
3584
|
const id = "flow-styles";
|
|
2899
3585
|
if (!document.getElementById(id)) {
|
|
2900
3586
|
const style = document.createElement("style");
|
|
@@ -2903,22 +3589,92 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2903
3589
|
document.head.appendChild(style);
|
|
2904
3590
|
}
|
|
2905
3591
|
}, []);
|
|
2906
|
-
const [showStart, setShowStart] =
|
|
2907
|
-
const [layoutChoice, setLayoutChoice] =
|
|
3592
|
+
const [showStart, setShowStart] = useState16(true);
|
|
3593
|
+
const [layoutChoice, setLayoutChoice] = useState16(() => {
|
|
2908
3594
|
try {
|
|
2909
3595
|
return localStorage.getItem("aa-layout") || null;
|
|
2910
3596
|
} catch {
|
|
2911
3597
|
return null;
|
|
2912
3598
|
}
|
|
2913
3599
|
});
|
|
2914
|
-
const [projectLoaded, setProjectLoaded] =
|
|
2915
|
-
const [hfToken, setHfToken] =
|
|
2916
|
-
const [hfTokenInput, setHfTokenInput] =
|
|
2917
|
-
const [isLoadingFromHF, setIsLoadingFromHF] =
|
|
2918
|
-
const [
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
3600
|
+
const [projectLoaded, setProjectLoaded] = useState16(false);
|
|
3601
|
+
const [hfToken, setHfToken] = useState16(initialHfToken || "");
|
|
3602
|
+
const [hfTokenInput, setHfTokenInput] = useState16(initialHfToken || "");
|
|
3603
|
+
const [isLoadingFromHF, setIsLoadingFromHF] = useState16(false);
|
|
3604
|
+
const [hfNamespaceLocal, setHfNamespaceLocal] = useState16(() => {
|
|
3605
|
+
try {
|
|
3606
|
+
const stored = localStorage.getItem("aa-hf-namespace");
|
|
3607
|
+
if (stored !== null) return stored;
|
|
3608
|
+
return allowDevNamespace ? "app.art-by-rolands.de/" : "";
|
|
3609
|
+
} catch {
|
|
3610
|
+
return "";
|
|
3611
|
+
}
|
|
3612
|
+
});
|
|
3613
|
+
const [hfNamespaceFromServer, setHfNamespaceFromServer] = useState16(null);
|
|
3614
|
+
useEffect6(() => {
|
|
3615
|
+
if (hfNamespace !== void 0) return;
|
|
3616
|
+
const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
|
|
3617
|
+
if (!backendUrl) return;
|
|
3618
|
+
fetch(`${backendUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
3619
|
+
if (typeof d.hfNamespace === "string" && d.hfNamespace) setHfNamespaceFromServer(d.hfNamespace);
|
|
3620
|
+
}).catch(() => {
|
|
3621
|
+
});
|
|
3622
|
+
}, [hfNamespace]);
|
|
3623
|
+
const effectiveNamespace = hfNamespace ?? hfNamespaceFromServer ?? hfNamespaceLocal;
|
|
3624
|
+
const {
|
|
3625
|
+
state: hfState,
|
|
3626
|
+
isLoading: isHfRefreshing,
|
|
3627
|
+
pendingBufferCount,
|
|
3628
|
+
eventCount,
|
|
3629
|
+
writeEvent: hfWriteEvent,
|
|
3630
|
+
refresh: refreshHF,
|
|
3631
|
+
hasStateZip
|
|
3632
|
+
} = useHFState(hfToken, effectiveNamespace);
|
|
3633
|
+
const [bootstrapLog, setBootstrapLog] = useState16([]);
|
|
3634
|
+
const [isBootstrapping, setIsBootstrapping] = useState16(false);
|
|
3635
|
+
const syncTopSlot = /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
3636
|
+
pendingBufferCount > 0 && /* @__PURE__ */ jsxs19("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
|
|
3637
|
+
pendingBufferCount,
|
|
3638
|
+
" \xC4nderung",
|
|
3639
|
+
pendingBufferCount > 1 ? "en" : "",
|
|
3640
|
+
" lokal \u2014 bei Flow-Reload verloren wenn nicht synchronisiert"
|
|
3641
|
+
] }),
|
|
3642
|
+
eventCount > 100 && /* @__PURE__ */ jsxs19("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
|
|
3643
|
+
"\u26A0 ",
|
|
3644
|
+
eventCount,
|
|
3645
|
+
" Events nicht konsolidiert \u2014 Konsolidierung dringend empfohlen"
|
|
3646
|
+
] }),
|
|
3647
|
+
eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ jsxs19("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
|
|
3648
|
+
eventCount,
|
|
3649
|
+
" Events seit letzter Konsolidierung \u2014 Konsolidierung empfohlen"
|
|
3650
|
+
] }),
|
|
3651
|
+
hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ jsxs19("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
|
|
3652
|
+
/* @__PURE__ */ jsx21("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" }),
|
|
3653
|
+
/* @__PURE__ */ jsx21(
|
|
3654
|
+
"button",
|
|
3655
|
+
{
|
|
3656
|
+
disabled: isBootstrapping || !effectiveNamespace,
|
|
3657
|
+
onClick: async () => {
|
|
3658
|
+
setIsBootstrapping(true);
|
|
3659
|
+
setBootstrapLog([]);
|
|
3660
|
+
try {
|
|
3661
|
+
await hfBootstrapFromLegacy(effectiveNamespace, hfToken, (msg) => setBootstrapLog((prev) => [...prev, msg]));
|
|
3662
|
+
setBootstrapLog((prev) => [...prev, "\u2713 Fertig"]);
|
|
3663
|
+
setTimeout(() => refreshHF(), 1500);
|
|
3664
|
+
} catch (e) {
|
|
3665
|
+
setBootstrapLog((prev) => [...prev, `Fehler: ${e.message}`]);
|
|
3666
|
+
} finally {
|
|
3667
|
+
setIsBootstrapping(false);
|
|
3668
|
+
}
|
|
3669
|
+
},
|
|
3670
|
+
style: { padding: "5px 12px", background: "#0ea5e9", color: "#fff", border: "none", borderRadius: 4, cursor: isBootstrapping || !effectiveNamespace ? "not-allowed" : "pointer", fontSize: 11, fontWeight: 600, opacity: isBootstrapping || !effectiveNamespace ? 0.6 : 1 },
|
|
3671
|
+
children: isBootstrapping ? "Migriere\u2026" : "Legacy-Migration starten"
|
|
3672
|
+
}
|
|
3673
|
+
),
|
|
3674
|
+
bootstrapLog.length > 0 && /* @__PURE__ */ jsx21("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ jsx21("div", { children: l }, i)) })
|
|
3675
|
+
] })
|
|
3676
|
+
] });
|
|
3677
|
+
const wsInputRef = useRef7(null);
|
|
2922
3678
|
const startApp = (choice) => {
|
|
2923
3679
|
try {
|
|
2924
3680
|
localStorage.setItem("aa-layout", choice);
|
|
@@ -2927,70 +3683,110 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2927
3683
|
setLayoutChoice(choice);
|
|
2928
3684
|
setShowStart(false);
|
|
2929
3685
|
};
|
|
2930
|
-
const [nodes, setNodes] =
|
|
2931
|
-
const [edges, setEdges] =
|
|
2932
|
-
const [history, setHistory] =
|
|
2933
|
-
const [galleryItems, setGalleryItems] =
|
|
2934
|
-
const galleryItemsRef =
|
|
2935
|
-
|
|
3686
|
+
const [nodes, setNodes] = useState16([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
|
|
3687
|
+
const [edges, setEdges] = useState16([]);
|
|
3688
|
+
const [history, setHistory] = useState16([]);
|
|
3689
|
+
const [galleryItems, setGalleryItems] = useState16([]);
|
|
3690
|
+
const galleryItemsRef = useRef7([]);
|
|
3691
|
+
useEffect6(() => {
|
|
2936
3692
|
galleryItemsRef.current = galleryItems;
|
|
2937
3693
|
}, [galleryItems]);
|
|
2938
|
-
const
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
3694
|
+
const hfImageNotFoundRef = useRef7(/* @__PURE__ */ new Set());
|
|
3695
|
+
useEffect6(() => {
|
|
3696
|
+
if (!hfState) return;
|
|
3697
|
+
if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
|
|
3698
|
+
const hfIds = new Set(hfState.metadata.map((m) => m.id));
|
|
3699
|
+
const skeletons = hfState.metadata.map((m) => ({
|
|
3700
|
+
id: m.id,
|
|
3701
|
+
nodeId: m.id,
|
|
3702
|
+
prompt: m.prompt,
|
|
3703
|
+
seed: m.seed,
|
|
3704
|
+
model: m.model,
|
|
3705
|
+
tags: m.tags || [],
|
|
3706
|
+
timestamp: m.timestamp,
|
|
3707
|
+
status: "done"
|
|
3708
|
+
}));
|
|
3709
|
+
setGalleryItems((prev) => {
|
|
3710
|
+
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
3711
|
+
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
3712
|
+
return [...localOnly, ...merged];
|
|
3713
|
+
});
|
|
3714
|
+
setHistory((prev) => {
|
|
3715
|
+
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
3716
|
+
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
3717
|
+
return [...localOnly, ...merged];
|
|
3718
|
+
});
|
|
3719
|
+
for (const entry of hfState.metadata) {
|
|
3720
|
+
if (hfImageNotFoundRef.current.has(entry.id)) continue;
|
|
3721
|
+
hfLoadImageAsBase64(entry.id, hfToken).then((b64) => {
|
|
3722
|
+
if (!b64) {
|
|
3723
|
+
hfImageNotFoundRef.current.add(entry.id);
|
|
3724
|
+
return;
|
|
3725
|
+
}
|
|
3726
|
+
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
3727
|
+
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
3728
|
+
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
3729
|
+
}).catch(() => {
|
|
3730
|
+
hfImageNotFoundRef.current.add(entry.id);
|
|
3731
|
+
});
|
|
3732
|
+
}
|
|
3733
|
+
}, [hfState]);
|
|
3734
|
+
const [activePrompt, setActivePrompt] = useState16("");
|
|
3735
|
+
const [isSynthesizing, setIsSynthesizing] = useState16(false);
|
|
3736
|
+
const [activeGenerationsCount, setActiveGenerationsCount] = useState16(0);
|
|
3737
|
+
const [currentResult, setCurrentResult] = useState16(null);
|
|
3738
|
+
const [focusedNodeId, setFocusedNodeId] = useState16(null);
|
|
3739
|
+
const [leftTab, setLeftTab] = useState16("prompt");
|
|
3740
|
+
const [promptFeedback, setPromptFeedback] = useState16(null);
|
|
3741
|
+
const [lastPromptPayload, setLastPromptPayload] = useState16(null);
|
|
3742
|
+
const [isPromptTabGenerating, setIsPromptTabGenerating] = useState16(false);
|
|
3743
|
+
const [activeTab, setActiveTab] = useState16("history");
|
|
3744
|
+
const [mobileTab, setMobileTab] = useState16("stage");
|
|
3745
|
+
const [middlePanel, setMiddlePanel] = useState16("stage");
|
|
3746
|
+
const [recentLabItems, setRecentLabItems] = useState16([]);
|
|
3747
|
+
const [aspectRatio, setAspectRatio] = useState16("1:1");
|
|
3748
|
+
const [selectedModel, setSelectedModel] = useState16("\u{1F34C} Nano Banana Pro");
|
|
3749
|
+
const [seed, setSeed] = useState16(Math.floor(Math.random() * 1e6));
|
|
3750
|
+
const [seedMode, setSeedMode] = useState16("random");
|
|
3751
|
+
const [isLeftCollapsed, setIsLeftCollapsed] = useState16(false);
|
|
3752
|
+
const [isRightCollapsed, setIsRightCollapsed] = useState16(false);
|
|
3753
|
+
const [leftPanelWidth, setLeftPanelWidth] = useState16(() => {
|
|
2958
3754
|
try {
|
|
2959
3755
|
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
2960
3756
|
} catch {
|
|
2961
3757
|
return 260;
|
|
2962
3758
|
}
|
|
2963
3759
|
});
|
|
2964
|
-
const [rightPanelWidth, setRightPanelWidth] =
|
|
3760
|
+
const [rightPanelWidth, setRightPanelWidth] = useState16(() => {
|
|
2965
3761
|
try {
|
|
2966
3762
|
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
2967
3763
|
} catch {
|
|
2968
3764
|
return 320;
|
|
2969
3765
|
}
|
|
2970
3766
|
});
|
|
2971
|
-
const [isPromptCollapsed, setIsPromptCollapsed] =
|
|
2972
|
-
const [projectActionState, setProjectActionState] =
|
|
2973
|
-
const syncServerDataRef =
|
|
2974
|
-
const [workspaceTags, setWorkspaceTags] =
|
|
2975
|
-
const [serverProjects, setServerProjects] =
|
|
2976
|
-
const [isLoadingFromServer, setIsLoadingFromServer] =
|
|
2977
|
-
const [highContrast, setHighContrast] =
|
|
3767
|
+
const [isPromptCollapsed, setIsPromptCollapsed] = useState16(false);
|
|
3768
|
+
const [projectActionState, setProjectActionState] = useState16("idle");
|
|
3769
|
+
const syncServerDataRef = useRef7(null);
|
|
3770
|
+
const [workspaceTags, setWorkspaceTags] = useState16(null);
|
|
3771
|
+
const [serverProjects, setServerProjects] = useState16([]);
|
|
3772
|
+
const [isLoadingFromServer, setIsLoadingFromServer] = useState16(false);
|
|
3773
|
+
const [highContrast, setHighContrast] = useState16(() => {
|
|
2978
3774
|
try {
|
|
2979
3775
|
return localStorage.getItem("aa-contrast") === "high";
|
|
2980
3776
|
} catch {
|
|
2981
3777
|
return false;
|
|
2982
3778
|
}
|
|
2983
3779
|
});
|
|
2984
|
-
const [activeReferenceId, setActiveReferenceId] =
|
|
2985
|
-
const [activeReferenceThumbnail, setActiveReferenceThumbnail] =
|
|
2986
|
-
const [isScanningImage, setIsScanningImage] =
|
|
2987
|
-
const [touchStartX, setTouchStartX] =
|
|
2988
|
-
const [isFullscreen, setIsFullscreen] =
|
|
2989
|
-
const [zoomScale, setZoomScale] =
|
|
2990
|
-
const [zoomOffset, setZoomOffset] =
|
|
2991
|
-
const lastPinchDist =
|
|
2992
|
-
const lastTapTime =
|
|
2993
|
-
const dragStart =
|
|
3780
|
+
const [activeReferenceId, setActiveReferenceId] = useState16(null);
|
|
3781
|
+
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = useState16(null);
|
|
3782
|
+
const [isScanningImage, setIsScanningImage] = useState16(false);
|
|
3783
|
+
const [touchStartX, setTouchStartX] = useState16(null);
|
|
3784
|
+
const [isFullscreen, setIsFullscreen] = useState16(false);
|
|
3785
|
+
const [zoomScale, setZoomScale] = useState16(1);
|
|
3786
|
+
const [zoomOffset, setZoomOffset] = useState16({ x: 0, y: 0 });
|
|
3787
|
+
const lastPinchDist = useRef7(null);
|
|
3788
|
+
const lastTapTime = useRef7(0);
|
|
3789
|
+
const dragStart = useRef7(null);
|
|
2994
3790
|
const openFullscreen = () => {
|
|
2995
3791
|
setIsFullscreen(true);
|
|
2996
3792
|
setZoomScale(1);
|
|
@@ -3134,16 +3930,16 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3134
3930
|
}
|
|
3135
3931
|
};
|
|
3136
3932
|
const currentIndex = useMemo2(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
3137
|
-
const goToPrev =
|
|
3933
|
+
const goToPrev = useCallback2(() => {
|
|
3138
3934
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
3139
3935
|
}, [currentIndex, history]);
|
|
3140
|
-
const goToNext =
|
|
3936
|
+
const goToNext = useCallback2(() => {
|
|
3141
3937
|
if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
|
|
3142
3938
|
}, [currentIndex, history]);
|
|
3143
3939
|
const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
|
|
3144
3940
|
const isGenerating = activeGenerationsCount > 0;
|
|
3145
3941
|
useKeyboardNavigation(history, currentResult, setCurrentResult);
|
|
3146
|
-
const getSubtreeFormat =
|
|
3942
|
+
const getSubtreeFormat = useCallback2((nodeId, depth = 0) => {
|
|
3147
3943
|
const node = nodes.find((n) => n.id === nodeId);
|
|
3148
3944
|
if (!node) return "";
|
|
3149
3945
|
const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
|
|
@@ -3183,7 +3979,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3183
3979
|
if (prev.id === genId || !options.silent) return finishedGen;
|
|
3184
3980
|
return prev;
|
|
3185
3981
|
});
|
|
3186
|
-
|
|
3982
|
+
console.log("[HF] handleGenerateImage \u2014 condition check:", { hfToken: !!hfToken, base64: !!base64, effectiveNamespace });
|
|
3983
|
+
if (hfToken && base64 && effectiveNamespace) {
|
|
3984
|
+
hfUploadImage(base64, genId, hfToken).catch((e) => {
|
|
3985
|
+
console.error("[HF] hfUploadImage failed:", e);
|
|
3986
|
+
});
|
|
3187
3987
|
const entry = {
|
|
3188
3988
|
id: genId,
|
|
3189
3989
|
prompt: promptToUse || void 0,
|
|
@@ -3193,20 +3993,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3193
3993
|
timestamp: Date.now(),
|
|
3194
3994
|
mimeType: "image/jpeg"
|
|
3195
3995
|
};
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
hfMetaSaveQueue.current = hfMetaSaveQueue.current.then(async () => {
|
|
3200
|
-
try {
|
|
3201
|
-
const existing = await hfLoadMetadata(token);
|
|
3202
|
-
const ids = new Set((existing || []).map((e) => e.id));
|
|
3203
|
-
if (!ids.has(genId)) {
|
|
3204
|
-
const next = [...existing || [], entry];
|
|
3205
|
-
await hfSaveMetadata(next, token);
|
|
3206
|
-
setHfMetadata(next);
|
|
3207
|
-
}
|
|
3208
|
-
} catch {
|
|
3209
|
-
}
|
|
3996
|
+
console.log("[HF] calling hfWriteEvent, namespace:", effectiveNamespace);
|
|
3997
|
+
hfWriteEvent("image_added", entry).catch((e) => {
|
|
3998
|
+
console.error("[HF] hfWriteEvent outer catch:", e);
|
|
3210
3999
|
});
|
|
3211
4000
|
}
|
|
3212
4001
|
} catch (err) {
|
|
@@ -3242,6 +4031,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3242
4031
|
all: [...prev.all, { ...newTagOption, category: tag.category }]
|
|
3243
4032
|
};
|
|
3244
4033
|
});
|
|
4034
|
+
if (hfToken && effectiveNamespace) {
|
|
4035
|
+
const p = { category: tag.category, label: tag.label, value: tag.value, is_user_created: true };
|
|
4036
|
+
hfWriteEvent("tag_upserted", p).catch(() => {
|
|
4037
|
+
});
|
|
4038
|
+
}
|
|
3245
4039
|
};
|
|
3246
4040
|
const handleTagUpdate = (originalLabel, originalCategory, updates) => {
|
|
3247
4041
|
setWorkspaceTags((prev) => {
|
|
@@ -3254,8 +4048,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3254
4048
|
);
|
|
3255
4049
|
return { by_category: { ...prev.by_category, [originalCategory]: updatedCat }, all: updatedAll };
|
|
3256
4050
|
});
|
|
4051
|
+
if (hfToken && effectiveNamespace) {
|
|
4052
|
+
const p = { category: originalCategory, label: updates.label, value: updates.value, is_user_created: true };
|
|
4053
|
+
hfWriteEvent("tag_upserted", p).catch(() => {
|
|
4054
|
+
});
|
|
4055
|
+
}
|
|
3257
4056
|
};
|
|
3258
4057
|
const handleTagDelete = (label, category) => {
|
|
4058
|
+
const tagValue = workspaceTags?.by_category[category]?.find((t) => t.label === label)?.value;
|
|
3259
4059
|
setWorkspaceTags((prev) => {
|
|
3260
4060
|
if (!prev) return prev;
|
|
3261
4061
|
const updatedCat = (prev.by_category[category] || []).map(
|
|
@@ -3266,6 +4066,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3266
4066
|
);
|
|
3267
4067
|
return { by_category: { ...prev.by_category, [category]: updatedCat }, all: updatedAll };
|
|
3268
4068
|
});
|
|
4069
|
+
if (hfToken && effectiveNamespace && tagValue) {
|
|
4070
|
+
const p = { category, label, value: tagValue, is_deleted: true };
|
|
4071
|
+
hfWriteEvent("tag_upserted", p).catch(() => {
|
|
4072
|
+
});
|
|
4073
|
+
}
|
|
3269
4074
|
};
|
|
3270
4075
|
const handleTagReorder = (category, reorderedTags) => {
|
|
3271
4076
|
setWorkspaceTags((prev) => {
|
|
@@ -3415,38 +4220,39 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3415
4220
|
await fetchServerProjects();
|
|
3416
4221
|
};
|
|
3417
4222
|
const handleHfInitialSync = async (onProgress) => {
|
|
3418
|
-
if (!hfToken) return;
|
|
3419
|
-
const
|
|
4223
|
+
if (!hfToken || !effectiveNamespace) return;
|
|
4224
|
+
const existingIds = new Set((hfState?.metadata || []).map((m) => m.id));
|
|
4225
|
+
const gens = galleryItems.filter((g) => g.base64 && g.status === "done" && !existingIds.has(g.id));
|
|
3420
4226
|
const total = gens.length;
|
|
3421
4227
|
onProgress(0, total);
|
|
3422
4228
|
let done = 0;
|
|
3423
4229
|
for (const gen of gens) {
|
|
3424
4230
|
const raw = gen.base64.includes(",") ? gen.base64.split(",")[1] : gen.base64;
|
|
3425
4231
|
const mimeType = gen.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg";
|
|
3426
|
-
await hfUploadImage(raw, gen.id, hfToken, mimeType)
|
|
4232
|
+
await hfUploadImage(raw, gen.id, hfToken, mimeType).catch(() => {
|
|
4233
|
+
});
|
|
4234
|
+
const entry = {
|
|
4235
|
+
id: gen.id,
|
|
4236
|
+
prompt: gen.prompt || void 0,
|
|
4237
|
+
seed: gen.seed,
|
|
4238
|
+
model: gen.model,
|
|
4239
|
+
tags: gen.tags || [],
|
|
4240
|
+
timestamp: gen.timestamp,
|
|
4241
|
+
mimeType
|
|
4242
|
+
};
|
|
4243
|
+
await hfWriteEvent("image_added", entry).catch(() => {
|
|
4244
|
+
});
|
|
3427
4245
|
done++;
|
|
3428
4246
|
onProgress(done, total);
|
|
3429
4247
|
}
|
|
3430
|
-
const localEntries = gens.map((g) => ({
|
|
3431
|
-
id: g.id,
|
|
3432
|
-
prompt: g.prompt || void 0,
|
|
3433
|
-
seed: g.seed,
|
|
3434
|
-
model: g.model,
|
|
3435
|
-
tags: g.tags || [],
|
|
3436
|
-
timestamp: g.timestamp,
|
|
3437
|
-
mimeType: g.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg"
|
|
3438
|
-
}));
|
|
3439
|
-
const existingMeta = await hfLoadMetadata(hfToken);
|
|
3440
|
-
const existingIds = new Set((existingMeta || []).map((e) => e.id));
|
|
3441
|
-
const newEntries = localEntries.filter((e) => !existingIds.has(e.id));
|
|
3442
|
-
const mergedMeta = [...existingMeta || [], ...newEntries];
|
|
3443
|
-
await hfSaveMetadata(mergedMeta, hfToken);
|
|
3444
|
-
setHfMetadata(mergedMeta);
|
|
3445
4248
|
if (workspaceTags) {
|
|
3446
|
-
const
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
4249
|
+
for (const [category, tags] of Object.entries(workspaceTags.by_category)) {
|
|
4250
|
+
for (const tag of tags) {
|
|
4251
|
+
const p = { category, label: tag.label, value: tag.value, is_user_created: tag.is_user_created, is_deleted: tag.is_deleted };
|
|
4252
|
+
await hfWriteEvent("tag_upserted", p).catch(() => {
|
|
4253
|
+
});
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
3450
4256
|
}
|
|
3451
4257
|
};
|
|
3452
4258
|
const handleComputeSyncDiff = async () => {
|
|
@@ -3485,87 +4291,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3485
4291
|
setTimeout(() => setProjectActionState("idle"), 4e3);
|
|
3486
4292
|
}
|
|
3487
4293
|
};
|
|
3488
|
-
|
|
4294
|
+
useEffect6(() => {
|
|
3489
4295
|
if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
|
|
3490
4296
|
}, [activeTab]);
|
|
3491
|
-
const [isHfRefreshing, setIsHfRefreshing] = useState14(false);
|
|
3492
|
-
const loadFromHF = useCallback(async (token) => {
|
|
3493
|
-
setIsHfRefreshing(true);
|
|
3494
|
-
try {
|
|
3495
|
-
hfLoadTags(token).then((tags) => {
|
|
3496
|
-
if (tags?.by_category) setWorkspaceTags(tags);
|
|
3497
|
-
}).catch(() => {
|
|
3498
|
-
});
|
|
3499
|
-
const entries = await hfLoadMetadata(token);
|
|
3500
|
-
if (!Array.isArray(entries) || entries.length === 0) return;
|
|
3501
|
-
setHfMetadata(entries);
|
|
3502
|
-
const hfIds = new Set(entries.map((e) => e.id));
|
|
3503
|
-
const hfSkeletons = entries.map((e) => ({
|
|
3504
|
-
id: e.id,
|
|
3505
|
-
nodeId: e.id,
|
|
3506
|
-
prompt: e.prompt,
|
|
3507
|
-
seed: e.seed,
|
|
3508
|
-
model: e.model,
|
|
3509
|
-
tags: e.tags || [],
|
|
3510
|
-
timestamp: e.timestamp,
|
|
3511
|
-
status: "done"
|
|
3512
|
-
}));
|
|
3513
|
-
setGalleryItems((prev) => {
|
|
3514
|
-
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
3515
|
-
const merged = hfSkeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
3516
|
-
return [...localOnly, ...merged];
|
|
3517
|
-
});
|
|
3518
|
-
setHistory((prev) => {
|
|
3519
|
-
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
3520
|
-
const merged = hfSkeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
3521
|
-
return [...localOnly, ...merged];
|
|
3522
|
-
});
|
|
3523
|
-
for (const entry of entries) {
|
|
3524
|
-
hfLoadImageAsBase64(entry.id, token).then((b64) => {
|
|
3525
|
-
if (!b64) return;
|
|
3526
|
-
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
3527
|
-
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
3528
|
-
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
3529
|
-
}).catch(() => {
|
|
3530
|
-
});
|
|
3531
|
-
}
|
|
3532
|
-
const localOnlyItems = galleryItemsRef.current.filter((g) => !hfIds.has(g.id) && g.base64 && g.status === "done");
|
|
3533
|
-
if (localOnlyItems.length > 0) {
|
|
3534
|
-
hfMetaSaveQueue.current = hfMetaSaveQueue.current.then(async () => {
|
|
3535
|
-
try {
|
|
3536
|
-
let currentMeta = await hfLoadMetadata(token);
|
|
3537
|
-
const existingIds = new Set((currentMeta || []).map((e) => e.id));
|
|
3538
|
-
for (const gen of localOnlyItems) {
|
|
3539
|
-
if (existingIds.has(gen.id)) continue;
|
|
3540
|
-
const raw = gen.base64.includes(",") ? gen.base64.split(",")[1] : gen.base64;
|
|
3541
|
-
const mimeType = gen.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg";
|
|
3542
|
-
await hfUploadImage(raw, gen.id, token, mimeType).catch(() => {
|
|
3543
|
-
});
|
|
3544
|
-
const entry = {
|
|
3545
|
-
id: gen.id,
|
|
3546
|
-
prompt: gen.prompt || void 0,
|
|
3547
|
-
seed: gen.seed,
|
|
3548
|
-
model: gen.model,
|
|
3549
|
-
tags: gen.tags || [],
|
|
3550
|
-
timestamp: gen.timestamp,
|
|
3551
|
-
mimeType
|
|
3552
|
-
};
|
|
3553
|
-
currentMeta = [...currentMeta || [], entry];
|
|
3554
|
-
existingIds.add(gen.id);
|
|
3555
|
-
}
|
|
3556
|
-
await hfSaveMetadata(currentMeta, token);
|
|
3557
|
-
setHfMetadata(currentMeta);
|
|
3558
|
-
} catch {
|
|
3559
|
-
}
|
|
3560
|
-
});
|
|
3561
|
-
}
|
|
3562
|
-
} finally {
|
|
3563
|
-
setIsHfRefreshing(false);
|
|
3564
|
-
}
|
|
3565
|
-
}, []);
|
|
3566
|
-
useEffect5(() => {
|
|
3567
|
-
if (hfToken) loadFromHF(hfToken);
|
|
3568
|
-
}, [hfToken]);
|
|
3569
4297
|
const mergeWorkspaceTags = (local, remote) => {
|
|
3570
4298
|
if (!remote?.by_category) return local;
|
|
3571
4299
|
const merged = {};
|
|
@@ -3585,25 +4313,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3585
4313
|
const all = Object.entries(merged).flatMap(([cat, tags]) => tags.map((t) => ({ ...t, category: cat })));
|
|
3586
4314
|
return { by_category: merged, all };
|
|
3587
4315
|
};
|
|
3588
|
-
useEffect5(() => {
|
|
3589
|
-
if (!hfToken || !workspaceTags) return;
|
|
3590
|
-
if (hfTagSaveTimer.current) clearTimeout(hfTagSaveTimer.current);
|
|
3591
|
-
hfTagSaveTimer.current = setTimeout(async () => {
|
|
3592
|
-
const remote = await hfLoadTags(hfToken).catch(() => null);
|
|
3593
|
-
const merged = mergeWorkspaceTags(workspaceTags, remote);
|
|
3594
|
-
await hfSaveTags(merged, hfToken).catch(() => {
|
|
3595
|
-
});
|
|
3596
|
-
if (Object.values(merged.by_category).some(
|
|
3597
|
-
(tags, i) => tags.length !== Object.values(workspaceTags.by_category)[i]?.length
|
|
3598
|
-
)) setWorkspaceTags(merged);
|
|
3599
|
-
}, 1500);
|
|
3600
|
-
return () => {
|
|
3601
|
-
if (hfTagSaveTimer.current) clearTimeout(hfTagSaveTimer.current);
|
|
3602
|
-
};
|
|
3603
|
-
}, [workspaceTags, hfToken]);
|
|
3604
4316
|
if (isFullscreen && currentResult?.base64) {
|
|
3605
4317
|
const fsBase64 = currentResult.base64.startsWith("data:") ? currentResult.base64 : `data:image/png;base64,${currentResult.base64}`;
|
|
3606
|
-
return /* @__PURE__ */
|
|
4318
|
+
return /* @__PURE__ */ jsxs19(
|
|
3607
4319
|
"div",
|
|
3608
4320
|
{
|
|
3609
4321
|
className: "fixed inset-0 bg-black z-50 flex items-center justify-center overflow-hidden touch-none",
|
|
@@ -3611,7 +4323,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3611
4323
|
onTouchMove: handleFsTouchMove,
|
|
3612
4324
|
onTouchEnd: handleFsTouchEnd,
|
|
3613
4325
|
children: [
|
|
3614
|
-
/* @__PURE__ */
|
|
4326
|
+
/* @__PURE__ */ jsx21(
|
|
3615
4327
|
"img",
|
|
3616
4328
|
{
|
|
3617
4329
|
src: fsBase64,
|
|
@@ -3628,77 +4340,77 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3628
4340
|
}
|
|
3629
4341
|
}
|
|
3630
4342
|
),
|
|
3631
|
-
/* @__PURE__ */
|
|
3632
|
-
zoomScale > 1 && /* @__PURE__ */
|
|
4343
|
+
/* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[22px]", children: "close" }) }),
|
|
4344
|
+
zoomScale > 1 && /* @__PURE__ */ jsx21("button", { onClick: () => {
|
|
3633
4345
|
setZoomScale(1);
|
|
3634
4346
|
setZoomOffset({ x: 0, y: 0 });
|
|
3635
|
-
}, 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__ */
|
|
3636
|
-
history.length > 1 && /* @__PURE__ */
|
|
3637
|
-
/* @__PURE__ */
|
|
4347
|
+
}, 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__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
|
|
4348
|
+
history.length > 1 && /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
4349
|
+
/* @__PURE__ */ jsx21("button", { onClick: () => {
|
|
3638
4350
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
3639
|
-
}, 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__ */
|
|
3640
|
-
/* @__PURE__ */
|
|
4351
|
+
}, 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__ */ jsx21("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
|
|
4352
|
+
/* @__PURE__ */ jsx21("button", { onClick: () => {
|
|
3641
4353
|
if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
|
|
3642
|
-
}, 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__ */
|
|
3643
|
-
/* @__PURE__ */
|
|
4354
|
+
}, 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__ */ jsx21("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
|
|
4355
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
3644
4356
|
currentIndex + 1,
|
|
3645
4357
|
" / ",
|
|
3646
4358
|
history.length
|
|
3647
4359
|
] })
|
|
3648
4360
|
] }),
|
|
3649
|
-
zoomScale === 1 && /* @__PURE__ */
|
|
4361
|
+
zoomScale === 1 && /* @__PURE__ */ jsx21("div", { className: "absolute bottom-6 right-4 text-[9px] text-white/20 font-mono", children: "Pinch zum Zoomen \xB7 Doppeltipp 2.5\xD7" })
|
|
3650
4362
|
]
|
|
3651
4363
|
}
|
|
3652
4364
|
);
|
|
3653
4365
|
}
|
|
3654
4366
|
if (showStart) {
|
|
3655
|
-
return /* @__PURE__ */
|
|
3656
|
-
/* @__PURE__ */
|
|
4367
|
+
return /* @__PURE__ */ jsxs19("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
|
|
4368
|
+
/* @__PURE__ */ jsx21("input", { ref: wsInputRef, type: "file", accept: ".zip", className: "hidden", onChange: (e) => {
|
|
3657
4369
|
const f = e.target.files?.[0];
|
|
3658
4370
|
if (f) handleProjectImport(f);
|
|
3659
4371
|
e.target.value = "";
|
|
3660
4372
|
} }),
|
|
3661
|
-
/* @__PURE__ */
|
|
3662
|
-
/* @__PURE__ */
|
|
3663
|
-
/* @__PURE__ */
|
|
3664
|
-
/* @__PURE__ */
|
|
4373
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-1", children: [
|
|
4374
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
|
|
4375
|
+
/* @__PURE__ */ jsx21("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
|
|
4376
|
+
/* @__PURE__ */ jsxs19("span", { className: "text-white text-[13px] font-mono", children: [
|
|
3665
4377
|
"v",
|
|
3666
4378
|
LIB_VERSION
|
|
3667
4379
|
] })
|
|
3668
4380
|
] }),
|
|
3669
|
-
/* @__PURE__ */
|
|
4381
|
+
/* @__PURE__ */ jsxs19(
|
|
3670
4382
|
"button",
|
|
3671
4383
|
{
|
|
3672
4384
|
onClick: toggleContrast,
|
|
3673
4385
|
className: "flex items-center gap-3 px-5 py-3 rounded-2xl border transition-colors",
|
|
3674
4386
|
style: { borderColor: highContrast ? "rgba(255,255,255,0.3)" : "rgba(255,255,255,0.08)", background: highContrast ? "rgba(255,255,255,0.08)" : "transparent" },
|
|
3675
4387
|
children: [
|
|
3676
|
-
/* @__PURE__ */
|
|
3677
|
-
/* @__PURE__ */
|
|
3678
|
-
/* @__PURE__ */
|
|
3679
|
-
/* @__PURE__ */
|
|
4388
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[22px]", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.35)" }, children: highContrast ? "light_mode" : "dark_mode" }),
|
|
4389
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-start", children: [
|
|
4390
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[13px] font-bold", style: { color: highContrast ? "#fff" : "rgba(255,255,255,0.5)" }, children: highContrast ? "Hoher Kontrast" : "Normaler Kontrast" }),
|
|
4391
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[10px]", style: { color: "rgba(255,255,255,0.25)" }, children: "Tippen zum Umschalten" })
|
|
3680
4392
|
] })
|
|
3681
4393
|
]
|
|
3682
4394
|
}
|
|
3683
4395
|
),
|
|
3684
|
-
/* @__PURE__ */
|
|
3685
|
-
/* @__PURE__ */
|
|
4396
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
|
|
4397
|
+
/* @__PURE__ */ jsxs19(
|
|
3686
4398
|
"button",
|
|
3687
4399
|
{
|
|
3688
4400
|
onClick: () => wsInputRef.current?.click(),
|
|
3689
4401
|
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",
|
|
3690
4402
|
style: { height: 56, background: projectLoaded ? "#16a34a" : "#0284c7" },
|
|
3691
4403
|
children: [
|
|
3692
|
-
/* @__PURE__ */
|
|
4404
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[22px]", children: projectLoaded ? "check_circle" : "folder_zip" }),
|
|
3693
4405
|
projectLoaded ? "Projekt geladen \u2713" : "Projekt laden (.zip)"
|
|
3694
4406
|
]
|
|
3695
4407
|
}
|
|
3696
4408
|
),
|
|
3697
|
-
!projectLoaded && /* @__PURE__ */
|
|
4409
|
+
!projectLoaded && /* @__PURE__ */ jsx21("span", { className: "text-white/20 text-[10px] text-center", children: "Baum, Bilder und Einstellungen wiederherstellen" })
|
|
3698
4410
|
] }),
|
|
3699
|
-
/* @__PURE__ */
|
|
3700
|
-
!initialHfToken && /* @__PURE__ */
|
|
3701
|
-
/* @__PURE__ */
|
|
4411
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
|
|
4412
|
+
!initialHfToken && /* @__PURE__ */ jsxs19("div", { className: "flex gap-2 w-full", children: [
|
|
4413
|
+
/* @__PURE__ */ jsx21(
|
|
3702
4414
|
"input",
|
|
3703
4415
|
{
|
|
3704
4416
|
type: "password",
|
|
@@ -3714,7 +4426,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3714
4426
|
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)" }
|
|
3715
4427
|
}
|
|
3716
4428
|
),
|
|
3717
|
-
hfTokenInput.trim() && /* @__PURE__ */
|
|
4429
|
+
hfTokenInput.trim() && /* @__PURE__ */ jsx21(
|
|
3718
4430
|
"button",
|
|
3719
4431
|
{
|
|
3720
4432
|
type: "button",
|
|
@@ -3725,14 +4437,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3725
4437
|
}
|
|
3726
4438
|
)
|
|
3727
4439
|
] }),
|
|
3728
|
-
hfToken && /* @__PURE__ */
|
|
4440
|
+
hfToken && /* @__PURE__ */ jsxs19(
|
|
3729
4441
|
"button",
|
|
3730
4442
|
{
|
|
3731
4443
|
disabled: isLoadingFromHF,
|
|
3732
4444
|
onClick: async () => {
|
|
3733
4445
|
setIsLoadingFromHF(true);
|
|
3734
4446
|
try {
|
|
3735
|
-
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
4447
|
+
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-6YYT6ATO.mjs");
|
|
3736
4448
|
const projects = await hfListProjects2(hfToken);
|
|
3737
4449
|
if (projects.length > 0) {
|
|
3738
4450
|
const file = await hfDownloadProject2(projects[0].path, hfToken);
|
|
@@ -3747,15 +4459,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3747
4459
|
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",
|
|
3748
4460
|
style: { height: 56, background: "#f59e0b" },
|
|
3749
4461
|
children: [
|
|
3750
|
-
/* @__PURE__ */
|
|
4462
|
+
/* @__PURE__ */ jsx21("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromHF ? " animate-spin" : ""}`, children: isLoadingFromHF ? "sync" : "cloud_download" }),
|
|
3751
4463
|
isLoadingFromHF ? "Laden\u2026" : "Von HF laden"
|
|
3752
4464
|
]
|
|
3753
4465
|
}
|
|
3754
4466
|
),
|
|
3755
|
-
hfToken && /* @__PURE__ */
|
|
4467
|
+
hfToken && /* @__PURE__ */ jsx21("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand von Hugging Face laden" })
|
|
3756
4468
|
] }),
|
|
3757
|
-
onFetchServerProjects && /* @__PURE__ */
|
|
3758
|
-
/* @__PURE__ */
|
|
4469
|
+
onFetchServerProjects && /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
|
|
4470
|
+
/* @__PURE__ */ jsxs19(
|
|
3759
4471
|
"button",
|
|
3760
4472
|
{
|
|
3761
4473
|
disabled: isLoadingFromServer,
|
|
@@ -3776,35 +4488,57 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3776
4488
|
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",
|
|
3777
4489
|
style: { height: 56, background: "#7c3aed" },
|
|
3778
4490
|
children: [
|
|
3779
|
-
/* @__PURE__ */
|
|
4491
|
+
/* @__PURE__ */ jsx21("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromServer ? " animate-spin" : ""}`, children: isLoadingFromServer ? "sync" : "cloud_download" }),
|
|
3780
4492
|
isLoadingFromServer ? "Laden\u2026" : "Vom Server laden"
|
|
3781
4493
|
]
|
|
3782
4494
|
}
|
|
3783
4495
|
),
|
|
3784
|
-
/* @__PURE__ */
|
|
4496
|
+
/* @__PURE__ */ jsx21("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand vom Server wiederherstellen" })
|
|
3785
4497
|
] }),
|
|
3786
|
-
/* @__PURE__ */
|
|
3787
|
-
/* @__PURE__ */
|
|
3788
|
-
/* @__PURE__ */
|
|
4498
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
|
|
4499
|
+
/* @__PURE__ */ jsx21("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "Layout w\xE4hlen & starten" }),
|
|
4500
|
+
/* @__PURE__ */ jsx21("div", { className: "grid grid-cols-2 gap-2 w-full", children: [
|
|
3789
4501
|
{ id: "mobile", icon: "smartphone", label: "Mobile" },
|
|
3790
4502
|
{ id: "mobile-desktop", icon: "phonelink", label: "Mobile+" },
|
|
3791
4503
|
{ id: "desktop", icon: "desktop_windows", label: "Desktop" },
|
|
3792
4504
|
{ id: "tablet-landscape", icon: "tablet", label: "Landscape" }
|
|
3793
|
-
].map((opt) => /* @__PURE__ */
|
|
4505
|
+
].map((opt) => /* @__PURE__ */ jsxs19(
|
|
3794
4506
|
"button",
|
|
3795
4507
|
{
|
|
3796
4508
|
onClick: () => startApp(opt.id),
|
|
3797
4509
|
className: "flex flex-col items-center gap-2 py-4 rounded-2xl border transition-colors",
|
|
3798
4510
|
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" },
|
|
3799
4511
|
children: [
|
|
3800
|
-
/* @__PURE__ */
|
|
3801
|
-
/* @__PURE__ */
|
|
4512
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[24px]", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.icon }),
|
|
4513
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[11px] font-bold", style: { color: layoutChoice === opt.id ? "#fff" : "rgba(255,255,255,0.4)" }, children: opt.label })
|
|
3802
4514
|
]
|
|
3803
4515
|
},
|
|
3804
4516
|
opt.id
|
|
3805
4517
|
)) }),
|
|
3806
|
-
layoutChoice === "mobile-desktop" && /* @__PURE__ */
|
|
3807
|
-
layoutChoice === "tablet-landscape" && /* @__PURE__ */
|
|
4518
|
+
layoutChoice === "mobile-desktop" && /* @__PURE__ */ jsx21("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
|
|
4519
|
+
layoutChoice === "tablet-landscape" && /* @__PURE__ */ jsx21("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
|
|
4520
|
+
] }),
|
|
4521
|
+
!hfNamespace && !hfNamespaceFromServer && /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3 w-full max-w-[280px]", children: [
|
|
4522
|
+
/* @__PURE__ */ jsx21("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "State:" }),
|
|
4523
|
+
["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ jsx21(
|
|
4524
|
+
"button",
|
|
4525
|
+
{
|
|
4526
|
+
onClick: () => {
|
|
4527
|
+
setHfNamespaceLocal(ns);
|
|
4528
|
+
try {
|
|
4529
|
+
localStorage.setItem("aa-hf-namespace", ns);
|
|
4530
|
+
} catch {
|
|
4531
|
+
}
|
|
4532
|
+
},
|
|
4533
|
+
className: "px-3 py-1 rounded-lg text-[11px] font-bold transition-colors",
|
|
4534
|
+
style: {
|
|
4535
|
+
background: hfNamespaceLocal === ns ? "#e7e5e4" : "#44403c",
|
|
4536
|
+
color: hfNamespaceLocal === ns ? "#1c1917" : "#e7e5e4"
|
|
4537
|
+
},
|
|
4538
|
+
children: i === 0 ? "PROD" : "DEV"
|
|
4539
|
+
},
|
|
4540
|
+
ns
|
|
4541
|
+
))
|
|
3808
4542
|
] })
|
|
3809
4543
|
] });
|
|
3810
4544
|
}
|
|
@@ -3813,21 +4547,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3813
4547
|
const mdScale = mdMode ? window.innerWidth / 430 : 1;
|
|
3814
4548
|
const mdW = mdMode ? 430 : void 0;
|
|
3815
4549
|
const mdH = mdMode ? Math.ceil(window.innerHeight / mdScale) : void 0;
|
|
3816
|
-
const mobileRoot = /* @__PURE__ */
|
|
4550
|
+
const mobileRoot = /* @__PURE__ */ jsxs19("div", { className: "flex flex-col bg-[#0e0e0e] text-white overflow-hidden", style: {
|
|
3817
4551
|
width: mdMode ? mdW : "100vw",
|
|
3818
4552
|
height: mdMode ? mdH : "100dvh",
|
|
3819
4553
|
transform: mdMode ? `scale(${mdScale})` : void 0,
|
|
3820
4554
|
transformOrigin: mdMode ? "top left" : void 0,
|
|
3821
4555
|
...hcStyle || {}
|
|
3822
4556
|
}, children: [
|
|
3823
|
-
mobileTab === "labs" && /* @__PURE__ */
|
|
4557
|
+
mobileTab === "labs" && /* @__PURE__ */ jsx21("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ jsx21(LabsTab, { services: labServices, onResult: (item) => {
|
|
3824
4558
|
const frame = item.frames[0];
|
|
3825
4559
|
if (frame?.base64) {
|
|
3826
4560
|
setCurrentResult(frameToGeneration(frame, item));
|
|
3827
4561
|
setMobileTab("stage");
|
|
3828
4562
|
}
|
|
3829
4563
|
} }) }),
|
|
3830
|
-
mobileTab === "tags" && workspaceTags && /* @__PURE__ */
|
|
4564
|
+
mobileTab === "tags" && workspaceTags && /* @__PURE__ */ jsx21("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ jsx21(
|
|
3831
4565
|
TagManagerPanel,
|
|
3832
4566
|
{
|
|
3833
4567
|
workspaceTags,
|
|
@@ -3838,21 +4572,21 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3838
4572
|
onTagMove: handleTagMove
|
|
3839
4573
|
}
|
|
3840
4574
|
) }),
|
|
3841
|
-
mobileTab === "stage" && /* @__PURE__ */
|
|
3842
|
-
/* @__PURE__ */
|
|
3843
|
-
/* @__PURE__ */
|
|
3844
|
-
/* @__PURE__ */
|
|
3845
|
-
/* @__PURE__ */
|
|
3846
|
-
activeReferenceThumbnail ? /* @__PURE__ */
|
|
3847
|
-
/* @__PURE__ */
|
|
3848
|
-
/* @__PURE__ */
|
|
3849
|
-
/* @__PURE__ */
|
|
3850
|
-
] }) : /* @__PURE__ */
|
|
3851
|
-
/* @__PURE__ */
|
|
3852
|
-
/* @__PURE__ */
|
|
4575
|
+
mobileTab === "stage" && /* @__PURE__ */ jsxs19("div", { className: "flex flex-col flex-1 min-h-0", children: [
|
|
4576
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
|
|
4577
|
+
/* @__PURE__ */ jsx21(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
|
|
4578
|
+
/* @__PURE__ */ jsx21(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" }] }),
|
|
4579
|
+
/* @__PURE__ */ jsx21("div", { className: "flex-1" }),
|
|
4580
|
+
activeReferenceThumbnail ? /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
|
|
4581
|
+
/* @__PURE__ */ jsx21("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
|
|
4582
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
|
|
4583
|
+
/* @__PURE__ */ jsx21("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
|
|
4584
|
+
] }) : /* @__PURE__ */ jsx21("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
|
|
4585
|
+
/* @__PURE__ */ jsx21("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
|
|
4586
|
+
/* @__PURE__ */ jsx21("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
|
|
3853
4587
|
] }),
|
|
3854
|
-
/* @__PURE__ */
|
|
3855
|
-
/* @__PURE__ */
|
|
4588
|
+
/* @__PURE__ */ jsx21("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ jsxs19("div", { className: `relative rounded-xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
|
|
4589
|
+
/* @__PURE__ */ jsx21(
|
|
3856
4590
|
"textarea",
|
|
3857
4591
|
{
|
|
3858
4592
|
value: activePrompt,
|
|
@@ -3862,26 +4596,26 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3862
4596
|
placeholder: "Prompt eingeben..."
|
|
3863
4597
|
}
|
|
3864
4598
|
),
|
|
3865
|
-
activePrompt && !isSynthesizing && /* @__PURE__ */
|
|
4599
|
+
activePrompt && !isSynthesizing && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
|
|
3866
4600
|
] }) }),
|
|
3867
|
-
/* @__PURE__ */
|
|
4601
|
+
/* @__PURE__ */ jsx21("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ jsx21(
|
|
3868
4602
|
"button",
|
|
3869
4603
|
{
|
|
3870
4604
|
onClick: () => handleGenerateImage(),
|
|
3871
4605
|
disabled: !activePrompt.trim() || isGenerating,
|
|
3872
4606
|
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",
|
|
3873
4607
|
style: { height: 48, background: activePrompt.trim() && !isGenerating ? "#0284c7" : void 0, border: "1px solid rgba(255,255,255,0.1)" },
|
|
3874
|
-
children: isGenerating ? /* @__PURE__ */
|
|
3875
|
-
/* @__PURE__ */
|
|
3876
|
-
/* @__PURE__ */
|
|
3877
|
-
] }) : /* @__PURE__ */
|
|
3878
|
-
/* @__PURE__ */
|
|
3879
|
-
/* @__PURE__ */
|
|
4608
|
+
children: isGenerating ? /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
4609
|
+
/* @__PURE__ */ jsx21("div", { className: "w-4 h-4 border-t-2 border-white rounded-full animate-spin" }),
|
|
4610
|
+
/* @__PURE__ */ jsx21("span", { children: "Generiere..." })
|
|
4611
|
+
] }) : /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
4612
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
|
|
4613
|
+
/* @__PURE__ */ jsx21("span", { children: "Generieren" })
|
|
3880
4614
|
] })
|
|
3881
4615
|
}
|
|
3882
4616
|
) }),
|
|
3883
|
-
/* @__PURE__ */
|
|
3884
|
-
/* @__PURE__ */
|
|
4617
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
|
|
4618
|
+
/* @__PURE__ */ jsxs19(
|
|
3885
4619
|
"div",
|
|
3886
4620
|
{
|
|
3887
4621
|
className: "w-full rounded-2xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center",
|
|
@@ -3895,25 +4629,25 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3895
4629
|
setTouchStartX(null);
|
|
3896
4630
|
},
|
|
3897
4631
|
children: [
|
|
3898
|
-
currentResult?.status === "processing" && /* @__PURE__ */
|
|
3899
|
-
/* @__PURE__ */
|
|
3900
|
-
/* @__PURE__ */
|
|
4632
|
+
currentResult?.status === "processing" && /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-3", children: [
|
|
4633
|
+
/* @__PURE__ */ jsx21("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
|
|
4634
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[11px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
3901
4635
|
] }),
|
|
3902
|
-
currentResult?.status === "error" && /* @__PURE__ */
|
|
3903
|
-
/* @__PURE__ */
|
|
3904
|
-
/* @__PURE__ */
|
|
3905
|
-
/* @__PURE__ */
|
|
4636
|
+
currentResult?.status === "error" && /* @__PURE__ */ jsxs19("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
|
|
4637
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
|
|
4638
|
+
/* @__PURE__ */ jsx21("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
|
|
4639
|
+
/* @__PURE__ */ jsx21("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" })
|
|
3906
4640
|
] }),
|
|
3907
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */
|
|
3908
|
-
!currentResult && /* @__PURE__ */
|
|
3909
|
-
/* @__PURE__ */
|
|
3910
|
-
/* @__PURE__ */
|
|
4641
|
+
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx21("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
|
|
4642
|
+
!currentResult && /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
4643
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
|
|
4644
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
3911
4645
|
] }),
|
|
3912
|
-
currentResult?.status === "done" && /* @__PURE__ */
|
|
3913
|
-
history.length > 1 && currentResult && /* @__PURE__ */
|
|
3914
|
-
/* @__PURE__ */
|
|
3915
|
-
/* @__PURE__ */
|
|
3916
|
-
/* @__PURE__ */
|
|
4646
|
+
currentResult?.status === "done" && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
|
|
4647
|
+
history.length > 1 && currentResult && /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
4648
|
+
/* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
|
|
4649
|
+
/* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
|
|
4650
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
3917
4651
|
currentIndex + 1,
|
|
3918
4652
|
" / ",
|
|
3919
4653
|
history.length
|
|
@@ -3922,33 +4656,33 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3922
4656
|
]
|
|
3923
4657
|
}
|
|
3924
4658
|
),
|
|
3925
|
-
currentResult?.status === "done" && /* @__PURE__ */
|
|
3926
|
-
/* @__PURE__ */
|
|
3927
|
-
/* @__PURE__ */
|
|
3928
|
-
/* @__PURE__ */
|
|
4659
|
+
currentResult?.status === "done" && /* @__PURE__ */ jsxs19("div", { className: "flex gap-2 mt-3", children: [
|
|
4660
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4661
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
|
|
4662
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[12px] text-white/60", children: "Prompt" })
|
|
3929
4663
|
] }),
|
|
3930
|
-
/* @__PURE__ */
|
|
3931
|
-
/* @__PURE__ */
|
|
3932
|
-
/* @__PURE__ */
|
|
4664
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4665
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
|
|
4666
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
|
|
3933
4667
|
] }),
|
|
3934
|
-
/* @__PURE__ */
|
|
3935
|
-
/* @__PURE__ */
|
|
3936
|
-
/* @__PURE__ */
|
|
4668
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4669
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "download" }),
|
|
4670
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[12px] text-white/60", children: "Laden" })
|
|
3937
4671
|
] })
|
|
3938
4672
|
] })
|
|
3939
4673
|
] })
|
|
3940
4674
|
] }),
|
|
3941
|
-
mobileTab === "browse" && /* @__PURE__ */
|
|
3942
|
-
/* @__PURE__ */
|
|
3943
|
-
["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */
|
|
3944
|
-
hfToken && /* @__PURE__ */
|
|
4675
|
+
mobileTab === "browse" && /* @__PURE__ */ jsxs19("div", { className: "flex flex-col flex-1 min-h-0", children: [
|
|
4676
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
|
|
4677
|
+
["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
|
|
4678
|
+
hfToken && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
|
|
3945
4679
|
] }),
|
|
3946
|
-
/* @__PURE__ */
|
|
3947
|
-
activeTab === "history" && /* @__PURE__ */
|
|
4680
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
4681
|
+
activeTab === "history" && /* @__PURE__ */ jsx21(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: (g) => {
|
|
3948
4682
|
setCurrentResult(g);
|
|
3949
4683
|
setMobileTab("stage");
|
|
3950
4684
|
}, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
3951
|
-
activeTab === "gallery" && /* @__PURE__ */
|
|
4685
|
+
activeTab === "gallery" && /* @__PURE__ */ jsx21(
|
|
3952
4686
|
MediaLibrary,
|
|
3953
4687
|
{
|
|
3954
4688
|
items: galleryItems,
|
|
@@ -3968,39 +4702,43 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3968
4702
|
}
|
|
3969
4703
|
}
|
|
3970
4704
|
),
|
|
3971
|
-
activeTab === "inspect" && /* @__PURE__ */
|
|
4705
|
+
activeTab === "inspect" && /* @__PURE__ */ jsx21(InspectPanel, { currentResult, history, onSelect: (g) => {
|
|
3972
4706
|
setCurrentResult(g);
|
|
3973
4707
|
} })
|
|
3974
4708
|
] })
|
|
3975
4709
|
] }),
|
|
3976
|
-
/* @__PURE__ */
|
|
3977
|
-
/* @__PURE__ */
|
|
3978
|
-
workspaceTags && /* @__PURE__ */
|
|
4710
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
|
|
4711
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
|
|
4712
|
+
workspaceTags && /* @__PURE__ */ jsxs19("button", { onClick: () => {
|
|
3979
4713
|
setLeftTab("prompt");
|
|
3980
4714
|
if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
|
|
3981
4715
|
}, 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: [
|
|
3982
|
-
/* @__PURE__ */
|
|
4716
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "auto_fix_high" }),
|
|
3983
4717
|
"Prompt"
|
|
3984
4718
|
] }),
|
|
3985
|
-
/* @__PURE__ */
|
|
4719
|
+
/* @__PURE__ */ jsxs19("button", { onClick: () => {
|
|
3986
4720
|
setLeftTab("hierarchy");
|
|
3987
4721
|
if (activeTab === "setup" || activeTab === "sync") setActiveTab("history");
|
|
3988
4722
|
}, 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: [
|
|
3989
|
-
/* @__PURE__ */
|
|
4723
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "account_tree" }),
|
|
3990
4724
|
"Hierarchie"
|
|
3991
4725
|
] }),
|
|
3992
|
-
/* @__PURE__ */
|
|
3993
|
-
/* @__PURE__ */
|
|
4726
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4727
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "settings" }),
|
|
3994
4728
|
"Setup"
|
|
3995
4729
|
] }),
|
|
3996
|
-
/* @__PURE__ */
|
|
3997
|
-
/* @__PURE__ */
|
|
4730
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4731
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "cloud_sync" }),
|
|
3998
4732
|
"Sync"
|
|
3999
4733
|
] }),
|
|
4000
|
-
|
|
4734
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4735
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
|
|
4736
|
+
"HF"
|
|
4737
|
+
] }),
|
|
4738
|
+
workspaceTags && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
|
|
4001
4739
|
] }),
|
|
4002
|
-
/* @__PURE__ */
|
|
4003
|
-
leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && /* @__PURE__ */
|
|
4740
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
4741
|
+
leftTab === "hierarchy" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" && /* @__PURE__ */ jsx21("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx21(
|
|
4004
4742
|
ListView,
|
|
4005
4743
|
{
|
|
4006
4744
|
nodes,
|
|
@@ -4031,14 +4769,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4031
4769
|
isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
|
|
4032
4770
|
}
|
|
4033
4771
|
) }),
|
|
4034
|
-
workspaceTags && /* @__PURE__ */
|
|
4772
|
+
workspaceTags && /* @__PURE__ */ jsx21("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ jsx21(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
|
|
4035
4773
|
handleGenerateImage(prompt);
|
|
4036
4774
|
setMobileTab("stage");
|
|
4037
4775
|
}, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
|
|
4038
|
-
activeTab === "setup" && /* @__PURE__ */
|
|
4039
|
-
activeTab === "sync" && /* @__PURE__ */
|
|
4776
|
+
activeTab === "setup" && /* @__PURE__ */ jsx21(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
|
|
4777
|
+
activeTab === "sync" && /* @__PURE__ */ jsx21(
|
|
4040
4778
|
ProjectSyncTab,
|
|
4041
4779
|
{
|
|
4780
|
+
topSlot: syncTopSlot,
|
|
4042
4781
|
onProjectExport: handleProjectExport,
|
|
4043
4782
|
onProjectImport: (f) => handleProjectImport(f),
|
|
4044
4783
|
onWorkspaceImport: handleWorkspaceImport,
|
|
@@ -4059,7 +4798,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4059
4798
|
onHfInitialSync: hfToken ? handleHfInitialSync : void 0
|
|
4060
4799
|
}
|
|
4061
4800
|
),
|
|
4062
|
-
activeTab === "tags" && workspaceTags && /* @__PURE__ */
|
|
4801
|
+
activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx21(
|
|
4063
4802
|
TagManagerPanel,
|
|
4064
4803
|
{
|
|
4065
4804
|
workspaceTags,
|
|
@@ -4069,22 +4808,23 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4069
4808
|
onTagReorder: handleTagReorder,
|
|
4070
4809
|
onTagMove: handleTagMove
|
|
4071
4810
|
}
|
|
4072
|
-
)
|
|
4811
|
+
),
|
|
4812
|
+
activeTab === "hftest" && /* @__PURE__ */ jsx21("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx21(HFTestTab, { token: hfToken, namespace: effectiveNamespace, galleryItems }) })
|
|
4073
4813
|
] })
|
|
4074
4814
|
] }),
|
|
4075
|
-
/* @__PURE__ */
|
|
4815
|
+
/* @__PURE__ */ jsx21("div", { className: "flex border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
|
|
4076
4816
|
{ id: "tools", icon: "auto_fix_high", label: "Prompt" },
|
|
4077
4817
|
{ id: "stage", icon: "palette", label: "Stage" },
|
|
4078
4818
|
{ id: "labs", icon: "science", label: "Labs" },
|
|
4079
4819
|
...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
|
|
4080
4820
|
{ id: "browse", icon: "photo_library", label: "Galerie" }
|
|
4081
|
-
].map((tab) => /* @__PURE__ */
|
|
4082
|
-
/* @__PURE__ */
|
|
4083
|
-
/* @__PURE__ */
|
|
4821
|
+
].map((tab) => /* @__PURE__ */ jsxs19("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: [
|
|
4822
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
|
|
4823
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
|
|
4084
4824
|
] }, tab.id)) })
|
|
4085
4825
|
] });
|
|
4086
4826
|
if (mdMode) {
|
|
4087
|
-
return /* @__PURE__ */
|
|
4827
|
+
return /* @__PURE__ */ jsx21("div", { style: { position: "fixed", inset: 0, overflow: "hidden", background: "#0e0e0e" }, children: mobileRoot });
|
|
4088
4828
|
}
|
|
4089
4829
|
return mobileRoot;
|
|
4090
4830
|
}
|
|
@@ -4092,17 +4832,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4092
4832
|
const tlScale = Math.min(window.innerWidth / 920, window.innerHeight / 520);
|
|
4093
4833
|
const tlW = 920;
|
|
4094
4834
|
const tlH = 520;
|
|
4095
|
-
return /* @__PURE__ */
|
|
4096
|
-
/* @__PURE__ */
|
|
4097
|
-
/* @__PURE__ */
|
|
4098
|
-
/* @__PURE__ */
|
|
4099
|
-
/* @__PURE__ */
|
|
4100
|
-
/* @__PURE__ */
|
|
4101
|
-
/* @__PURE__ */
|
|
4102
|
-
/* @__PURE__ */
|
|
4835
|
+
return /* @__PURE__ */ jsx21("div", { style: { position: "fixed", inset: 0, background: "#0e0e0e", display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", ...hcStyle || {} }, children: /* @__PURE__ */ jsxs19("div", { style: { width: tlW, height: tlH, transform: `scale(${tlScale})`, transformOrigin: "center center", display: "flex", flexDirection: "row", color: "#fff", overflow: "hidden", borderRadius: 0 }, children: [
|
|
4836
|
+
/* @__PURE__ */ jsxs19("div", { style: { width: 320, height: tlH, display: "flex", flexDirection: "column", borderRight: "1px solid rgba(255,255,255,0.05)", background: "#000", flexShrink: 0 }, children: [
|
|
4837
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4838
|
+
/* @__PURE__ */ jsx21(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
|
|
4839
|
+
/* @__PURE__ */ jsx21(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" }] }),
|
|
4840
|
+
/* @__PURE__ */ jsx21("div", { style: { flex: 1 } }),
|
|
4841
|
+
/* @__PURE__ */ jsx21("button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
|
|
4842
|
+
/* @__PURE__ */ jsx21("button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
|
|
4103
4843
|
] }),
|
|
4104
|
-
/* @__PURE__ */
|
|
4105
|
-
/* @__PURE__ */
|
|
4844
|
+
/* @__PURE__ */ jsx21("div", { style: { padding: "12px 12px 8px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs19("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: [
|
|
4845
|
+
/* @__PURE__ */ jsx21(
|
|
4106
4846
|
"textarea",
|
|
4107
4847
|
{
|
|
4108
4848
|
value: activePrompt,
|
|
@@ -4111,27 +4851,27 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4111
4851
|
placeholder: "Prompt eingeben..."
|
|
4112
4852
|
}
|
|
4113
4853
|
),
|
|
4114
|
-
activePrompt && /* @__PURE__ */
|
|
4854
|
+
activePrompt && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
|
|
4115
4855
|
] }) }),
|
|
4116
|
-
/* @__PURE__ */
|
|
4856
|
+
/* @__PURE__ */ jsx21("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ jsx21(
|
|
4117
4857
|
"button",
|
|
4118
4858
|
{
|
|
4119
4859
|
onClick: () => handleGenerateImage(),
|
|
4120
4860
|
disabled: !activePrompt.trim() || isGenerating,
|
|
4121
4861
|
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" },
|
|
4122
|
-
children: isGenerating ? /* @__PURE__ */
|
|
4123
|
-
/* @__PURE__ */
|
|
4124
|
-
/* @__PURE__ */
|
|
4125
|
-
] }) : /* @__PURE__ */
|
|
4126
|
-
/* @__PURE__ */
|
|
4127
|
-
/* @__PURE__ */
|
|
4862
|
+
children: isGenerating ? /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
4863
|
+
/* @__PURE__ */ jsx21("div", { style: { width: 14, height: 14, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
|
|
4864
|
+
/* @__PURE__ */ jsx21("span", { children: "Generiere..." })
|
|
4865
|
+
] }) : /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
4866
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
|
|
4867
|
+
/* @__PURE__ */ jsx21("span", { children: "Generieren" })
|
|
4128
4868
|
] })
|
|
4129
4869
|
}
|
|
4130
4870
|
) }),
|
|
4131
|
-
/* @__PURE__ */
|
|
4871
|
+
/* @__PURE__ */ jsx21("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ jsx21(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }) })
|
|
4132
4872
|
] }),
|
|
4133
|
-
/* @__PURE__ */
|
|
4134
|
-
/* @__PURE__ */
|
|
4873
|
+
/* @__PURE__ */ jsxs19("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
|
|
4874
|
+
/* @__PURE__ */ jsx21(
|
|
4135
4875
|
"div",
|
|
4136
4876
|
{
|
|
4137
4877
|
style: { flex: 1, padding: 16, display: "flex", alignItems: "center", justifyContent: "center", position: "relative" },
|
|
@@ -4143,26 +4883,26 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4143
4883
|
else if (dx > 50) goToPrev();
|
|
4144
4884
|
setTouchStartX(null);
|
|
4145
4885
|
},
|
|
4146
|
-
children: /* @__PURE__ */
|
|
4147
|
-
currentResult?.status === "processing" && /* @__PURE__ */
|
|
4148
|
-
/* @__PURE__ */
|
|
4149
|
-
/* @__PURE__ */
|
|
4886
|
+
children: /* @__PURE__ */ jsxs19("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: [
|
|
4887
|
+
currentResult?.status === "processing" && /* @__PURE__ */ jsxs19("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
|
|
4888
|
+
/* @__PURE__ */ jsx21("div", { style: { width: 36, height: 36, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
|
|
4889
|
+
/* @__PURE__ */ jsx21("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.4)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
|
|
4150
4890
|
] }),
|
|
4151
|
-
currentResult?.status === "error" && /* @__PURE__ */
|
|
4152
|
-
/* @__PURE__ */
|
|
4153
|
-
/* @__PURE__ */
|
|
4154
|
-
/* @__PURE__ */
|
|
4891
|
+
currentResult?.status === "error" && /* @__PURE__ */ jsxs19("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
|
|
4892
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
|
|
4893
|
+
/* @__PURE__ */ jsx21("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
|
|
4894
|
+
/* @__PURE__ */ jsx21("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" })
|
|
4155
4895
|
] }),
|
|
4156
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */
|
|
4157
|
-
!currentResult && /* @__PURE__ */
|
|
4158
|
-
/* @__PURE__ */
|
|
4159
|
-
/* @__PURE__ */
|
|
4896
|
+
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx21("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
|
|
4897
|
+
!currentResult && /* @__PURE__ */ jsxs19("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
|
|
4898
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
|
|
4899
|
+
/* @__PURE__ */ jsx21("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
|
|
4160
4900
|
] }),
|
|
4161
|
-
currentResult?.status === "done" && /* @__PURE__ */
|
|
4162
|
-
history.length > 1 && currentResult && /* @__PURE__ */
|
|
4163
|
-
/* @__PURE__ */
|
|
4164
|
-
/* @__PURE__ */
|
|
4165
|
-
/* @__PURE__ */
|
|
4901
|
+
currentResult?.status === "done" && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
|
|
4902
|
+
history.length > 1 && currentResult && /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
4903
|
+
/* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
|
|
4904
|
+
/* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
|
|
4905
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4166
4906
|
currentIndex + 1,
|
|
4167
4907
|
" / ",
|
|
4168
4908
|
history.length
|
|
@@ -4171,42 +4911,42 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4171
4911
|
] })
|
|
4172
4912
|
}
|
|
4173
4913
|
),
|
|
4174
|
-
currentResult?.status === "done" && /* @__PURE__ */
|
|
4175
|
-
/* @__PURE__ */
|
|
4176
|
-
/* @__PURE__ */
|
|
4177
|
-
/* @__PURE__ */
|
|
4914
|
+
currentResult?.status === "done" && /* @__PURE__ */ jsxs19("div", { style: { padding: "0 16px 16px", display: "flex", gap: 8, flexShrink: 0 }, children: [
|
|
4915
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4916
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
|
|
4917
|
+
/* @__PURE__ */ jsx21("span", { children: "Prompt" })
|
|
4178
4918
|
] }),
|
|
4179
|
-
/* @__PURE__ */
|
|
4180
|
-
/* @__PURE__ */
|
|
4181
|
-
/* @__PURE__ */
|
|
4919
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4920
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
|
|
4921
|
+
/* @__PURE__ */ jsx21("span", { children: "Referenz" })
|
|
4182
4922
|
] }),
|
|
4183
|
-
/* @__PURE__ */
|
|
4184
|
-
/* @__PURE__ */
|
|
4185
|
-
/* @__PURE__ */
|
|
4923
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4924
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "download" }),
|
|
4925
|
+
/* @__PURE__ */ jsx21("span", { children: "Laden" })
|
|
4186
4926
|
] })
|
|
4187
4927
|
] })
|
|
4188
4928
|
] })
|
|
4189
4929
|
] }) });
|
|
4190
4930
|
}
|
|
4191
|
-
return /* @__PURE__ */
|
|
4192
|
-
/* @__PURE__ */
|
|
4193
|
-
/* @__PURE__ */
|
|
4194
|
-
/* @__PURE__ */
|
|
4195
|
-
!isLeftCollapsed && /* @__PURE__ */
|
|
4196
|
-
workspaceTags && /* @__PURE__ */
|
|
4197
|
-
/* @__PURE__ */
|
|
4931
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
|
|
4932
|
+
/* @__PURE__ */ jsx21("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ jsx21("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
|
|
4933
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4934
|
+
/* @__PURE__ */ jsxs19("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
|
|
4935
|
+
!isLeftCollapsed && /* @__PURE__ */ jsxs19("div", { className: "flex flex-1 gap-1", children: [
|
|
4936
|
+
workspaceTags && /* @__PURE__ */ jsxs19("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: [
|
|
4937
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }),
|
|
4198
4938
|
"Prompt"
|
|
4199
4939
|
] }),
|
|
4200
|
-
/* @__PURE__ */
|
|
4201
|
-
/* @__PURE__ */
|
|
4940
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
4941
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[14px]", children: "account_tree" }),
|
|
4202
4942
|
"Hierarchie"
|
|
4203
4943
|
] }),
|
|
4204
|
-
workspaceTags && /* @__PURE__ */
|
|
4944
|
+
workspaceTags && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
|
|
4205
4945
|
] }),
|
|
4206
|
-
/* @__PURE__ */
|
|
4946
|
+
/* @__PURE__ */ jsx21("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" })
|
|
4207
4947
|
] }),
|
|
4208
|
-
!isLeftCollapsed && /* @__PURE__ */
|
|
4209
|
-
activeTab === "tags" && workspaceTags && /* @__PURE__ */
|
|
4948
|
+
!isLeftCollapsed && /* @__PURE__ */ jsxs19("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
4949
|
+
activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx21(
|
|
4210
4950
|
TagManagerPanel,
|
|
4211
4951
|
{
|
|
4212
4952
|
workspaceTags,
|
|
@@ -4217,11 +4957,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4217
4957
|
onTagMove: handleTagMove
|
|
4218
4958
|
}
|
|
4219
4959
|
),
|
|
4220
|
-
activeTab === "tags" && !workspaceTags && /* @__PURE__ */
|
|
4221
|
-
/* @__PURE__ */
|
|
4222
|
-
/* @__PURE__ */
|
|
4960
|
+
activeTab === "tags" && !workspaceTags && /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ jsxs19("div", { children: [
|
|
4961
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
|
|
4962
|
+
/* @__PURE__ */ jsx21("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
|
|
4223
4963
|
] }) }),
|
|
4224
|
-
leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */
|
|
4964
|
+
leftTab === "hierarchy" && activeTab !== "tags" && /* @__PURE__ */ jsx21("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx21(
|
|
4225
4965
|
ListView,
|
|
4226
4966
|
{
|
|
4227
4967
|
nodes,
|
|
@@ -4246,18 +4986,18 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4246
4986
|
isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
|
|
4247
4987
|
}
|
|
4248
4988
|
) }),
|
|
4249
|
-
leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */
|
|
4989
|
+
leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ jsx21(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 })
|
|
4250
4990
|
] })
|
|
4251
4991
|
] }),
|
|
4252
|
-
!isLeftCollapsed && /* @__PURE__ */
|
|
4253
|
-
/* @__PURE__ */
|
|
4254
|
-
/* @__PURE__ */
|
|
4255
|
-
/* @__PURE__ */
|
|
4256
|
-
/* @__PURE__ */
|
|
4257
|
-
/* @__PURE__ */
|
|
4992
|
+
!isLeftCollapsed && /* @__PURE__ */ jsx21("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
4993
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
|
|
4994
|
+
/* @__PURE__ */ jsxs19("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
|
|
4995
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1.5", children: [
|
|
4996
|
+
/* @__PURE__ */ jsx21(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
|
|
4997
|
+
/* @__PURE__ */ jsx21(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" }] })
|
|
4258
4998
|
] }),
|
|
4259
|
-
/* @__PURE__ */
|
|
4260
|
-
/* @__PURE__ */
|
|
4999
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1 mx-auto", children: [
|
|
5000
|
+
/* @__PURE__ */ jsx21(
|
|
4261
5001
|
"button",
|
|
4262
5002
|
{
|
|
4263
5003
|
onClick: () => setMiddlePanel("stage"),
|
|
@@ -4265,7 +5005,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4265
5005
|
children: "Stage"
|
|
4266
5006
|
}
|
|
4267
5007
|
),
|
|
4268
|
-
/* @__PURE__ */
|
|
5008
|
+
/* @__PURE__ */ jsx21(
|
|
4269
5009
|
"button",
|
|
4270
5010
|
{
|
|
4271
5011
|
onClick: () => setMiddlePanel("labs"),
|
|
@@ -4274,68 +5014,68 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4274
5014
|
}
|
|
4275
5015
|
)
|
|
4276
5016
|
] }),
|
|
4277
|
-
/* @__PURE__ */
|
|
4278
|
-
activeReferenceThumbnail ? /* @__PURE__ */
|
|
4279
|
-
/* @__PURE__ */
|
|
4280
|
-
/* @__PURE__ */
|
|
4281
|
-
/* @__PURE__ */
|
|
4282
|
-
] }) : /* @__PURE__ */
|
|
4283
|
-
/* @__PURE__ */
|
|
4284
|
-
/* @__PURE__ */
|
|
5017
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
|
|
5018
|
+
activeReferenceThumbnail ? /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
|
|
5019
|
+
/* @__PURE__ */ jsx21("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
|
|
5020
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
|
|
5021
|
+
/* @__PURE__ */ jsx21("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
|
|
5022
|
+
] }) : /* @__PURE__ */ jsxs19("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: [
|
|
5023
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
|
|
5024
|
+
/* @__PURE__ */ jsx21("span", { children: "Ref" })
|
|
4285
5025
|
] }),
|
|
4286
|
-
/* @__PURE__ */
|
|
4287
|
-
/* @__PURE__ */
|
|
5026
|
+
/* @__PURE__ */ jsx21("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
|
|
5027
|
+
/* @__PURE__ */ jsx21(PillButton, { variant: "solid", icon: "bolt", loading: isGenerating, disabled: !activePrompt.trim(), onClick: () => handleGenerateImage(), children: "Generieren" })
|
|
4288
5028
|
] })
|
|
4289
5029
|
] }),
|
|
4290
|
-
/* @__PURE__ */
|
|
4291
|
-
!isPromptCollapsed && /* @__PURE__ */
|
|
4292
|
-
/* @__PURE__ */
|
|
4293
|
-
activePrompt && !isSynthesizing && /* @__PURE__ */
|
|
5030
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
|
|
5031
|
+
!isPromptCollapsed && /* @__PURE__ */ jsx21("div", { className: "px-6 py-4 border-b border-white/5 bg-black/10 overflow-hidden shrink-0", children: /* @__PURE__ */ jsxs19("div", { className: `relative min-h-[60px] p-4 rounded-2xl border transition-all ${isSynthesizing ? "prompt-loading" : "bg-white/5 border-white/10"}`, children: [
|
|
5032
|
+
/* @__PURE__ */ jsx21("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..." }),
|
|
5033
|
+
activePrompt && !isSynthesizing && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
|
|
4294
5034
|
] }) }),
|
|
4295
|
-
middlePanel === "labs" ? /* @__PURE__ */
|
|
5035
|
+
middlePanel === "labs" ? /* @__PURE__ */ jsx21("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx21(LabsTab, { services: labServices, onResult: (item) => {
|
|
4296
5036
|
const frame = item.frames[0];
|
|
4297
5037
|
if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
|
|
4298
|
-
} }) }) : /* @__PURE__ */
|
|
4299
|
-
isGenerating && currentResult?.status === "done" && /* @__PURE__ */
|
|
4300
|
-
/* @__PURE__ */
|
|
4301
|
-
/* @__PURE__ */
|
|
5038
|
+
} }) }) : /* @__PURE__ */ jsx21("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ jsxs19("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: [
|
|
5039
|
+
isGenerating && currentResult?.status === "done" && /* @__PURE__ */ jsxs19("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: [
|
|
5040
|
+
/* @__PURE__ */ jsx21("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
|
|
5041
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
|
|
4302
5042
|
] }),
|
|
4303
|
-
currentResult ? currentResult.status === "processing" ? /* @__PURE__ */
|
|
4304
|
-
/* @__PURE__ */
|
|
4305
|
-
/* @__PURE__ */
|
|
4306
|
-
] }) : currentResult.status === "error" ? /* @__PURE__ */
|
|
4307
|
-
/* @__PURE__ */
|
|
4308
|
-
/* @__PURE__ */
|
|
4309
|
-
/* @__PURE__ */
|
|
4310
|
-
/* @__PURE__ */
|
|
5043
|
+
currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-4", children: [
|
|
5044
|
+
/* @__PURE__ */ jsx21("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
|
|
5045
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
5046
|
+
] }) : currentResult.status === "error" ? /* @__PURE__ */ jsxs19("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
|
|
5047
|
+
/* @__PURE__ */ jsx21("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
|
|
5048
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-2", children: [
|
|
5049
|
+
/* @__PURE__ */ jsx21("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
|
|
5050
|
+
/* @__PURE__ */ jsx21("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
4311
5051
|
] }),
|
|
4312
|
-
/* @__PURE__ */
|
|
4313
|
-
] }) : /* @__PURE__ */
|
|
4314
|
-
/* @__PURE__ */
|
|
4315
|
-
/* @__PURE__ */
|
|
4316
|
-
/* @__PURE__ */
|
|
4317
|
-
/* @__PURE__ */
|
|
4318
|
-
/* @__PURE__ */
|
|
5052
|
+
/* @__PURE__ */ jsx21(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
|
|
5053
|
+
] }) : /* @__PURE__ */ jsxs19("div", { className: "h-full w-full relative flex items-center justify-center", children: [
|
|
5054
|
+
/* @__PURE__ */ jsx21("img", { src: currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
|
|
5055
|
+
/* @__PURE__ */ jsxs19("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: [
|
|
5056
|
+
/* @__PURE__ */ jsx21(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
|
|
5057
|
+
/* @__PURE__ */ jsx21(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
|
|
5058
|
+
/* @__PURE__ */ jsx21(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
|
|
4319
5059
|
] })
|
|
4320
|
-
] }) : /* @__PURE__ */
|
|
4321
|
-
/* @__PURE__ */
|
|
4322
|
-
/* @__PURE__ */
|
|
5060
|
+
] }) : /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
5061
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
|
|
5062
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
4323
5063
|
] })
|
|
4324
5064
|
] }) })
|
|
4325
5065
|
] })
|
|
4326
5066
|
] }),
|
|
4327
|
-
!isRightCollapsed && /* @__PURE__ */
|
|
4328
|
-
/* @__PURE__ */
|
|
4329
|
-
/* @__PURE__ */
|
|
4330
|
-
/* @__PURE__ */
|
|
5067
|
+
!isRightCollapsed && /* @__PURE__ */ jsx21("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
5068
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
|
|
5069
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
|
|
5070
|
+
/* @__PURE__ */ jsx21("div", { className: "flex flex-1", children: ["history", "gallery", "inspect", "setup", "sync", "tags"].map((tab) => /* @__PURE__ */ jsx21("button", { onClick: () => {
|
|
4331
5071
|
setActiveTab(tab);
|
|
4332
5072
|
setIsRightCollapsed(false);
|
|
4333
|
-
}, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */
|
|
4334
|
-
hfToken && /* @__PURE__ */
|
|
4335
|
-
/* @__PURE__ */
|
|
5073
|
+
}, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ jsx21("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)) }),
|
|
5074
|
+
hfToken && /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
|
|
5075
|
+
/* @__PURE__ */ jsx21("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
|
|
4336
5076
|
] }),
|
|
4337
|
-
!isRightCollapsed && /* @__PURE__ */
|
|
4338
|
-
activeTab === "tags" && workspaceTags && /* @__PURE__ */
|
|
5077
|
+
!isRightCollapsed && /* @__PURE__ */ jsxs19("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
5078
|
+
activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx21(
|
|
4339
5079
|
TagManagerPanel,
|
|
4340
5080
|
{
|
|
4341
5081
|
workspaceTags,
|
|
@@ -4346,12 +5086,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4346
5086
|
onTagMove: handleTagMove
|
|
4347
5087
|
}
|
|
4348
5088
|
),
|
|
4349
|
-
activeTab === "tags" && !workspaceTags && /* @__PURE__ */
|
|
4350
|
-
/* @__PURE__ */
|
|
4351
|
-
/* @__PURE__ */
|
|
5089
|
+
activeTab === "tags" && !workspaceTags && /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center h-full p-8 text-center", children: /* @__PURE__ */ jsxs19("div", { children: [
|
|
5090
|
+
/* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
|
|
5091
|
+
/* @__PURE__ */ jsx21("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
|
|
4352
5092
|
] }) }),
|
|
4353
|
-
activeTab === "history" && /* @__PURE__ */
|
|
4354
|
-
activeTab === "gallery" && /* @__PURE__ */
|
|
5093
|
+
activeTab === "history" && /* @__PURE__ */ jsx21(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: setCurrentResult, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
5094
|
+
activeTab === "gallery" && /* @__PURE__ */ jsx21(
|
|
4355
5095
|
MediaLibrary,
|
|
4356
5096
|
{
|
|
4357
5097
|
items: galleryItems,
|
|
@@ -4365,11 +5105,12 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4365
5105
|
onGenerateReference: (item) => handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true })
|
|
4366
5106
|
}
|
|
4367
5107
|
),
|
|
4368
|
-
activeTab === "inspect" && /* @__PURE__ */
|
|
4369
|
-
activeTab === "setup" && /* @__PURE__ */
|
|
4370
|
-
activeTab === "sync" && /* @__PURE__ */
|
|
5108
|
+
activeTab === "inspect" && /* @__PURE__ */ jsx21(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
|
|
5109
|
+
activeTab === "setup" && /* @__PURE__ */ jsx21(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
|
|
5110
|
+
activeTab === "sync" && /* @__PURE__ */ jsx21(
|
|
4371
5111
|
ProjectSyncTab,
|
|
4372
5112
|
{
|
|
5113
|
+
topSlot: syncTopSlot,
|
|
4373
5114
|
onProjectExport: handleProjectExport,
|
|
4374
5115
|
onProjectImport: (f) => handleProjectImport(f),
|
|
4375
5116
|
onWorkspaceImport: handleWorkspaceImport,
|
|
@@ -4396,7 +5137,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4396
5137
|
}
|
|
4397
5138
|
|
|
4398
5139
|
// src/components/FaApp.tsx
|
|
4399
|
-
import {
|
|
5140
|
+
import { useState as useState17, useEffect as useEffect7 } from "react";
|
|
5141
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
4400
5142
|
function FaApp({
|
|
4401
5143
|
onGenerateImage,
|
|
4402
5144
|
onGeneratePrompt,
|
|
@@ -4407,17 +5149,27 @@ function FaApp({
|
|
|
4407
5149
|
onFlowUpload: _onFlowUpload,
|
|
4408
5150
|
onFlowMediaUpload: _onFlowMediaUpload,
|
|
4409
5151
|
libToken,
|
|
5152
|
+
allowDevNamespace,
|
|
5153
|
+
serverBaseUrl,
|
|
4410
5154
|
onFetchServerProjects,
|
|
4411
5155
|
onServerSave,
|
|
4412
5156
|
onServerLoad,
|
|
4413
5157
|
onServerDelete,
|
|
4414
5158
|
buildInfo
|
|
4415
5159
|
}) {
|
|
5160
|
+
const [hfNamespace, setHfNamespace] = useState17(void 0);
|
|
5161
|
+
useEffect7(() => {
|
|
5162
|
+
if (!serverBaseUrl) return;
|
|
5163
|
+
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
5164
|
+
if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
|
|
5165
|
+
}).catch(() => {
|
|
5166
|
+
});
|
|
5167
|
+
}, [serverBaseUrl]);
|
|
4416
5168
|
const wrappedPrompt = async (text, options) => {
|
|
4417
5169
|
const result = await onGeneratePrompt(text, options);
|
|
4418
5170
|
return result.text;
|
|
4419
5171
|
};
|
|
4420
|
-
return /* @__PURE__ */
|
|
5172
|
+
return /* @__PURE__ */ jsx22(
|
|
4421
5173
|
AvatarArchitectApp,
|
|
4422
5174
|
{
|
|
4423
5175
|
onGenerateImage,
|
|
@@ -4425,6 +5177,8 @@ function FaApp({
|
|
|
4425
5177
|
onDownload,
|
|
4426
5178
|
onSelectMedia,
|
|
4427
5179
|
initialHfToken: libToken ? libToken.startsWith("hf_") ? libToken : `hf_${libToken}` : void 0,
|
|
5180
|
+
hfNamespace,
|
|
5181
|
+
allowDevNamespace: !hfNamespace && allowDevNamespace,
|
|
4428
5182
|
onFetchServerProjects,
|
|
4429
5183
|
onServerSave,
|
|
4430
5184
|
onServerLoad,
|
|
@@ -4435,7 +5189,7 @@ function FaApp({
|
|
|
4435
5189
|
}
|
|
4436
5190
|
|
|
4437
5191
|
// src/index.ts
|
|
4438
|
-
var LIB_VERSION = "
|
|
5192
|
+
var LIB_VERSION = "2.0.13";
|
|
4439
5193
|
export {
|
|
4440
5194
|
AvatarArchitectApp,
|
|
4441
5195
|
CollapsibleCard,
|
|
@@ -4460,9 +5214,12 @@ export {
|
|
|
4460
5214
|
SectionLabel,
|
|
4461
5215
|
SetupPanel,
|
|
4462
5216
|
TagManagerPanel,
|
|
5217
|
+
applyEvent,
|
|
5218
|
+
applyEvents,
|
|
4463
5219
|
autoLabel,
|
|
4464
5220
|
buildBlendInstruction,
|
|
4465
5221
|
buildCompareInstruction,
|
|
5222
|
+
buildDag,
|
|
4466
5223
|
buildFallbackPrompt,
|
|
4467
5224
|
buildGenerationPrompt,
|
|
4468
5225
|
buildImageGenerationOptions,
|
|
@@ -4474,27 +5231,36 @@ export {
|
|
|
4474
5231
|
cleanAiResponse,
|
|
4475
5232
|
createFlowServices,
|
|
4476
5233
|
exportProjectToZip,
|
|
5234
|
+
findForks,
|
|
5235
|
+
findTips,
|
|
4477
5236
|
formatTreeToMarkdown,
|
|
4478
5237
|
frameToGeneration,
|
|
4479
5238
|
getFormattedTimestamp,
|
|
4480
5239
|
getHFToken,
|
|
5240
|
+
getSessionClientId,
|
|
4481
5241
|
groupGenerationsToLabItems,
|
|
5242
|
+
hfBatchArchive,
|
|
5243
|
+
hfBootstrapFromLegacy,
|
|
4482
5244
|
hfDeleteProject,
|
|
4483
5245
|
hfDownloadProject,
|
|
5246
|
+
hfListDir,
|
|
4484
5247
|
hfListProjects,
|
|
4485
5248
|
hfLoadImageAsBase64,
|
|
4486
|
-
hfLoadMetadata,
|
|
4487
|
-
hfLoadTags,
|
|
4488
|
-
hfSaveMetadata,
|
|
4489
|
-
hfSaveTags,
|
|
4490
5249
|
hfUploadImage,
|
|
4491
5250
|
hfUploadProjectForm,
|
|
5251
|
+
hfUploadSmallFile,
|
|
4492
5252
|
importProjectFromZip,
|
|
4493
5253
|
injectXMPMetadata,
|
|
4494
5254
|
interpretSdkError,
|
|
5255
|
+
loadHFState,
|
|
5256
|
+
loadPendingEvents,
|
|
4495
5257
|
parsePromptFile,
|
|
4496
5258
|
parsePromptResponse,
|
|
4497
5259
|
setHFToken,
|
|
5260
|
+
topoSort,
|
|
5261
|
+
tsFromEventPath,
|
|
5262
|
+
useHFState,
|
|
4498
5263
|
useKeyboardNavigation,
|
|
4499
|
-
useOnClickOutside
|
|
5264
|
+
useOnClickOutside,
|
|
5265
|
+
writeHFEvent
|
|
4500
5266
|
};
|