@teamflojo/floimg-studio-ui 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { jsxs as c, jsx as e, Fragment as P } from "react/jsx-runtime";
2
- import { memo as T, useRef as xe, useCallback as C, useState as N, useEffect as M, useMemo as te } from "react";
3
- import ke, { Handle as L, Position as W, applyNodeChanges as we, applyEdgeChanges as ve, MarkerType as ye, Background as Ne, Controls as ze, MiniMap as Ce, ReactFlowProvider as Se } from "reactflow";
4
- import { create as se } from "zustand";
5
- import { useQuery as _ } from "@tanstack/react-query";
6
- function Ie(r, i) {
1
+ import { jsxs as s, jsx as e, Fragment as U } from "react/jsx-runtime";
2
+ import { memo as E, useRef as Q, useCallback as L, useState as I, useEffect as D, useMemo as ne } from "react";
3
+ import we, { Handle as A, Position as P, applyNodeChanges as Ne, applyEdgeChanges as ze, MarkerType as Ce, Background as Ie, Controls as Se, MiniMap as Le, ReactFlowProvider as We, useReactFlow as Ae } from "reactflow";
4
+ import { create as ce } from "zustand";
5
+ import { useQuery as F } from "@tanstack/react-query";
6
+ function Pe(r, l) {
7
7
  let t;
8
8
  try {
9
9
  t = r();
@@ -11,250 +11,265 @@ function Ie(r, i) {
11
11
  return;
12
12
  }
13
13
  return {
14
- getItem: (s) => {
15
- var d;
16
- const m = (n) => n === null ? null : JSON.parse(n, void 0), o = (d = t.getItem(s)) != null ? d : null;
17
- return o instanceof Promise ? o.then(m) : m(o);
14
+ getItem: (o) => {
15
+ var i;
16
+ const m = (a) => a === null ? null : JSON.parse(a, void 0), d = (i = t.getItem(o)) != null ? i : null;
17
+ return d instanceof Promise ? d.then(m) : m(d);
18
18
  },
19
- setItem: (s, d) => t.setItem(s, JSON.stringify(d, void 0)),
20
- removeItem: (s) => t.removeItem(s)
19
+ setItem: (o, i) => t.setItem(o, JSON.stringify(i, void 0)),
20
+ removeItem: (o) => t.removeItem(o)
21
21
  };
22
22
  }
23
- const H = (r) => (i) => {
23
+ const Y = (r) => (l) => {
24
24
  try {
25
- const t = r(i);
25
+ const t = r(l);
26
26
  return t instanceof Promise ? t : {
27
- then(a) {
28
- return H(a)(t);
27
+ then(n) {
28
+ return Y(n)(t);
29
29
  },
30
- catch(a) {
30
+ catch(n) {
31
31
  return this;
32
32
  }
33
33
  };
34
34
  } catch (t) {
35
35
  return {
36
- then(a) {
36
+ then(n) {
37
37
  return this;
38
38
  },
39
- catch(a) {
40
- return H(a)(t);
39
+ catch(n) {
40
+ return Y(n)(t);
41
41
  }
42
42
  };
43
43
  }
44
- }, Le = (r, i) => (t, a, s) => {
45
- let d = {
46
- storage: Ie(() => localStorage),
47
- partialize: (g) => g,
44
+ }, $e = (r, l) => (t, n, o) => {
45
+ let i = {
46
+ storage: Pe(() => localStorage),
47
+ partialize: (v) => v,
48
48
  version: 0,
49
- merge: (g, v) => ({
50
- ...v,
51
- ...g
49
+ merge: (v, y) => ({
50
+ ...y,
51
+ ...v
52
52
  }),
53
- ...i
53
+ ...l
54
54
  }, m = !1;
55
- const o = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
56
- let u = d.storage;
57
- if (!u)
55
+ const d = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
56
+ let p = i.storage;
57
+ if (!p)
58
58
  return r(
59
- (...g) => {
59
+ (...v) => {
60
60
  console.warn(
61
- `[zustand persist middleware] Unable to update item '${d.name}', the given storage is currently unavailable.`
62
- ), t(...g);
61
+ `[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`
62
+ ), t(...v);
63
63
  },
64
- a,
65
- s
64
+ n,
65
+ o
66
66
  );
67
- const l = () => {
68
- const g = d.partialize({ ...a() });
69
- return u.setItem(d.name, {
70
- state: g,
71
- version: d.version
67
+ const c = () => {
68
+ const v = i.partialize({ ...n() });
69
+ return p.setItem(i.name, {
70
+ state: v,
71
+ version: i.version
72
72
  });
73
- }, p = s.setState;
74
- s.setState = (g, v) => (p(g, v), l());
75
- const f = r(
76
- (...g) => (t(...g), l()),
77
- a,
78
- s
73
+ }, u = o.setState;
74
+ o.setState = (v, y) => (u(v, y), c());
75
+ const h = r(
76
+ (...v) => (t(...v), c()),
77
+ n,
78
+ o
79
79
  );
80
- s.getInitialState = () => f;
81
- let b;
82
- const k = () => {
83
- var g, v;
84
- if (!u) return;
85
- m = !1, o.forEach((h) => {
86
- var z;
87
- return h((z = a()) != null ? z : f);
80
+ o.getInitialState = () => h;
81
+ let f;
82
+ const w = () => {
83
+ var v, y;
84
+ if (!p) return;
85
+ m = !1, d.forEach((g) => {
86
+ var N;
87
+ return g((N = n()) != null ? N : h);
88
88
  });
89
- const w = ((v = d.onRehydrateStorage) == null ? void 0 : v.call(d, (g = a()) != null ? g : f)) || void 0;
90
- return H(u.getItem.bind(u))(d.name).then((h) => {
91
- if (h)
92
- if (typeof h.version == "number" && h.version !== d.version) {
93
- if (d.migrate) {
94
- const z = d.migrate(
95
- h.state,
96
- h.version
89
+ const b = ((y = i.onRehydrateStorage) == null ? void 0 : y.call(i, (v = n()) != null ? v : h)) || void 0;
90
+ return Y(p.getItem.bind(p))(i.name).then((g) => {
91
+ if (g)
92
+ if (typeof g.version == "number" && g.version !== i.version) {
93
+ if (i.migrate) {
94
+ const N = i.migrate(
95
+ g.state,
96
+ g.version
97
97
  );
98
- return z instanceof Promise ? z.then((S) => [!0, S]) : [!0, z];
98
+ return N instanceof Promise ? N.then((W) => [!0, W]) : [!0, N];
99
99
  }
100
100
  console.error(
101
101
  "State loaded from storage couldn't be migrated since no migrate function was provided"
102
102
  );
103
103
  } else
104
- return [!1, h.state];
104
+ return [!1, g.state];
105
105
  return [!1, void 0];
106
- }).then((h) => {
107
- var z;
108
- const [S, B] = h;
109
- if (b = d.merge(
110
- B,
111
- (z = a()) != null ? z : f
112
- ), t(b, !0), S)
113
- return l();
106
+ }).then((g) => {
107
+ var N;
108
+ const [W, x] = g;
109
+ if (f = i.merge(
110
+ x,
111
+ (N = n()) != null ? N : h
112
+ ), t(f, !0), W)
113
+ return c();
114
114
  }).then(() => {
115
- w == null || w(b, void 0), b = a(), m = !0, n.forEach((h) => h(b));
116
- }).catch((h) => {
117
- w == null || w(void 0, h);
115
+ b == null || b(f, void 0), f = n(), m = !0, a.forEach((g) => g(f));
116
+ }).catch((g) => {
117
+ b == null || b(void 0, g);
118
118
  });
119
119
  };
120
- return s.persist = {
121
- setOptions: (g) => {
122
- d = {
123
- ...d,
124
- ...g
125
- }, g.storage && (u = g.storage);
120
+ return o.persist = {
121
+ setOptions: (v) => {
122
+ i = {
123
+ ...i,
124
+ ...v
125
+ }, v.storage && (p = v.storage);
126
126
  },
127
127
  clearStorage: () => {
128
- u == null || u.removeItem(d.name);
128
+ p == null || p.removeItem(i.name);
129
129
  },
130
- getOptions: () => d,
131
- rehydrate: () => k(),
130
+ getOptions: () => i,
131
+ rehydrate: () => w(),
132
132
  hasHydrated: () => m,
133
- onHydrate: (g) => (o.add(g), () => {
134
- o.delete(g);
133
+ onHydrate: (v) => (d.add(v), () => {
134
+ d.delete(v);
135
135
  }),
136
- onFinishHydration: (g) => (n.add(g), () => {
137
- n.delete(g);
136
+ onFinishHydration: (v) => (a.add(v), () => {
137
+ a.delete(v);
138
138
  })
139
- }, d.skipHydration || k(), b || f;
140
- }, ie = Le, I = "/api";
141
- async function A(r, i) {
139
+ }, i.skipHydration || w(), f || h;
140
+ }, me = $e, $ = "/api";
141
+ async function j(r, l) {
142
142
  const t = await fetch(r, {
143
- ...i,
143
+ ...l,
144
144
  headers: {
145
145
  "Content-Type": "application/json",
146
- ...i == null ? void 0 : i.headers
146
+ ...l == null ? void 0 : l.headers
147
147
  }
148
148
  });
149
149
  if (!t.ok) {
150
- const a = await t.json().catch(() => ({ error: "Unknown error" }));
151
- throw new Error(a.error || `HTTP ${t.status}`);
150
+ const n = await t.json().catch(() => ({ error: "Unknown error" }));
151
+ throw new Error(n.error || `HTTP ${t.status}`);
152
152
  }
153
153
  return t.json();
154
154
  }
155
- async function We() {
156
- return A(`${I}/nodes/generators`);
155
+ async function Me() {
156
+ return j(`${$}/nodes/generators`);
157
+ }
158
+ async function je() {
159
+ return j(`${$}/nodes/transforms`);
157
160
  }
158
- async function Ae() {
159
- return A(`${I}/nodes/transforms`);
161
+ async function De() {
162
+ return j(`${$}/nodes/text`);
163
+ }
164
+ async function Te() {
165
+ return j(`${$}/nodes/vision`);
160
166
  }
161
- async function De(r, i, t) {
162
- return A(`${I}/execute/sync`, {
167
+ async function Ue(r, l, t) {
168
+ return j(`${$}/execute/sync`, {
163
169
  method: "POST",
164
- body: JSON.stringify({ nodes: r, edges: i, aiProviders: t })
170
+ body: JSON.stringify({ nodes: r, edges: l, aiProviders: t })
165
171
  });
166
172
  }
167
- async function $e(r, i) {
168
- return A(`${I}/export/yaml`, {
173
+ async function Oe(r, l) {
174
+ return j(`${$}/export/yaml`, {
169
175
  method: "POST",
170
- body: JSON.stringify({ nodes: r, edges: i })
176
+ body: JSON.stringify({ nodes: r, edges: l })
171
177
  });
172
178
  }
173
- async function Me() {
174
- return A(`${I}/images`);
179
+ async function Re() {
180
+ return j(`${$}/images`);
175
181
  }
176
- function F(r) {
177
- return `${I}/images/${r}/blob`;
182
+ function oe(r) {
183
+ return `${$}/images/${r}/blob`;
178
184
  }
179
- async function je(r) {
185
+ async function Ee(r) {
180
186
  try {
181
- return await A(`${I}/images/${r}/workflow`);
187
+ return await j(`${$}/images/${r}/workflow`);
182
188
  } catch {
183
189
  return null;
184
190
  }
185
191
  }
186
- async function Pe(r) {
187
- const i = new FormData();
188
- i.append("file", r);
189
- const t = await fetch(`${I}/uploads`, {
192
+ async function Be(r) {
193
+ const l = new FormData();
194
+ l.append("file", r);
195
+ const t = await fetch(`${$}/uploads`, {
190
196
  method: "POST",
191
- body: i
197
+ body: l
192
198
  });
193
199
  if (!t.ok) {
194
- const a = await t.json().catch(() => ({ error: "Upload failed" }));
195
- throw new Error(a.error || `HTTP ${t.status}`);
200
+ const n = await t.json().catch(() => ({ error: "Upload failed" }));
201
+ throw new Error(n.error || `HTTP ${t.status}`);
196
202
  }
197
203
  return t.json();
198
204
  }
199
- async function Te() {
200
- return A(`${I}/uploads`);
205
+ async function Ge() {
206
+ return j(`${$}/uploads`);
201
207
  }
202
- async function Ue(r) {
203
- const i = await fetch(`${I}/uploads/${r}`, {
208
+ async function Ve(r) {
209
+ const l = await fetch(`${$}/uploads/${r}`, {
204
210
  method: "DELETE"
205
211
  });
206
- if (!i.ok)
207
- throw new Error(`Failed to delete upload: ${i.status}`);
212
+ if (!l.ok)
213
+ throw new Error(`Failed to delete upload: ${l.status}`);
208
214
  }
209
- function de(r) {
210
- return `${I}/uploads/${r}/blob`;
215
+ function pe(r) {
216
+ return `${$}/uploads/${r}/blob`;
211
217
  }
212
- async function Ee(r) {
213
- return A(`${I}/import`, {
218
+ async function Fe(r) {
219
+ return j(`${$}/import`, {
214
220
  method: "POST",
215
221
  body: JSON.stringify({ yaml: r })
216
222
  });
217
223
  }
218
- async function Oe(r) {
219
- return A(`${I}/import/validate`, {
224
+ async function He(r) {
225
+ return j(`${$}/import/validate`, {
220
226
  method: "POST",
221
227
  body: JSON.stringify({ yaml: r })
222
228
  });
223
229
  }
224
- const re = "http://localhost:11434", ae = "http://localhost:1234", $ = se()(
225
- ie(
226
- (r, i) => ({
230
+ async function _e(r) {
231
+ return j(`${$}/generate/workflow`, {
232
+ method: "POST",
233
+ body: JSON.stringify(r)
234
+ });
235
+ }
236
+ async function Ke() {
237
+ return j(`${$}/generate/status`);
238
+ }
239
+ const se = "http://localhost:11434", ie = "http://localhost:1234", O = ce()(
240
+ me(
241
+ (r, l) => ({
227
242
  ai: {
228
243
  ollama: {
229
- baseUrl: re,
244
+ baseUrl: se,
230
245
  enabled: !1
231
246
  },
232
247
  lmstudio: {
233
- baseUrl: ae,
248
+ baseUrl: ie,
234
249
  enabled: !1
235
250
  }
236
251
  },
237
252
  showSettings: !1,
238
- setAIProvider: (t, a) => {
239
- r((s) => ({
253
+ setAIProvider: (t, n) => {
254
+ r((o) => ({
240
255
  ai: {
241
- ...s.ai,
242
- [t]: a
256
+ ...o.ai,
257
+ [t]: n
243
258
  }
244
259
  }));
245
260
  },
246
261
  clearAIProvider: (t) => {
247
- r((a) => {
248
- const s = { ...a.ai };
249
- return delete s[t], { ai: s };
262
+ r((n) => {
263
+ const o = { ...n.ai };
264
+ return delete o[t], { ai: o };
250
265
  });
251
266
  },
252
267
  openSettings: () => r({ showSettings: !0 }),
253
268
  closeSettings: () => r({ showSettings: !1 }),
254
269
  getConfiguredProviders: () => {
255
- var s, d, m, o, n, u;
256
- const { ai: t } = i(), a = {};
257
- return (s = t.openai) != null && s.enabled && t.openai.apiKey && (a.openai = { apiKey: t.openai.apiKey }), (d = t.anthropic) != null && d.enabled && t.anthropic.apiKey && (a.anthropic = { apiKey: t.anthropic.apiKey }), (m = t.gemini) != null && m.enabled && t.gemini.apiKey && (a.gemini = { apiKey: t.gemini.apiKey }), (o = t.openrouter) != null && o.enabled && t.openrouter.apiKey && (a.openrouter = { apiKey: t.openrouter.apiKey }), (n = t.ollama) != null && n.enabled && (a.ollama = { baseUrl: t.ollama.baseUrl || re }), (u = t.lmstudio) != null && u.enabled && (a.lmstudio = { baseUrl: t.lmstudio.baseUrl || ae }), a;
270
+ var o, i, m, d, a, p, c;
271
+ const { ai: t } = l(), n = {};
272
+ return (o = t.openai) != null && o.enabled && t.openai.apiKey && (n.openai = { apiKey: t.openai.apiKey }), (i = t.anthropic) != null && i.enabled && t.anthropic.apiKey && (n.anthropic = { apiKey: t.anthropic.apiKey }), (m = t.gemini) != null && m.enabled && t.gemini.apiKey && (n.gemini = { apiKey: t.gemini.apiKey }), (d = t.grok) != null && d.enabled && t.grok.apiKey && (n.grok = { apiKey: t.grok.apiKey }), (a = t.openrouter) != null && a.enabled && t.openrouter.apiKey && (n.openrouter = { apiKey: t.openrouter.apiKey }), (p = t.ollama) != null && p.enabled && (n.ollama = { baseUrl: t.ollama.baseUrl || se }), (c = t.lmstudio) != null && c.enabled && (n.lmstudio = { baseUrl: t.lmstudio.baseUrl || ie }), n;
258
273
  }
259
274
  }),
260
275
  {
@@ -264,17 +279,17 @@ const re = "http://localhost:11434", ae = "http://localhost:1234", $ = se()(
264
279
  }
265
280
  )
266
281
  );
267
- let Be = 0;
268
- function K() {
269
- return `node_${++Be}`;
282
+ let qe = 0;
283
+ function G() {
284
+ return `node_${++qe}`;
270
285
  }
271
- function oe() {
272
- const r = Date.now(), i = Math.random().toString(36).substring(2, 8);
273
- return `wf_${r}_${i}`;
286
+ function le() {
287
+ const r = Date.now(), l = Math.random().toString(36).substring(2, 8);
288
+ return `wf_${r}_${l}`;
274
289
  }
275
- const x = se()(
276
- ie(
277
- (r, i) => ({
290
+ const k = ce()(
291
+ me(
292
+ (r, l) => ({
278
293
  nodes: [],
279
294
  edges: [],
280
295
  selectedNodeId: null,
@@ -282,6 +297,8 @@ const x = se()(
282
297
  previewVisible: {},
283
298
  generators: [],
284
299
  transforms: [],
300
+ textProviders: [],
301
+ visionProviders: [],
285
302
  // Workflow persistence state
286
303
  savedWorkflows: [],
287
304
  activeWorkflowId: null,
@@ -291,36 +308,38 @@ const x = se()(
291
308
  execution: {
292
309
  status: "idle",
293
310
  imageIds: [],
311
+ imageUrls: [],
294
312
  previews: {},
295
313
  dataOutputs: {},
296
314
  nodeStatus: {}
297
315
  },
298
316
  loadTemplate: (t) => {
299
- const a = /* @__PURE__ */ new Map(), s = t.workflow.nodes.map((m) => {
300
- const o = K();
301
- return a.set(m.id, o), {
302
- id: o,
317
+ const n = /* @__PURE__ */ new Map(), o = t.workflow.nodes.map((m) => {
318
+ const d = G();
319
+ return n.set(m.id, d), {
320
+ id: d,
303
321
  type: m.type,
304
322
  position: m.position,
305
323
  data: m.data
306
324
  };
307
- }), d = t.workflow.edges.map((m) => {
308
- const o = a.get(m.source) || m.source, n = a.get(m.target) || m.target;
325
+ }), i = t.workflow.edges.map((m) => {
326
+ const d = n.get(m.source) || m.source, a = n.get(m.target) || m.target;
309
327
  return {
310
- id: `edge_${o}_${n}`,
311
- source: o,
312
- target: n
328
+ id: `edge_${d}_${a}`,
329
+ source: d,
330
+ target: a
313
331
  };
314
332
  });
315
333
  r({
316
- nodes: s,
317
- edges: d,
334
+ nodes: o,
335
+ edges: i,
318
336
  selectedNodeId: null,
319
337
  currentTemplateId: t.id,
320
338
  previewVisible: {},
321
339
  execution: {
322
340
  status: "idle",
323
341
  imageIds: [],
342
+ imageUrls: [],
324
343
  previews: {},
325
344
  dataOutputs: {},
326
345
  nodeStatus: {}
@@ -337,6 +356,7 @@ const x = se()(
337
356
  execution: {
338
357
  status: "idle",
339
358
  imageIds: [],
359
+ imageUrls: [],
340
360
  previews: {},
341
361
  dataOutputs: {},
342
362
  nodeStatus: {}
@@ -344,198 +364,245 @@ const x = se()(
344
364
  });
345
365
  },
346
366
  togglePreview: (t) => {
347
- r((a) => ({
367
+ r((n) => ({
348
368
  previewVisible: {
349
- ...a.previewVisible,
350
- [t]: a.previewVisible[t] === !1
369
+ ...n.previewVisible,
370
+ [t]: n.previewVisible[t] === !1
351
371
  // default true, toggle
352
372
  }
353
373
  }));
354
374
  },
355
375
  setGenerators: (t) => r({ generators: t }),
356
376
  setTransforms: (t) => r({ transforms: t }),
357
- addNode: (t, a) => {
358
- var o, n, u;
359
- const s = K();
360
- let d;
377
+ setTextProviders: (t) => r({ textProviders: t }),
378
+ setVisionProviders: (t) => r({ visionProviders: t }),
379
+ addNode: (t, n) => {
380
+ var d, a, p;
381
+ const o = G();
382
+ let i;
361
383
  if (t.type === "generator")
362
- d = {
384
+ i = {
363
385
  generatorName: t.name,
364
- params: R(t)
386
+ params: _(t),
387
+ isAI: t.isAI,
388
+ // Track if this is an AI generator (can accept text input)
389
+ acceptsReferenceImages: t.acceptsReferenceImages,
390
+ maxReferenceImages: t.maxReferenceImages
365
391
  };
366
392
  else if (t.type === "transform")
367
- d = {
393
+ i = {
368
394
  operation: t.name,
369
- params: R(t)
395
+ providerName: t.providerName,
396
+ // Track which provider this transform belongs to
397
+ isAI: t.isAI,
398
+ // Track if this is an AI transform (can accept text input)
399
+ params: _(t),
400
+ acceptsReferenceImages: t.acceptsReferenceImages,
401
+ maxReferenceImages: t.maxReferenceImages
370
402
  };
371
403
  else if (t.type === "input")
372
- d = {
404
+ i = {
373
405
  uploadId: void 0,
374
406
  filename: void 0,
375
407
  mime: void 0
376
408
  };
377
409
  else if (t.type === "vision")
378
- d = {
410
+ i = {
379
411
  providerName: t.name,
380
- params: R(t)
412
+ providerLabel: t.label,
413
+ // Human-readable label (e.g., "Gemini Vision")
414
+ params: _(t)
381
415
  };
382
416
  else if (t.type === "text")
383
- d = {
417
+ i = {
384
418
  providerName: t.name,
385
- params: R(t)
419
+ providerLabel: t.label,
420
+ // Human-readable label (e.g., "Gemini Text")
421
+ params: _(t)
386
422
  };
387
423
  else {
388
- const l = ((o = t.params) == null ? void 0 : o.properties) || {}, p = ((n = l.provider) == null ? void 0 : n.default) || "filesystem";
389
- d = {
390
- destination: ((u = l.destination) == null ? void 0 : u.default) || "./output/image.png",
391
- provider: p
424
+ const c = ((d = t.params) == null ? void 0 : d.properties) || {}, u = ((a = c.provider) == null ? void 0 : a.default) || "filesystem";
425
+ i = {
426
+ destination: ((p = c.destination) == null ? void 0 : p.default) || "./output/image.png",
427
+ provider: u
392
428
  };
393
429
  }
394
430
  const m = {
395
- id: s,
431
+ id: o,
396
432
  type: t.type,
397
- position: a,
398
- data: d
433
+ position: n,
434
+ data: i
399
435
  };
400
- r((l) => ({
401
- nodes: [...l.nodes, m]
436
+ r((c) => ({
437
+ nodes: [...c.nodes, m]
402
438
  }));
403
439
  },
404
- updateNodeData: (t, a) => {
405
- r((s) => ({
406
- nodes: s.nodes.map(
407
- (d) => d.id === t ? { ...d, data: { ...d.data, ...a } } : d
440
+ updateNodeData: (t, n) => {
441
+ r((o) => ({
442
+ nodes: o.nodes.map(
443
+ (i) => i.id === t ? { ...i, data: { ...i.data, ...n } } : i
408
444
  )
409
445
  }));
410
446
  },
411
447
  deleteNode: (t) => {
412
- r((a) => ({
413
- nodes: a.nodes.filter((s) => s.id !== t),
414
- edges: a.edges.filter((s) => s.source !== t && s.target !== t),
415
- selectedNodeId: a.selectedNodeId === t ? null : a.selectedNodeId
448
+ r((n) => ({
449
+ nodes: n.nodes.filter((o) => o.id !== t),
450
+ edges: n.edges.filter((o) => o.source !== t && o.target !== t),
451
+ selectedNodeId: n.selectedNodeId === t ? null : n.selectedNodeId
416
452
  }));
417
453
  },
454
+ duplicateNode: (t) => {
455
+ const n = l(), o = n.nodes.find((d) => d.id === t);
456
+ if (!o) return;
457
+ const i = G(), m = {
458
+ ...o,
459
+ id: i,
460
+ position: {
461
+ x: o.position.x + 50,
462
+ y: o.position.y + 50
463
+ },
464
+ data: JSON.parse(JSON.stringify(o.data)),
465
+ // Deep clone
466
+ selected: !1
467
+ };
468
+ r({
469
+ nodes: [...n.nodes, m],
470
+ selectedNodeId: i
471
+ // Select the new node
472
+ });
473
+ },
418
474
  setNodes: (t) => r({ nodes: t }),
419
475
  addEdge: (t) => {
420
476
  if (!t.source || !t.target) return;
421
- const s = {
422
- id: `edge_${t.source}_${t.target}`,
477
+ const n = [t.sourceHandle, t.targetHandle].filter(Boolean).join("_"), i = {
478
+ id: n ? `edge_${t.source}_${t.target}_${n}` : `edge_${t.source}_${t.target}`,
423
479
  source: t.source,
424
- target: t.target
480
+ target: t.target,
481
+ sourceHandle: t.sourceHandle ?? void 0,
482
+ targetHandle: t.targetHandle ?? void 0
425
483
  };
426
- r((d) => ({
427
- edges: [...d.edges, s]
484
+ r((m) => ({
485
+ edges: [...m.edges, i]
428
486
  }));
429
487
  },
430
488
  deleteEdge: (t) => {
431
- r((a) => ({
432
- edges: a.edges.filter((s) => s.id !== t)
489
+ r((n) => ({
490
+ edges: n.edges.filter((o) => o.id !== t)
433
491
  }));
434
492
  },
435
493
  setEdges: (t) => r({ edges: t }),
436
494
  setSelectedNode: (t) => r({ selectedNodeId: t }),
437
495
  execute: async () => {
438
- const { nodes: t, edges: a } = i(), s = t.map((n) => ({
439
- id: n.id,
440
- type: n.type,
441
- position: n.position,
442
- data: n.data
443
- })), d = a.map((n) => ({
444
- id: n.id,
445
- source: n.source,
446
- target: n.target
447
- })), m = $.getState().getConfiguredProviders(), o = {};
448
- for (const n of t)
449
- o[n.id] = "running";
496
+ const { nodes: t, edges: n } = l(), o = t.map((a) => ({
497
+ id: a.id,
498
+ type: a.type,
499
+ position: a.position,
500
+ data: a.data
501
+ })), i = n.map((a) => ({
502
+ id: a.id,
503
+ source: a.source,
504
+ target: a.target,
505
+ sourceHandle: a.sourceHandle ?? void 0,
506
+ targetHandle: a.targetHandle ?? void 0
507
+ })), m = O.getState().getConfiguredProviders(), d = {};
508
+ for (const a of t)
509
+ d[a.id] = "running";
450
510
  r({
451
511
  execution: {
452
512
  status: "running",
453
513
  imageIds: [],
514
+ imageUrls: [],
454
515
  previews: {},
455
516
  dataOutputs: {},
456
- nodeStatus: o
517
+ nodeStatus: d
457
518
  }
458
519
  });
459
520
  try {
460
- const n = await De(s, d, m), u = {};
461
- for (const l of t)
462
- u[l.id] = n.status === "completed" ? "completed" : "error";
463
- n.status === "completed" ? r({
521
+ const a = await Ue(o, i, m), p = {};
522
+ for (const c of t)
523
+ p[c.id] = a.status === "completed" ? "completed" : "error";
524
+ a.status === "completed" ? r({
464
525
  execution: {
465
526
  status: "completed",
466
- imageIds: n.imageIds,
467
- previews: n.previews || {},
468
- dataOutputs: n.dataOutputs || {},
469
- nodeStatus: u
527
+ imageIds: a.imageIds,
528
+ imageUrls: a.imageUrls || [],
529
+ previews: a.previews || {},
530
+ dataOutputs: a.dataOutputs || {},
531
+ nodeStatus: p
470
532
  }
471
533
  }) : r({
472
534
  execution: {
473
535
  status: "error",
474
536
  imageIds: [],
537
+ imageUrls: [],
475
538
  previews: {},
476
539
  dataOutputs: {},
477
- nodeStatus: u,
478
- error: n.error
540
+ nodeStatus: p,
541
+ error: a.error
479
542
  }
480
543
  });
481
- } catch (n) {
482
- const u = {};
483
- for (const l of t)
484
- u[l.id] = "error";
544
+ } catch (a) {
545
+ const p = {};
546
+ for (const c of t)
547
+ p[c.id] = "error";
485
548
  r({
486
549
  execution: {
487
550
  status: "error",
488
551
  imageIds: [],
552
+ imageUrls: [],
489
553
  previews: {},
490
554
  dataOutputs: {},
491
- nodeStatus: u,
492
- error: n instanceof Error ? n.message : "Unknown error"
555
+ nodeStatus: p,
556
+ error: a instanceof Error ? a.message : "Unknown error"
493
557
  }
494
558
  });
495
559
  }
496
560
  },
497
561
  exportToYaml: async () => {
498
- const { nodes: t, edges: a } = i(), s = t.map((o) => ({
499
- id: o.id,
500
- type: o.type,
501
- position: o.position,
502
- data: o.data
503
- })), d = a.map((o) => ({
504
- id: o.id,
505
- source: o.source,
506
- target: o.target
562
+ const { nodes: t, edges: n } = l(), o = t.map((d) => ({
563
+ id: d.id,
564
+ type: d.type,
565
+ position: d.position,
566
+ data: d.data
567
+ })), i = n.map((d) => ({
568
+ id: d.id,
569
+ source: d.source,
570
+ target: d.target,
571
+ sourceHandle: d.sourceHandle ?? void 0,
572
+ targetHandle: d.targetHandle ?? void 0
507
573
  }));
508
- return (await $e(s, d)).yaml;
574
+ return (await Oe(o, i)).yaml;
509
575
  },
510
- importFromYaml: (t, a, s) => {
511
- const d = /* @__PURE__ */ new Map(), m = t.map((n) => {
512
- const u = K();
513
- return d.set(n.id, u), {
514
- id: u,
515
- type: n.type,
516
- position: n.position,
517
- data: n.data
576
+ importFromYaml: (t, n, o) => {
577
+ const i = /* @__PURE__ */ new Map(), m = t.map((a) => {
578
+ const p = G();
579
+ return i.set(a.id, p), {
580
+ id: p,
581
+ type: a.type,
582
+ position: a.position,
583
+ data: a.data
518
584
  };
519
- }), o = a.map((n) => {
520
- const u = d.get(n.source) || n.source, l = d.get(n.target) || n.target;
585
+ }), d = n.map((a) => {
586
+ const p = i.get(a.source) || a.source, c = i.get(a.target) || a.target;
521
587
  return {
522
- id: `edge_${u}_${l}`,
523
- source: u,
524
- target: l
588
+ id: `edge_${p}_${c}`,
589
+ source: p,
590
+ target: c
525
591
  };
526
592
  });
527
593
  r({
528
594
  nodes: m,
529
- edges: o,
595
+ edges: d,
530
596
  selectedNodeId: null,
531
597
  currentTemplateId: null,
532
598
  previewVisible: {},
533
599
  activeWorkflowId: null,
534
- activeWorkflowName: s || "Imported Workflow",
600
+ activeWorkflowName: o || "Imported Workflow",
535
601
  hasUnsavedChanges: !0,
536
602
  execution: {
537
603
  status: "idle",
538
604
  imageIds: [],
605
+ imageUrls: [],
539
606
  previews: {},
540
607
  dataOutputs: {},
541
608
  nodeStatus: {}
@@ -559,6 +626,7 @@ const x = se()(
559
626
  execution: {
560
627
  status: "idle",
561
628
  imageIds: [],
629
+ imageUrls: [],
562
630
  previews: {},
563
631
  dataOutputs: {},
564
632
  nodeStatus: {}
@@ -567,54 +635,55 @@ const x = se()(
567
635
  },
568
636
  saveWorkflow: (t) => {
569
637
  const {
570
- nodes: a,
571
- edges: s,
572
- activeWorkflowId: d,
638
+ nodes: n,
639
+ edges: o,
640
+ activeWorkflowId: i,
573
641
  activeWorkflowName: m,
574
- savedWorkflows: o,
575
- currentTemplateId: n
576
- } = i(), u = Date.now();
577
- if (d) {
578
- const l = o.map(
579
- (p) => p.id === d ? { ...p, name: t || m, nodes: a, edges: s, updatedAt: u } : p
642
+ savedWorkflows: d,
643
+ currentTemplateId: a
644
+ } = l(), p = Date.now();
645
+ if (i) {
646
+ const c = d.map(
647
+ (u) => u.id === i ? { ...u, name: t || m, nodes: n, edges: o, updatedAt: p } : u
580
648
  );
581
649
  return r({
582
- savedWorkflows: l,
650
+ savedWorkflows: c,
583
651
  activeWorkflowName: t || m,
584
652
  hasUnsavedChanges: !1
585
- }), d;
653
+ }), i;
586
654
  } else {
587
- const l = oe(), p = {
588
- id: l,
655
+ const c = le(), u = {
656
+ id: c,
589
657
  name: t || m,
590
- nodes: a,
591
- edges: s,
592
- createdAt: u,
593
- updatedAt: u,
594
- templateId: n || void 0
658
+ nodes: n,
659
+ edges: o,
660
+ createdAt: p,
661
+ updatedAt: p,
662
+ templateId: a || void 0
595
663
  };
596
664
  return r({
597
- savedWorkflows: [...o, p],
598
- activeWorkflowId: l,
665
+ savedWorkflows: [...d, u],
666
+ activeWorkflowId: c,
599
667
  activeWorkflowName: t || m,
600
668
  hasUnsavedChanges: !1
601
- }), l;
669
+ }), c;
602
670
  }
603
671
  },
604
672
  loadWorkflow: (t) => {
605
- const { savedWorkflows: a } = i(), s = a.find((d) => d.id === t);
606
- s && r({
607
- nodes: s.nodes,
608
- edges: s.edges,
673
+ const { savedWorkflows: n } = l(), o = n.find((i) => i.id === t);
674
+ o && r({
675
+ nodes: o.nodes,
676
+ edges: o.edges,
609
677
  selectedNodeId: null,
610
- currentTemplateId: s.templateId || null,
678
+ currentTemplateId: o.templateId || null,
611
679
  previewVisible: {},
612
680
  activeWorkflowId: t,
613
- activeWorkflowName: s.name,
681
+ activeWorkflowName: o.name,
614
682
  hasUnsavedChanges: !1,
615
683
  execution: {
616
684
  status: "idle",
617
685
  imageIds: [],
686
+ imageUrls: [],
618
687
  previews: {},
619
688
  dataOutputs: {},
620
689
  nodeStatus: {}
@@ -622,9 +691,9 @@ const x = se()(
622
691
  });
623
692
  },
624
693
  deleteWorkflow: (t) => {
625
- const { savedWorkflows: a, activeWorkflowId: s } = i(), d = a.filter((m) => m.id !== t);
626
- r(s === t ? {
627
- savedWorkflows: d,
694
+ const { savedWorkflows: n, activeWorkflowId: o } = l(), i = n.filter((m) => m.id !== t);
695
+ r(o === t ? {
696
+ savedWorkflows: i,
628
697
  nodes: [],
629
698
  edges: [],
630
699
  selectedNodeId: null,
@@ -636,32 +705,125 @@ const x = se()(
636
705
  execution: {
637
706
  status: "idle",
638
707
  imageIds: [],
708
+ imageUrls: [],
639
709
  previews: {},
640
710
  dataOutputs: {},
641
711
  nodeStatus: {}
642
712
  }
643
- } : { savedWorkflows: d });
713
+ } : { savedWorkflows: i });
644
714
  },
645
- renameWorkflow: (t, a) => {
646
- const { savedWorkflows: s, activeWorkflowId: d } = i(), m = s.map(
647
- (o) => o.id === t ? { ...o, name: a, updatedAt: Date.now() } : o
715
+ renameWorkflow: (t, n) => {
716
+ const { savedWorkflows: o, activeWorkflowId: i } = l(), m = o.map(
717
+ (d) => d.id === t ? { ...d, name: n, updatedAt: Date.now() } : d
648
718
  );
649
719
  r({
650
720
  savedWorkflows: m,
651
- ...d === t ? { activeWorkflowName: a } : {}
721
+ ...i === t ? { activeWorkflowName: n } : {}
652
722
  });
653
723
  },
654
724
  duplicateWorkflow: (t) => {
655
- const { savedWorkflows: a } = i(), s = a.find((n) => n.id === t);
656
- if (!s) return "";
657
- const d = Date.now(), m = oe(), o = {
658
- ...s,
725
+ const { savedWorkflows: n } = l(), o = n.find((a) => a.id === t);
726
+ if (!o) return "";
727
+ const i = Date.now(), m = le(), d = {
728
+ ...o,
659
729
  id: m,
660
- name: `${s.name} (Copy)`,
661
- createdAt: d,
662
- updatedAt: d
730
+ name: `${o.name} (Copy)`,
731
+ createdAt: i,
732
+ updatedAt: i
663
733
  };
664
- return r({ savedWorkflows: [...a, o] }), m;
734
+ return r({ savedWorkflows: [...n, d] }), m;
735
+ },
736
+ loadGeneratedWorkflow: (t) => {
737
+ const n = /* @__PURE__ */ new Map(), o = 250, i = 150, m = 3, d = t.nodes.map((p, c) => {
738
+ const u = G();
739
+ n.set(p.id, u);
740
+ const h = p.nodeType.split(":"), f = h[0], w = Math.floor(c / m), y = {
741
+ x: 100 + c % m * o,
742
+ y: 100 + w * i
743
+ };
744
+ let b;
745
+ if (f === "generator")
746
+ b = {
747
+ generatorName: h.slice(1).join(":"),
748
+ params: p.parameters,
749
+ isAI: !0
750
+ // Assume AI since we're generating from AI
751
+ };
752
+ else if (f === "transform") {
753
+ const g = h[1];
754
+ b = {
755
+ operation: h.slice(2).join(":"),
756
+ providerName: g,
757
+ params: p.parameters
758
+ };
759
+ } else if (f === "input")
760
+ b = {
761
+ uploadId: void 0,
762
+ filename: void 0,
763
+ mime: void 0
764
+ };
765
+ else if (f === "vision")
766
+ b = {
767
+ providerName: h.slice(1).join(":"),
768
+ params: p.parameters
769
+ };
770
+ else if (f === "text") {
771
+ const g = h.slice(1).join(":"), N = p.parameters.jsonSchema, W = N != null && N.properties ? {
772
+ type: "object",
773
+ properties: Object.fromEntries(
774
+ Object.entries(N.properties).map(([x, C]) => [
775
+ x,
776
+ {
777
+ type: C.type || "string",
778
+ description: C.description
779
+ }
780
+ ])
781
+ )
782
+ } : void 0;
783
+ b = {
784
+ providerName: g,
785
+ params: p.parameters,
786
+ outputSchema: W
787
+ };
788
+ } else
789
+ b = {
790
+ destination: p.parameters.destination || "./output/image.png",
791
+ provider: p.parameters.provider || "filesystem"
792
+ };
793
+ return {
794
+ id: u,
795
+ type: f,
796
+ position: y,
797
+ data: b
798
+ };
799
+ }), a = t.edges.map((p) => {
800
+ const c = n.get(p.source) || p.source, u = n.get(p.target) || p.target, h = [p.sourceHandle, p.targetHandle].filter(Boolean).join("_");
801
+ return {
802
+ id: h ? `edge_${c}_${u}_${h}` : `edge_${c}_${u}`,
803
+ source: c,
804
+ target: u,
805
+ sourceHandle: p.sourceHandle ?? void 0,
806
+ targetHandle: p.targetHandle ?? void 0
807
+ };
808
+ });
809
+ r({
810
+ nodes: d,
811
+ edges: a,
812
+ selectedNodeId: null,
813
+ currentTemplateId: null,
814
+ previewVisible: {},
815
+ activeWorkflowId: null,
816
+ activeWorkflowName: "AI Generated Workflow",
817
+ hasUnsavedChanges: !0,
818
+ execution: {
819
+ status: "idle",
820
+ imageIds: [],
821
+ imageUrls: [],
822
+ previews: {},
823
+ dataOutputs: {},
824
+ nodeStatus: {}
825
+ }
826
+ });
665
827
  }
666
828
  }),
667
829
  {
@@ -673,28 +835,28 @@ const x = se()(
673
835
  }
674
836
  )
675
837
  );
676
- function R(r) {
838
+ function _(r) {
677
839
  var t;
678
- const i = {};
840
+ const l = {};
679
841
  if ((t = r.params) != null && t.properties)
680
- for (const [a, s] of Object.entries(r.params.properties))
681
- s.default !== void 0 && (i[a] = s.default);
682
- return i;
842
+ for (const [n, o] of Object.entries(r.params.properties))
843
+ o.default !== void 0 && (l[n] = o.default);
844
+ return l;
683
845
  }
684
- function U(r) {
846
+ function B(r) {
685
847
  return r === "running" ? "border-yellow-400 animate-pulse" : r === "completed" ? "border-green-500" : r === "error" ? "border-red-500" : "";
686
848
  }
687
- function Q({ nodeId: r, color: i }) {
688
- const t = x((s) => s.previewVisible[r] !== !1), a = x((s) => s.togglePreview);
849
+ function X({ nodeId: r, color: l }) {
850
+ const t = k((o) => o.previewVisible[r] !== !1), n = k((o) => o.togglePreview);
689
851
  return /* @__PURE__ */ e(
690
852
  "button",
691
853
  {
692
- onClick: (s) => {
693
- s.stopPropagation(), a(r);
854
+ onClick: (o) => {
855
+ o.stopPropagation(), n(r);
694
856
  },
695
857
  className: `ml-auto p-1 rounded hover:bg-gray-200 dark:hover:bg-zinc-600 transition-colors ${t ? "opacity-100" : "opacity-40"}`,
696
858
  title: t ? "Hide preview" : "Show preview",
697
- children: /* @__PURE__ */ e("svg", { className: `w-3.5 h-3.5 ${i}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: t ? /* @__PURE__ */ e(
859
+ children: /* @__PURE__ */ e("svg", { className: `w-3.5 h-3.5 ${l}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: t ? /* @__PURE__ */ e(
698
860
  "path",
699
861
  {
700
862
  strokeLinecap: "round",
@@ -714,72 +876,139 @@ function Q({ nodeId: r, color: i }) {
714
876
  }
715
877
  );
716
878
  }
717
- const Re = T(function({
718
- id: i,
879
+ const Je = E(function({
880
+ id: l,
719
881
  data: t,
720
- selected: a
882
+ selected: n
721
883
  }) {
722
- const s = x((u) => u.execution.previews[i]), d = x((u) => u.execution.nodeStatus[i]), m = x((u) => u.previewVisible[i] !== !1), n = U(d) || (a ? "border-blue-500" : "border-blue-200");
723
- return /* @__PURE__ */ c(
884
+ const o = k((u) => u.execution.previews[l]), i = k((u) => u.execution.nodeStatus[l]), m = k((u) => u.previewVisible[l] !== !1), a = B(i) || (n ? "border-blue-500" : "border-blue-200"), p = t.isAI, c = t.acceptsReferenceImages;
885
+ return /* @__PURE__ */ s(
724
886
  "div",
725
887
  {
726
- className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${n}`,
888
+ className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${a}`,
727
889
  children: [
728
- s && m && /* @__PURE__ */ e("div", { className: "bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ e("img", { src: s, alt: "Preview", className: "w-full h-24 object-contain" }) }),
729
- /* @__PURE__ */ c("div", { className: "px-4 py-3", children: [
730
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2 mb-2", children: [
890
+ p && /* @__PURE__ */ e(
891
+ A,
892
+ {
893
+ type: "target",
894
+ position: P.Top,
895
+ id: "text",
896
+ className: "w-3 h-3 !bg-pink-500",
897
+ title: "Text input (optional prompt from text/vision node)"
898
+ }
899
+ ),
900
+ c && /* @__PURE__ */ e(
901
+ A,
902
+ {
903
+ type: "target",
904
+ position: P.Left,
905
+ id: "references",
906
+ className: "w-3 h-3 !bg-violet-500",
907
+ style: { top: "50%" },
908
+ title: `Reference images (up to ${t.maxReferenceImages || 14})`
909
+ }
910
+ ),
911
+ o && m && /* @__PURE__ */ e("div", { className: "bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ e("img", { src: o, alt: "Preview", className: "w-full h-24 object-contain" }) }),
912
+ /* @__PURE__ */ s("div", { className: "px-4 py-3", children: [
913
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2 mb-2", children: [
731
914
  /* @__PURE__ */ e("div", { className: "w-3 h-3 rounded-full bg-blue-500" }),
732
915
  /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-blue-700 dark:text-blue-400", children: t.generatorName }),
733
- /* @__PURE__ */ e(Q, { nodeId: i, color: "text-blue-500 dark:text-blue-400" })
916
+ /* @__PURE__ */ e(X, { nodeId: l, color: "text-blue-500 dark:text-blue-400" })
734
917
  ] }),
735
- /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400", children: Object.entries(t.params).filter(([, u]) => typeof u != "object" || u === null).slice(0, 2).map(([u, l]) => /* @__PURE__ */ c("div", { className: "truncate", children: [
918
+ p && /* @__PURE__ */ e("div", { className: "text-[10px] text-pink-500 dark:text-pink-400 mb-1", children: "↑ Connect text node for dynamic prompt" }),
919
+ c && /* @__PURE__ */ e("div", { className: "text-[10px] text-violet-500 dark:text-violet-400 mb-1", children: "← Connect reference images" }),
920
+ /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400", children: Object.entries(t.params).filter(([, u]) => typeof u != "object" || u === null).slice(0, 2).map(([u, h]) => /* @__PURE__ */ s("div", { className: "truncate", children: [
736
921
  u,
737
922
  ": ",
738
- String(l).slice(0, 20)
923
+ String(h).slice(0, 20)
739
924
  ] }, u)) })
740
925
  ] }),
741
- /* @__PURE__ */ e(L, { type: "source", position: W.Right, className: "w-3 h-3 !bg-blue-500" })
926
+ /* @__PURE__ */ e(A, { type: "source", position: P.Right, className: "w-3 h-3 !bg-blue-500" })
742
927
  ]
743
928
  }
744
929
  );
745
- }), Fe = T(function({
746
- id: i,
930
+ }), Qe = E(function({
931
+ id: l,
747
932
  data: t,
748
- selected: a
933
+ selected: n
749
934
  }) {
750
- const s = x((u) => u.execution.previews[i]), d = x((u) => u.execution.nodeStatus[i]), m = x((u) => u.previewVisible[i] !== !1), n = U(d) || (a ? "border-teal-500" : "border-teal-200");
751
- return /* @__PURE__ */ c(
935
+ const o = k((u) => u.execution.previews[l]), i = k((u) => u.execution.nodeStatus[l]), m = k((u) => u.previewVisible[l] !== !1), a = B(i) || (n ? "border-teal-500" : "border-teal-200"), p = t.isAI, c = t.acceptsReferenceImages;
936
+ return /* @__PURE__ */ s(
752
937
  "div",
753
938
  {
754
- className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${n}`,
939
+ className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${a}`,
755
940
  children: [
756
- /* @__PURE__ */ e(L, { type: "target", position: W.Left, className: "w-3 h-3 !bg-teal-500" }),
757
- s && m && /* @__PURE__ */ e("div", { className: "bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ e("img", { src: s, alt: "Preview", className: "w-full h-24 object-contain" }) }),
758
- /* @__PURE__ */ c("div", { className: "px-4 py-3", children: [
759
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2 mb-2", children: [
760
- /* @__PURE__ */ e("div", { className: "w-3 h-3 rounded-full bg-teal-500" }),
761
- /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-teal-700 dark:text-teal-400", children: t.operation }),
762
- /* @__PURE__ */ e(Q, { nodeId: i, color: "text-teal-500 dark:text-teal-400" })
941
+ p && /* @__PURE__ */ e(
942
+ A,
943
+ {
944
+ type: "target",
945
+ position: P.Top,
946
+ id: "text",
947
+ className: "w-3 h-3 !bg-pink-500",
948
+ title: "Text input (optional prompt from text/vision node)"
949
+ }
950
+ ),
951
+ /* @__PURE__ */ e(A, { type: "target", position: P.Left, id: "image", className: "w-3 h-3 !bg-teal-500" }),
952
+ c && /* @__PURE__ */ e(
953
+ A,
954
+ {
955
+ type: "target",
956
+ position: P.Bottom,
957
+ id: "references",
958
+ className: "w-3 h-3 !bg-violet-500",
959
+ title: `Reference images (up to ${t.maxReferenceImages || 13})`
960
+ }
961
+ ),
962
+ o && m && /* @__PURE__ */ e("div", { className: "bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ e("img", { src: o, alt: "Preview", className: "w-full h-24 object-contain" }) }),
963
+ /* @__PURE__ */ s("div", { className: "px-4 py-3", children: [
964
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2 mb-2", children: [
965
+ p ? /* @__PURE__ */ s("svg", { className: "w-3 h-3 text-purple-500", fill: "currentColor", viewBox: "0 0 20 20", children: [
966
+ /* @__PURE__ */ e("path", { d: "M13 7H7v6h6V7z" }),
967
+ /* @__PURE__ */ e(
968
+ "path",
969
+ {
970
+ fillRule: "evenodd",
971
+ d: "M7 2a1 1 0 012 0v1h2V2a1 1 0 112 0v1h2a2 2 0 012 2v2h1a1 1 0 110 2h-1v2h1a1 1 0 110 2h-1v2a2 2 0 01-2 2h-2v1a1 1 0 11-2 0v-1H9v1a1 1 0 11-2 0v-1H5a2 2 0 01-2-2v-2H2a1 1 0 110-2h1V9H2a1 1 0 010-2h1V5a2 2 0 012-2h2V2zM5 5h10v10H5V5z",
972
+ clipRule: "evenodd"
973
+ }
974
+ )
975
+ ] }) : /* @__PURE__ */ e("div", { className: "w-3 h-3 rounded-full bg-teal-500" }),
976
+ /* @__PURE__ */ e(
977
+ "span",
978
+ {
979
+ className: `font-semibold text-sm ${p ? "text-purple-700 dark:text-purple-400" : "text-teal-700 dark:text-teal-400"}`,
980
+ children: t.operation
981
+ }
982
+ ),
983
+ /* @__PURE__ */ e(
984
+ X,
985
+ {
986
+ nodeId: l,
987
+ color: p ? "text-purple-500 dark:text-purple-400" : "text-teal-500 dark:text-teal-400"
988
+ }
989
+ )
763
990
  ] }),
764
- /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400", children: Object.entries(t.params).filter(([, u]) => typeof u != "object" || u === null).slice(0, 2).map(([u, l]) => /* @__PURE__ */ c("div", { className: "truncate", children: [
991
+ p && /* @__PURE__ */ e("div", { className: "text-[10px] text-pink-500 dark:text-pink-400 mb-1", children: "↑ Connect text node for dynamic prompt" }),
992
+ c && /* @__PURE__ */ e("div", { className: "text-[10px] text-violet-500 dark:text-violet-400 mb-1", children: "↓ Connect reference images" }),
993
+ /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400", children: Object.entries(t.params).filter(([, u]) => typeof u != "object" || u === null).slice(0, 2).map(([u, h]) => /* @__PURE__ */ s("div", { className: "truncate", children: [
765
994
  u,
766
995
  ": ",
767
- String(l).slice(0, 20)
996
+ String(h).slice(0, 20)
768
997
  ] }, u)) })
769
998
  ] }),
770
- /* @__PURE__ */ e(L, { type: "source", position: W.Right, className: "w-3 h-3 !bg-teal-500" })
999
+ /* @__PURE__ */ e(A, { type: "source", position: P.Right, className: "w-3 h-3 !bg-teal-500" })
771
1000
  ]
772
1001
  }
773
1002
  );
774
- }), Ve = T(function({ id: i, data: t, selected: a }) {
775
- const s = x((o) => o.execution.nodeStatus[i]), m = U(s) || (a ? "border-green-500" : "border-green-200");
776
- return /* @__PURE__ */ c(
1003
+ }), Ye = E(function({ id: l, data: t, selected: n }) {
1004
+ const o = k((d) => d.execution.nodeStatus[l]), m = B(o) || (n ? "border-green-500" : "border-green-200");
1005
+ return /* @__PURE__ */ s(
777
1006
  "div",
778
1007
  {
779
1008
  className: `px-4 py-3 rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] ${m}`,
780
1009
  children: [
781
- /* @__PURE__ */ e(L, { type: "target", position: W.Left, className: "w-3 h-3 !bg-green-500" }),
782
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2 mb-2", children: [
1010
+ /* @__PURE__ */ e(A, { type: "target", position: P.Left, className: "w-3 h-3 !bg-green-500" }),
1011
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2 mb-2", children: [
783
1012
  /* @__PURE__ */ e("div", { className: "w-3 h-3 rounded-full bg-green-500" }),
784
1013
  /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-green-700 dark:text-green-400", children: "Save" })
785
1014
  ] }),
@@ -787,54 +1016,54 @@ const Re = T(function({
787
1016
  ]
788
1017
  }
789
1018
  );
790
- }), Ge = T(function({ id: i, data: t, selected: a }) {
791
- const s = x((v) => v.execution.previews[i]), d = x((v) => v.execution.nodeStatus[i]), m = x((v) => v.previewVisible[i] !== !1), o = x((v) => v.updateNodeData), n = xe(null), l = U(d) || (a ? "border-amber-500" : "border-amber-200"), p = C(
792
- async (v) => {
1019
+ }), Xe = E(function({ id: l, data: t, selected: n }) {
1020
+ const o = k((y) => y.execution.previews[l]), i = k((y) => y.execution.nodeStatus[l]), m = k((y) => y.previewVisible[l] !== !1), d = k((y) => y.updateNodeData), a = Q(null), c = B(i) || (n ? "border-amber-500" : "border-amber-200"), u = L(
1021
+ async (y) => {
793
1022
  try {
794
- const w = await Pe(v);
795
- o(i, {
796
- uploadId: w.id,
797
- filename: w.filename,
798
- mime: w.mime
1023
+ const b = await Be(y);
1024
+ d(l, {
1025
+ uploadId: b.id,
1026
+ filename: b.filename,
1027
+ mime: b.mime
799
1028
  });
800
- } catch (w) {
801
- console.error("Upload failed:", w);
1029
+ } catch (b) {
1030
+ console.error("Upload failed:", b);
802
1031
  }
803
1032
  },
804
- [i, o]
805
- ), f = C(
806
- (v) => {
807
- v.preventDefault(), v.stopPropagation();
808
- const w = v.dataTransfer.files[0];
809
- w && w.type.startsWith("image/") && p(w);
1033
+ [l, d]
1034
+ ), h = L(
1035
+ (y) => {
1036
+ y.preventDefault(), y.stopPropagation();
1037
+ const b = y.dataTransfer.files[0];
1038
+ b && b.type.startsWith("image/") && u(b);
810
1039
  },
811
- [p]
812
- ), b = C((v) => {
813
- v.preventDefault(), v.stopPropagation();
814
- }, []), k = C(
815
- (v) => {
816
- var h;
817
- const w = (h = v.target.files) == null ? void 0 : h[0];
818
- w && p(w);
1040
+ [u]
1041
+ ), f = L((y) => {
1042
+ y.preventDefault(), y.stopPropagation();
1043
+ }, []), w = L(
1044
+ (y) => {
1045
+ var g;
1046
+ const b = (g = y.target.files) == null ? void 0 : g[0];
1047
+ b && u(b);
819
1048
  },
820
- [p]
821
- ), g = s || (t.uploadId ? de(t.uploadId) : null);
822
- return /* @__PURE__ */ c(
1049
+ [u]
1050
+ ), v = o || (t.uploadId ? pe(t.uploadId) : null);
1051
+ return /* @__PURE__ */ s(
823
1052
  "div",
824
1053
  {
825
- className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${l}`,
826
- onDrop: f,
827
- onDragOver: b,
1054
+ className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${c}`,
1055
+ onDrop: h,
1056
+ onDragOver: f,
828
1057
  children: [
829
- g && m ? /* @__PURE__ */ e("div", { className: "bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ e("img", { src: g, alt: "Uploaded", className: "w-full h-24 object-contain" }) }) : g ? null : /* @__PURE__ */ e(
1058
+ v && m ? /* @__PURE__ */ e("div", { className: "bg-gray-100 dark:bg-zinc-900 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ e("img", { src: v, alt: "Uploaded", className: "w-full h-24 object-contain" }) }) : v ? null : /* @__PURE__ */ e(
830
1059
  "div",
831
1060
  {
832
1061
  className: "bg-amber-50 dark:bg-amber-900/30 border-b border-amber-100 dark:border-amber-800 h-24 flex items-center justify-center cursor-pointer hover:bg-amber-100 dark:hover:bg-amber-900/50 transition-colors",
833
1062
  onClick: () => {
834
- var v;
835
- return (v = n.current) == null ? void 0 : v.click();
1063
+ var y;
1064
+ return (y = a.current) == null ? void 0 : y.click();
836
1065
  },
837
- children: /* @__PURE__ */ c("div", { className: "text-center text-amber-600 dark:text-amber-400", children: [
1066
+ children: /* @__PURE__ */ s("div", { className: "text-center text-amber-600 dark:text-amber-400", children: [
838
1067
  /* @__PURE__ */ e("div", { className: "text-2xl mb-1", children: "+" }),
839
1068
  /* @__PURE__ */ e("div", { className: "text-xs", children: "Drop image or click" })
840
1069
  ] })
@@ -843,48 +1072,48 @@ const Re = T(function({
843
1072
  /* @__PURE__ */ e(
844
1073
  "input",
845
1074
  {
846
- ref: n,
1075
+ ref: a,
847
1076
  type: "file",
848
1077
  accept: "image/*",
849
1078
  className: "hidden",
850
- onChange: k
1079
+ onChange: w
851
1080
  }
852
1081
  ),
853
- /* @__PURE__ */ c("div", { className: "px-4 py-3", children: [
854
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2 mb-2", children: [
1082
+ /* @__PURE__ */ s("div", { className: "px-4 py-3", children: [
1083
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2 mb-2", children: [
855
1084
  /* @__PURE__ */ e("div", { className: "w-3 h-3 rounded-full bg-amber-500" }),
856
1085
  /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-amber-700 dark:text-amber-400", children: "Input" }),
857
- /* @__PURE__ */ e(Q, { nodeId: i, color: "text-amber-500 dark:text-amber-400" })
1086
+ /* @__PURE__ */ e(X, { nodeId: l, color: "text-amber-500 dark:text-amber-400" })
858
1087
  ] }),
859
1088
  /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 truncate", children: t.filename || "No image selected" })
860
1089
  ] }),
861
- /* @__PURE__ */ e(L, { type: "source", position: W.Right, className: "w-3 h-3 !bg-amber-500" })
1090
+ /* @__PURE__ */ e(A, { type: "source", position: P.Right, className: "w-3 h-3 !bg-amber-500" })
862
1091
  ]
863
1092
  }
864
1093
  );
865
- }), qe = T(function({
866
- id: i,
1094
+ }), Ze = E(function({
1095
+ id: l,
867
1096
  data: t,
868
- selected: a
1097
+ selected: n
869
1098
  }) {
870
- var n, u;
871
- const s = x((l) => l.execution.nodeStatus[i]), d = x((l) => {
872
- var p;
873
- return (p = l.execution.dataOutputs) == null ? void 0 : p[i];
874
- }), o = U(s) || (a ? "border-cyan-500" : "border-cyan-200");
875
- return /* @__PURE__ */ c(
1099
+ var c, u, h;
1100
+ const o = k((f) => f.execution.nodeStatus[l]), i = k((f) => {
1101
+ var w;
1102
+ return (w = f.execution.dataOutputs) == null ? void 0 : w[l];
1103
+ }), d = B(o) || (n ? "border-cyan-500" : "border-cyan-200"), a = (c = t.outputSchema) != null && c.properties ? Object.entries(t.outputSchema.properties) : [], p = a.length > 0;
1104
+ return /* @__PURE__ */ s(
876
1105
  "div",
877
1106
  {
878
- className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${o}`,
1107
+ className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${d}`,
879
1108
  children: [
880
- /* @__PURE__ */ e(L, { type: "target", position: W.Left, className: "w-3 h-3 !bg-cyan-500" }),
881
- d && /* @__PURE__ */ e("div", { className: "bg-cyan-50 dark:bg-cyan-900/30 border-b border-cyan-100 dark:border-cyan-800 p-2 max-h-24 overflow-auto", children: /* @__PURE__ */ c("pre", { className: "text-xs text-cyan-800 dark:text-cyan-200 whitespace-pre-wrap", children: [
882
- (n = d.content) == null ? void 0 : n.slice(0, 200),
883
- (((u = d.content) == null ? void 0 : u.length) || 0) > 200 && "..."
1109
+ /* @__PURE__ */ e(A, { type: "target", position: P.Left, className: "w-3 h-3 !bg-cyan-500" }),
1110
+ i && /* @__PURE__ */ e("div", { className: "bg-cyan-50 dark:bg-cyan-900/30 border-b border-cyan-100 dark:border-cyan-800 p-2 max-h-24 overflow-auto", children: /* @__PURE__ */ s("pre", { className: "text-xs text-cyan-800 dark:text-cyan-200 whitespace-pre-wrap", children: [
1111
+ (u = i.content) == null ? void 0 : u.slice(0, 200),
1112
+ (((h = i.content) == null ? void 0 : h.length) || 0) > 200 && "..."
884
1113
  ] }) }),
885
- /* @__PURE__ */ c("div", { className: "px-4 py-3", children: [
886
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2 mb-2", children: [
887
- /* @__PURE__ */ c("svg", { className: "w-3 h-3 text-cyan-500", fill: "currentColor", viewBox: "0 0 20 20", children: [
1114
+ /* @__PURE__ */ s("div", { className: "px-4 py-3", children: [
1115
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2 mb-2", children: [
1116
+ /* @__PURE__ */ s("svg", { className: "w-3 h-3 text-cyan-500", fill: "currentColor", viewBox: "0 0 20 20", children: [
888
1117
  /* @__PURE__ */ e("path", { d: "M10 12a2 2 0 100-4 2 2 0 000 4z" }),
889
1118
  /* @__PURE__ */ e(
890
1119
  "path",
@@ -895,35 +1124,75 @@ const Re = T(function({
895
1124
  }
896
1125
  )
897
1126
  ] }),
898
- /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-cyan-700 dark:text-cyan-400", children: t.providerName })
1127
+ /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-cyan-700 dark:text-cyan-400", children: t.providerLabel || t.providerName })
899
1128
  ] }),
900
- /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400", children: t.params.prompt ? /* @__PURE__ */ c("div", { className: "truncate", children: [
1129
+ /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400", children: t.params.prompt ? /* @__PURE__ */ s("div", { className: "truncate", children: [
901
1130
  String(t.params.prompt).slice(0, 30),
902
1131
  "..."
903
- ] }) : null })
1132
+ ] }) : null }),
1133
+ p && /* @__PURE__ */ s("div", { className: "mt-2 pt-2 border-t border-cyan-200 dark:border-cyan-800", children: [
1134
+ /* @__PURE__ */ e("div", { className: "text-[10px] text-cyan-500 dark:text-cyan-400 font-medium mb-1", children: "Outputs:" }),
1135
+ a.map(([f]) => /* @__PURE__ */ s(
1136
+ "div",
1137
+ {
1138
+ className: "text-[10px] text-gray-500 dark:text-zinc-400 flex items-center gap-1",
1139
+ children: [
1140
+ /* @__PURE__ */ e("span", { className: "w-1.5 h-1.5 rounded-full bg-cyan-400" }),
1141
+ f
1142
+ ]
1143
+ },
1144
+ f
1145
+ ))
1146
+ ] })
904
1147
  ] }),
905
- /* @__PURE__ */ e(L, { type: "source", position: W.Right, className: "w-3 h-3 !bg-cyan-500" })
1148
+ p ? /* @__PURE__ */ s(U, { children: [
1149
+ /* @__PURE__ */ e(
1150
+ A,
1151
+ {
1152
+ type: "source",
1153
+ position: P.Right,
1154
+ id: "output",
1155
+ className: "w-3 h-3 !bg-cyan-500",
1156
+ style: { top: "50%" },
1157
+ title: "Full JSON output"
1158
+ }
1159
+ ),
1160
+ a.map(([f, w], v) => /* @__PURE__ */ e(
1161
+ A,
1162
+ {
1163
+ type: "source",
1164
+ position: P.Right,
1165
+ id: `output.${f}`,
1166
+ className: "w-2.5 h-2.5 !bg-cyan-400",
1167
+ style: {
1168
+ top: `${70 + v * 14}%`
1169
+ },
1170
+ title: `${f}: ${w.description || w.type}`
1171
+ },
1172
+ f
1173
+ ))
1174
+ ] }) : /* @__PURE__ */ e(A, { type: "source", position: P.Right, className: "w-3 h-3 !bg-cyan-500" })
906
1175
  ]
907
1176
  }
908
1177
  );
909
- }), Ke = T(function({ id: i, data: t, selected: a }) {
910
- var n, u;
911
- const s = x((l) => l.execution.nodeStatus[i]), d = x((l) => {
912
- var p;
913
- return (p = l.execution.dataOutputs) == null ? void 0 : p[i];
914
- }), o = U(s) || (a ? "border-pink-500" : "border-pink-200");
915
- return /* @__PURE__ */ c(
1178
+ }), et = E(function({ id: l, data: t, selected: n }) {
1179
+ var c, u, h;
1180
+ const o = k((f) => f.execution.nodeStatus[l]), i = k((f) => {
1181
+ var w;
1182
+ return (w = f.execution.dataOutputs) == null ? void 0 : w[l];
1183
+ }), d = B(o) || (n ? "border-pink-500" : "border-pink-200"), a = (c = t.outputSchema) != null && c.properties ? Object.entries(t.outputSchema.properties) : [], p = a.length > 0;
1184
+ return /* @__PURE__ */ s(
916
1185
  "div",
917
1186
  {
918
- className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${o}`,
1187
+ className: `rounded-lg border-2 bg-white dark:bg-zinc-800 shadow-md min-w-[180px] overflow-hidden ${d}`,
919
1188
  children: [
920
- /* @__PURE__ */ e(L, { type: "target", position: W.Left, className: "w-3 h-3 !bg-pink-500" }),
921
- d && /* @__PURE__ */ e("div", { className: "bg-pink-50 dark:bg-pink-900/30 border-b border-pink-100 dark:border-pink-800 p-2 max-h-24 overflow-auto", children: /* @__PURE__ */ c("pre", { className: "text-xs text-pink-800 dark:text-pink-200 whitespace-pre-wrap", children: [
922
- (n = d.content) == null ? void 0 : n.slice(0, 200),
923
- (((u = d.content) == null ? void 0 : u.length) || 0) > 200 && "..."
1189
+ /* @__PURE__ */ e(A, { type: "target", position: P.Left, className: "w-3 h-3 !bg-pink-500" }),
1190
+ i && /* @__PURE__ */ e("div", { className: "bg-pink-50 dark:bg-pink-900/30 border-b border-pink-100 dark:border-pink-800 p-2 max-h-24 overflow-auto", children: /* @__PURE__ */ s("pre", { className: "text-xs text-pink-800 dark:text-pink-200 whitespace-pre-wrap", children: [
1191
+ (u = i.content) == null ? void 0 : u.slice(0, 200),
1192
+ (((h = i.content) == null ? void 0 : h.length) || 0) > 200 && "..."
924
1193
  ] }) }),
925
- /* @__PURE__ */ c("div", { className: "px-4 py-3", children: [
926
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2 mb-2", children: [
1194
+ /* @__PURE__ */ s("div", { className: "px-4 py-3", children: [
1195
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2 mb-2", children: [
927
1196
  /* @__PURE__ */ e("svg", { className: "w-3 h-3 text-pink-500", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ e(
928
1197
  "path",
929
1198
  {
@@ -932,29 +1201,69 @@ const Re = T(function({
932
1201
  clipRule: "evenodd"
933
1202
  }
934
1203
  ) }),
935
- /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-pink-700 dark:text-pink-400", children: t.providerName })
1204
+ /* @__PURE__ */ e("span", { className: "font-semibold text-sm text-pink-700 dark:text-pink-400", children: t.providerLabel || t.providerName })
936
1205
  ] }),
937
- /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400", children: t.params.prompt ? /* @__PURE__ */ c("div", { className: "truncate", children: [
1206
+ /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400", children: t.params.prompt ? /* @__PURE__ */ s("div", { className: "truncate", children: [
938
1207
  String(t.params.prompt).slice(0, 30),
939
1208
  "..."
940
- ] }) : null })
1209
+ ] }) : null }),
1210
+ p && /* @__PURE__ */ s("div", { className: "mt-2 pt-2 border-t border-pink-200 dark:border-pink-800", children: [
1211
+ /* @__PURE__ */ e("div", { className: "text-[10px] text-pink-500 dark:text-pink-400 font-medium mb-1", children: "Outputs:" }),
1212
+ a.map(([f]) => /* @__PURE__ */ s(
1213
+ "div",
1214
+ {
1215
+ className: "text-[10px] text-gray-500 dark:text-zinc-400 flex items-center gap-1",
1216
+ children: [
1217
+ /* @__PURE__ */ e("span", { className: "w-1.5 h-1.5 rounded-full bg-pink-400" }),
1218
+ f
1219
+ ]
1220
+ },
1221
+ f
1222
+ ))
1223
+ ] })
941
1224
  ] }),
942
- /* @__PURE__ */ e(L, { type: "source", position: W.Right, className: "w-3 h-3 !bg-pink-500" })
1225
+ p ? /* @__PURE__ */ s(U, { children: [
1226
+ /* @__PURE__ */ e(
1227
+ A,
1228
+ {
1229
+ type: "source",
1230
+ position: P.Right,
1231
+ id: "output",
1232
+ className: "w-3 h-3 !bg-pink-500",
1233
+ style: { top: "50%" },
1234
+ title: "Full JSON output"
1235
+ }
1236
+ ),
1237
+ a.map(([f, w], v) => /* @__PURE__ */ e(
1238
+ A,
1239
+ {
1240
+ type: "source",
1241
+ position: P.Right,
1242
+ id: `output.${f}`,
1243
+ className: "w-2.5 h-2.5 !bg-pink-400",
1244
+ style: {
1245
+ top: `${70 + v * 14}%`
1246
+ },
1247
+ title: `${f}: ${w.description || w.type}`
1248
+ },
1249
+ f
1250
+ ))
1251
+ ] }) : /* @__PURE__ */ e(A, { type: "source", position: P.Right, className: "w-3 h-3 !bg-pink-500" })
943
1252
  ]
944
1253
  }
945
1254
  );
946
- }), _e = {
947
- generator: Re,
948
- transform: Fe,
949
- save: Ve,
950
- input: Ge,
951
- vision: qe,
952
- text: Ke
953
- }, He = {
1255
+ }), tt = {
1256
+ generator: Je,
1257
+ transform: Qe,
1258
+ save: Ye,
1259
+ input: Xe,
1260
+ vision: Ze,
1261
+ text: et
1262
+ }, rt = {
954
1263
  type: "smoothstep",
955
1264
  animated: !1,
956
1265
  markerEnd: {
957
- type: ye.ArrowClosed,
1266
+ type: Ce.ArrowClosed,
958
1267
  color: "#64748b",
959
1268
  width: 20,
960
1269
  height: 20
@@ -964,50 +1273,52 @@ const Re = T(function({
964
1273
  strokeWidth: 2
965
1274
  }
966
1275
  };
967
- function Qe() {
968
- const r = x((f) => f.nodes), i = x((f) => f.edges), t = x((f) => f.setNodes), a = x((f) => f.setEdges), s = x((f) => f.addEdge), d = x((f) => f.setSelectedNode), m = C(
969
- (f) => {
970
- const { source: b, target: k } = f;
971
- if (!b || !k) return !1;
972
- const g = r.find((h) => h.id === b), v = r.find((h) => h.id === k);
973
- return !(!g || !v || g.type === "save" || v.type === "generator" || v.type === "input" || i.find((h) => h.target === k) || b === k);
1276
+ function at() {
1277
+ const r = k((h) => h.nodes), l = k((h) => h.edges), t = k((h) => h.setNodes), n = k((h) => h.setEdges), o = k((h) => h.addEdge), i = k((h) => h.setSelectedNode), m = L(
1278
+ (h) => {
1279
+ const { source: f, target: w } = h;
1280
+ if (!f || !w) return !1;
1281
+ const v = r.find((g) => g.id === f), y = r.find((g) => g.id === w);
1282
+ return !(!v || !y || v.type === "save" || y.type === "generator" || y.type === "input" || l.find(
1283
+ (g) => g.target === w && g.targetHandle === h.targetHandle
1284
+ ) || f === w);
974
1285
  },
975
- [r, i]
976
- ), o = C(
977
- (f) => {
978
- t(we(f, r));
1286
+ [r, l]
1287
+ ), d = L(
1288
+ (h) => {
1289
+ t(Ne(h, r));
979
1290
  },
980
1291
  [r, t]
981
- ), n = C(
982
- (f) => {
983
- a(ve(f, i));
1292
+ ), a = L(
1293
+ (h) => {
1294
+ n(ze(h, l));
984
1295
  },
985
- [i, a]
986
- ), u = C(
987
- (f) => {
988
- s(f);
1296
+ [l, n]
1297
+ ), p = L(
1298
+ (h) => {
1299
+ o(h);
989
1300
  },
990
- [s]
991
- ), l = C(
992
- (f, b) => {
993
- d(b.id);
1301
+ [o]
1302
+ ), c = L(
1303
+ (h, f) => {
1304
+ i(f.id);
994
1305
  },
995
- [d]
996
- ), p = C(() => {
997
- d(null);
998
- }, [d]);
999
- return /* @__PURE__ */ e("div", { className: "h-full w-full", children: /* @__PURE__ */ c(
1000
- ke,
1306
+ [i]
1307
+ ), u = L(() => {
1308
+ i(null);
1309
+ }, [i]);
1310
+ return /* @__PURE__ */ e("div", { className: "h-full w-full", children: /* @__PURE__ */ s(
1311
+ we,
1001
1312
  {
1002
1313
  nodes: r,
1003
- edges: i,
1004
- onNodesChange: o,
1005
- onEdgesChange: n,
1006
- onConnect: u,
1007
- onNodeClick: l,
1008
- onPaneClick: p,
1009
- nodeTypes: _e,
1010
- defaultEdgeOptions: He,
1314
+ edges: l,
1315
+ onNodesChange: d,
1316
+ onEdgesChange: a,
1317
+ onConnect: p,
1318
+ onNodeClick: c,
1319
+ onPaneClick: u,
1320
+ nodeTypes: tt,
1321
+ defaultEdgeOptions: rt,
1011
1322
  isValidConnection: m,
1012
1323
  nodesDraggable: !0,
1013
1324
  nodesConnectable: !0,
@@ -1017,93 +1328,103 @@ function Qe() {
1017
1328
  snapToGrid: !0,
1018
1329
  snapGrid: [15, 15],
1019
1330
  children: [
1020
- /* @__PURE__ */ e(Ne, {}),
1021
- /* @__PURE__ */ e(ze, {}),
1022
- /* @__PURE__ */ e(Ce, { nodeStrokeWidth: 3, zoomable: !0, pannable: !0 })
1331
+ /* @__PURE__ */ e(Ie, {}),
1332
+ /* @__PURE__ */ e(Se, {}),
1333
+ /* @__PURE__ */ e(Le, { nodeStrokeWidth: 3, zoomable: !0, pannable: !0 })
1023
1334
  ]
1024
1335
  }
1025
1336
  ) });
1026
1337
  }
1027
- function Je({ onSelect: r }) {
1028
- const [i, t] = N([]), [a, s] = N(!0), [d, m] = N(null), o = async () => {
1338
+ function nt({ onSelect: r }) {
1339
+ const [l, t] = I([]), [n, o] = I(!0), [i, m] = I(null), d = async () => {
1029
1340
  try {
1030
- s(!0);
1031
- const l = await Te();
1032
- t(l), m(null);
1033
- } catch (l) {
1034
- m(l instanceof Error ? l.message : "Failed to load uploads");
1341
+ o(!0);
1342
+ const c = await Ge();
1343
+ t(c), m(null);
1344
+ } catch (c) {
1345
+ m(c instanceof Error ? c.message : "Failed to load uploads");
1035
1346
  } finally {
1036
- s(!1);
1347
+ o(!1);
1037
1348
  }
1038
1349
  };
1039
- M(() => {
1040
- o();
1350
+ D(() => {
1351
+ d();
1041
1352
  }, []);
1042
- const n = async (l, p) => {
1043
- if (p.stopPropagation(), !!confirm("Delete this upload?"))
1353
+ const a = async (c, u) => {
1354
+ if (u.stopPropagation(), !!confirm("Delete this upload?"))
1044
1355
  try {
1045
- await Ue(l), t((f) => f.filter((b) => b.id !== l));
1046
- } catch (f) {
1047
- console.error("Failed to delete:", f);
1356
+ await Ve(c), t((h) => h.filter((f) => f.id !== c));
1357
+ } catch (h) {
1358
+ console.error("Failed to delete:", h);
1048
1359
  }
1049
- }, u = (l) => l < 1024 ? `${l} B` : l < 1024 * 1024 ? `${(l / 1024).toFixed(1)} KB` : `${(l / (1024 * 1024)).toFixed(1)} MB`;
1050
- return a ? /* @__PURE__ */ e("div", { className: "p-4 text-center text-gray-500 dark:text-zinc-400", children: "Loading uploads..." }) : d ? /* @__PURE__ */ c("div", { className: "p-4 text-center text-red-500 dark:text-red-400", children: [
1051
- d,
1360
+ }, p = (c) => c < 1024 ? `${c} B` : c < 1024 * 1024 ? `${(c / 1024).toFixed(1)} KB` : `${(c / (1024 * 1024)).toFixed(1)} MB`;
1361
+ return n ? /* @__PURE__ */ e("div", { className: "p-4 text-center text-gray-500 dark:text-zinc-400", children: "Loading uploads..." }) : i ? /* @__PURE__ */ s("div", { className: "p-4 text-center text-red-500 dark:text-red-400", children: [
1362
+ i,
1052
1363
  /* @__PURE__ */ e(
1053
1364
  "button",
1054
1365
  {
1055
- onClick: o,
1366
+ onClick: d,
1056
1367
  className: "ml-2 text-teal-500 dark:text-teal-400 hover:underline",
1057
1368
  children: "Retry"
1058
1369
  }
1059
1370
  )
1060
- ] }) : i.length === 0 ? /* @__PURE__ */ e("div", { className: "p-4 text-center text-gray-500 dark:text-zinc-400", children: "No uploads yet. Drag an image onto an Input node to upload." }) : /* @__PURE__ */ e("div", { className: "p-2", children: /* @__PURE__ */ e("div", { className: "grid grid-cols-2 gap-2", children: i.map((l) => /* @__PURE__ */ c(
1371
+ ] }) : l.length === 0 ? /* @__PURE__ */ e("div", { className: "p-4 text-center text-gray-500 dark:text-zinc-400", children: "No uploads yet. Drag an image onto an Input node to upload." }) : /* @__PURE__ */ e("div", { className: "p-2", children: /* @__PURE__ */ e("div", { className: "grid grid-cols-2 gap-2", children: l.map((c) => /* @__PURE__ */ s(
1061
1372
  "div",
1062
1373
  {
1063
1374
  className: "relative group rounded border border-gray-200 dark:border-zinc-700 overflow-hidden cursor-pointer hover:border-amber-400 dark:hover:border-amber-500 transition-colors",
1064
- onClick: () => r == null ? void 0 : r(l),
1375
+ onClick: () => r == null ? void 0 : r(c),
1065
1376
  children: [
1066
1377
  /* @__PURE__ */ e(
1067
1378
  "img",
1068
1379
  {
1069
- src: de(l.id),
1070
- alt: l.filename,
1380
+ src: pe(c.id),
1381
+ alt: c.filename,
1071
1382
  className: "w-full h-20 object-cover"
1072
1383
  }
1073
1384
  ),
1074
1385
  /* @__PURE__ */ e("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center", children: /* @__PURE__ */ e(
1075
1386
  "button",
1076
1387
  {
1077
- onClick: (p) => n(l.id, p),
1388
+ onClick: (u) => a(c.id, u),
1078
1389
  className: "p-1 bg-red-500 rounded text-white text-xs hover:bg-red-600",
1079
1390
  children: "Delete"
1080
1391
  }
1081
1392
  ) }),
1082
- /* @__PURE__ */ e("div", { className: "p-1 text-xs truncate bg-white dark:bg-zinc-800 text-gray-800 dark:text-zinc-200", children: l.filename }),
1083
- /* @__PURE__ */ e("div", { className: "px-1 pb-1 text-xs text-gray-400 dark:text-zinc-500 bg-white dark:bg-zinc-800", children: u(l.size) })
1393
+ /* @__PURE__ */ e("div", { className: "p-1 text-xs truncate bg-white dark:bg-zinc-800 text-gray-800 dark:text-zinc-200", children: c.filename }),
1394
+ /* @__PURE__ */ e("div", { className: "px-1 pb-1 text-xs text-gray-400 dark:text-zinc-500 bg-white dark:bg-zinc-800", children: p(c.size) })
1084
1395
  ]
1085
1396
  },
1086
- l.id
1397
+ c.id
1087
1398
  )) }) });
1088
1399
  }
1089
- function Ye() {
1090
- const r = x((g) => g.setGenerators), i = x((g) => g.setTransforms), t = x((g) => g.generators), a = x((g) => g.transforms), s = x((g) => g.addNode), [d, m] = N(!1), { data: o } = _({
1400
+ function ot() {
1401
+ const r = k((x) => x.setGenerators), l = k((x) => x.setTransforms), t = k((x) => x.setTextProviders), n = k((x) => x.setVisionProviders), o = k((x) => x.generators), i = k((x) => x.transforms), m = k((x) => x.textProviders), d = k((x) => x.visionProviders), a = k((x) => x.addNode), [p, c] = I(!1), { data: u } = F({
1091
1402
  queryKey: ["generators"],
1092
- queryFn: We
1093
- }), { data: n } = _({
1403
+ queryFn: Me
1404
+ }), { data: h } = F({
1094
1405
  queryKey: ["transforms"],
1095
- queryFn: Ae
1406
+ queryFn: je
1407
+ }), { data: f } = F({
1408
+ queryKey: ["textProviders"],
1409
+ queryFn: De
1410
+ }), { data: w } = F({
1411
+ queryKey: ["visionProviders"],
1412
+ queryFn: Te
1096
1413
  });
1097
- M(() => {
1098
- o && r(o);
1099
- }, [o, r]), M(() => {
1100
- n && i(n);
1101
- }, [n, i]);
1102
- const u = (g, v) => {
1103
- g.dataTransfer.setData("application/json", JSON.stringify(v)), g.dataTransfer.effectAllowed = "move";
1104
- }, l = (g) => {
1105
- s(g, { x: 250, y: 150 + Math.random() * 100 });
1106
- }, p = {
1414
+ D(() => {
1415
+ u && r(u);
1416
+ }, [u, r]), D(() => {
1417
+ h && l(h);
1418
+ }, [h, l]), D(() => {
1419
+ f && t(f);
1420
+ }, [f, t]), D(() => {
1421
+ w && n(w);
1422
+ }, [w, n]);
1423
+ const v = (x, C) => {
1424
+ x.dataTransfer.setData("application/json", JSON.stringify(C)), x.dataTransfer.effectAllowed = "move";
1425
+ }, y = (x) => {
1426
+ a(x, { x: 250, y: 150 + Math.random() * 100 });
1427
+ }, b = {
1107
1428
  id: "input:upload",
1108
1429
  type: "input",
1109
1430
  name: "upload",
@@ -1114,7 +1435,7 @@ function Ye() {
1114
1435
  type: "object",
1115
1436
  properties: {}
1116
1437
  }
1117
- }, f = {
1438
+ }, g = {
1118
1439
  id: "save:filesystem",
1119
1440
  type: "save",
1120
1441
  name: "save",
@@ -1135,42 +1456,42 @@ function Ye() {
1135
1456
  }
1136
1457
  }
1137
1458
  }
1138
- }, b = t.reduce(
1139
- (g, v) => {
1140
- const w = v.category || "Other";
1141
- return g[w] || (g[w] = []), g[w].push(v), g;
1459
+ }, N = o.reduce(
1460
+ (x, C) => {
1461
+ const S = C.category || "Other";
1462
+ return x[S] || (x[S] = []), x[S].push(C), x;
1142
1463
  },
1143
1464
  {}
1144
- ), k = a.reduce(
1145
- (g, v) => {
1146
- const w = v.category || "Other";
1147
- return g[w] || (g[w] = []), g[w].push(v), g;
1465
+ ), W = i.reduce(
1466
+ (x, C) => {
1467
+ const S = C.category || "Other";
1468
+ return x[S] || (x[S] = []), x[S].push(C), x;
1148
1469
  },
1149
1470
  {}
1150
1471
  );
1151
- return /* @__PURE__ */ e("div", { className: "w-64 bg-gray-50 dark:bg-zinc-800 border-r border-gray-200 dark:border-zinc-700 overflow-y-auto", children: /* @__PURE__ */ c("div", { className: "p-4", children: [
1472
+ return /* @__PURE__ */ e("div", { className: "w-64 bg-gray-50 dark:bg-zinc-800 border-r border-gray-200 dark:border-zinc-700 overflow-y-auto", children: /* @__PURE__ */ s("div", { className: "p-4", children: [
1152
1473
  /* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-gray-800 dark:text-white mb-4", children: "Nodes" }),
1153
- /* @__PURE__ */ c("div", { className: "mb-6", children: [
1154
- /* @__PURE__ */ c("div", { className: "flex items-center justify-between mb-2", children: [
1474
+ /* @__PURE__ */ s("div", { className: "mb-6", children: [
1475
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between mb-2", children: [
1155
1476
  /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-amber-600 dark:text-amber-400 uppercase tracking-wide", children: "Input" }),
1156
- /* @__PURE__ */ c(
1477
+ /* @__PURE__ */ s(
1157
1478
  "button",
1158
1479
  {
1159
- onClick: () => m(!d),
1480
+ onClick: () => c(!p),
1160
1481
  className: "text-xs text-amber-600 dark:text-amber-400 hover:text-amber-700 dark:hover:text-amber-300",
1161
1482
  children: [
1162
- d ? "Hide" : "Browse",
1483
+ p ? "Hide" : "Browse",
1163
1484
  " Uploads"
1164
1485
  ]
1165
1486
  }
1166
1487
  )
1167
1488
  ] }),
1168
- /* @__PURE__ */ c(
1489
+ /* @__PURE__ */ s(
1169
1490
  "div",
1170
1491
  {
1171
1492
  draggable: !0,
1172
- onDragStart: (g) => u(g, p),
1173
- onDoubleClick: () => l(p),
1493
+ onDragStart: (x) => v(x, b),
1494
+ onDoubleClick: () => y(b),
1174
1495
  className: "px-3 py-2 bg-amber-50 dark:bg-amber-900/30 border border-amber-200 dark:border-amber-700 rounded cursor-grab active:cursor-grabbing hover:bg-amber-100 dark:hover:bg-amber-900/50 transition-colors",
1175
1496
  children: [
1176
1497
  /* @__PURE__ */ e("div", { className: "text-sm font-medium text-amber-700 dark:text-amber-300", children: "Upload Image" }),
@@ -1178,56 +1499,90 @@ function Ye() {
1178
1499
  ]
1179
1500
  }
1180
1501
  ),
1181
- d && /* @__PURE__ */ e("div", { className: "mt-2 border border-amber-200 dark:border-amber-700 rounded bg-white dark:bg-zinc-900 max-h-64 overflow-y-auto", children: /* @__PURE__ */ e(Je, {}) })
1502
+ p && /* @__PURE__ */ e("div", { className: "mt-2 border border-amber-200 dark:border-amber-700 rounded bg-white dark:bg-zinc-900 max-h-64 overflow-y-auto", children: /* @__PURE__ */ e(nt, {}) })
1182
1503
  ] }),
1183
- /* @__PURE__ */ c("div", { className: "mb-6", children: [
1504
+ /* @__PURE__ */ s("div", { className: "mb-6", children: [
1184
1505
  /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-blue-600 dark:text-blue-400 uppercase tracking-wide mb-2", children: "Generators" }),
1185
- Object.entries(b).map(([g, v]) => /* @__PURE__ */ c("div", { className: "mb-3", children: [
1186
- /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 mb-1", children: g }),
1187
- v.map((w) => /* @__PURE__ */ c(
1506
+ Object.entries(N).map(([x, C]) => /* @__PURE__ */ s("div", { className: "mb-3", children: [
1507
+ /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 mb-1", children: x }),
1508
+ C.map((S) => /* @__PURE__ */ s(
1188
1509
  "div",
1189
1510
  {
1190
1511
  draggable: !0,
1191
- onDragStart: (h) => u(h, w),
1192
- onDoubleClick: () => l(w),
1512
+ onDragStart: (T) => v(T, S),
1513
+ onDoubleClick: () => y(S),
1193
1514
  className: "px-3 py-2 bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-blue-100 dark:hover:bg-blue-900/50 transition-colors",
1194
1515
  children: [
1195
- /* @__PURE__ */ e("div", { className: "text-sm font-medium text-blue-700 dark:text-blue-300", children: w.label }),
1196
- w.description && /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 truncate", children: w.description })
1516
+ /* @__PURE__ */ e("div", { className: "text-sm font-medium text-blue-700 dark:text-blue-300", children: S.label }),
1517
+ S.description && /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 truncate", children: S.description })
1197
1518
  ]
1198
1519
  },
1199
- w.id
1520
+ S.id
1200
1521
  ))
1201
- ] }, g))
1522
+ ] }, x))
1202
1523
  ] }),
1203
- /* @__PURE__ */ c("div", { className: "mb-6", children: [
1524
+ /* @__PURE__ */ s("div", { className: "mb-6", children: [
1204
1525
  /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-teal-600 dark:text-teal-400 uppercase tracking-wide mb-2", children: "Transforms" }),
1205
- Object.entries(k).map(([g, v]) => /* @__PURE__ */ c("div", { className: "mb-3", children: [
1206
- /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 mb-1", children: g }),
1207
- v.map((w) => /* @__PURE__ */ c(
1526
+ Object.entries(W).map(([x, C]) => /* @__PURE__ */ s("div", { className: "mb-3", children: [
1527
+ /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 mb-1", children: x }),
1528
+ C.map((S) => /* @__PURE__ */ s(
1208
1529
  "div",
1209
1530
  {
1210
1531
  draggable: !0,
1211
- onDragStart: (h) => u(h, w),
1212
- onDoubleClick: () => l(w),
1532
+ onDragStart: (T) => v(T, S),
1533
+ onDoubleClick: () => y(S),
1213
1534
  className: "px-3 py-2 bg-teal-50 dark:bg-teal-900/30 border border-teal-200 dark:border-teal-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-teal-100 dark:hover:bg-teal-900/50 transition-colors",
1214
1535
  children: [
1215
- /* @__PURE__ */ e("div", { className: "text-sm font-medium text-teal-700 dark:text-teal-300", children: w.label }),
1216
- w.description && /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 truncate", children: w.description })
1536
+ /* @__PURE__ */ e("div", { className: "text-sm font-medium text-teal-700 dark:text-teal-300", children: S.label }),
1537
+ S.description && /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 truncate", children: S.description })
1217
1538
  ]
1218
1539
  },
1219
- w.id
1540
+ S.id
1220
1541
  ))
1221
- ] }, g))
1542
+ ] }, x))
1222
1543
  ] }),
1223
- /* @__PURE__ */ c("div", { className: "mb-6", children: [
1544
+ m.length > 0 && /* @__PURE__ */ s("div", { className: "mb-6", children: [
1545
+ /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-pink-600 dark:text-pink-400 uppercase tracking-wide mb-2", children: "AI Text" }),
1546
+ m.map((x) => /* @__PURE__ */ s(
1547
+ "div",
1548
+ {
1549
+ draggable: !0,
1550
+ onDragStart: (C) => v(C, x),
1551
+ onDoubleClick: () => y(x),
1552
+ className: "px-3 py-2 bg-pink-50 dark:bg-pink-900/30 border border-pink-200 dark:border-pink-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-pink-100 dark:hover:bg-pink-900/50 transition-colors",
1553
+ children: [
1554
+ /* @__PURE__ */ e("div", { className: "text-sm font-medium text-pink-700 dark:text-pink-300", children: x.label }),
1555
+ x.description && /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 truncate", children: x.description })
1556
+ ]
1557
+ },
1558
+ x.id
1559
+ ))
1560
+ ] }),
1561
+ d.length > 0 && /* @__PURE__ */ s("div", { className: "mb-6", children: [
1562
+ /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-cyan-600 dark:text-cyan-400 uppercase tracking-wide mb-2", children: "AI Vision" }),
1563
+ d.map((x) => /* @__PURE__ */ s(
1564
+ "div",
1565
+ {
1566
+ draggable: !0,
1567
+ onDragStart: (C) => v(C, x),
1568
+ onDoubleClick: () => y(x),
1569
+ className: "px-3 py-2 bg-cyan-50 dark:bg-cyan-900/30 border border-cyan-200 dark:border-cyan-700 rounded mb-1 cursor-grab active:cursor-grabbing hover:bg-cyan-100 dark:hover:bg-cyan-900/50 transition-colors",
1570
+ children: [
1571
+ /* @__PURE__ */ e("div", { className: "text-sm font-medium text-cyan-700 dark:text-cyan-300", children: x.label }),
1572
+ x.description && /* @__PURE__ */ e("div", { className: "text-xs text-gray-500 dark:text-zinc-400 truncate", children: x.description })
1573
+ ]
1574
+ },
1575
+ x.id
1576
+ ))
1577
+ ] }),
1578
+ /* @__PURE__ */ s("div", { className: "mb-6", children: [
1224
1579
  /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-green-600 dark:text-green-400 uppercase tracking-wide mb-2", children: "Output" }),
1225
- /* @__PURE__ */ c(
1580
+ /* @__PURE__ */ s(
1226
1581
  "div",
1227
1582
  {
1228
1583
  draggable: !0,
1229
- onDragStart: (g) => u(g, f),
1230
- onDoubleClick: () => l(f),
1584
+ onDragStart: (x) => v(x, g),
1585
+ onDoubleClick: () => y(g),
1231
1586
  className: "px-3 py-2 bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-700 rounded cursor-grab active:cursor-grabbing hover:bg-green-100 dark:hover:bg-green-900/50 transition-colors",
1232
1587
  children: [
1233
1588
  /* @__PURE__ */ e("div", { className: "text-sm font-medium text-green-700 dark:text-green-300", children: "Save" }),
@@ -1238,120 +1593,153 @@ function Ye() {
1238
1593
  ] })
1239
1594
  ] }) });
1240
1595
  }
1241
- function Xe() {
1242
- var p, f;
1243
- const r = x((b) => b.selectedNodeId), i = x((b) => b.nodes), t = x((b) => b.generators), a = x((b) => b.transforms), s = x((b) => b.updateNodeData), d = x((b) => b.deleteNode), m = i.find((b) => b.id === r);
1244
- if (!m)
1596
+ function st() {
1597
+ var f, w, v, y;
1598
+ const r = k((b) => b.selectedNodeId), l = k((b) => b.nodes), t = k((b) => b.generators), n = k((b) => b.transforms), o = k((b) => b.textProviders), i = k((b) => b.visionProviders), m = k((b) => b.updateNodeData), d = k((b) => b.deleteNode), a = l.find((b) => b.id === r);
1599
+ if (!a)
1245
1600
  return /* @__PURE__ */ e("div", { className: "w-80 bg-gray-50 dark:bg-zinc-800 border-l border-gray-200 dark:border-zinc-700 p-4", children: /* @__PURE__ */ e("div", { className: "text-gray-500 dark:text-zinc-400 text-sm", children: "Select a node to edit its properties" }) });
1246
- let o, n = "";
1247
- if (m.type === "generator") {
1248
- const b = m.data, k = t.find((g) => g.name === b.generatorName);
1249
- o = (p = k == null ? void 0 : k.params) == null ? void 0 : p.properties, n = (k == null ? void 0 : k.label) || b.generatorName;
1250
- } else if (m.type === "transform") {
1251
- const b = m.data, k = a.find((g) => g.name === b.operation);
1252
- o = (f = k == null ? void 0 : k.params) == null ? void 0 : f.properties, n = (k == null ? void 0 : k.label) || b.operation;
1253
- } else m.type === "save" && (n = "Save", o = {
1254
- destination: {
1255
- type: "string",
1256
- title: "Destination",
1257
- description: "File path to save the image"
1258
- }
1259
- });
1260
- const u = (b, k) => {
1261
- if (m.type === "generator") {
1262
- const g = m.data;
1263
- s(m.id, {
1264
- params: { ...g.params, [b]: k }
1601
+ let p, c = "";
1602
+ if (a.type === "generator") {
1603
+ const b = a.data, g = t.find((N) => N.name === b.generatorName);
1604
+ p = (f = g == null ? void 0 : g.params) == null ? void 0 : f.properties, c = (g == null ? void 0 : g.label) || b.generatorName;
1605
+ } else if (a.type === "transform") {
1606
+ const b = a.data, g = n.find((N) => N.name === b.operation);
1607
+ p = (w = g == null ? void 0 : g.params) == null ? void 0 : w.properties, c = (g == null ? void 0 : g.label) || b.operation;
1608
+ } else if (a.type === "save") {
1609
+ const g = a.data.provider === "floimg-cloud";
1610
+ c = g ? "Save to FloImg Cloud" : "Save", p = {
1611
+ destination: {
1612
+ type: "string",
1613
+ title: g ? "Filename" : "Destination",
1614
+ description: g ? "Filename for cloud storage" : "File path to save the image"
1615
+ }
1616
+ };
1617
+ } else if (a.type === "text") {
1618
+ const b = a.data, g = o.find((N) => N.name === b.providerName);
1619
+ p = (v = g == null ? void 0 : g.params) == null ? void 0 : v.properties, c = (g == null ? void 0 : g.label) || b.providerName;
1620
+ } else if (a.type === "vision") {
1621
+ const b = a.data, g = i.find((N) => N.name === b.providerName);
1622
+ p = (y = g == null ? void 0 : g.params) == null ? void 0 : y.properties, c = (g == null ? void 0 : g.label) || b.providerName;
1623
+ }
1624
+ const u = (b, g) => {
1625
+ if (a.type === "generator") {
1626
+ const N = a.data;
1627
+ m(a.id, {
1628
+ params: { ...N.params, [b]: g }
1629
+ });
1630
+ } else if (a.type === "transform") {
1631
+ const N = a.data;
1632
+ m(a.id, {
1633
+ params: { ...N.params, [b]: g }
1265
1634
  });
1266
- } else if (m.type === "transform") {
1267
- const g = m.data;
1268
- s(m.id, {
1269
- params: { ...g.params, [b]: k }
1635
+ } else if (a.type === "save")
1636
+ m(a.id, { [b]: g });
1637
+ else if (a.type === "text") {
1638
+ const N = a.data;
1639
+ m(a.id, {
1640
+ params: { ...N.params, [b]: g }
1270
1641
  });
1271
- } else m.type === "save" && s(m.id, { [b]: k });
1272
- }, l = (b) => {
1273
- if (m.type === "generator")
1274
- return m.data.params[b];
1275
- if (m.type === "transform")
1276
- return m.data.params[b];
1277
- if (m.type === "save")
1278
- return m.data[b];
1642
+ } else if (a.type === "vision") {
1643
+ const N = a.data;
1644
+ m(a.id, {
1645
+ params: { ...N.params, [b]: g }
1646
+ });
1647
+ }
1648
+ }, h = (b) => {
1649
+ if (a.type === "generator")
1650
+ return a.data.params[b];
1651
+ if (a.type === "transform")
1652
+ return a.data.params[b];
1653
+ if (a.type === "save")
1654
+ return a.data[b];
1655
+ if (a.type === "text")
1656
+ return a.data.params[b];
1657
+ if (a.type === "vision")
1658
+ return a.data.params[b];
1279
1659
  };
1280
- return /* @__PURE__ */ e("div", { className: "w-80 bg-gray-50 dark:bg-zinc-800 border-l border-gray-200 dark:border-zinc-700 overflow-y-auto", children: /* @__PURE__ */ c("div", { className: "p-4", children: [
1281
- /* @__PURE__ */ c("div", { className: "flex items-center justify-between mb-4", children: [
1282
- /* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-gray-800 dark:text-white", children: n }),
1660
+ return /* @__PURE__ */ e("div", { className: "w-80 bg-gray-50 dark:bg-zinc-800 border-l border-gray-200 dark:border-zinc-700 overflow-y-auto", children: /* @__PURE__ */ s("div", { className: "p-4", children: [
1661
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between mb-4", children: [
1662
+ /* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-gray-800 dark:text-white", children: c }),
1283
1663
  /* @__PURE__ */ e(
1284
1664
  "button",
1285
1665
  {
1286
- onClick: () => d(m.id),
1666
+ onClick: () => d(a.id),
1287
1667
  className: "text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 text-sm",
1288
1668
  children: "Delete"
1289
1669
  }
1290
1670
  )
1291
1671
  ] }),
1292
- /* @__PURE__ */ e("div", { className: "space-y-4", children: o && Object.entries(o).map(([b, k]) => /* @__PURE__ */ e(
1293
- Ze,
1672
+ /* @__PURE__ */ e("div", { className: "space-y-4", children: p && Object.entries(p).map(([b, g]) => /* @__PURE__ */ e(
1673
+ it,
1294
1674
  {
1295
1675
  name: b,
1296
- field: k,
1297
- value: l(b),
1298
- onChange: (g) => u(b, g)
1676
+ field: g,
1677
+ value: h(b),
1678
+ onChange: (N) => u(b, N)
1299
1679
  },
1300
1680
  b
1301
- )) })
1681
+ )) }),
1682
+ (a.type === "text" || a.type === "vision") && /* @__PURE__ */ e(
1683
+ lt,
1684
+ {
1685
+ nodeId: a.id,
1686
+ outputSchema: a.data.outputSchema,
1687
+ updateNodeData: m
1688
+ }
1689
+ )
1302
1690
  ] }) });
1303
1691
  }
1304
- function Ze({ name: r, field: i, value: t, onChange: a }) {
1305
- const s = i.title || r, d = "w-full px-3 py-2 border border-gray-300 dark:border-zinc-600 rounded-md shadow-sm focus:ring-teal-500 focus:border-teal-500 bg-white dark:bg-zinc-900 text-gray-900 dark:text-zinc-100";
1306
- return i.enum ? /* @__PURE__ */ c("div", { children: [
1307
- /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: s }),
1308
- /* @__PURE__ */ c(
1692
+ function it({ name: r, field: l, value: t, onChange: n }) {
1693
+ const o = l.title || r, i = "w-full px-3 py-2 border border-gray-300 dark:border-zinc-600 rounded-md shadow-sm focus:ring-teal-500 focus:border-teal-500 bg-white dark:bg-zinc-900 text-gray-900 dark:text-zinc-100";
1694
+ return l.enum ? /* @__PURE__ */ s("div", { children: [
1695
+ /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: o }),
1696
+ /* @__PURE__ */ s(
1309
1697
  "select",
1310
1698
  {
1311
1699
  value: String(t || ""),
1312
- onChange: (m) => a(m.target.value),
1313
- className: d,
1700
+ onChange: (m) => n(m.target.value),
1701
+ className: i,
1314
1702
  children: [
1315
1703
  /* @__PURE__ */ e("option", { value: "", children: "Select..." }),
1316
- i.enum.map((m) => /* @__PURE__ */ e("option", { value: m, children: m }, m))
1704
+ l.enum.map((m) => /* @__PURE__ */ e("option", { value: m, children: m }, m))
1317
1705
  ]
1318
1706
  }
1319
1707
  ),
1320
- i.description && /* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-500 dark:text-zinc-400", children: i.description })
1321
- ] }) : i.type === "number" ? /* @__PURE__ */ c("div", { children: [
1322
- /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: s }),
1708
+ l.description && /* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-500 dark:text-zinc-400", children: l.description })
1709
+ ] }) : l.type === "number" ? /* @__PURE__ */ s("div", { children: [
1710
+ /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: o }),
1323
1711
  /* @__PURE__ */ e(
1324
1712
  "input",
1325
1713
  {
1326
1714
  type: "number",
1327
1715
  value: t !== void 0 ? Number(t) : "",
1328
- onChange: (m) => a(Number(m.target.value)),
1329
- min: i.minimum,
1330
- max: i.maximum,
1331
- className: d
1716
+ onChange: (m) => n(Number(m.target.value)),
1717
+ min: l.minimum,
1718
+ max: l.maximum,
1719
+ className: i
1332
1720
  }
1333
1721
  ),
1334
- i.description && /* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-500 dark:text-zinc-400", children: i.description })
1335
- ] }) : i.type === "boolean" ? /* @__PURE__ */ c("div", { className: "flex items-center gap-2", children: [
1722
+ l.description && /* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-500 dark:text-zinc-400", children: l.description })
1723
+ ] }) : l.type === "boolean" ? /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
1336
1724
  /* @__PURE__ */ e(
1337
1725
  "input",
1338
1726
  {
1339
1727
  type: "checkbox",
1340
1728
  checked: !!t,
1341
- onChange: (m) => a(m.target.checked),
1729
+ onChange: (m) => n(m.target.checked),
1342
1730
  className: "h-4 w-4 text-teal-600 focus:ring-teal-500 border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-900"
1343
1731
  }
1344
1732
  ),
1345
- /* @__PURE__ */ e("label", { className: "text-sm font-medium text-gray-700 dark:text-zinc-300", children: s })
1346
- ] }) : r.toLowerCase().includes("color") && typeof t == "string" && t.startsWith("#") ? /* @__PURE__ */ c("div", { children: [
1347
- /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: s }),
1348
- /* @__PURE__ */ c("div", { className: "flex gap-2", children: [
1733
+ /* @__PURE__ */ e("label", { className: "text-sm font-medium text-gray-700 dark:text-zinc-300", children: o })
1734
+ ] }) : r.toLowerCase().includes("color") && typeof t == "string" && t.startsWith("#") ? /* @__PURE__ */ s("div", { children: [
1735
+ /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: o }),
1736
+ /* @__PURE__ */ s("div", { className: "flex gap-2", children: [
1349
1737
  /* @__PURE__ */ e(
1350
1738
  "input",
1351
1739
  {
1352
1740
  type: "color",
1353
1741
  value: String(t || "#000000"),
1354
- onChange: (m) => a(m.target.value),
1742
+ onChange: (m) => n(m.target.value),
1355
1743
  className: "h-10 w-14 p-1 border border-gray-300 dark:border-zinc-600 rounded"
1356
1744
  }
1357
1745
  ),
@@ -1360,142 +1748,266 @@ function Ze({ name: r, field: i, value: t, onChange: a }) {
1360
1748
  {
1361
1749
  type: "text",
1362
1750
  value: String(t || ""),
1363
- onChange: (m) => a(m.target.value),
1364
- className: d + " flex-1"
1751
+ onChange: (m) => n(m.target.value),
1752
+ className: i + " flex-1"
1365
1753
  }
1366
1754
  )
1367
1755
  ] })
1368
- ] }) : i.type === "object" ? /* @__PURE__ */ c("div", { children: [
1369
- /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: s }),
1756
+ ] }) : l.type === "object" ? /* @__PURE__ */ s("div", { children: [
1757
+ /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: o }),
1370
1758
  /* @__PURE__ */ e(
1371
1759
  "textarea",
1372
1760
  {
1373
1761
  value: t ? JSON.stringify(t, null, 2) : "{}",
1374
1762
  onChange: (m) => {
1375
1763
  try {
1376
- a(JSON.parse(m.target.value));
1764
+ n(JSON.parse(m.target.value));
1377
1765
  } catch {
1378
1766
  }
1379
1767
  },
1380
1768
  rows: 4,
1381
- className: d + " font-mono text-xs"
1769
+ className: i + " font-mono text-xs"
1382
1770
  }
1383
1771
  ),
1384
- i.description && /* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-500 dark:text-zinc-400", children: i.description })
1385
- ] }) : /* @__PURE__ */ c("div", { children: [
1386
- /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: s }),
1772
+ l.description && /* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-500 dark:text-zinc-400", children: l.description })
1773
+ ] }) : /* @__PURE__ */ s("div", { children: [
1774
+ /* @__PURE__ */ e("label", { className: "block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1", children: o }),
1387
1775
  r === "prompt" || r === "code" || r === "text" ? /* @__PURE__ */ e(
1388
1776
  "textarea",
1389
1777
  {
1390
1778
  value: String(t || ""),
1391
- onChange: (m) => a(m.target.value),
1779
+ onChange: (m) => n(m.target.value),
1392
1780
  rows: 3,
1393
- className: d
1781
+ className: i
1394
1782
  }
1395
1783
  ) : /* @__PURE__ */ e(
1396
1784
  "input",
1397
1785
  {
1398
1786
  type: "text",
1399
1787
  value: String(t || ""),
1400
- onChange: (m) => a(m.target.value),
1401
- className: d
1788
+ onChange: (m) => n(m.target.value),
1789
+ className: i
1402
1790
  }
1403
1791
  ),
1404
- i.description && /* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-500 dark:text-zinc-400", children: i.description })
1792
+ l.description && /* @__PURE__ */ e("p", { className: "mt-1 text-xs text-gray-500 dark:text-zinc-400", children: l.description })
1405
1793
  ] });
1406
1794
  }
1407
- function et(r, i) {
1408
- const t = new Map(r.map((o) => [o.id, o])), a = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
1409
- for (const o of r)
1410
- a.set(o.id, 0), s.set(o.id, []);
1411
- for (const o of i) {
1412
- const n = s.get(o.source) || [];
1413
- n.push(o.target), s.set(o.source, n), a.set(o.target, (a.get(o.target) || 0) + 1);
1795
+ function lt({ nodeId: r, outputSchema: l, updateNodeData: t }) {
1796
+ const [n, o] = I(""), i = (l == null ? void 0 : l.properties) || {}, m = Object.entries(i), d = () => {
1797
+ if (!n.trim()) return;
1798
+ const u = {
1799
+ type: "object",
1800
+ properties: {
1801
+ ...i,
1802
+ [n.trim()]: { type: "string" }
1803
+ }
1804
+ };
1805
+ t(r, { outputSchema: u }), o("");
1806
+ }, a = (u) => {
1807
+ const h = { ...i };
1808
+ delete h[u], Object.keys(h).length === 0 ? t(r, { outputSchema: void 0 }) : t(r, {
1809
+ outputSchema: { type: "object", properties: h }
1810
+ });
1811
+ }, p = (u, h) => {
1812
+ t(r, {
1813
+ outputSchema: {
1814
+ type: "object",
1815
+ properties: {
1816
+ ...i,
1817
+ [u]: { ...i[u], type: h }
1818
+ }
1819
+ }
1820
+ });
1821
+ }, c = (u, h) => {
1822
+ t(r, {
1823
+ outputSchema: {
1824
+ type: "object",
1825
+ properties: {
1826
+ ...i,
1827
+ [u]: { ...i[u], description: h || void 0 }
1828
+ }
1829
+ }
1830
+ });
1831
+ };
1832
+ return /* @__PURE__ */ s("div", { className: "mt-6 pt-4 border-t border-gray-200 dark:border-zinc-700", children: [
1833
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between mb-3", children: [
1834
+ /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-gray-700 dark:text-zinc-300", children: "Output Schema" }),
1835
+ /* @__PURE__ */ e("span", { className: "text-xs text-gray-500 dark:text-zinc-500", children: m.length > 0 ? `${m.length} output${m.length > 1 ? "s" : ""}` : "No outputs defined" })
1836
+ ] }),
1837
+ /* @__PURE__ */ e("p", { className: "text-xs text-gray-500 dark:text-zinc-400 mb-3", children: "Define output properties to enable connecting individual JSON fields to other nodes." }),
1838
+ m.length > 0 && /* @__PURE__ */ e("div", { className: "space-y-2 mb-3", children: m.map(([u, h]) => /* @__PURE__ */ s(
1839
+ "div",
1840
+ {
1841
+ className: "flex items-center gap-2 p-2 bg-pink-50 dark:bg-pink-900/20 rounded border border-pink-200 dark:border-pink-800",
1842
+ children: [
1843
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
1844
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
1845
+ /* @__PURE__ */ e("span", { className: "text-sm font-medium text-pink-700 dark:text-pink-300 truncate", children: u }),
1846
+ /* @__PURE__ */ s(
1847
+ "select",
1848
+ {
1849
+ value: h.type,
1850
+ onChange: (f) => p(u, f.target.value),
1851
+ className: "text-xs px-1.5 py-0.5 rounded border border-pink-300 dark:border-pink-700 bg-white dark:bg-zinc-800 text-gray-700 dark:text-zinc-300",
1852
+ children: [
1853
+ /* @__PURE__ */ e("option", { value: "string", children: "string" }),
1854
+ /* @__PURE__ */ e("option", { value: "number", children: "number" }),
1855
+ /* @__PURE__ */ e("option", { value: "boolean", children: "boolean" }),
1856
+ /* @__PURE__ */ e("option", { value: "object", children: "object" }),
1857
+ /* @__PURE__ */ e("option", { value: "array", children: "array" })
1858
+ ]
1859
+ }
1860
+ )
1861
+ ] }),
1862
+ /* @__PURE__ */ e(
1863
+ "input",
1864
+ {
1865
+ type: "text",
1866
+ value: h.description || "",
1867
+ onChange: (f) => c(u, f.target.value),
1868
+ placeholder: "Description (optional)",
1869
+ className: "mt-1 w-full text-xs px-2 py-1 rounded border border-pink-200 dark:border-pink-700 bg-white dark:bg-zinc-800 text-gray-600 dark:text-zinc-400 placeholder-gray-400 dark:placeholder-zinc-500"
1870
+ }
1871
+ )
1872
+ ] }),
1873
+ /* @__PURE__ */ e(
1874
+ "button",
1875
+ {
1876
+ onClick: () => a(u),
1877
+ className: "text-pink-500 hover:text-pink-700 dark:text-pink-400 dark:hover:text-pink-300 p-1",
1878
+ title: "Remove property",
1879
+ children: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
1880
+ "path",
1881
+ {
1882
+ strokeLinecap: "round",
1883
+ strokeLinejoin: "round",
1884
+ strokeWidth: 2,
1885
+ d: "M6 18L18 6M6 6l12 12"
1886
+ }
1887
+ ) })
1888
+ }
1889
+ )
1890
+ ]
1891
+ },
1892
+ u
1893
+ )) }),
1894
+ /* @__PURE__ */ s("div", { className: "flex gap-2", children: [
1895
+ /* @__PURE__ */ e(
1896
+ "input",
1897
+ {
1898
+ type: "text",
1899
+ value: n,
1900
+ onChange: (u) => o(u.target.value),
1901
+ onKeyDown: (u) => u.key === "Enter" && d(),
1902
+ placeholder: "Property name...",
1903
+ className: "flex-1 px-2 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-900 text-gray-900 dark:text-zinc-100 placeholder-gray-400 dark:placeholder-zinc-500"
1904
+ }
1905
+ ),
1906
+ /* @__PURE__ */ e(
1907
+ "button",
1908
+ {
1909
+ onClick: d,
1910
+ disabled: !n.trim(),
1911
+ className: "px-3 py-1.5 text-sm font-medium text-white bg-pink-500 rounded hover:bg-pink-600 disabled:opacity-50 disabled:cursor-not-allowed",
1912
+ children: "Add"
1913
+ }
1914
+ )
1915
+ ] }),
1916
+ m.length > 0 && /* @__PURE__ */ e("p", { className: "mt-3 text-xs text-gray-500 dark:text-zinc-500", children: "Connect from the small pink handles on the right of the node to route individual properties." })
1917
+ ] });
1918
+ }
1919
+ function dt(r, l) {
1920
+ const t = new Map(r.map((d) => [d.id, d])), n = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
1921
+ for (const d of r)
1922
+ n.set(d.id, 0), o.set(d.id, []);
1923
+ for (const d of l) {
1924
+ const a = o.get(d.source) || [];
1925
+ a.push(d.target), o.set(d.source, a), n.set(d.target, (n.get(d.target) || 0) + 1);
1414
1926
  }
1415
- const d = [];
1416
- for (const [o, n] of a)
1417
- n === 0 && d.push(o);
1927
+ const i = [];
1928
+ for (const [d, a] of n)
1929
+ a === 0 && i.push(d);
1418
1930
  const m = [];
1419
- for (; d.length > 0; ) {
1420
- const o = d.shift(), n = t.get(o);
1421
- n && m.push(n);
1422
- const u = s.get(o) || [];
1423
- for (const l of u) {
1424
- const p = (a.get(l) || 1) - 1;
1425
- a.set(l, p), p === 0 && d.push(l);
1931
+ for (; i.length > 0; ) {
1932
+ const d = i.shift(), a = t.get(d);
1933
+ a && m.push(a);
1934
+ const p = o.get(d) || [];
1935
+ for (const c of p) {
1936
+ const u = (n.get(c) || 1) - 1;
1937
+ n.set(c, u), u === 0 && i.push(c);
1426
1938
  }
1427
1939
  }
1428
1940
  return m;
1429
1941
  }
1430
- function tt(r) {
1431
- const i = r.type || "node", t = r.id.replace(/[^a-zA-Z0-9]/g, "_");
1432
- return `${i}_${t}`;
1942
+ function ct(r) {
1943
+ const l = r.type || "node", t = r.id.replace(/[^a-zA-Z0-9]/g, "_");
1944
+ return `${l}_${t}`;
1433
1945
  }
1434
- function E(r) {
1946
+ function V(r) {
1435
1947
  return typeof r == "string" ? r.includes(`
1436
1948
  `) ? "`" + r.replace(/`/g, "\\`").replace(/\$/g, "\\$") + "`" : JSON.stringify(r) : JSON.stringify(r, null, 2);
1437
1949
  }
1438
- function rt(r, i, t) {
1439
- const a = t.get(r.id), s = [], d = i.find((o) => o.target === r.id), m = d ? t.get(d.source) : null;
1950
+ function mt(r, l, t) {
1951
+ const n = t.get(r.id), o = [], i = l.find((d) => d.target === r.id), m = i ? t.get(i.source) : null;
1440
1952
  switch (r.type) {
1441
1953
  case "generator": {
1442
- const o = r.data;
1443
- s.push(o.generatorName);
1444
- const n = o.params || {}, u = Object.entries(n).filter(([, l]) => l !== void 0 && l !== "").map(([l, p]) => ` ${l}: ${E(p)}`).join(`,
1954
+ const d = r.data;
1955
+ o.push(d.generatorName);
1956
+ const a = d.params || {}, p = Object.entries(a).filter(([, c]) => c !== void 0 && c !== "").map(([c, u]) => ` ${c}: ${V(u)}`).join(`,
1445
1957
  `);
1446
1958
  return {
1447
- code: `// Generate image using ${o.generatorName}
1448
- const ${a} = await ${o.generatorName}({
1449
- ${u}
1959
+ code: `// Generate image using ${d.generatorName}
1960
+ const ${n} = await ${d.generatorName}({
1961
+ ${p}
1450
1962
  });`,
1451
- imports: s
1963
+ imports: o
1452
1964
  };
1453
1965
  }
1454
1966
  case "input":
1455
1967
  return {
1456
1968
  code: `// Load input image
1457
- const ${a} = await flo.loadImage("./input.png");`,
1969
+ const ${n} = await flo.loadImage("./input.png");`,
1458
1970
  imports: []
1459
1971
  };
1460
1972
  case "transform": {
1461
- const o = r.data, n = o.params || {}, u = Object.entries(n).filter(([, p]) => p !== void 0 && p !== "").map(([p, f]) => `${p}: ${E(f)}`).join(", "), l = m || "image";
1973
+ const d = r.data, a = d.params || {}, p = Object.entries(a).filter(([, u]) => u !== void 0 && u !== "").map(([u, h]) => `${u}: ${V(h)}`).join(", "), c = m || "image";
1462
1974
  return {
1463
- code: `// Apply ${o.operation} transform
1464
- const ${a} = await flo.transform(${l}, "${o.operation}"${u ? `, { ${u} }` : ""});`,
1975
+ code: `// Apply ${d.operation} transform
1976
+ const ${n} = await flo.transform(${c}, "${d.operation}"${p ? `, { ${p} }` : ""});`,
1465
1977
  imports: []
1466
1978
  };
1467
1979
  }
1468
1980
  case "vision": {
1469
- const o = r.data;
1470
- s.push(o.providerName);
1471
- const n = o.params || {}, u = m || "image", l = Object.entries(n).filter(([, p]) => p !== void 0 && p !== "").map(([p, f]) => ` ${p}: ${E(f)}`).join(`,
1981
+ const d = r.data;
1982
+ o.push(d.providerName);
1983
+ const a = d.params || {}, p = m || "image", c = Object.entries(a).filter(([, u]) => u !== void 0 && u !== "").map(([u, h]) => ` ${u}: ${V(h)}`).join(`,
1472
1984
  `);
1473
1985
  return {
1474
- code: `// Analyze image with ${o.providerName}
1475
- const ${a} = await ${o.providerName}.analyze(${u}, {
1476
- ${l}
1986
+ code: `// Analyze image with ${d.providerName}
1987
+ const ${n} = await ${d.providerName}.analyze(${p}, {
1988
+ ${c}
1477
1989
  });`,
1478
- imports: s
1990
+ imports: o
1479
1991
  };
1480
1992
  }
1481
1993
  case "text": {
1482
- const o = r.data;
1483
- s.push(o.providerName);
1484
- const n = o.params || {}, u = Object.entries(n).filter(([, l]) => l !== void 0 && l !== "").map(([l, p]) => ` ${l}: ${E(p)}`).join(`,
1994
+ const d = r.data;
1995
+ o.push(d.providerName);
1996
+ const a = d.params || {}, p = Object.entries(a).filter(([, c]) => c !== void 0 && c !== "").map(([c, u]) => ` ${c}: ${V(u)}`).join(`,
1485
1997
  `);
1486
1998
  return {
1487
- code: `// Generate text with ${o.providerName}
1488
- const ${a} = await ${o.providerName}.generate({
1489
- ${u}
1999
+ code: `// Generate text with ${d.providerName}
2000
+ const ${n} = await ${d.providerName}.generate({
2001
+ ${p}
1490
2002
  });`,
1491
- imports: s
2003
+ imports: o
1492
2004
  };
1493
2005
  }
1494
2006
  case "save": {
1495
- const o = r.data;
2007
+ const d = r.data;
1496
2008
  return {
1497
2009
  code: `// Save result
1498
- await flo.save(${m || "result"}, ${E(o.destination)});`,
2010
+ await flo.save(${m || "result"}, ${V(d.destination)});`,
1499
2011
  imports: []
1500
2012
  };
1501
2013
  }
@@ -1506,33 +2018,33 @@ await flo.save(${m || "result"}, ${E(o.destination)});`,
1506
2018
  };
1507
2019
  }
1508
2020
  }
1509
- function at(r, i) {
2021
+ function pt(r, l) {
1510
2022
  if (r.length === 0)
1511
2023
  return `// Empty workflow
1512
2024
  // Add nodes to your canvas to generate code`;
1513
- const t = et(r, i), a = /* @__PURE__ */ new Map();
1514
- for (const u of t)
1515
- a.set(u.id, tt(u));
1516
- const s = /* @__PURE__ */ new Set(), d = [];
1517
- for (const u of t) {
1518
- const { code: l, imports: p } = rt(u, i, a);
1519
- d.push(l);
1520
- for (const f of p)
1521
- s.add(f);
2025
+ const t = dt(r, l), n = /* @__PURE__ */ new Map();
2026
+ for (const p of t)
2027
+ n.set(p.id, ct(p));
2028
+ const o = /* @__PURE__ */ new Set(), i = [];
2029
+ for (const p of t) {
2030
+ const { code: c, imports: u } = mt(p, l, n);
2031
+ i.push(c);
2032
+ for (const h of u)
2033
+ o.add(h);
1522
2034
  }
1523
2035
  const m = [];
1524
- s.size > 0 && m.push(`import { ${Array.from(s).join(", ")} } from "@teamflojo/floimg";`), m.push('import * as flo from "@teamflojo/floimg";');
1525
- const o = `/**
2036
+ o.size > 0 && m.push(`import { ${Array.from(o).join(", ")} } from "@teamflojo/floimg";`), m.push('import * as flo from "@teamflojo/floimg";');
2037
+ const d = `/**
1526
2038
  * FloImg Workflow
1527
2039
  * Generated by FloImg Studio
1528
2040
  * https://floimg.com
1529
2041
  */
1530
2042
 
1531
- `, n = `
2043
+ `, a = `
1532
2044
  async function runWorkflow() {
1533
- ${d.map(
1534
- (u) => u.split(`
1535
- `).map((l) => " " + l).join(`
2045
+ ${i.map(
2046
+ (p) => p.split(`
2047
+ `).map((c) => " " + c).join(`
1536
2048
  `)
1537
2049
  ).join(`
1538
2050
 
@@ -1542,80 +2054,80 @@ ${d.map(
1542
2054
  // Run the workflow
1543
2055
  runWorkflow().catch(console.error);
1544
2056
  `;
1545
- return o + m.join(`
2057
+ return d + m.join(`
1546
2058
  `) + `
1547
- ` + n;
2059
+ ` + a;
1548
2060
  }
1549
- function ot({ isOpen: r, onClose: i, onImport: t }) {
1550
- const [a, s] = N(""), [d, m] = N(!1), [o, n] = N(null), [u, l] = N(!1), p = C(async () => {
1551
- if (!a.trim()) {
1552
- n({ message: "Please enter or paste YAML content" });
2061
+ function ut({ isOpen: r, onClose: l, onImport: t }) {
2062
+ const [n, o] = I(""), [i, m] = I(!1), [d, a] = I(null), [p, c] = I(!1), u = L(async () => {
2063
+ if (!n.trim()) {
2064
+ a({ message: "Please enter or paste YAML content" });
1553
2065
  return;
1554
2066
  }
1555
- m(!0), n(null);
2067
+ m(!0), a(null);
1556
2068
  try {
1557
- const h = await Ee(a);
1558
- h.success ? (t(h.nodes, h.edges, h.name), s(""), i()) : n({
1559
- message: h.error || "Import failed",
1560
- line: h.line,
1561
- column: h.column
2069
+ const g = await Fe(n);
2070
+ g.success ? (t(g.nodes, g.edges, g.name), o(""), l()) : a({
2071
+ message: g.error || "Import failed",
2072
+ line: g.line,
2073
+ column: g.column
1562
2074
  });
1563
- } catch (h) {
1564
- n({ message: h instanceof Error ? h.message : "Import failed" });
2075
+ } catch (g) {
2076
+ a({ message: g instanceof Error ? g.message : "Import failed" });
1565
2077
  } finally {
1566
2078
  m(!1);
1567
2079
  }
1568
- }, [a, t, i]), f = C(async () => {
1569
- if (!a.trim()) {
1570
- n({ message: "Please enter or paste YAML content" });
2080
+ }, [n, t, l]), h = L(async () => {
2081
+ if (!n.trim()) {
2082
+ a({ message: "Please enter or paste YAML content" });
1571
2083
  return;
1572
2084
  }
1573
- m(!0), n(null);
2085
+ m(!0), a(null);
1574
2086
  try {
1575
- const h = await Oe(a);
1576
- h.valid ? (n(null), n({ message: "Valid YAML!" }), setTimeout(() => n(null), 2e3)) : h.errors.length > 0 && n(h.errors[0]);
1577
- } catch (h) {
1578
- n({ message: h instanceof Error ? h.message : "Validation failed" });
2087
+ const g = await He(n);
2088
+ g.valid ? (a(null), a({ message: "Valid YAML!" }), setTimeout(() => a(null), 2e3)) : g.errors.length > 0 && a(g.errors[0]);
2089
+ } catch (g) {
2090
+ a({ message: g instanceof Error ? g.message : "Validation failed" });
1579
2091
  } finally {
1580
2092
  m(!1);
1581
2093
  }
1582
- }, [a]), b = C(async (h) => {
1583
- if (!h.name.endsWith(".yaml") && !h.name.endsWith(".yml")) {
1584
- n({ message: "Please upload a .yaml or .yml file" });
2094
+ }, [n]), f = L(async (g) => {
2095
+ if (!g.name.endsWith(".yaml") && !g.name.endsWith(".yml")) {
2096
+ a({ message: "Please upload a .yaml or .yml file" });
1585
2097
  return;
1586
2098
  }
1587
2099
  try {
1588
- const z = await h.text();
1589
- s(z), n(null);
2100
+ const N = await g.text();
2101
+ o(N), a(null);
1590
2102
  } catch {
1591
- n({ message: "Failed to read file" });
2103
+ a({ message: "Failed to read file" });
1592
2104
  }
1593
- }, []), k = C((h) => {
1594
- h.preventDefault(), l(!0);
1595
- }, []), g = C((h) => {
1596
- h.preventDefault(), l(!1);
1597
- }, []), v = C(
1598
- (h) => {
1599
- h.preventDefault(), l(!1);
1600
- const z = h.dataTransfer.files[0];
1601
- z && b(z);
2105
+ }, []), w = L((g) => {
2106
+ g.preventDefault(), c(!0);
2107
+ }, []), v = L((g) => {
2108
+ g.preventDefault(), c(!1);
2109
+ }, []), y = L(
2110
+ (g) => {
2111
+ g.preventDefault(), c(!1);
2112
+ const N = g.dataTransfer.files[0];
2113
+ N && f(N);
1602
2114
  },
1603
- [b]
1604
- ), w = C(
1605
- (h) => {
1606
- var S;
1607
- const z = (S = h.target.files) == null ? void 0 : S[0];
1608
- z && b(z);
2115
+ [f]
2116
+ ), b = L(
2117
+ (g) => {
2118
+ var W;
2119
+ const N = (W = g.target.files) == null ? void 0 : W[0];
2120
+ N && f(N);
1609
2121
  },
1610
- [b]
2122
+ [f]
1611
2123
  );
1612
- return r ? /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ c("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col", children: [
1613
- /* @__PURE__ */ c("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700", children: [
2124
+ return r ? /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col", children: [
2125
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700", children: [
1614
2126
  /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "Import Workflow" }),
1615
2127
  /* @__PURE__ */ e(
1616
2128
  "button",
1617
2129
  {
1618
- onClick: i,
2130
+ onClick: l,
1619
2131
  className: "text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200",
1620
2132
  children: /* @__PURE__ */ e("svg", { className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
1621
2133
  "path",
@@ -1629,27 +2141,27 @@ function ot({ isOpen: r, onClose: i, onImport: t }) {
1629
2141
  }
1630
2142
  )
1631
2143
  ] }),
1632
- /* @__PURE__ */ c("div", { className: "p-4 flex-1 overflow-auto", children: [
2144
+ /* @__PURE__ */ s("div", { className: "p-4 flex-1 overflow-auto", children: [
1633
2145
  /* @__PURE__ */ e("p", { className: "text-sm text-gray-600 dark:text-zinc-400 mb-4", children: "Paste YAML content or drag and drop a .yaml file to import a workflow." }),
1634
- /* @__PURE__ */ c(
2146
+ /* @__PURE__ */ s(
1635
2147
  "div",
1636
2148
  {
1637
- onDragOver: k,
1638
- onDragLeave: g,
1639
- onDrop: v,
1640
- className: `border-2 border-dashed rounded-lg p-4 mb-4 text-center transition-colors ${u ? "border-teal-500 bg-teal-50 dark:bg-teal-900/20" : "border-gray-300 dark:border-zinc-600"}`,
2149
+ onDragOver: w,
2150
+ onDragLeave: v,
2151
+ onDrop: y,
2152
+ className: `border-2 border-dashed rounded-lg p-4 mb-4 text-center transition-colors ${p ? "border-teal-500 bg-teal-50 dark:bg-teal-900/20" : "border-gray-300 dark:border-zinc-600"}`,
1641
2153
  children: [
1642
2154
  /* @__PURE__ */ e(
1643
2155
  "input",
1644
2156
  {
1645
2157
  type: "file",
1646
2158
  accept: ".yaml,.yml",
1647
- onChange: w,
2159
+ onChange: b,
1648
2160
  className: "hidden",
1649
2161
  id: "yaml-file-input"
1650
2162
  }
1651
2163
  ),
1652
- /* @__PURE__ */ c(
2164
+ /* @__PURE__ */ s(
1653
2165
  "label",
1654
2166
  {
1655
2167
  htmlFor: "yaml-file-input",
@@ -1687,9 +2199,9 @@ function ot({ isOpen: r, onClose: i, onImport: t }) {
1687
2199
  /* @__PURE__ */ e(
1688
2200
  "textarea",
1689
2201
  {
1690
- value: a,
1691
- onChange: (h) => {
1692
- s(h.target.value), n(null);
2202
+ value: n,
2203
+ onChange: (g) => {
2204
+ o(g.target.value), a(null);
1693
2205
  },
1694
2206
  placeholder: `name: My Workflow
1695
2207
  steps:
@@ -1713,42 +2225,42 @@ steps:
1713
2225
  className: "w-full h-64 p-3 font-mono text-sm bg-gray-100 dark:bg-zinc-900 border border-gray-300 dark:border-zinc-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-teal-500 text-gray-800 dark:text-zinc-200"
1714
2226
  }
1715
2227
  ),
1716
- o && /* @__PURE__ */ c(
2228
+ d && /* @__PURE__ */ s(
1717
2229
  "div",
1718
2230
  {
1719
- className: `mt-4 p-3 rounded-lg text-sm ${o.message === "Valid YAML!" ? "bg-green-50 dark:bg-green-900/30 text-green-700 dark:text-green-400" : "bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-400"}`,
2231
+ className: `mt-4 p-3 rounded-lg text-sm ${d.message === "Valid YAML!" ? "bg-green-50 dark:bg-green-900/30 text-green-700 dark:text-green-400" : "bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-400"}`,
1720
2232
  children: [
1721
- /* @__PURE__ */ e("span", { className: "font-medium", children: o.message }),
1722
- o.line && /* @__PURE__ */ c("span", { className: "ml-2 text-xs", children: [
2233
+ /* @__PURE__ */ e("span", { className: "font-medium", children: d.message }),
2234
+ d.line && /* @__PURE__ */ s("span", { className: "ml-2 text-xs", children: [
1723
2235
  "(line ",
1724
- o.line,
1725
- o.column ? `, column ${o.column}` : "",
2236
+ d.line,
2237
+ d.column ? `, column ${d.column}` : "",
1726
2238
  ")"
1727
2239
  ] })
1728
2240
  ]
1729
2241
  }
1730
2242
  )
1731
2243
  ] }),
1732
- /* @__PURE__ */ c("div", { className: "flex justify-between items-center px-4 py-3 border-t border-gray-200 dark:border-zinc-700", children: [
2244
+ /* @__PURE__ */ s("div", { className: "flex justify-between items-center px-4 py-3 border-t border-gray-200 dark:border-zinc-700", children: [
1733
2245
  /* @__PURE__ */ e("span", { className: "text-xs text-gray-500 dark:text-zinc-400", children: "Use with floimg CLI: floimg run workflow.yaml" }),
1734
- /* @__PURE__ */ c("div", { className: "flex gap-2", children: [
2246
+ /* @__PURE__ */ s("div", { className: "flex gap-2", children: [
1735
2247
  /* @__PURE__ */ e(
1736
2248
  "button",
1737
2249
  {
1738
- onClick: f,
1739
- disabled: d || !a.trim(),
2250
+ onClick: h,
2251
+ disabled: i || !n.trim(),
1740
2252
  className: "px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600 disabled:opacity-50 disabled:cursor-not-allowed",
1741
2253
  children: "Validate"
1742
2254
  }
1743
2255
  ),
1744
- /* @__PURE__ */ c(
2256
+ /* @__PURE__ */ s(
1745
2257
  "button",
1746
2258
  {
1747
- onClick: p,
1748
- disabled: d || !a.trim(),
2259
+ onClick: u,
2260
+ disabled: i || !n.trim(),
1749
2261
  className: "px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2",
1750
2262
  children: [
1751
- d && /* @__PURE__ */ c("svg", { className: "animate-spin h-4 w-4", viewBox: "0 0 24 24", fill: "none", children: [
2263
+ i && /* @__PURE__ */ s("svg", { className: "animate-spin h-4 w-4", viewBox: "0 0 24 24", fill: "none", children: [
1752
2264
  /* @__PURE__ */ e(
1753
2265
  "circle",
1754
2266
  {
@@ -1777,56 +2289,58 @@ steps:
1777
2289
  ] })
1778
2290
  ] }) }) : null;
1779
2291
  }
1780
- function nt({
2292
+ function gt({
1781
2293
  brandingSlot: r,
1782
- beforeActionsSlot: i,
2294
+ beforeActionsSlot: l,
1783
2295
  afterActionsSlot: t,
1784
- hideAttribution: a = !1
2296
+ hideAttribution: n = !1
1785
2297
  } = {}) {
1786
- const s = x((y) => y.execution), d = x((y) => y.execute), m = x((y) => y.exportToYaml), o = x((y) => y.importFromYaml), n = x((y) => y.nodes), u = x((y) => y.edges), l = $((y) => y.openSettings), p = x((y) => y.activeWorkflowName), f = x((y) => y.hasUnsavedChanges), b = x((y) => y.saveWorkflow), k = x((y) => y.toggleLibrary), g = x((y) => y.setActiveWorkflowName), [v, w] = N(!1), [h, z] = N(!1), [S, B] = N("yaml"), [J, le] = N(""), [Y, ce] = N(""), [X, j] = N(null), [me, V] = N(!1), [Z, G] = N("");
1787
- M(() => {
1788
- const y = () => {
1789
- j("New workflow created"), setTimeout(() => j(null), 2e3);
2298
+ const o = k((z) => z.execution), i = k((z) => z.execute), m = k((z) => z.exportToYaml), d = k((z) => z.importFromYaml), a = k((z) => z.nodes), p = k((z) => z.edges), c = O((z) => z.openSettings), u = k((z) => z.activeWorkflowName), h = k((z) => z.hasUnsavedChanges), f = k((z) => z.saveWorkflow), w = k((z) => z.toggleLibrary), v = k((z) => z.setActiveWorkflowName), y = k((z) => z.selectedNodeId), b = k((z) => z.duplicateNode), [g, N] = I(!1), [W, x] = I(!1), [C, S] = I("yaml"), [T, ue] = I(""), [Z, ge] = I(""), [ee, R] = I(null), [he, K] = I(!1), [te, q] = I("");
2299
+ D(() => {
2300
+ const z = () => {
2301
+ R("New workflow created"), setTimeout(() => R(null), 2e3);
1790
2302
  };
1791
- return window.addEventListener("new-workflow-created", y), () => window.removeEventListener("new-workflow-created", y);
2303
+ return window.addEventListener("new-workflow-created", z), () => window.removeEventListener("new-workflow-created", z);
1792
2304
  }, []);
1793
- const q = C(() => {
1794
- n.length !== 0 && (b(), j("Saved!"), setTimeout(() => j(null), 2e3));
1795
- }, [n.length, b]), ue = () => {
1796
- G(p), V(!0);
1797
- }, ee = () => {
1798
- const y = Z.trim();
1799
- y && y !== p && g(y), V(!1);
1800
- };
1801
- M(() => {
1802
- function y(D) {
1803
- (D.metaKey || D.ctrlKey) && D.key === "s" && (D.preventDefault(), q());
2305
+ const J = L(() => {
2306
+ a.length !== 0 && (f(), R("Saved!"), setTimeout(() => R(null), 2e3));
2307
+ }, [a.length, f]), xe = () => {
2308
+ q(u), K(!0);
2309
+ }, re = () => {
2310
+ const z = te.trim();
2311
+ z && z !== u && v(z), K(!1);
2312
+ }, ae = L(() => {
2313
+ y && b(y);
2314
+ }, [y, b]);
2315
+ D(() => {
2316
+ function z(M) {
2317
+ (M.metaKey || M.ctrlKey) && M.key === "s" && (M.preventDefault(), J()), (M.metaKey || M.ctrlKey) && M.key === "d" && (M.preventDefault(), ae());
1804
2318
  }
1805
- return document.addEventListener("keydown", y), () => document.removeEventListener("keydown", y);
1806
- }, [q]);
1807
- const ge = async () => {
1808
- await d();
1809
- }, pe = async () => {
1810
- const y = await m();
1811
- le(y);
1812
- const D = at(n, u);
1813
- ce(D), w(!0);
1814
- }, he = () => {
1815
- const y = S === "yaml" ? J : Y;
1816
- navigator.clipboard.writeText(y);
1817
- }, fe = C(
1818
- (y, D, be) => {
1819
- o(y, D, be), j("Workflow imported!"), setTimeout(() => j(null), 2e3);
2319
+ return document.addEventListener("keydown", z), () => document.removeEventListener("keydown", z);
2320
+ }, [J, ae]);
2321
+ const be = async () => {
2322
+ await i();
2323
+ }, fe = async () => {
2324
+ const z = await m();
2325
+ ue(z);
2326
+ const M = pt(a, p);
2327
+ ge(M), N(!0);
2328
+ }, ke = () => {
2329
+ const z = C === "yaml" ? T : Z;
2330
+ navigator.clipboard.writeText(z);
2331
+ }, ve = L(
2332
+ (z, M, ye) => {
2333
+ d(z, M, ye), R("Workflow imported!"), setTimeout(() => R(null), 2e3);
1820
2334
  },
1821
- [o]
2335
+ [d]
1822
2336
  );
1823
- return /* @__PURE__ */ c(P, { children: [
1824
- /* @__PURE__ */ c("div", { className: "h-14 bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700 flex items-center justify-between px-4", children: [
1825
- /* @__PURE__ */ c("div", { className: "flex items-center gap-4", children: [
2337
+ return /* @__PURE__ */ s(U, { children: [
2338
+ /* @__PURE__ */ s("div", { className: "h-14 bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700 flex items-center justify-between px-4", children: [
2339
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-4", children: [
1826
2340
  /* @__PURE__ */ e(
1827
2341
  "button",
1828
2342
  {
1829
- onClick: k,
2343
+ onClick: w,
1830
2344
  className: "p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md",
1831
2345
  title: "My Workflows",
1832
2346
  children: /* @__PURE__ */ e("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
@@ -1840,10 +2354,10 @@ function nt({
1840
2354
  ) })
1841
2355
  }
1842
2356
  ),
1843
- /* @__PURE__ */ c("div", { className: "flex items-baseline gap-2", children: [
2357
+ /* @__PURE__ */ s("div", { className: "flex items-baseline gap-2", children: [
1844
2358
  /* @__PURE__ */ e("h1", { className: "text-xl font-bold text-gray-800 dark:text-white", children: "FloImg Studio" }),
1845
2359
  r,
1846
- !a && /* @__PURE__ */ e(
2360
+ !n && /* @__PURE__ */ e(
1847
2361
  "a",
1848
2362
  {
1849
2363
  href: "https://flojo.io",
@@ -1854,16 +2368,16 @@ function nt({
1854
2368
  }
1855
2369
  )
1856
2370
  ] }),
1857
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2", children: [
1858
- me ? /* @__PURE__ */ e(
2371
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
2372
+ he ? /* @__PURE__ */ e(
1859
2373
  "input",
1860
2374
  {
1861
2375
  type: "text",
1862
- value: Z,
1863
- onChange: (y) => G(y.target.value),
1864
- onBlur: ee,
1865
- onKeyDown: (y) => {
1866
- y.key === "Enter" && ee(), y.key === "Escape" && (G(p), V(!1));
2376
+ value: te,
2377
+ onChange: (z) => q(z.target.value),
2378
+ onBlur: re,
2379
+ onKeyDown: (z) => {
2380
+ z.key === "Enter" && re(), z.key === "Escape" && (q(u), K(!1));
1867
2381
  },
1868
2382
  className: "w-48 px-2 py-1 text-sm font-medium bg-white dark:bg-zinc-900 border border-teal-500 rounded focus:outline-none focus:ring-1 focus:ring-teal-500 text-gray-900 dark:text-zinc-100",
1869
2383
  autoFocus: !0
@@ -1871,30 +2385,30 @@ function nt({
1871
2385
  ) : /* @__PURE__ */ e(
1872
2386
  "button",
1873
2387
  {
1874
- onClick: ue,
2388
+ onClick: xe,
1875
2389
  className: "text-sm text-gray-700 dark:text-zinc-300 font-medium hover:text-gray-900 dark:hover:text-zinc-100 rounded px-2 py-1 -mx-2 hover:bg-gray-100 dark:hover:bg-zinc-700 transition-colors",
1876
2390
  title: "Click to rename",
1877
- children: p
2391
+ children: u
1878
2392
  }
1879
2393
  ),
1880
- f && /* @__PURE__ */ e("span", { className: "text-xs text-amber-600 dark:text-amber-400", children: "(unsaved)" }),
1881
- X && /* @__PURE__ */ e("span", { className: "text-xs text-green-600 dark:text-green-400", children: X })
2394
+ h && /* @__PURE__ */ e("span", { className: "text-xs text-amber-600 dark:text-amber-400", children: "(unsaved)" }),
2395
+ ee && /* @__PURE__ */ e("span", { className: "text-xs text-green-600 dark:text-green-400", children: ee })
1882
2396
  ] }),
1883
- /* @__PURE__ */ c("span", { className: "text-sm text-gray-500 dark:text-zinc-400", children: [
1884
- n.length,
2397
+ /* @__PURE__ */ s("span", { className: "text-sm text-gray-500 dark:text-zinc-400", children: [
2398
+ a.length,
1885
2399
  " node",
1886
- n.length !== 1 ? "s" : ""
2400
+ a.length !== 1 ? "s" : ""
1887
2401
  ] })
1888
2402
  ] }),
1889
- /* @__PURE__ */ c("div", { className: "flex items-center gap-3", children: [
1890
- i,
2403
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-3", children: [
2404
+ l,
1891
2405
  /* @__PURE__ */ e(
1892
2406
  "button",
1893
2407
  {
1894
- onClick: l,
2408
+ onClick: c,
1895
2409
  className: "p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md",
1896
2410
  title: "AI Settings",
1897
- children: /* @__PURE__ */ c("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: [
2411
+ children: /* @__PURE__ */ s("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: [
1898
2412
  /* @__PURE__ */ e(
1899
2413
  "path",
1900
2414
  {
@@ -1919,8 +2433,8 @@ function nt({
1919
2433
  /* @__PURE__ */ e(
1920
2434
  "button",
1921
2435
  {
1922
- onClick: q,
1923
- disabled: n.length === 0,
2436
+ onClick: J,
2437
+ disabled: a.length === 0,
1924
2438
  className: "p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed",
1925
2439
  title: "Save Workflow (Cmd+S)",
1926
2440
  children: /* @__PURE__ */ e("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
@@ -1937,7 +2451,7 @@ function nt({
1937
2451
  /* @__PURE__ */ e(
1938
2452
  "button",
1939
2453
  {
1940
- onClick: () => z(!0),
2454
+ onClick: () => x(!0),
1941
2455
  className: "px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600",
1942
2456
  children: "Import"
1943
2457
  }
@@ -1945,8 +2459,8 @@ function nt({
1945
2459
  /* @__PURE__ */ e(
1946
2460
  "button",
1947
2461
  {
1948
- onClick: pe,
1949
- disabled: n.length === 0,
2462
+ onClick: fe,
2463
+ disabled: a.length === 0,
1950
2464
  className: "px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600 disabled:opacity-50 disabled:cursor-not-allowed",
1951
2465
  children: "Export"
1952
2466
  }
@@ -1954,11 +2468,11 @@ function nt({
1954
2468
  /* @__PURE__ */ e(
1955
2469
  "button",
1956
2470
  {
1957
- onClick: ge,
1958
- disabled: n.length === 0 || s.status === "running",
2471
+ onClick: be,
2472
+ disabled: a.length === 0 || o.status === "running",
1959
2473
  className: "px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2",
1960
- children: s.status === "running" ? /* @__PURE__ */ c(P, { children: [
1961
- /* @__PURE__ */ c("svg", { className: "animate-spin h-4 w-4", viewBox: "0 0 24 24", fill: "none", children: [
2474
+ children: o.status === "running" ? /* @__PURE__ */ s(U, { children: [
2475
+ /* @__PURE__ */ s("svg", { className: "animate-spin h-4 w-4", viewBox: "0 0 24 24", fill: "none", children: [
1962
2476
  /* @__PURE__ */ e(
1963
2477
  "circle",
1964
2478
  {
@@ -1980,8 +2494,8 @@ function nt({
1980
2494
  )
1981
2495
  ] }),
1982
2496
  "Running..."
1983
- ] }) : /* @__PURE__ */ c(P, { children: [
1984
- /* @__PURE__ */ c("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: [
2497
+ ] }) : /* @__PURE__ */ s(U, { children: [
2498
+ /* @__PURE__ */ s("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: [
1985
2499
  /* @__PURE__ */ e(
1986
2500
  "path",
1987
2501
  {
@@ -2008,54 +2522,44 @@ function nt({
2008
2522
  t
2009
2523
  ] })
2010
2524
  ] }),
2011
- s.status === "completed" && s.imageIds.length > 0 && /* @__PURE__ */ e("div", { className: "bg-green-50 dark:bg-green-900/30 border-b border-green-200 dark:border-green-800 px-4 py-3", children: /* @__PURE__ */ c("div", { className: "flex items-center gap-4", children: [
2012
- /* @__PURE__ */ c("span", { className: "text-green-700 dark:text-green-400 font-medium", children: [
2525
+ o.status === "completed" && o.imageIds.length > 0 && /* @__PURE__ */ e("div", { className: "bg-green-50 dark:bg-green-900/30 border-b border-green-200 dark:border-green-800 px-4 py-3", children: /* @__PURE__ */ s("div", { className: "flex items-center gap-4", children: [
2526
+ /* @__PURE__ */ s("span", { className: "text-green-700 dark:text-green-400 font-medium", children: [
2013
2527
  "Generated ",
2014
- s.imageIds.length,
2528
+ o.imageIds.length,
2015
2529
  " image",
2016
- s.imageIds.length !== 1 ? "s" : ""
2530
+ o.imageIds.length !== 1 ? "s" : ""
2017
2531
  ] }),
2018
- /* @__PURE__ */ e("div", { className: "flex gap-2", children: s.imageIds.slice(0, 4).map((y) => /* @__PURE__ */ e(
2019
- "a",
2532
+ /* @__PURE__ */ e("div", { className: "flex gap-2", children: o.imageUrls.slice(0, 4).map((z, M) => /* @__PURE__ */ e("a", { href: z, target: "_blank", rel: "noopener noreferrer", className: "block", children: /* @__PURE__ */ e(
2533
+ "img",
2020
2534
  {
2021
- href: F(y),
2022
- target: "_blank",
2023
- rel: "noopener noreferrer",
2024
- className: "block",
2025
- children: /* @__PURE__ */ e(
2026
- "img",
2027
- {
2028
- src: F(y),
2029
- alt: "Generated",
2030
- className: "h-12 w-12 object-cover rounded border border-green-300 dark:border-green-700"
2031
- }
2032
- )
2033
- },
2034
- y
2035
- )) })
2535
+ src: z,
2536
+ alt: "Generated",
2537
+ className: "h-12 w-12 object-cover rounded border border-green-300 dark:border-green-700"
2538
+ }
2539
+ ) }, M)) })
2036
2540
  ] }) }),
2037
- s.status === "error" && /* @__PURE__ */ e("div", { className: "bg-red-50 dark:bg-red-900/30 border-b border-red-200 dark:border-red-800 px-4 py-3", children: /* @__PURE__ */ c("span", { className: "text-red-700 dark:text-red-400", children: [
2541
+ o.status === "error" && /* @__PURE__ */ e("div", { className: "bg-red-50 dark:bg-red-900/30 border-b border-red-200 dark:border-red-800 px-4 py-3", children: /* @__PURE__ */ s("span", { className: "text-red-700 dark:text-red-400", children: [
2038
2542
  "Error: ",
2039
- s.error
2543
+ o.error
2040
2544
  ] }) }),
2041
- v && /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ c("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col", children: [
2042
- /* @__PURE__ */ c("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700", children: [
2043
- /* @__PURE__ */ c("div", { className: "flex items-center gap-4", children: [
2545
+ g && /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[80vh] flex flex-col", children: [
2546
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700", children: [
2547
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-4", children: [
2044
2548
  /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "Export Workflow" }),
2045
- /* @__PURE__ */ c("div", { className: "flex gap-1 bg-gray-100 dark:bg-zinc-700 rounded-lg p-1", children: [
2549
+ /* @__PURE__ */ s("div", { className: "flex gap-1 bg-gray-100 dark:bg-zinc-700 rounded-lg p-1", children: [
2046
2550
  /* @__PURE__ */ e(
2047
2551
  "button",
2048
2552
  {
2049
- onClick: () => B("yaml"),
2050
- className: `px-3 py-1 text-sm font-medium rounded-md transition-colors ${S === "yaml" ? "bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm" : "text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white"}`,
2553
+ onClick: () => S("yaml"),
2554
+ className: `px-3 py-1 text-sm font-medium rounded-md transition-colors ${C === "yaml" ? "bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm" : "text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white"}`,
2051
2555
  children: "YAML"
2052
2556
  }
2053
2557
  ),
2054
2558
  /* @__PURE__ */ e(
2055
2559
  "button",
2056
2560
  {
2057
- onClick: () => B("javascript"),
2058
- className: `px-3 py-1 text-sm font-medium rounded-md transition-colors ${S === "javascript" ? "bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm" : "text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white"}`,
2561
+ onClick: () => S("javascript"),
2562
+ className: `px-3 py-1 text-sm font-medium rounded-md transition-colors ${C === "javascript" ? "bg-white dark:bg-zinc-600 text-gray-900 dark:text-white shadow-sm" : "text-gray-600 dark:text-zinc-400 hover:text-gray-900 dark:hover:text-white"}`,
2059
2563
  children: "JavaScript"
2060
2564
  }
2061
2565
  )
@@ -2064,7 +2568,7 @@ function nt({
2064
2568
  /* @__PURE__ */ e(
2065
2569
  "button",
2066
2570
  {
2067
- onClick: () => w(!1),
2571
+ onClick: () => N(!1),
2068
2572
  className: "text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200",
2069
2573
  children: /* @__PURE__ */ e("svg", { className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
2070
2574
  "path",
@@ -2078,14 +2582,14 @@ function nt({
2078
2582
  }
2079
2583
  )
2080
2584
  ] }),
2081
- /* @__PURE__ */ e("div", { className: "p-4 overflow-auto flex-1", children: /* @__PURE__ */ e("pre", { className: "bg-gray-100 dark:bg-zinc-900 p-4 rounded text-sm font-mono whitespace-pre-wrap text-gray-800 dark:text-zinc-200", children: S === "yaml" ? J : Y }) }),
2082
- /* @__PURE__ */ c("div", { className: "flex justify-between items-center px-4 py-3 border-t border-gray-200 dark:border-zinc-700", children: [
2083
- /* @__PURE__ */ e("span", { className: "text-xs text-gray-500 dark:text-zinc-400", children: S === "yaml" ? "Use with floimg CLI: floimg run workflow.yaml" : "Run with Node.js or Bun" }),
2084
- /* @__PURE__ */ c("div", { className: "flex gap-2", children: [
2585
+ /* @__PURE__ */ e("div", { className: "p-4 overflow-auto flex-1", children: /* @__PURE__ */ e("pre", { className: "bg-gray-100 dark:bg-zinc-900 p-4 rounded text-sm font-mono whitespace-pre-wrap text-gray-800 dark:text-zinc-200", children: C === "yaml" ? T : Z }) }),
2586
+ /* @__PURE__ */ s("div", { className: "flex justify-between items-center px-4 py-3 border-t border-gray-200 dark:border-zinc-700", children: [
2587
+ /* @__PURE__ */ e("span", { className: "text-xs text-gray-500 dark:text-zinc-400", children: C === "yaml" ? "Use with floimg CLI: floimg run workflow.yaml" : "Run with Node.js or Bun" }),
2588
+ /* @__PURE__ */ s("div", { className: "flex gap-2", children: [
2085
2589
  /* @__PURE__ */ e(
2086
2590
  "button",
2087
2591
  {
2088
- onClick: he,
2592
+ onClick: ke,
2089
2593
  className: "px-4 py-2 text-sm font-medium text-gray-700 dark:text-zinc-200 bg-white dark:bg-zinc-700 border border-gray-300 dark:border-zinc-600 rounded-md hover:bg-gray-50 dark:hover:bg-zinc-600",
2090
2594
  children: "Copy to Clipboard"
2091
2595
  }
@@ -2093,7 +2597,7 @@ function nt({
2093
2597
  /* @__PURE__ */ e(
2094
2598
  "button",
2095
2599
  {
2096
- onClick: () => w(!1),
2600
+ onClick: () => N(!1),
2097
2601
  className: "px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700",
2098
2602
  children: "Close"
2099
2603
  }
@@ -2102,64 +2606,64 @@ function nt({
2102
2606
  ] })
2103
2607
  ] }) }),
2104
2608
  /* @__PURE__ */ e(
2105
- ot,
2609
+ ut,
2106
2610
  {
2107
- isOpen: h,
2108
- onClose: () => z(!1),
2109
- onImport: fe
2611
+ isOpen: W,
2612
+ onClose: () => x(!1),
2613
+ onImport: ve
2110
2614
  }
2111
2615
  )
2112
2616
  ] });
2113
2617
  }
2114
- function st() {
2115
- const r = x((n) => n.loadTemplate), [i, t] = N(null), {
2116
- data: a,
2117
- isLoading: s,
2118
- error: d,
2618
+ function ht() {
2619
+ const r = k((a) => a.loadTemplate), [l, t] = I(null), {
2620
+ data: n,
2621
+ isLoading: o,
2622
+ error: i,
2119
2623
  refetch: m
2120
- } = _({
2624
+ } = F({
2121
2625
  queryKey: ["images"],
2122
- queryFn: Me,
2626
+ queryFn: Re,
2123
2627
  refetchInterval: 5e3
2124
2628
  // Auto-refresh every 5 seconds
2125
- }), o = async (n) => {
2126
- t(n);
2629
+ }), d = async (a) => {
2630
+ t(a);
2127
2631
  try {
2128
- const u = await je(n);
2129
- if (u != null && u.workflow) {
2130
- const l = {
2131
- id: `image-${n}`,
2132
- name: `Workflow from ${n}`,
2632
+ const p = await Ee(a);
2633
+ if (p != null && p.workflow) {
2634
+ const c = {
2635
+ id: `image-${a}`,
2636
+ name: `Workflow from ${a}`,
2133
2637
  description: "Loaded from gallery image",
2134
2638
  category: "Gallery",
2135
2639
  generator: "unknown",
2136
2640
  workflow: {
2137
- nodes: u.workflow.nodes,
2138
- edges: u.workflow.edges
2641
+ nodes: p.workflow.nodes,
2642
+ edges: p.workflow.edges
2139
2643
  }
2140
2644
  };
2141
- r(l), window.dispatchEvent(new CustomEvent("workflow-loaded"));
2645
+ r(c), window.dispatchEvent(new CustomEvent("workflow-loaded"));
2142
2646
  } else
2143
2647
  alert("No workflow metadata available for this image");
2144
- } catch (u) {
2145
- console.error("Failed to load workflow:", u), alert("Failed to load workflow");
2648
+ } catch (p) {
2649
+ console.error("Failed to load workflow:", p), alert("Failed to load workflow");
2146
2650
  } finally {
2147
2651
  t(null);
2148
2652
  }
2149
2653
  };
2150
- return s ? /* @__PURE__ */ e("div", { className: "p-8 text-center text-gray-500 dark:text-zinc-400", children: "Loading images..." }) : d ? /* @__PURE__ */ c("div", { className: "p-8 text-center text-red-500 dark:text-red-400", children: [
2654
+ return o ? /* @__PURE__ */ e("div", { className: "p-8 text-center text-gray-500 dark:text-zinc-400", children: "Loading images..." }) : i ? /* @__PURE__ */ s("div", { className: "p-8 text-center text-red-500 dark:text-red-400", children: [
2151
2655
  "Error loading images: ",
2152
- d instanceof Error ? d.message : "Unknown error"
2153
- ] }) : !a || a.length === 0 ? /* @__PURE__ */ c("div", { className: "p-8 text-center text-gray-500 dark:text-zinc-400", children: [
2656
+ i instanceof Error ? i.message : "Unknown error"
2657
+ ] }) : !n || n.length === 0 ? /* @__PURE__ */ s("div", { className: "p-8 text-center text-gray-500 dark:text-zinc-400", children: [
2154
2658
  /* @__PURE__ */ e("div", { className: "text-lg mb-2", children: "No images yet" }),
2155
2659
  /* @__PURE__ */ e("div", { className: "text-sm", children: "Create a workflow and click Execute to generate images" })
2156
- ] }) : /* @__PURE__ */ c("div", { className: "p-4 bg-gray-100 dark:bg-zinc-900 min-h-full", children: [
2157
- /* @__PURE__ */ c("div", { className: "flex items-center justify-between mb-4", children: [
2158
- /* @__PURE__ */ c("h2", { className: "text-lg font-semibold text-gray-800 dark:text-white", children: [
2660
+ ] }) : /* @__PURE__ */ s("div", { className: "p-4 bg-gray-100 dark:bg-zinc-900 min-h-full", children: [
2661
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between mb-4", children: [
2662
+ /* @__PURE__ */ s("h2", { className: "text-lg font-semibold text-gray-800 dark:text-white", children: [
2159
2663
  "Gallery (",
2160
- a.length,
2664
+ n.length,
2161
2665
  " image",
2162
- a.length !== 1 ? "s" : "",
2666
+ n.length !== 1 ? "s" : "",
2163
2667
  ")"
2164
2668
  ] }),
2165
2669
  /* @__PURE__ */ e(
@@ -2171,32 +2675,32 @@ function st() {
2171
2675
  }
2172
2676
  )
2173
2677
  ] }),
2174
- /* @__PURE__ */ e("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: a.map((n) => /* @__PURE__ */ e(
2175
- it,
2678
+ /* @__PURE__ */ e("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: n.map((a) => /* @__PURE__ */ e(
2679
+ xt,
2176
2680
  {
2177
- image: n,
2178
- onLoadWorkflow: () => o(n.id),
2179
- isLoading: i === n.id
2681
+ image: a,
2682
+ onLoadWorkflow: () => d(a.id),
2683
+ isLoading: l === a.id
2180
2684
  },
2181
- n.id
2685
+ a.id
2182
2686
  )) })
2183
2687
  ] });
2184
2688
  }
2185
- function it({ image: r, onLoadWorkflow: i, isLoading: t }) {
2186
- const a = (d) => new Date(d).toLocaleString(), s = (d) => d < 1024 ? `${d} B` : d < 1048576 ? `${(d / 1024).toFixed(1)} KB` : `${(d / 1048576).toFixed(1)} MB`;
2187
- return /* @__PURE__ */ c("div", { className: "bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden shadow-sm hover:shadow-md transition-shadow group", children: [
2188
- /* @__PURE__ */ c("div", { className: "relative", children: [
2689
+ function xt({ image: r, onLoadWorkflow: l, isLoading: t }) {
2690
+ const n = (i) => new Date(i).toLocaleString(), o = (i) => i < 1024 ? `${i} B` : i < 1048576 ? `${(i / 1024).toFixed(1)} KB` : `${(i / 1048576).toFixed(1)} MB`;
2691
+ return /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden shadow-sm hover:shadow-md transition-shadow group", children: [
2692
+ /* @__PURE__ */ s("div", { className: "relative", children: [
2189
2693
  /* @__PURE__ */ e(
2190
2694
  "a",
2191
2695
  {
2192
- href: F(r.id),
2696
+ href: oe(r.id),
2193
2697
  target: "_blank",
2194
2698
  rel: "noopener noreferrer",
2195
2699
  className: "block aspect-square bg-gray-100 dark:bg-zinc-900",
2196
2700
  children: /* @__PURE__ */ e(
2197
2701
  "img",
2198
2702
  {
2199
- src: F(r.id),
2703
+ src: oe(r.id),
2200
2704
  alt: r.filename,
2201
2705
  className: "w-full h-full object-cover",
2202
2706
  loading: "lazy"
@@ -2207,8 +2711,8 @@ function it({ image: r, onLoadWorkflow: i, isLoading: t }) {
2207
2711
  /* @__PURE__ */ e("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center", children: /* @__PURE__ */ e(
2208
2712
  "button",
2209
2713
  {
2210
- onClick: (d) => {
2211
- d.preventDefault(), i();
2714
+ onClick: (i) => {
2715
+ i.preventDefault(), l();
2212
2716
  },
2213
2717
  disabled: t,
2214
2718
  className: "px-3 py-1.5 bg-teal-600 text-white text-sm rounded-lg hover:bg-teal-700 disabled:opacity-50",
@@ -2216,18 +2720,18 @@ function it({ image: r, onLoadWorkflow: i, isLoading: t }) {
2216
2720
  }
2217
2721
  ) })
2218
2722
  ] }),
2219
- /* @__PURE__ */ c("div", { className: "p-3", children: [
2723
+ /* @__PURE__ */ s("div", { className: "p-3", children: [
2220
2724
  /* @__PURE__ */ e("div", { className: "text-sm font-medium text-gray-800 dark:text-white truncate", children: r.filename }),
2221
- /* @__PURE__ */ c("div", { className: "text-xs text-gray-500 dark:text-zinc-400 mt-1", children: [
2725
+ /* @__PURE__ */ s("div", { className: "text-xs text-gray-500 dark:text-zinc-400 mt-1", children: [
2222
2726
  r.mime,
2223
2727
  " • ",
2224
- s(r.size)
2728
+ o(r.size)
2225
2729
  ] }),
2226
- /* @__PURE__ */ e("div", { className: "text-xs text-gray-400 dark:text-zinc-500 mt-1", children: a(r.createdAt) })
2730
+ /* @__PURE__ */ e("div", { className: "text-xs text-gray-400 dark:text-zinc-500 mt-1", children: n(r.createdAt) })
2227
2731
  ] })
2228
2732
  ] });
2229
2733
  }
2230
- const dt = {
2734
+ const bt = {
2231
2735
  id: "sales-dashboard",
2232
2736
  name: "Sales Dashboard",
2233
2737
  description: "Quarterly revenue bar chart with gradient styling",
@@ -2277,7 +2781,7 @@ const dt = {
2277
2781
  ],
2278
2782
  edges: []
2279
2783
  }
2280
- }, lt = {
2784
+ }, ft = {
2281
2785
  id: "user-growth",
2282
2786
  name: "User Growth Line Chart",
2283
2787
  description: "Monthly user growth with smooth bezier curves",
@@ -2325,7 +2829,7 @@ const dt = {
2325
2829
  ],
2326
2830
  edges: []
2327
2831
  }
2328
- }, ct = {
2832
+ }, kt = {
2329
2833
  id: "api-flow",
2330
2834
  name: "API Request Flow",
2331
2835
  description: "Sequence diagram showing API authentication flow",
@@ -2367,7 +2871,7 @@ const dt = {
2367
2871
  ],
2368
2872
  edges: []
2369
2873
  }
2370
- }, mt = {
2874
+ }, vt = {
2371
2875
  id: "system-architecture",
2372
2876
  name: "System Architecture",
2373
2877
  description: "Microservices architecture diagram",
@@ -2425,7 +2929,7 @@ const dt = {
2425
2929
  ],
2426
2930
  edges: []
2427
2931
  }
2428
- }, ut = {
2932
+ }, yt = {
2429
2933
  id: "git-workflow",
2430
2934
  name: "Git Branch Workflow",
2431
2935
  description: "Git branching strategy with feature and release branches",
@@ -2468,7 +2972,7 @@ const dt = {
2468
2972
  ],
2469
2973
  edges: []
2470
2974
  }
2471
- }, gt = {
2975
+ }, wt = {
2472
2976
  id: "website-qr",
2473
2977
  name: "Website QR Code",
2474
2978
  description: "QR code linking to your website with custom styling",
@@ -2496,7 +3000,7 @@ const dt = {
2496
3000
  ],
2497
3001
  edges: []
2498
3002
  }
2499
- }, pt = {
3003
+ }, Nt = {
2500
3004
  id: "wifi-qr",
2501
3005
  name: "WiFi QR Code",
2502
3006
  description: "Scannable QR code for WiFi network access",
@@ -2524,7 +3028,7 @@ const dt = {
2524
3028
  ],
2525
3029
  edges: []
2526
3030
  }
2527
- }, ht = {
3031
+ }, zt = {
2528
3032
  id: "chart-watermark",
2529
3033
  name: "Chart with Watermark",
2530
3034
  description: "Bar chart with company watermark and rounded corners",
@@ -2590,7 +3094,7 @@ const dt = {
2590
3094
  { id: "e2", source: "transform-1", target: "transform-2" }
2591
3095
  ]
2592
3096
  }
2593
- }, ft = {
3097
+ }, Ct = {
2594
3098
  id: "diagram-webp",
2595
3099
  name: "Diagram to WebP",
2596
3100
  description: "Mermaid diagram converted to optimized WebP format",
@@ -2631,108 +3135,108 @@ const dt = {
2631
3135
  ],
2632
3136
  edges: [{ id: "e1", source: "gen-1", target: "transform-1" }]
2633
3137
  }
2634
- }, O = [
3138
+ }, H = [
2635
3139
  // Charts
2636
- dt,
2637
- lt,
3140
+ bt,
3141
+ ft,
2638
3142
  // Diagrams
2639
- ct,
2640
- mt,
2641
- ut,
3143
+ kt,
3144
+ vt,
3145
+ yt,
2642
3146
  // QR Codes
2643
- gt,
2644
- pt,
3147
+ wt,
3148
+ Nt,
2645
3149
  // Pipelines
2646
- ht,
2647
- ft
3150
+ zt,
3151
+ Ct
2648
3152
  ];
2649
- function bt() {
2650
- const r = new Set(O.map((i) => i.category));
3153
+ function It() {
3154
+ const r = new Set(H.map((l) => l.category));
2651
3155
  return Array.from(r).sort();
2652
3156
  }
2653
- function $t(r) {
2654
- return O.filter((i) => i.category === r);
3157
+ function Vt(r) {
3158
+ return H.filter((l) => l.category === r);
2655
3159
  }
2656
- function ne(r) {
2657
- return O.find((i) => i.id === r);
3160
+ function de(r) {
3161
+ return H.find((l) => l.id === r);
2658
3162
  }
2659
- function Mt(r) {
2660
- const i = r.toLowerCase();
2661
- return O.filter(
3163
+ function Ft(r) {
3164
+ const l = r.toLowerCase();
3165
+ return H.filter(
2662
3166
  (t) => {
2663
- var a;
2664
- return t.name.toLowerCase().includes(i) || t.description.toLowerCase().includes(i) || t.category.toLowerCase().includes(i) || t.generator.toLowerCase().includes(i) || ((a = t.tags) == null ? void 0 : a.some((s) => s.toLowerCase().includes(i)));
3167
+ var n;
3168
+ return t.name.toLowerCase().includes(l) || t.description.toLowerCase().includes(l) || t.category.toLowerCase().includes(l) || t.generator.toLowerCase().includes(l) || ((n = t.tags) == null ? void 0 : n.some((o) => o.toLowerCase().includes(l)));
2665
3169
  }
2666
3170
  );
2667
3171
  }
2668
- function xt({ onSelect: r }) {
2669
- const [i, t] = N(null), [a, s] = N(""), d = te(() => bt(), []), m = te(() => {
2670
- let o = O;
2671
- if (i && (o = o.filter((n) => n.category === i)), a) {
2672
- const n = a.toLowerCase();
2673
- o = o.filter(
2674
- (u) => {
2675
- var l;
2676
- return u.name.toLowerCase().includes(n) || u.description.toLowerCase().includes(n) || u.generator.toLowerCase().includes(n) || ((l = u.tags) == null ? void 0 : l.some((p) => p.toLowerCase().includes(n)));
3172
+ function St({ onSelect: r }) {
3173
+ const [l, t] = I(null), [n, o] = I(""), i = ne(() => It(), []), m = ne(() => {
3174
+ let d = H;
3175
+ if (l && (d = d.filter((a) => a.category === l)), n) {
3176
+ const a = n.toLowerCase();
3177
+ d = d.filter(
3178
+ (p) => {
3179
+ var c;
3180
+ return p.name.toLowerCase().includes(a) || p.description.toLowerCase().includes(a) || p.generator.toLowerCase().includes(a) || ((c = p.tags) == null ? void 0 : c.some((u) => u.toLowerCase().includes(a)));
2677
3181
  }
2678
3182
  );
2679
3183
  }
2680
- return o;
2681
- }, [i, a]);
2682
- return /* @__PURE__ */ c("div", { className: "p-6", children: [
2683
- /* @__PURE__ */ c("div", { className: "mb-6", children: [
3184
+ return d;
3185
+ }, [l, n]);
3186
+ return /* @__PURE__ */ s("div", { className: "p-6", children: [
3187
+ /* @__PURE__ */ s("div", { className: "mb-6", children: [
2684
3188
  /* @__PURE__ */ e("h2", { className: "text-2xl font-bold text-gray-900 dark:text-white mb-2", children: "Templates" }),
2685
3189
  /* @__PURE__ */ e("p", { className: "text-gray-600 dark:text-zinc-400", children: "Start with a pre-built workflow. Click any template to load it into the editor." })
2686
3190
  ] }),
2687
- /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-4 mb-6", children: [
3191
+ /* @__PURE__ */ s("div", { className: "flex flex-wrap gap-4 mb-6", children: [
2688
3192
  /* @__PURE__ */ e(
2689
3193
  "input",
2690
3194
  {
2691
3195
  type: "text",
2692
3196
  placeholder: "Search templates...",
2693
- value: a,
2694
- onChange: (o) => s(o.target.value),
3197
+ value: n,
3198
+ onChange: (d) => o(d.target.value),
2695
3199
  className: "px-4 py-2 border border-gray-300 dark:border-zinc-600 rounded-lg bg-white dark:bg-zinc-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-teal-500 focus:border-transparent w-64"
2696
3200
  }
2697
3201
  ),
2698
- /* @__PURE__ */ c("div", { className: "flex gap-2 flex-wrap", children: [
3202
+ /* @__PURE__ */ s("div", { className: "flex gap-2 flex-wrap", children: [
2699
3203
  /* @__PURE__ */ e(
2700
3204
  "button",
2701
3205
  {
2702
3206
  onClick: () => t(null),
2703
- className: `px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${i === null ? "bg-teal-600 text-white" : "bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600"}`,
3207
+ className: `px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${l === null ? "bg-teal-600 text-white" : "bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600"}`,
2704
3208
  children: "All"
2705
3209
  }
2706
3210
  ),
2707
- d.map((o) => /* @__PURE__ */ e(
3211
+ i.map((d) => /* @__PURE__ */ e(
2708
3212
  "button",
2709
3213
  {
2710
- onClick: () => t(o),
2711
- className: `px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${i === o ? "bg-teal-600 text-white" : "bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600"}`,
2712
- children: o
3214
+ onClick: () => t(d),
3215
+ className: `px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${l === d ? "bg-teal-600 text-white" : "bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600"}`,
3216
+ children: d
2713
3217
  },
2714
- o
3218
+ d
2715
3219
  ))
2716
3220
  ] })
2717
3221
  ] }),
2718
- m.length === 0 ? /* @__PURE__ */ e("div", { className: "text-center py-12 text-gray-500 dark:text-zinc-400", children: "No templates found matching your criteria." }) : /* @__PURE__ */ e("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: m.map((o) => /* @__PURE__ */ e(
2719
- kt,
3222
+ m.length === 0 ? /* @__PURE__ */ e("div", { className: "text-center py-12 text-gray-500 dark:text-zinc-400", children: "No templates found matching your criteria." }) : /* @__PURE__ */ e("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: m.map((d) => /* @__PURE__ */ e(
3223
+ Lt,
2720
3224
  {
2721
- template: o,
2722
- onSelect: () => r(o.id)
3225
+ template: d,
3226
+ onSelect: () => r(d.id)
2723
3227
  },
2724
- o.id
3228
+ d.id
2725
3229
  )) })
2726
3230
  ] });
2727
3231
  }
2728
- function kt({ template: r, onSelect: i }) {
2729
- const t = r.workflow.nodes.length, a = r.workflow.edges.length, s = {
3232
+ function Lt({ template: r, onSelect: l }) {
3233
+ const t = r.workflow.nodes.length, n = r.workflow.edges.length, o = {
2730
3234
  quickchart: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300",
2731
3235
  mermaid: "bg-pink-100 text-pink-800 dark:bg-pink-900/30 dark:text-pink-300",
2732
3236
  qr: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300",
2733
3237
  d3: "bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-300"
2734
3238
  };
2735
- return /* @__PURE__ */ c("div", { className: "bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden hover:shadow-lg transition-shadow", children: [
3239
+ return /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden hover:shadow-lg transition-shadow", children: [
2736
3240
  /* @__PURE__ */ e("div", { className: "aspect-video bg-gray-100 dark:bg-zinc-900 flex items-center justify-center p-4", children: r.preview ? /* @__PURE__ */ e(
2737
3241
  "img",
2738
3242
  {
@@ -2740,7 +3244,7 @@ function kt({ template: r, onSelect: i }) {
2740
3244
  alt: r.name,
2741
3245
  className: "max-w-full max-h-full object-contain"
2742
3246
  }
2743
- ) : /* @__PURE__ */ c("div", { className: "text-center text-gray-400 dark:text-zinc-500", children: [
3247
+ ) : /* @__PURE__ */ s("div", { className: "text-center text-gray-400 dark:text-zinc-500", children: [
2744
3248
  /* @__PURE__ */ e(
2745
3249
  "svg",
2746
3250
  {
@@ -2761,20 +3265,20 @@ function kt({ template: r, onSelect: i }) {
2761
3265
  ),
2762
3266
  /* @__PURE__ */ e("span", { className: "text-sm", children: "No preview" })
2763
3267
  ] }) }),
2764
- /* @__PURE__ */ c("div", { className: "p-4", children: [
2765
- /* @__PURE__ */ c("div", { className: "flex items-start justify-between mb-2", children: [
3268
+ /* @__PURE__ */ s("div", { className: "p-4", children: [
3269
+ /* @__PURE__ */ s("div", { className: "flex items-start justify-between mb-2", children: [
2766
3270
  /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: r.name }),
2767
3271
  /* @__PURE__ */ e(
2768
3272
  "span",
2769
3273
  {
2770
- className: `px-2 py-0.5 rounded text-xs font-medium ${s[r.generator] || "bg-gray-100 text-gray-800 dark:bg-zinc-700 dark:text-zinc-300"}`,
3274
+ className: `px-2 py-0.5 rounded text-xs font-medium ${o[r.generator] || "bg-gray-100 text-gray-800 dark:bg-zinc-700 dark:text-zinc-300"}`,
2771
3275
  children: r.generator
2772
3276
  }
2773
3277
  )
2774
3278
  ] }),
2775
3279
  /* @__PURE__ */ e("p", { className: "text-sm text-gray-600 dark:text-zinc-400 mb-3", children: r.description }),
2776
- /* @__PURE__ */ c("div", { className: "flex items-center gap-4 text-xs text-gray-500 dark:text-zinc-500 mb-4", children: [
2777
- /* @__PURE__ */ c("span", { className: "flex items-center gap-1", children: [
3280
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-4 text-xs text-gray-500 dark:text-zinc-500 mb-4", children: [
3281
+ /* @__PURE__ */ s("span", { className: "flex items-center gap-1", children: [
2778
3282
  /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e(
2779
3283
  "path",
2780
3284
  {
@@ -2788,7 +3292,7 @@ function kt({ template: r, onSelect: i }) {
2788
3292
  " node",
2789
3293
  t !== 1 ? "s" : ""
2790
3294
  ] }),
2791
- a > 0 && /* @__PURE__ */ c("span", { className: "flex items-center gap-1", children: [
3295
+ n > 0 && /* @__PURE__ */ s("span", { className: "flex items-center gap-1", children: [
2792
3296
  /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e(
2793
3297
  "path",
2794
3298
  {
@@ -2798,23 +3302,23 @@ function kt({ template: r, onSelect: i }) {
2798
3302
  d: "M13 7l5 5m0 0l-5 5m5-5H6"
2799
3303
  }
2800
3304
  ) }),
2801
- a,
3305
+ n,
2802
3306
  " edge",
2803
- a !== 1 ? "s" : ""
3307
+ n !== 1 ? "s" : ""
2804
3308
  ] })
2805
3309
  ] }),
2806
- r.tags && r.tags.length > 0 && /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1 mb-4", children: r.tags.slice(0, 4).map((d) => /* @__PURE__ */ e(
3310
+ r.tags && r.tags.length > 0 && /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1 mb-4", children: r.tags.slice(0, 4).map((i) => /* @__PURE__ */ e(
2807
3311
  "span",
2808
3312
  {
2809
3313
  className: "px-2 py-0.5 bg-gray-100 dark:bg-zinc-700 text-gray-600 dark:text-zinc-400 rounded text-xs",
2810
- children: d
3314
+ children: i
2811
3315
  },
2812
- d
3316
+ i
2813
3317
  )) }),
2814
3318
  /* @__PURE__ */ e(
2815
3319
  "button",
2816
3320
  {
2817
- onClick: i,
3321
+ onClick: l,
2818
3322
  className: "w-full py-2 px-4 bg-teal-600 hover:bg-teal-700 text-white rounded-lg font-medium transition-colors",
2819
3323
  children: "Use Template"
2820
3324
  }
@@ -2822,67 +3326,67 @@ function kt({ template: r, onSelect: i }) {
2822
3326
  ] })
2823
3327
  ] });
2824
3328
  }
2825
- function wt({
3329
+ function Wt({
2826
3330
  workflow: r,
2827
- isActive: i,
3331
+ isActive: l,
2828
3332
  onLoad: t,
2829
- onDelete: a,
2830
- onRename: s,
2831
- onDuplicate: d
3333
+ onDelete: n,
3334
+ onRename: o,
3335
+ onDuplicate: i
2832
3336
  }) {
2833
- const [m, o] = N(!1), [n, u] = N(r.name), [l, p] = N(!1), f = () => {
2834
- n.trim() && n !== r.name && s(n.trim()), o(!1);
2835
- }, b = (k) => {
2836
- const g = new Date(k), w = (/* @__PURE__ */ new Date()).getTime() - g.getTime(), h = Math.floor(w / 6e4), z = Math.floor(w / 36e5), S = Math.floor(w / 864e5);
2837
- return h < 1 ? "Just now" : h < 60 ? `${h}m ago` : z < 24 ? `${z}h ago` : S < 7 ? `${S}d ago` : g.toLocaleDateString();
3337
+ const [m, d] = I(!1), [a, p] = I(r.name), [c, u] = I(!1), h = () => {
3338
+ a.trim() && a !== r.name && o(a.trim()), d(!1);
3339
+ }, f = (w) => {
3340
+ const v = new Date(w), b = (/* @__PURE__ */ new Date()).getTime() - v.getTime(), g = Math.floor(b / 6e4), N = Math.floor(b / 36e5), W = Math.floor(b / 864e5);
3341
+ return g < 1 ? "Just now" : g < 60 ? `${g}m ago` : N < 24 ? `${N}h ago` : W < 7 ? `${W}d ago` : v.toLocaleDateString();
2838
3342
  };
2839
- return /* @__PURE__ */ c(
3343
+ return /* @__PURE__ */ s(
2840
3344
  "div",
2841
3345
  {
2842
- className: `group relative p-3 rounded-lg border transition-colors ${i ? "bg-teal-50 dark:bg-teal-900/20 border-teal-200 dark:border-teal-800" : "bg-white dark:bg-zinc-800 border-zinc-200 dark:border-zinc-700 hover:border-zinc-300 dark:hover:border-zinc-600"}`,
3346
+ className: `group relative p-3 rounded-lg border transition-colors ${l ? "bg-teal-50 dark:bg-teal-900/20 border-teal-200 dark:border-teal-800" : "bg-white dark:bg-zinc-800 border-zinc-200 dark:border-zinc-700 hover:border-zinc-300 dark:hover:border-zinc-600"}`,
2843
3347
  children: [
2844
- /* @__PURE__ */ c("div", { className: "flex items-start justify-between gap-2", children: [
2845
- /* @__PURE__ */ c("button", { onClick: t, className: "flex-1 text-left min-w-0", children: [
3348
+ /* @__PURE__ */ s("div", { className: "flex items-start justify-between gap-2", children: [
3349
+ /* @__PURE__ */ s("button", { onClick: t, className: "flex-1 text-left min-w-0", children: [
2846
3350
  m ? /* @__PURE__ */ e(
2847
3351
  "input",
2848
3352
  {
2849
3353
  type: "text",
2850
- value: n,
2851
- onChange: (k) => u(k.target.value),
2852
- onBlur: f,
2853
- onKeyDown: (k) => {
2854
- k.key === "Enter" && f(), k.key === "Escape" && (u(r.name), o(!1));
3354
+ value: a,
3355
+ onChange: (w) => p(w.target.value),
3356
+ onBlur: h,
3357
+ onKeyDown: (w) => {
3358
+ w.key === "Enter" && h(), w.key === "Escape" && (p(r.name), d(!1));
2855
3359
  },
2856
3360
  className: "w-full px-1 py-0.5 text-sm font-medium bg-white dark:bg-zinc-900 border border-teal-500 rounded focus:outline-none focus:ring-1 focus:ring-teal-500",
2857
3361
  autoFocus: !0,
2858
- onClick: (k) => k.stopPropagation()
3362
+ onClick: (w) => w.stopPropagation()
2859
3363
  }
2860
3364
  ) : /* @__PURE__ */ e("span", { className: "block text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate", children: r.name }),
2861
- /* @__PURE__ */ c("span", { className: "block text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: [
3365
+ /* @__PURE__ */ s("span", { className: "block text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: [
2862
3366
  r.nodes.length,
2863
3367
  " nodes · Updated ",
2864
- b(r.updatedAt)
3368
+ f(r.updatedAt)
2865
3369
  ] })
2866
3370
  ] }),
2867
- /* @__PURE__ */ c("div", { className: "relative", children: [
3371
+ /* @__PURE__ */ s("div", { className: "relative", children: [
2868
3372
  /* @__PURE__ */ e(
2869
3373
  "button",
2870
3374
  {
2871
- onClick: (k) => {
2872
- k.stopPropagation(), p(!l);
3375
+ onClick: (w) => {
3376
+ w.stopPropagation(), u(!c);
2873
3377
  },
2874
3378
  className: "p-1 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300 rounded opacity-0 group-hover:opacity-100 transition-opacity",
2875
3379
  children: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ e("path", { d: "M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" }) })
2876
3380
  }
2877
3381
  ),
2878
- l && /* @__PURE__ */ c(P, { children: [
2879
- /* @__PURE__ */ e("div", { className: "fixed inset-0 z-10", onClick: () => p(!1) }),
2880
- /* @__PURE__ */ c("div", { className: "absolute right-0 top-full mt-1 w-36 bg-white dark:bg-zinc-800 rounded-lg shadow-lg border border-zinc-200 dark:border-zinc-700 py-1 z-20", children: [
3382
+ c && /* @__PURE__ */ s(U, { children: [
3383
+ /* @__PURE__ */ e("div", { className: "fixed inset-0 z-10", onClick: () => u(!1) }),
3384
+ /* @__PURE__ */ s("div", { className: "absolute right-0 top-full mt-1 w-36 bg-white dark:bg-zinc-800 rounded-lg shadow-lg border border-zinc-200 dark:border-zinc-700 py-1 z-20", children: [
2881
3385
  /* @__PURE__ */ e(
2882
3386
  "button",
2883
3387
  {
2884
- onClick: (k) => {
2885
- k.stopPropagation(), o(!0), p(!1);
3388
+ onClick: (w) => {
3389
+ w.stopPropagation(), d(!0), u(!1);
2886
3390
  },
2887
3391
  className: "w-full px-3 py-1.5 text-left text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700",
2888
3392
  children: "Rename"
@@ -2891,8 +3395,8 @@ function wt({
2891
3395
  /* @__PURE__ */ e(
2892
3396
  "button",
2893
3397
  {
2894
- onClick: (k) => {
2895
- k.stopPropagation(), d(), p(!1);
3398
+ onClick: (w) => {
3399
+ w.stopPropagation(), i(), u(!1);
2896
3400
  },
2897
3401
  className: "w-full px-3 py-1.5 text-left text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700",
2898
3402
  children: "Duplicate"
@@ -2901,8 +3405,8 @@ function wt({
2901
3405
  /* @__PURE__ */ e(
2902
3406
  "button",
2903
3407
  {
2904
- onClick: (k) => {
2905
- k.stopPropagation(), window.confirm("Delete this workflow?") && a(), p(!1);
3408
+ onClick: (w) => {
3409
+ w.stopPropagation(), window.confirm("Delete this workflow?") && n(), u(!1);
2906
3410
  },
2907
3411
  className: "w-full px-3 py-1.5 text-left text-sm text-red-600 dark:text-red-400 hover:bg-zinc-100 dark:hover:bg-zinc-700",
2908
3412
  children: "Delete"
@@ -2912,24 +3416,24 @@ function wt({
2912
3416
  ] })
2913
3417
  ] })
2914
3418
  ] }),
2915
- i && /* @__PURE__ */ e("span", { className: "absolute top-2 right-2 w-2 h-2 bg-teal-500 rounded-full" })
3419
+ l && /* @__PURE__ */ e("span", { className: "absolute top-2 right-2 w-2 h-2 bg-teal-500 rounded-full" })
2916
3420
  ]
2917
3421
  }
2918
3422
  );
2919
3423
  }
2920
- function vt() {
2921
- const r = x((l) => l.showLibrary), i = x((l) => l.toggleLibrary), t = x((l) => l.savedWorkflows), a = x((l) => l.activeWorkflowId), s = x((l) => l.loadWorkflow), d = x((l) => l.deleteWorkflow), m = x((l) => l.renameWorkflow), o = x((l) => l.duplicateWorkflow), n = x((l) => l.newWorkflow);
3424
+ function At() {
3425
+ const r = k((c) => c.showLibrary), l = k((c) => c.toggleLibrary), t = k((c) => c.savedWorkflows), n = k((c) => c.activeWorkflowId), o = k((c) => c.loadWorkflow), i = k((c) => c.deleteWorkflow), m = k((c) => c.renameWorkflow), d = k((c) => c.duplicateWorkflow), a = k((c) => c.newWorkflow);
2922
3426
  if (!r) return null;
2923
- const u = [...t].sort((l, p) => p.updatedAt - l.updatedAt);
2924
- return /* @__PURE__ */ c(P, { children: [
2925
- /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black/20 dark:bg-black/40 z-40", onClick: i }),
2926
- /* @__PURE__ */ c("div", { className: "fixed left-0 top-0 bottom-0 w-80 bg-zinc-50 dark:bg-zinc-900 border-r border-zinc-200 dark:border-zinc-700 z-50 flex flex-col shadow-xl", children: [
2927
- /* @__PURE__ */ c("div", { className: "flex items-center justify-between px-4 py-3 border-b border-zinc-200 dark:border-zinc-700", children: [
3427
+ const p = [...t].sort((c, u) => u.updatedAt - c.updatedAt);
3428
+ return /* @__PURE__ */ s(U, { children: [
3429
+ /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black/20 dark:bg-black/40 z-40", onClick: l }),
3430
+ /* @__PURE__ */ s("div", { className: "fixed left-0 top-0 bottom-0 w-80 bg-zinc-50 dark:bg-zinc-900 border-r border-zinc-200 dark:border-zinc-700 z-50 flex flex-col shadow-xl", children: [
3431
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between px-4 py-3 border-b border-zinc-200 dark:border-zinc-700", children: [
2928
3432
  /* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-zinc-900 dark:text-zinc-100", children: "My Workflows" }),
2929
3433
  /* @__PURE__ */ e(
2930
3434
  "button",
2931
3435
  {
2932
- onClick: i,
3436
+ onClick: l,
2933
3437
  className: "p-1 text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300 rounded",
2934
3438
  children: /* @__PURE__ */ e("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
2935
3439
  "path",
@@ -2943,11 +3447,11 @@ function vt() {
2943
3447
  }
2944
3448
  )
2945
3449
  ] }),
2946
- /* @__PURE__ */ e("div", { className: "p-4 border-b border-zinc-200 dark:border-zinc-700", children: /* @__PURE__ */ c(
3450
+ /* @__PURE__ */ e("div", { className: "p-4 border-b border-zinc-200 dark:border-zinc-700", children: /* @__PURE__ */ s(
2947
3451
  "button",
2948
3452
  {
2949
3453
  onClick: () => {
2950
- n(), i(), window.dispatchEvent(new window.CustomEvent("new-workflow-created"));
3454
+ a(), l(), window.dispatchEvent(new window.CustomEvent("new-workflow-created"));
2951
3455
  },
2952
3456
  className: "w-full flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-lg hover:bg-teal-700 transition-colors",
2953
3457
  children: [
@@ -2964,7 +3468,7 @@ function vt() {
2964
3468
  ]
2965
3469
  }
2966
3470
  ) }),
2967
- /* @__PURE__ */ e("div", { className: "flex-1 overflow-y-auto p-4", children: u.length === 0 ? /* @__PURE__ */ c("div", { className: "text-center py-8", children: [
3471
+ /* @__PURE__ */ e("div", { className: "flex-1 overflow-y-auto p-4", children: p.length === 0 ? /* @__PURE__ */ s("div", { className: "text-center py-8", children: [
2968
3472
  /* @__PURE__ */ e("div", { className: "w-12 h-12 mx-auto mb-3 rounded-full bg-zinc-200 dark:bg-zinc-700 flex items-center justify-center", children: /* @__PURE__ */ e(
2969
3473
  "svg",
2970
3474
  {
@@ -2985,21 +3489,21 @@ function vt() {
2985
3489
  ) }),
2986
3490
  /* @__PURE__ */ e("p", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No saved workflows yet" }),
2987
3491
  /* @__PURE__ */ e("p", { className: "text-xs text-zinc-400 dark:text-zinc-500 mt-1", children: "Build a workflow and save it to see it here" })
2988
- ] }) : /* @__PURE__ */ e("div", { className: "space-y-2", children: u.map((l) => /* @__PURE__ */ e(
2989
- wt,
3492
+ ] }) : /* @__PURE__ */ e("div", { className: "space-y-2", children: p.map((c) => /* @__PURE__ */ e(
3493
+ Wt,
2990
3494
  {
2991
- workflow: l,
2992
- isActive: l.id === a,
3495
+ workflow: c,
3496
+ isActive: c.id === n,
2993
3497
  onLoad: () => {
2994
- s(l.id), i();
3498
+ o(c.id), l();
2995
3499
  },
2996
- onDelete: () => d(l.id),
2997
- onRename: (p) => m(l.id, p),
2998
- onDuplicate: () => o(l.id)
3500
+ onDelete: () => i(c.id),
3501
+ onRename: (u) => m(c.id, u),
3502
+ onDuplicate: () => d(c.id)
2999
3503
  },
3000
- l.id
3504
+ c.id
3001
3505
  )) }) }),
3002
- /* @__PURE__ */ c("div", { className: "px-4 py-3 border-t border-zinc-200 dark:border-zinc-700 text-xs text-zinc-500 dark:text-zinc-400", children: [
3506
+ /* @__PURE__ */ s("div", { className: "px-4 py-3 border-t border-zinc-200 dark:border-zinc-700 text-xs text-zinc-500 dark:text-zinc-400", children: [
3003
3507
  t.length,
3004
3508
  " workflow",
3005
3509
  t.length !== 1 ? "s" : "",
@@ -3008,7 +3512,7 @@ function vt() {
3008
3512
  ] })
3009
3513
  ] });
3010
3514
  }
3011
- const yt = [
3515
+ const Pt = [
3012
3516
  {
3013
3517
  id: "openai",
3014
3518
  name: "OpenAI",
@@ -3026,10 +3530,17 @@ const yt = [
3026
3530
  {
3027
3531
  id: "gemini",
3028
3532
  name: "Google AI",
3029
- description: "Gemini Vision, Gemini Text",
3533
+ description: "Gemini Vision, Gemini Text, Gemini Edit",
3030
3534
  placeholder: "AIza...",
3031
3535
  docsUrl: "https://aistudio.google.com/apikey"
3032
3536
  },
3537
+ {
3538
+ id: "grok",
3539
+ name: "xAI (Grok)",
3540
+ description: "Grok Vision, Grok Text",
3541
+ placeholder: "xai-...",
3542
+ docsUrl: "https://console.x.ai/"
3543
+ },
3033
3544
  {
3034
3545
  id: "openrouter",
3035
3546
  name: "OpenRouter",
@@ -3037,7 +3548,7 @@ const yt = [
3037
3548
  placeholder: "sk-or-...",
3038
3549
  docsUrl: "https://openrouter.ai/keys"
3039
3550
  }
3040
- ], Nt = [
3551
+ ], $t = [
3041
3552
  {
3042
3553
  id: "ollama",
3043
3554
  name: "Ollama",
@@ -3053,21 +3564,21 @@ const yt = [
3053
3564
  docsUrl: "https://lmstudio.ai"
3054
3565
  }
3055
3566
  ];
3056
- function zt({ provider: r }) {
3057
- const i = $((f) => f.ai), t = $((f) => f.setAIProvider), a = i[r.id], s = (a == null ? void 0 : a.enabled) ?? !1, d = (a == null ? void 0 : a.apiKey) ?? "", [m, o] = N(d), [n, u] = N(!1), l = () => {
3567
+ function Mt({ provider: r }) {
3568
+ const l = O((h) => h.ai), t = O((h) => h.setAIProvider), n = l[r.id], o = (n == null ? void 0 : n.enabled) ?? !1, i = (n == null ? void 0 : n.apiKey) ?? "", [m, d] = I(i), [a, p] = I(!1), c = () => {
3058
3569
  t(r.id, {
3059
3570
  apiKey: m,
3060
- enabled: !s
3571
+ enabled: !o
3061
3572
  });
3062
- }, p = (f) => {
3063
- o(f), t(r.id, {
3064
- apiKey: f,
3065
- enabled: s
3573
+ }, u = (h) => {
3574
+ d(h), t(r.id, {
3575
+ apiKey: h,
3576
+ enabled: o
3066
3577
  });
3067
3578
  };
3068
- return /* @__PURE__ */ c("div", { className: "flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg", children: [
3069
- /* @__PURE__ */ c("div", { className: "flex-1 min-w-0", children: [
3070
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2", children: [
3579
+ return /* @__PURE__ */ s("div", { className: "flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg", children: [
3580
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
3581
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3071
3582
  /* @__PURE__ */ e("span", { className: "font-medium text-gray-900 dark:text-white", children: r.name }),
3072
3583
  /* @__PURE__ */ e(
3073
3584
  "a",
@@ -3081,13 +3592,13 @@ function zt({ provider: r }) {
3081
3592
  )
3082
3593
  ] }),
3083
3594
  /* @__PURE__ */ e("p", { className: "text-sm text-gray-500 dark:text-zinc-400 mt-0.5", children: r.description }),
3084
- /* @__PURE__ */ e("div", { className: "mt-2 flex items-center gap-2", children: /* @__PURE__ */ c("div", { className: "relative flex-1", children: [
3595
+ /* @__PURE__ */ e("div", { className: "mt-2 flex items-center gap-2", children: /* @__PURE__ */ s("div", { className: "relative flex-1", children: [
3085
3596
  /* @__PURE__ */ e(
3086
3597
  "input",
3087
3598
  {
3088
- type: n ? "text" : "password",
3599
+ type: a ? "text" : "password",
3089
3600
  value: m,
3090
- onChange: (f) => p(f.target.value),
3601
+ onChange: (h) => u(h.target.value),
3091
3602
  placeholder: r.placeholder,
3092
3603
  className: "w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500"
3093
3604
  }
@@ -3096,9 +3607,9 @@ function zt({ provider: r }) {
3096
3607
  "button",
3097
3608
  {
3098
3609
  type: "button",
3099
- onClick: () => u(!n),
3610
+ onClick: () => p(!a),
3100
3611
  className: "absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-zinc-300",
3101
- children: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: n ? /* @__PURE__ */ e(
3612
+ children: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: a ? /* @__PURE__ */ e(
3102
3613
  "path",
3103
3614
  {
3104
3615
  strokeLinecap: "round",
@@ -3122,33 +3633,33 @@ function zt({ provider: r }) {
3122
3633
  /* @__PURE__ */ e("div", { className: "flex items-center", children: /* @__PURE__ */ e(
3123
3634
  "button",
3124
3635
  {
3125
- onClick: l,
3126
- className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${s ? "bg-teal-600" : "bg-gray-300 dark:bg-zinc-600"}`,
3636
+ onClick: c,
3637
+ className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${o ? "bg-teal-600" : "bg-gray-300 dark:bg-zinc-600"}`,
3127
3638
  children: /* @__PURE__ */ e(
3128
3639
  "span",
3129
3640
  {
3130
- className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${s ? "translate-x-6" : "translate-x-1"}`
3641
+ className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${o ? "translate-x-6" : "translate-x-1"}`
3131
3642
  }
3132
3643
  )
3133
3644
  }
3134
3645
  ) })
3135
3646
  ] });
3136
3647
  }
3137
- function Ct({ provider: r }) {
3138
- const i = $((l) => l.ai), t = $((l) => l.setAIProvider), a = i[r.id], s = (a == null ? void 0 : a.enabled) ?? !1, d = (a == null ? void 0 : a.baseUrl) ?? r.defaultUrl, [m, o] = N(d), n = () => {
3648
+ function jt({ provider: r }) {
3649
+ const l = O((c) => c.ai), t = O((c) => c.setAIProvider), n = l[r.id], o = (n == null ? void 0 : n.enabled) ?? !1, i = (n == null ? void 0 : n.baseUrl) ?? r.defaultUrl, [m, d] = I(i), a = () => {
3139
3650
  t(r.id, {
3140
3651
  baseUrl: m,
3141
- enabled: !s
3652
+ enabled: !o
3142
3653
  });
3143
- }, u = (l) => {
3144
- o(l), t(r.id, {
3145
- baseUrl: l,
3146
- enabled: s
3654
+ }, p = (c) => {
3655
+ d(c), t(r.id, {
3656
+ baseUrl: c,
3657
+ enabled: o
3147
3658
  });
3148
3659
  };
3149
- return /* @__PURE__ */ c("div", { className: "flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg", children: [
3150
- /* @__PURE__ */ c("div", { className: "flex-1 min-w-0", children: [
3151
- /* @__PURE__ */ c("div", { className: "flex items-center gap-2", children: [
3660
+ return /* @__PURE__ */ s("div", { className: "flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg", children: [
3661
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
3662
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3152
3663
  /* @__PURE__ */ e("span", { className: "font-medium text-gray-900 dark:text-white", children: r.name }),
3153
3664
  /* @__PURE__ */ e(
3154
3665
  "a",
@@ -3168,7 +3679,7 @@ function Ct({ provider: r }) {
3168
3679
  {
3169
3680
  type: "text",
3170
3681
  value: m,
3171
- onChange: (l) => u(l.target.value),
3682
+ onChange: (c) => p(c.target.value),
3172
3683
  placeholder: r.defaultUrl,
3173
3684
  className: "w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500"
3174
3685
  }
@@ -3177,30 +3688,30 @@ function Ct({ provider: r }) {
3177
3688
  /* @__PURE__ */ e("div", { className: "flex items-center", children: /* @__PURE__ */ e(
3178
3689
  "button",
3179
3690
  {
3180
- onClick: n,
3181
- className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${s ? "bg-teal-600" : "bg-gray-300 dark:bg-zinc-600"}`,
3691
+ onClick: a,
3692
+ className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${o ? "bg-teal-600" : "bg-gray-300 dark:bg-zinc-600"}`,
3182
3693
  children: /* @__PURE__ */ e(
3183
3694
  "span",
3184
3695
  {
3185
- className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${s ? "translate-x-6" : "translate-x-1"}`
3696
+ className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${o ? "translate-x-6" : "translate-x-1"}`
3186
3697
  }
3187
3698
  )
3188
3699
  }
3189
3700
  ) })
3190
3701
  ] });
3191
3702
  }
3192
- function St() {
3193
- const r = $((t) => t.showSettings), i = $((t) => t.closeSettings);
3194
- return r ? /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ c("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-xl w-full mx-4 max-h-[85vh] flex flex-col", children: [
3195
- /* @__PURE__ */ c("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-zinc-700", children: [
3196
- /* @__PURE__ */ c("div", { children: [
3703
+ function Dt() {
3704
+ const r = O((t) => t.showSettings), l = O((t) => t.closeSettings);
3705
+ return r ? /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-xl w-full mx-4 max-h-[85vh] flex flex-col", children: [
3706
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-zinc-700", children: [
3707
+ /* @__PURE__ */ s("div", { children: [
3197
3708
  /* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "AI Provider Settings" }),
3198
3709
  /* @__PURE__ */ e("p", { className: "text-sm text-gray-500 dark:text-zinc-400 mt-0.5", children: "Configure your AI providers for vision and text generation" })
3199
3710
  ] }),
3200
3711
  /* @__PURE__ */ e(
3201
3712
  "button",
3202
3713
  {
3203
- onClick: i,
3714
+ onClick: l,
3204
3715
  className: "text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200",
3205
3716
  children: /* @__PURE__ */ e("svg", { className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
3206
3717
  "path",
@@ -3214,16 +3725,16 @@ function St() {
3214
3725
  }
3215
3726
  )
3216
3727
  ] }),
3217
- /* @__PURE__ */ c("div", { className: "flex-1 overflow-y-auto p-6 space-y-6", children: [
3218
- /* @__PURE__ */ c("section", { children: [
3728
+ /* @__PURE__ */ s("div", { className: "flex-1 overflow-y-auto p-6 space-y-6", children: [
3729
+ /* @__PURE__ */ s("section", { children: [
3219
3730
  /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-gray-700 dark:text-zinc-300 mb-3", children: "Cloud Providers" }),
3220
- /* @__PURE__ */ e("div", { className: "space-y-3", children: yt.map((t) => /* @__PURE__ */ e(zt, { provider: t }, t.id)) })
3731
+ /* @__PURE__ */ e("div", { className: "space-y-3", children: Pt.map((t) => /* @__PURE__ */ e(Mt, { provider: t }, t.id)) })
3221
3732
  ] }),
3222
- /* @__PURE__ */ c("section", { children: [
3733
+ /* @__PURE__ */ s("section", { children: [
3223
3734
  /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-gray-700 dark:text-zinc-300 mb-3", children: "Local Providers" }),
3224
- /* @__PURE__ */ e("div", { className: "space-y-3", children: Nt.map((t) => /* @__PURE__ */ e(Ct, { provider: t }, t.id)) })
3735
+ /* @__PURE__ */ e("div", { className: "space-y-3", children: $t.map((t) => /* @__PURE__ */ e(jt, { provider: t }, t.id)) })
3225
3736
  ] }),
3226
- /* @__PURE__ */ e("div", { className: "bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4", children: /* @__PURE__ */ c("div", { className: "flex items-start gap-3", children: [
3737
+ /* @__PURE__ */ e("div", { className: "bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4", children: /* @__PURE__ */ s("div", { className: "flex items-start gap-3", children: [
3227
3738
  /* @__PURE__ */ e(
3228
3739
  "svg",
3229
3740
  {
@@ -3242,7 +3753,7 @@ function St() {
3242
3753
  )
3243
3754
  }
3244
3755
  ),
3245
- /* @__PURE__ */ c("div", { children: [
3756
+ /* @__PURE__ */ s("div", { children: [
3246
3757
  /* @__PURE__ */ e("p", { className: "text-sm font-medium text-blue-900 dark:text-blue-300", children: "Your keys stay local" }),
3247
3758
  /* @__PURE__ */ e("p", { className: "text-sm text-blue-700 dark:text-blue-400 mt-1", children: "API keys are stored in your browser only and sent directly to providers. They never pass through our servers." })
3248
3759
  ] })
@@ -3251,116 +3762,436 @@ function St() {
3251
3762
  /* @__PURE__ */ e("div", { className: "flex justify-end px-6 py-4 border-t border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ e(
3252
3763
  "button",
3253
3764
  {
3254
- onClick: i,
3765
+ onClick: l,
3255
3766
  className: "px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700",
3256
3767
  children: "Done"
3257
3768
  }
3258
3769
  ) })
3259
3770
  ] }) }) : null;
3260
3771
  }
3261
- function jt() {
3262
- const [r, i] = N("editor"), t = x((o) => o.addNode), a = x((o) => o.loadTemplate);
3263
- M(() => {
3264
- const n = new URLSearchParams(window.location.search).get("template");
3265
- if (n) {
3266
- const u = ne(n);
3267
- u && (a(u), window.history.replaceState({}, "", window.location.pathname));
3268
- }
3269
- }, [a]), M(() => {
3270
- const o = () => {
3271
- i("editor");
3272
- };
3273
- return window.addEventListener("workflow-loaded", o), () => {
3274
- window.removeEventListener("workflow-loaded", o);
3772
+ function Tt({ isOpen: r, onClose: l, onApplyWorkflow: t }) {
3773
+ const [n, o] = I([]), [i, m] = I(""), [d, a] = I(!1), [p, c] = I(null), [u, h] = I(null), [f, w] = I(""), v = Q(null), y = Q(null);
3774
+ D(() => {
3775
+ r && u === null && Ke().then((x) => {
3776
+ h(x.available), w(x.message);
3777
+ }).catch(() => {
3778
+ h(!1), w("Failed to check AI availability");
3779
+ });
3780
+ }, [r, u]), D(() => {
3781
+ r && y.current && y.current.focus();
3782
+ }, [r]), D(() => {
3783
+ var x;
3784
+ (x = v.current) == null || x.scrollIntoView({ behavior: "smooth" });
3785
+ }, [n]);
3786
+ const b = L(async () => {
3787
+ if (!i.trim() || d) return;
3788
+ const x = {
3789
+ role: "user",
3790
+ content: i.trim(),
3791
+ timestamp: Date.now()
3275
3792
  };
3276
- }, []);
3277
- const s = C(
3278
- (o) => {
3279
- const n = ne(o);
3280
- n && (a(n), i("editor"));
3281
- },
3282
- [a]
3283
- ), d = C(
3284
- (o) => {
3285
- var u;
3286
- o.preventDefault();
3287
- const n = o.dataTransfer.getData("application/json");
3288
- if (n)
3289
- try {
3290
- const l = JSON.parse(n), p = (u = document.querySelector(".react-flow")) == null ? void 0 : u.getBoundingClientRect();
3291
- if (!p) return;
3292
- const f = {
3293
- x: o.clientX - p.left,
3294
- y: o.clientY - p.top
3295
- };
3296
- t(l, f);
3297
- } catch (l) {
3298
- console.error("Failed to parse dropped node:", l);
3299
- }
3300
- },
3301
- [t]
3302
- ), m = C((o) => {
3303
- o.preventDefault(), o.dataTransfer.dropEffect = "move";
3304
- }, []);
3305
- return /* @__PURE__ */ c(Se, { children: [
3306
- /* @__PURE__ */ e(St, {}),
3307
- /* @__PURE__ */ e(vt, {}),
3308
- /* @__PURE__ */ c("div", { className: "h-screen flex flex-col bg-gray-100 dark:bg-zinc-900", children: [
3309
- /* @__PURE__ */ e(nt, {}),
3310
- /* @__PURE__ */ e("div", { className: "bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ c("div", { className: "flex", children: [
3311
- /* @__PURE__ */ e(
3793
+ o((C) => [...C, x]), m(""), a(!0), c(null);
3794
+ try {
3795
+ const C = await _e({
3796
+ prompt: x.content,
3797
+ history: n
3798
+ }), S = {
3799
+ role: "assistant",
3800
+ content: C.message,
3801
+ workflow: C.workflow,
3802
+ timestamp: Date.now()
3803
+ };
3804
+ o((T) => [...T, S]), !C.success && C.error && c(C.error);
3805
+ } catch (C) {
3806
+ c(C instanceof Error ? C.message : "Failed to generate workflow");
3807
+ } finally {
3808
+ a(!1);
3809
+ }
3810
+ }, [i, d, n]), g = (x) => {
3811
+ x.key === "Enter" && !x.shiftKey && (x.preventDefault(), b());
3812
+ }, N = (x) => {
3813
+ t(x), l();
3814
+ }, W = () => {
3815
+ o([]), c(null);
3816
+ };
3817
+ return r ? /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black/50 flex items-center justify-center z-50", children: /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl w-full max-w-2xl mx-4 h-[80vh] flex flex-col", children: [
3818
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700", children: [
3819
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-3", children: [
3820
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3821
+ /* @__PURE__ */ e(
3822
+ "svg",
3823
+ {
3824
+ className: "h-5 w-5 text-teal-600",
3825
+ fill: "none",
3826
+ viewBox: "0 0 24 24",
3827
+ stroke: "currentColor",
3828
+ children: /* @__PURE__ */ e(
3829
+ "path",
3830
+ {
3831
+ strokeLinecap: "round",
3832
+ strokeLinejoin: "round",
3833
+ strokeWidth: 2,
3834
+ d: "M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
3835
+ }
3836
+ )
3837
+ }
3838
+ ),
3839
+ /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "AI Workflow Generator" })
3840
+ ] }),
3841
+ /* @__PURE__ */ e("span", { className: "text-xs bg-teal-100 dark:bg-teal-900 text-teal-700 dark:text-teal-300 px-2 py-0.5 rounded", children: "Gemini 3 Pro" })
3842
+ ] }),
3843
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3844
+ n.length > 0 && /* @__PURE__ */ e(
3312
3845
  "button",
3313
3846
  {
3314
- onClick: () => i("editor"),
3315
- className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "editor" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
3316
- children: "Editor"
3847
+ onClick: W,
3848
+ className: "p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded",
3849
+ title: "New Chat",
3850
+ children: /* @__PURE__ */ e("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
3851
+ "path",
3852
+ {
3853
+ strokeLinecap: "round",
3854
+ strokeLinejoin: "round",
3855
+ strokeWidth: 2,
3856
+ d: "M12 4v16m8-8H4"
3857
+ }
3858
+ ) })
3317
3859
  }
3318
3860
  ),
3319
3861
  /* @__PURE__ */ e(
3320
3862
  "button",
3321
3863
  {
3322
- onClick: () => i("gallery"),
3323
- className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "gallery" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
3324
- children: "Gallery"
3864
+ onClick: l,
3865
+ className: "p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded",
3866
+ children: /* @__PURE__ */ e("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
3867
+ "path",
3868
+ {
3869
+ strokeLinecap: "round",
3870
+ strokeLinejoin: "round",
3871
+ strokeWidth: 2,
3872
+ d: "M6 18L18 6M6 6l12 12"
3873
+ }
3874
+ ) })
3875
+ }
3876
+ )
3877
+ ] })
3878
+ ] }),
3879
+ /* @__PURE__ */ s("div", { className: "flex-1 overflow-auto p-4 space-y-4", children: [
3880
+ u === !1 && /* @__PURE__ */ e("div", { className: "bg-amber-50 dark:bg-amber-900/30 border border-amber-200 dark:border-amber-800 rounded-lg p-4", children: /* @__PURE__ */ s("div", { className: "flex items-start gap-3", children: [
3881
+ /* @__PURE__ */ e(
3882
+ "svg",
3883
+ {
3884
+ className: "h-5 w-5 text-amber-600 dark:text-amber-400 mt-0.5",
3885
+ fill: "none",
3886
+ viewBox: "0 0 24 24",
3887
+ stroke: "currentColor",
3888
+ children: /* @__PURE__ */ e(
3889
+ "path",
3890
+ {
3891
+ strokeLinecap: "round",
3892
+ strokeLinejoin: "round",
3893
+ strokeWidth: 2,
3894
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
3895
+ }
3896
+ )
3897
+ }
3898
+ ),
3899
+ /* @__PURE__ */ s("div", { children: [
3900
+ /* @__PURE__ */ e("p", { className: "font-medium text-amber-800 dark:text-amber-200", children: "AI Generation Not Available" }),
3901
+ /* @__PURE__ */ e("p", { className: "text-sm text-amber-700 dark:text-amber-300 mt-1", children: f }),
3902
+ /* @__PURE__ */ e("p", { className: "text-xs text-amber-600 dark:text-amber-400 mt-2", children: "Set GEMINI_API_KEY in your environment to enable this feature." })
3903
+ ] })
3904
+ ] }) }),
3905
+ n.length === 0 && u !== !1 && /* @__PURE__ */ s("div", { className: "text-center py-8", children: [
3906
+ /* @__PURE__ */ e("div", { className: "inline-flex items-center justify-center w-16 h-16 bg-teal-100 dark:bg-teal-900/50 rounded-full mb-4", children: /* @__PURE__ */ e(
3907
+ "svg",
3908
+ {
3909
+ className: "h-8 w-8 text-teal-600 dark:text-teal-400",
3910
+ fill: "none",
3911
+ viewBox: "0 0 24 24",
3912
+ stroke: "currentColor",
3913
+ children: /* @__PURE__ */ e(
3914
+ "path",
3915
+ {
3916
+ strokeLinecap: "round",
3917
+ strokeLinejoin: "round",
3918
+ strokeWidth: 2,
3919
+ d: "M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"
3920
+ }
3921
+ )
3922
+ }
3923
+ ) }),
3924
+ /* @__PURE__ */ e("h4", { className: "text-lg font-medium text-gray-900 dark:text-white mb-2", children: "Describe your workflow" }),
3925
+ /* @__PURE__ */ e("p", { className: "text-sm text-gray-500 dark:text-zinc-400 max-w-md mx-auto", children: "Tell me what you want to create and I'll generate a workflow for you. For example:" }),
3926
+ /* @__PURE__ */ e("div", { className: "mt-4 space-y-2", children: [
3927
+ "Generate an image of a sunset and resize it to 800x600",
3928
+ "Use Gemini text to generate 3 creative image prompts about space exploration, then generate images from each prompt",
3929
+ "Generate an image with Gemini, then use it as a reference to create a variation with different lighting",
3930
+ "Create a product mockup: generate a minimalist logo, then composite it onto a t-shirt image",
3931
+ "Build an AI art pipeline: generate a base image, apply artistic style transfer, then upscale to 4K"
3932
+ ].map((x, C) => /* @__PURE__ */ s(
3933
+ "button",
3934
+ {
3935
+ onClick: () => m(x),
3936
+ className: "block w-full text-left text-sm px-4 py-2 bg-gray-100 dark:bg-zinc-700 hover:bg-gray-200 dark:hover:bg-zinc-600 rounded-lg text-gray-700 dark:text-zinc-300 transition-colors",
3937
+ children: [
3938
+ '"',
3939
+ x,
3940
+ '"'
3941
+ ]
3942
+ },
3943
+ C
3944
+ )) })
3945
+ ] }),
3946
+ n.map((x, C) => /* @__PURE__ */ e(
3947
+ "div",
3948
+ {
3949
+ className: `flex ${x.role === "user" ? "justify-end" : "justify-start"}`,
3950
+ children: /* @__PURE__ */ s(
3951
+ "div",
3952
+ {
3953
+ className: `max-w-[80%] rounded-lg px-4 py-3 ${x.role === "user" ? "bg-teal-600 text-white" : "bg-gray-100 dark:bg-zinc-700 text-gray-900 dark:text-white"}`,
3954
+ children: [
3955
+ /* @__PURE__ */ e("p", { className: "text-sm whitespace-pre-wrap", children: x.content }),
3956
+ x.role === "assistant" && x.workflow && /* @__PURE__ */ s("div", { className: "mt-3 pt-3 border-t border-gray-200 dark:border-zinc-600", children: [
3957
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between mb-2", children: [
3958
+ /* @__PURE__ */ e("span", { className: "text-xs font-medium text-gray-500 dark:text-zinc-400", children: "Generated Workflow" }),
3959
+ /* @__PURE__ */ e(
3960
+ "button",
3961
+ {
3962
+ onClick: () => N(x.workflow),
3963
+ className: "text-xs px-3 py-1 bg-teal-600 hover:bg-teal-700 text-white rounded transition-colors",
3964
+ children: "Apply to Canvas"
3965
+ }
3966
+ )
3967
+ ] }),
3968
+ /* @__PURE__ */ e("div", { className: "bg-white dark:bg-zinc-800 rounded p-2 text-xs", children: /* @__PURE__ */ s("div", { className: "space-y-1", children: [
3969
+ x.workflow.nodes.map((S, T) => /* @__PURE__ */ s(
3970
+ "div",
3971
+ {
3972
+ className: "flex items-center gap-2 text-gray-600 dark:text-zinc-300",
3973
+ children: [
3974
+ /* @__PURE__ */ e("span", { className: "font-mono bg-gray-100 dark:bg-zinc-700 px-1.5 py-0.5 rounded", children: S.nodeType.split(":").pop() }),
3975
+ S.label && /* @__PURE__ */ s("span", { className: "text-gray-400", children: [
3976
+ "(",
3977
+ S.label,
3978
+ ")"
3979
+ ] })
3980
+ ]
3981
+ },
3982
+ T
3983
+ )),
3984
+ x.workflow.edges.length > 0 && /* @__PURE__ */ s("div", { className: "text-gray-400 dark:text-zinc-500 pt-1", children: [
3985
+ x.workflow.edges.length,
3986
+ " connection",
3987
+ x.workflow.edges.length !== 1 ? "s" : ""
3988
+ ] })
3989
+ ] }) })
3990
+ ] })
3991
+ ]
3992
+ }
3993
+ )
3994
+ },
3995
+ C
3996
+ )),
3997
+ d && /* @__PURE__ */ e("div", { className: "flex justify-start", children: /* @__PURE__ */ e("div", { className: "bg-gray-100 dark:bg-zinc-700 rounded-lg px-4 py-3", children: /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3998
+ /* @__PURE__ */ s("div", { className: "flex space-x-1", children: [
3999
+ /* @__PURE__ */ e("div", { className: "w-2 h-2 bg-gray-400 dark:bg-zinc-500 rounded-full animate-bounce" }),
4000
+ /* @__PURE__ */ e(
4001
+ "div",
4002
+ {
4003
+ className: "w-2 h-2 bg-gray-400 dark:bg-zinc-500 rounded-full animate-bounce",
4004
+ style: { animationDelay: "0.1s" }
4005
+ }
4006
+ ),
4007
+ /* @__PURE__ */ e(
4008
+ "div",
4009
+ {
4010
+ className: "w-2 h-2 bg-gray-400 dark:bg-zinc-500 rounded-full animate-bounce",
4011
+ style: { animationDelay: "0.2s" }
4012
+ }
4013
+ )
4014
+ ] }),
4015
+ /* @__PURE__ */ e("span", { className: "text-sm text-gray-500 dark:text-zinc-400", children: "Generating workflow..." })
4016
+ ] }) }) }),
4017
+ p && /* @__PURE__ */ e("div", { className: "bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg p-3", children: /* @__PURE__ */ e("p", { className: "text-sm text-red-700 dark:text-red-300", children: p }) }),
4018
+ /* @__PURE__ */ e("div", { ref: v })
4019
+ ] }),
4020
+ /* @__PURE__ */ s("div", { className: "border-t border-gray-200 dark:border-zinc-700 p-4", children: [
4021
+ /* @__PURE__ */ s("div", { className: "flex gap-2", children: [
4022
+ /* @__PURE__ */ e(
4023
+ "textarea",
4024
+ {
4025
+ ref: y,
4026
+ value: i,
4027
+ onChange: (x) => m(x.target.value),
4028
+ onKeyDown: g,
4029
+ placeholder: u === !1 ? "AI generation not available" : "Describe what workflow you want to create...",
4030
+ disabled: d || u === !1,
4031
+ rows: 2,
4032
+ className: "flex-1 resize-none rounded-lg border border-gray-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 px-4 py-2 text-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500 focus:border-teal-500 focus:outline-none focus:ring-1 focus:ring-teal-500 disabled:opacity-50 disabled:cursor-not-allowed"
3325
4033
  }
3326
4034
  ),
3327
4035
  /* @__PURE__ */ e(
3328
4036
  "button",
3329
4037
  {
3330
- onClick: () => i("templates"),
3331
- className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "templates" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
3332
- children: "Templates"
4038
+ onClick: b,
4039
+ disabled: !i.trim() || d || u === !1,
4040
+ className: "self-end px-4 py-2 bg-teal-600 hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed text-white rounded-lg transition-colors",
4041
+ children: /* @__PURE__ */ e("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
4042
+ "path",
4043
+ {
4044
+ strokeLinecap: "round",
4045
+ strokeLinejoin: "round",
4046
+ strokeWidth: 2,
4047
+ d: "M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
4048
+ }
4049
+ ) })
4050
+ }
4051
+ )
4052
+ ] }),
4053
+ /* @__PURE__ */ e("p", { className: "text-xs text-gray-400 dark:text-zinc-500 mt-2", children: "Press Enter to send, Shift+Enter for new line" })
4054
+ ] })
4055
+ ] }) }) : null;
4056
+ }
4057
+ function Ut() {
4058
+ const { screenToFlowPosition: r } = Ae(), l = k((o) => o.addNode), t = L(
4059
+ (o) => {
4060
+ o.preventDefault();
4061
+ const i = o.dataTransfer.getData("application/json");
4062
+ if (i)
4063
+ try {
4064
+ const m = JSON.parse(i), d = r({
4065
+ x: o.clientX,
4066
+ y: o.clientY
4067
+ });
4068
+ l(m, d);
4069
+ } catch (m) {
4070
+ console.error("Failed to parse dropped node:", m);
4071
+ }
4072
+ },
4073
+ [l, r]
4074
+ ), n = L((o) => {
4075
+ o.preventDefault(), o.dataTransfer.dropEffect = "move";
4076
+ }, []);
4077
+ return /* @__PURE__ */ e("div", { className: "flex-1", onDrop: t, onDragOver: n, children: /* @__PURE__ */ e(at, {}) });
4078
+ }
4079
+ function Ht() {
4080
+ const [r, l] = I("editor"), [t, n] = I(!1), o = k((a) => a.loadTemplate), i = k((a) => a.loadGeneratedWorkflow);
4081
+ D(() => {
4082
+ const p = new URLSearchParams(window.location.search).get("template");
4083
+ if (p) {
4084
+ const c = de(p);
4085
+ c && (o(c), window.history.replaceState({}, "", window.location.pathname));
4086
+ }
4087
+ }, [o]), D(() => {
4088
+ const a = () => {
4089
+ l("editor");
4090
+ };
4091
+ return window.addEventListener("workflow-loaded", a), () => {
4092
+ window.removeEventListener("workflow-loaded", a);
4093
+ };
4094
+ }, []);
4095
+ const m = L(
4096
+ (a) => {
4097
+ const p = de(a);
4098
+ p && (o(p), l("editor"));
4099
+ },
4100
+ [o]
4101
+ ), d = L(
4102
+ (a) => {
4103
+ i(a), l("editor");
4104
+ },
4105
+ [i]
4106
+ );
4107
+ return /* @__PURE__ */ s(We, { children: [
4108
+ /* @__PURE__ */ e(Dt, {}),
4109
+ /* @__PURE__ */ e(
4110
+ Tt,
4111
+ {
4112
+ isOpen: t,
4113
+ onClose: () => n(!1),
4114
+ onApplyWorkflow: d
4115
+ }
4116
+ ),
4117
+ /* @__PURE__ */ e(At, {}),
4118
+ /* @__PURE__ */ s("div", { className: "h-screen flex flex-col bg-gray-100 dark:bg-zinc-900", children: [
4119
+ /* @__PURE__ */ e(gt, {}),
4120
+ /* @__PURE__ */ e("div", { className: "bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ s("div", { className: "flex items-center justify-between", children: [
4121
+ /* @__PURE__ */ s("div", { className: "flex", children: [
4122
+ /* @__PURE__ */ e(
4123
+ "button",
4124
+ {
4125
+ onClick: () => l("editor"),
4126
+ className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "editor" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
4127
+ children: "Editor"
4128
+ }
4129
+ ),
4130
+ /* @__PURE__ */ e(
4131
+ "button",
4132
+ {
4133
+ onClick: () => l("gallery"),
4134
+ className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "gallery" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
4135
+ children: "Gallery"
4136
+ }
4137
+ ),
4138
+ /* @__PURE__ */ e(
4139
+ "button",
4140
+ {
4141
+ onClick: () => l("templates"),
4142
+ className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "templates" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
4143
+ children: "Templates"
4144
+ }
4145
+ )
4146
+ ] }),
4147
+ /* @__PURE__ */ s(
4148
+ "button",
4149
+ {
4150
+ onClick: () => n(!0),
4151
+ className: "mr-4 px-4 py-1.5 text-sm font-medium text-white bg-gradient-to-r from-teal-500 to-cyan-500 hover:from-teal-600 hover:to-cyan-600 rounded-full flex items-center gap-2 transition-all shadow-sm hover:shadow",
4152
+ children: [
4153
+ /* @__PURE__ */ e("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
4154
+ "path",
4155
+ {
4156
+ strokeLinecap: "round",
4157
+ strokeLinejoin: "round",
4158
+ strokeWidth: 2,
4159
+ d: "M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
4160
+ }
4161
+ ) }),
4162
+ "AI Generate"
4163
+ ]
3333
4164
  }
3334
4165
  )
3335
4166
  ] }) }),
3336
- /* @__PURE__ */ c("div", { className: "flex-1 flex overflow-hidden", children: [
3337
- r === "editor" && /* @__PURE__ */ c(P, { children: [
3338
- /* @__PURE__ */ e(Ye, {}),
3339
- /* @__PURE__ */ e("div", { className: "flex-1", onDrop: d, onDragOver: m, children: /* @__PURE__ */ e(Qe, {}) }),
3340
- /* @__PURE__ */ e(Xe, {})
4167
+ /* @__PURE__ */ s("div", { className: "flex-1 flex overflow-hidden", children: [
4168
+ r === "editor" && /* @__PURE__ */ s(U, { children: [
4169
+ /* @__PURE__ */ e(ot, {}),
4170
+ /* @__PURE__ */ e(Ut, {}),
4171
+ /* @__PURE__ */ e(st, {})
3341
4172
  ] }),
3342
- r === "gallery" && /* @__PURE__ */ e("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ e(st, {}) }),
3343
- r === "templates" && /* @__PURE__ */ e("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ e(xt, { onSelect: s }) })
4173
+ r === "gallery" && /* @__PURE__ */ e("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ e(ht, {}) }),
4174
+ r === "templates" && /* @__PURE__ */ e("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ e(St, { onSelect: m }) })
3344
4175
  ] })
3345
4176
  ] })
3346
4177
  ] });
3347
4178
  }
3348
4179
  export {
3349
- St as AISettings,
3350
- jt as App,
3351
- st as Gallery,
3352
- Xe as NodeInspector,
3353
- Ye as NodePalette,
3354
- xt as TemplateGallery,
3355
- nt as Toolbar,
3356
- Je as UploadGallery,
3357
- Qe as WorkflowEditor,
3358
- vt as WorkflowLibrary,
3359
- bt as getCategories,
3360
- ne as getTemplateById,
3361
- $t as getTemplatesByCategory,
3362
- Mt as searchTemplates,
3363
- O as templates,
3364
- x as useWorkflowStore
4180
+ Dt as AISettings,
4181
+ Ht as App,
4182
+ ht as Gallery,
4183
+ st as NodeInspector,
4184
+ ot as NodePalette,
4185
+ St as TemplateGallery,
4186
+ gt as Toolbar,
4187
+ nt as UploadGallery,
4188
+ at as WorkflowEditor,
4189
+ At as WorkflowLibrary,
4190
+ It as getCategories,
4191
+ de as getTemplateById,
4192
+ Vt as getTemplatesByCategory,
4193
+ Ft as searchTemplates,
4194
+ H as templates,
4195
+ k as useWorkflowStore
3365
4196
  };
3366
4197
  //# sourceMappingURL=index.js.map