@rslsp1/fa-app-tools 1.2.4 → 1.2.5
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-UFXDXENC.mjs +218 -0
- package/dist/chunk-UZE44WOR.mjs +99 -0
- package/dist/hfStateService-Y563AT2M.mjs +18 -0
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +437 -123
- package/dist/index.mjs +197 -219
- package/dist/project-O4ORKXY5.mjs +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// src/lib/project.ts
|
|
2
|
+
import JSZip from "jszip";
|
|
3
|
+
|
|
4
|
+
// src/lib/metadata.ts
|
|
5
|
+
var crcTable = (() => {
|
|
6
|
+
let c;
|
|
7
|
+
const table = new Uint32Array(256);
|
|
8
|
+
for (let n = 0; n < 256; n++) {
|
|
9
|
+
c = n;
|
|
10
|
+
for (let k = 0; k < 8; k++) {
|
|
11
|
+
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
12
|
+
}
|
|
13
|
+
table[n] = c;
|
|
14
|
+
}
|
|
15
|
+
return table;
|
|
16
|
+
})();
|
|
17
|
+
function calculateCRC(bytes) {
|
|
18
|
+
let crc = 4294967295;
|
|
19
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
20
|
+
crc = crcTable[(crc ^ bytes[i]) & 255] ^ crc >>> 8;
|
|
21
|
+
}
|
|
22
|
+
return (crc ^ 4294967295) >>> 0;
|
|
23
|
+
}
|
|
24
|
+
function indexOfBytes(buffer, search, start = 0) {
|
|
25
|
+
for (let i = start; i <= buffer.length - search.length; i++) {
|
|
26
|
+
let found = true;
|
|
27
|
+
for (let j = 0; j < search.length; j++) {
|
|
28
|
+
if (buffer[i + j] !== search[j]) {
|
|
29
|
+
found = false;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (found) return i;
|
|
34
|
+
}
|
|
35
|
+
return -1;
|
|
36
|
+
}
|
|
37
|
+
function createXMPPacket(prompt, seed, model, id, tags = [], hierarchy) {
|
|
38
|
+
const sanitize = (str) => (str || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
39
|
+
const escPrompt = sanitize(prompt);
|
|
40
|
+
const escModel = sanitize(model || "AI Model");
|
|
41
|
+
const escHierarchy = sanitize(hierarchy || "");
|
|
42
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
43
|
+
const allTags = [.../* @__PURE__ */ new Set([...tags, "Avatar Architect", escModel])];
|
|
44
|
+
const rdfTags = allTags.map((t) => `<rdf:li>${sanitize(t)}</rdf:li>`).join("");
|
|
45
|
+
const BOM = "\uFEFF";
|
|
46
|
+
return `<?xpacket begin="${BOM}" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
|
47
|
+
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c140">
|
|
48
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
49
|
+
<rdf:Description rdf:about=""
|
|
50
|
+
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
|
|
51
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
52
|
+
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
|
|
53
|
+
xmlns:ai="http://ns.flow.creative/ai/1.0/">
|
|
54
|
+
<dc:format>image/png</dc:format>
|
|
55
|
+
<dc:description><rdf:Alt><rdf:li xml:lang="x-default">${escPrompt}</rdf:li></rdf:Alt></dc:description>
|
|
56
|
+
<dc:subject><rdf:Bag>${rdfTags}</rdf:Bag></dc:subject>
|
|
57
|
+
<photoshop:Instructions>Seed: ${seed} | Model: ${escModel}</photoshop:Instructions>
|
|
58
|
+
<xmp:CreateDate>${timestamp}</xmp:CreateDate>
|
|
59
|
+
<ai:prompt>${escPrompt}</ai:prompt>
|
|
60
|
+
<ai:seed>${seed ?? "0"}</ai:seed>
|
|
61
|
+
<ai:model>${escModel}</ai:model>
|
|
62
|
+
<ai:hierarchy>${escHierarchy}</ai:hierarchy>
|
|
63
|
+
</rdf:Description>
|
|
64
|
+
</rdf:RDF>
|
|
65
|
+
</x:xmpmeta>${" ".repeat(1024)}<?xpacket end="w"?>`;
|
|
66
|
+
}
|
|
67
|
+
function bytesToBase64(bytes) {
|
|
68
|
+
let binary = "";
|
|
69
|
+
const len = bytes.byteLength;
|
|
70
|
+
for (let i = 0; i < len; i++) binary += String.fromCharCode(bytes[i]);
|
|
71
|
+
return btoa(binary);
|
|
72
|
+
}
|
|
73
|
+
function base64ToBytes(base64) {
|
|
74
|
+
const clean = base64.includes(",") ? base64.split(",")[1] : base64.trim();
|
|
75
|
+
try {
|
|
76
|
+
const binary = atob(clean);
|
|
77
|
+
const bytes = new Uint8Array(binary.length);
|
|
78
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
79
|
+
return bytes;
|
|
80
|
+
} catch (e) {
|
|
81
|
+
return new Uint8Array(0);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function injectXMPMetadata(base64, prompt, seed, model, id, tags = [], hierarchy) {
|
|
85
|
+
try {
|
|
86
|
+
const bytes = base64ToBytes(base64);
|
|
87
|
+
if (bytes.length < 8 || bytes[0] !== 137 || bytes[1] !== 80) {
|
|
88
|
+
console.warn("Metadaten-Injektion \xFCbersprungen: Datei ist kein PNG.");
|
|
89
|
+
return base64;
|
|
90
|
+
}
|
|
91
|
+
const xmpData = createXMPPacket(prompt, seed, model, id, tags, hierarchy);
|
|
92
|
+
const encoder = new TextEncoder();
|
|
93
|
+
const keyword = encoder.encode("XML:com.adobe.xmp");
|
|
94
|
+
const textBytes = encoder.encode(xmpData);
|
|
95
|
+
const chunkData = new Uint8Array(keyword.length + 5 + textBytes.length);
|
|
96
|
+
chunkData.set(keyword, 0);
|
|
97
|
+
chunkData.set(textBytes, keyword.length + 5);
|
|
98
|
+
const type = encoder.encode("iTXt");
|
|
99
|
+
const crcInput = new Uint8Array(type.length + chunkData.length);
|
|
100
|
+
crcInput.set(type, 0);
|
|
101
|
+
crcInput.set(chunkData, type.length);
|
|
102
|
+
const crc = calculateCRC(crcInput);
|
|
103
|
+
const fullChunk = new Uint8Array(4 + 4 + chunkData.length + 4);
|
|
104
|
+
const view = new DataView(fullChunk.buffer);
|
|
105
|
+
view.setUint32(0, chunkData.length);
|
|
106
|
+
fullChunk.set(type, 4);
|
|
107
|
+
fullChunk.set(chunkData, 8);
|
|
108
|
+
view.setUint32(8 + chunkData.length, crc);
|
|
109
|
+
const IDAT = encoder.encode("IDAT");
|
|
110
|
+
const idatPos = indexOfBytes(bytes, IDAT);
|
|
111
|
+
const insertPos = idatPos !== -1 ? idatPos - 4 : 8;
|
|
112
|
+
const result = new Uint8Array(bytes.length + fullChunk.length);
|
|
113
|
+
result.set(bytes.slice(0, insertPos), 0);
|
|
114
|
+
result.set(fullChunk, insertPos);
|
|
115
|
+
result.set(bytes.slice(insertPos), insertPos + fullChunk.length);
|
|
116
|
+
return bytesToBase64(result);
|
|
117
|
+
} catch (e) {
|
|
118
|
+
console.error("Fehler beim Einbetten der Metadaten:", e);
|
|
119
|
+
return base64;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/lib/project.ts
|
|
124
|
+
function generateMarkdownReport(nodes, history) {
|
|
125
|
+
let md = "# Avatar Architect - Projekt Report\n\n";
|
|
126
|
+
md += `Exportiert: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
127
|
+
|
|
128
|
+
`;
|
|
129
|
+
md += "## Hierarchie\n";
|
|
130
|
+
nodes.forEach((n) => {
|
|
131
|
+
md += `- **${n.data?.label || "Unbenannt"}**
|
|
132
|
+
`;
|
|
133
|
+
});
|
|
134
|
+
md += "\n## Historie der Generationen\n";
|
|
135
|
+
history.forEach((h, i) => {
|
|
136
|
+
md += `### ${i + 1}. Generation (${h.model || "AI"})
|
|
137
|
+
`;
|
|
138
|
+
md += `- **Zeitstempel**: ${new Date(h.timestamp).toLocaleString()}
|
|
139
|
+
`;
|
|
140
|
+
md += `- **Seed**: ${h.seed}
|
|
141
|
+
`;
|
|
142
|
+
md += `- **Prompt**:
|
|
143
|
+
> ${h.prompt}
|
|
144
|
+
|
|
145
|
+
`;
|
|
146
|
+
});
|
|
147
|
+
return md;
|
|
148
|
+
}
|
|
149
|
+
async function exportProjectToZip(nodes, edges, history, galleryItems, settings, workspaceTags, recentLabItemIds) {
|
|
150
|
+
const zip = new JSZip();
|
|
151
|
+
const projectData = {
|
|
152
|
+
nodes,
|
|
153
|
+
edges,
|
|
154
|
+
history: history.map((h) => ({ ...h, base64: void 0 })),
|
|
155
|
+
galleryItems: galleryItems.map((g) => ({ ...g, base64: void 0 })),
|
|
156
|
+
settings,
|
|
157
|
+
workspaceTags: workspaceTags || null,
|
|
158
|
+
recentLabItemIds: recentLabItemIds || [],
|
|
159
|
+
version: "1.3.0"
|
|
160
|
+
};
|
|
161
|
+
zip.file("project.json", JSON.stringify(projectData, null, 2));
|
|
162
|
+
zip.file("projekt_bericht.md", generateMarkdownReport(nodes, history));
|
|
163
|
+
const imgFolder = zip.folder("images");
|
|
164
|
+
if (imgFolder) {
|
|
165
|
+
const allItems = [...history, ...galleryItems];
|
|
166
|
+
for (const item of allItems) {
|
|
167
|
+
if (item.base64) {
|
|
168
|
+
try {
|
|
169
|
+
const cleanB64 = item.base64.includes(",") ? item.base64.split(",")[1] : item.base64;
|
|
170
|
+
const withMeta = injectXMPMetadata(cleanB64, item.prompt || "", item.seed, item.model, item.id, item.tags || []);
|
|
171
|
+
imgFolder.file(`${item.id}.png`, withMeta, { base64: true });
|
|
172
|
+
} catch (e) {
|
|
173
|
+
console.error("Fehler beim Packen eines Bildes:", e);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const blob = await zip.generateAsync({ type: "blob", compression: "STORE" });
|
|
179
|
+
return blobToBase64(blob);
|
|
180
|
+
}
|
|
181
|
+
async function blobToBase64(blob) {
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
const reader = new FileReader();
|
|
184
|
+
reader.onloadend = () => {
|
|
185
|
+
const result = reader.result;
|
|
186
|
+
resolve({ base64: result.split(",")[1] });
|
|
187
|
+
};
|
|
188
|
+
reader.onerror = reject;
|
|
189
|
+
reader.readAsDataURL(blob);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
async function importProjectFromZip(file) {
|
|
193
|
+
const zip = await JSZip.loadAsync(file);
|
|
194
|
+
const jsonStr = await zip.file("project.json")?.async("string");
|
|
195
|
+
if (!jsonStr) throw new Error("Keine project.json gefunden.");
|
|
196
|
+
const data = JSON.parse(jsonStr);
|
|
197
|
+
const imgFolder = zip.folder("images");
|
|
198
|
+
if (imgFolder) {
|
|
199
|
+
const loadImgs = async (items) => {
|
|
200
|
+
if (!items) return [];
|
|
201
|
+
return Promise.all(items.map(async (h) => {
|
|
202
|
+
const imgFile = zip.file(`images/${h.id}.png`);
|
|
203
|
+
if (!imgFile) return h;
|
|
204
|
+
const b64 = await imgFile.async("base64");
|
|
205
|
+
return { ...h, base64: `data:image/png;base64,${b64}` };
|
|
206
|
+
}));
|
|
207
|
+
};
|
|
208
|
+
data.history = await loadImgs(data.history || []);
|
|
209
|
+
data.galleryItems = await loadImgs(data.galleryItems || []);
|
|
210
|
+
}
|
|
211
|
+
return data;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export {
|
|
215
|
+
injectXMPMetadata,
|
|
216
|
+
exportProjectToZip,
|
|
217
|
+
importProjectFromZip
|
|
218
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// src/lib/hfStateService.ts
|
|
2
|
+
var HF_BASE = "https://huggingface.co";
|
|
3
|
+
var HF_REPO = "RolandSch/fa-app-state";
|
|
4
|
+
var HF_TOKEN_KEY = "hf-token";
|
|
5
|
+
function getHFToken() {
|
|
6
|
+
try {
|
|
7
|
+
return localStorage.getItem(HF_TOKEN_KEY);
|
|
8
|
+
} catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function setHFToken(token) {
|
|
13
|
+
try {
|
|
14
|
+
localStorage.setItem(HF_TOKEN_KEY, token);
|
|
15
|
+
} catch {
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function hfListProjects(token) {
|
|
19
|
+
const res = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/tree/main`, {
|
|
20
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
21
|
+
});
|
|
22
|
+
if (!res.ok) throw new Error(`HF list failed: ${res.status} ${res.statusText}`);
|
|
23
|
+
const files = await res.json();
|
|
24
|
+
return files.filter((f) => f.type === "file" && f.path.endsWith(".zip")).map((f) => ({
|
|
25
|
+
id: f.path.replace(/\.zip$/, ""),
|
|
26
|
+
name: f.path.replace(/\.zip$/, ""),
|
|
27
|
+
path: f.path,
|
|
28
|
+
size: f.size,
|
|
29
|
+
isLfs: !!f.lfs
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
async function hfDownloadProject(path, token) {
|
|
33
|
+
const res = await fetch(
|
|
34
|
+
`${HF_BASE}/datasets/${HF_REPO}/resolve/main/${path}?download=true`,
|
|
35
|
+
{ headers: { Authorization: `Bearer ${token}` } }
|
|
36
|
+
);
|
|
37
|
+
if (!res.ok) throw new Error(`HF download failed: ${res.status} ${res.statusText}`);
|
|
38
|
+
const blob = await res.blob();
|
|
39
|
+
return new File([blob], path, { type: "application/zip" });
|
|
40
|
+
}
|
|
41
|
+
async function hfUploadProject(zipBase64, name, token) {
|
|
42
|
+
const filename = name.endsWith(".zip") ? name : `${name}.zip`;
|
|
43
|
+
const binary = atob(zipBase64);
|
|
44
|
+
const bytes = new Uint8Array(binary.length);
|
|
45
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
46
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", bytes);
|
|
47
|
+
const oid = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
48
|
+
const size = bytes.length;
|
|
49
|
+
const preRes = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/preupload/main`, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
52
|
+
body: JSON.stringify({ files: [{ path: filename, sample: btoa(String.fromCharCode(...bytes.slice(0, 128))) }] })
|
|
53
|
+
});
|
|
54
|
+
if (!preRes.ok) throw new Error(`HF preupload failed: ${preRes.status} ${preRes.statusText}`);
|
|
55
|
+
const preData = await preRes.json();
|
|
56
|
+
const fileInfo = preData.files?.[0];
|
|
57
|
+
if (fileInfo?.uploadMode === "lfs" && fileInfo?.uploadUrl) {
|
|
58
|
+
const uploadRes = await fetch(fileInfo.uploadUrl, {
|
|
59
|
+
method: "PUT",
|
|
60
|
+
headers: { "Content-Type": "application/octet-stream", ...fileInfo.header || {} },
|
|
61
|
+
body: bytes
|
|
62
|
+
});
|
|
63
|
+
if (!uploadRes.ok) throw new Error(`HF LFS upload failed: ${uploadRes.status}`);
|
|
64
|
+
}
|
|
65
|
+
const commitRes = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" },
|
|
68
|
+
body: [
|
|
69
|
+
JSON.stringify({ key: "header", value: { summary: `Upload ${filename}`, description: "" } }),
|
|
70
|
+
JSON.stringify({ key: "lfsFile", value: { path: filename, algo: "sha256", oid, size } })
|
|
71
|
+
].join("\n")
|
|
72
|
+
});
|
|
73
|
+
if (!commitRes.ok) {
|
|
74
|
+
const err = await commitRes.text();
|
|
75
|
+
throw new Error(`HF commit failed: ${commitRes.status} \u2014 ${err}`);
|
|
76
|
+
}
|
|
77
|
+
return { id: filename.replace(/\.zip$/, ""), name: filename.replace(/\.zip$/, ""), path: filename, size, isLfs: true };
|
|
78
|
+
}
|
|
79
|
+
async function hfDeleteProject(path, token) {
|
|
80
|
+
const res = await fetch(`${HF_BASE}/api/datasets/${HF_REPO}/commit/main`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" },
|
|
83
|
+
body: [
|
|
84
|
+
JSON.stringify({ key: "header", value: { summary: `Delete ${path}`, description: "" } }),
|
|
85
|
+
JSON.stringify({ key: "deletedFile", value: { path } })
|
|
86
|
+
].join("\n")
|
|
87
|
+
});
|
|
88
|
+
if (!res.ok) throw new Error(`HF delete failed: ${res.status} ${res.statusText}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export {
|
|
92
|
+
HF_TOKEN_KEY,
|
|
93
|
+
getHFToken,
|
|
94
|
+
setHFToken,
|
|
95
|
+
hfListProjects,
|
|
96
|
+
hfDownloadProject,
|
|
97
|
+
hfUploadProject,
|
|
98
|
+
hfDeleteProject
|
|
99
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HF_TOKEN_KEY,
|
|
3
|
+
getHFToken,
|
|
4
|
+
hfDeleteProject,
|
|
5
|
+
hfDownloadProject,
|
|
6
|
+
hfListProjects,
|
|
7
|
+
hfUploadProject,
|
|
8
|
+
setHFToken
|
|
9
|
+
} from "./chunk-UZE44WOR.mjs";
|
|
10
|
+
export {
|
|
11
|
+
HF_TOKEN_KEY,
|
|
12
|
+
getHFToken,
|
|
13
|
+
hfDeleteProject,
|
|
14
|
+
hfDownloadProject,
|
|
15
|
+
hfListProjects,
|
|
16
|
+
hfUploadProject,
|
|
17
|
+
setHFToken
|
|
18
|
+
};
|
package/dist/index.d.mts
CHANGED
|
@@ -356,6 +356,9 @@ interface ProjectSyncTabProps {
|
|
|
356
356
|
onRefreshServerProjects?: () => Promise<void>;
|
|
357
357
|
onComputeSyncDiff?: () => Promise<SyncDiff>;
|
|
358
358
|
onExecuteSync?: (selectedLocalIds: string[]) => Promise<void>;
|
|
359
|
+
hfToken?: string;
|
|
360
|
+
onHfLoad?: (file: File) => void;
|
|
361
|
+
onProjectExportBase64?: () => Promise<string>;
|
|
359
362
|
}
|
|
360
363
|
declare const ProjectSyncTab: React.FC<ProjectSyncTabProps>;
|
|
361
364
|
|
|
@@ -445,6 +448,6 @@ declare function buildLoopInstruction(rounds: Array<{
|
|
|
445
448
|
declare function autoLabel(index: number): string;
|
|
446
449
|
declare function buildReferenceImageMediaIds(images: SelectedLabImage[]): string[];
|
|
447
450
|
|
|
448
|
-
declare const LIB_VERSION = "1.2.
|
|
451
|
+
declare const LIB_VERSION = "1.2.5";
|
|
449
452
|
|
|
450
453
|
export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, HistoryPanel, InspectPanel, LIB_VERSION, LabBlend, LabCompare, type LabFrame, LabImagePicker, type LabItem, LabLoop, LabRemix, type LabServices, LabsTab, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedLabImage, type SelectedTag, SetupPanel, type SyncDiff, TagManagerPanel, type TagOption, type WorkspaceTags, autoLabel, buildBlendInstruction, buildCompareInstruction, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildLoopInstruction, buildPromptTabPayload, buildReferenceImageMediaIds, buildRemixInstruction, buildScanInstruction, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, frameToGeneration, getFormattedTimestamp, groupGenerationsToLabItems, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, useKeyboardNavigation, useOnClickOutside };
|
package/dist/index.d.ts
CHANGED
|
@@ -356,6 +356,9 @@ interface ProjectSyncTabProps {
|
|
|
356
356
|
onRefreshServerProjects?: () => Promise<void>;
|
|
357
357
|
onComputeSyncDiff?: () => Promise<SyncDiff>;
|
|
358
358
|
onExecuteSync?: (selectedLocalIds: string[]) => Promise<void>;
|
|
359
|
+
hfToken?: string;
|
|
360
|
+
onHfLoad?: (file: File) => void;
|
|
361
|
+
onProjectExportBase64?: () => Promise<string>;
|
|
359
362
|
}
|
|
360
363
|
declare const ProjectSyncTab: React.FC<ProjectSyncTabProps>;
|
|
361
364
|
|
|
@@ -445,6 +448,6 @@ declare function buildLoopInstruction(rounds: Array<{
|
|
|
445
448
|
declare function autoLabel(index: number): string;
|
|
446
449
|
declare function buildReferenceImageMediaIds(images: SelectedLabImage[]): string[];
|
|
447
450
|
|
|
448
|
-
declare const LIB_VERSION = "1.2.
|
|
451
|
+
declare const LIB_VERSION = "1.2.5";
|
|
449
452
|
|
|
450
453
|
export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, HistoryPanel, InspectPanel, LIB_VERSION, LabBlend, LabCompare, type LabFrame, LabImagePicker, type LabItem, LabLoop, LabRemix, type LabServices, LabsTab, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedLabImage, type SelectedTag, SetupPanel, type SyncDiff, TagManagerPanel, type TagOption, type WorkspaceTags, autoLabel, buildBlendInstruction, buildCompareInstruction, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildLoopInstruction, buildPromptTabPayload, buildReferenceImageMediaIds, buildRemixInstruction, buildScanInstruction, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, frameToGeneration, getFormattedTimestamp, groupGenerationsToLabItems, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, useKeyboardNavigation, useOnClickOutside };
|