@teamflojo/floimg-studio-ui 0.1.7 → 0.2.1

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