@teamflojo/floimg-studio-ui 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { jsxs as c, jsx as e, Fragment as 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 Ge() {
206
+ return j(`${$}/uploads`);
201
207
  }
202
- async function Te(r) {
203
- const i = await fetch(`${I}/uploads/${r}`, {
208
+ async function Ve(r) {
209
+ const l = await fetch(`${$}/uploads/${r}`, {
204
210
  method: "DELETE"
205
211
  });
206
- if (!i.ok)
207
- throw new Error(`Failed to delete upload: ${i.status}`);
212
+ if (!l.ok)
213
+ throw new Error(`Failed to delete upload: ${l.status}`);
208
214
  }
209
- function de(r) {
210
- return `${I}/uploads/${r}/blob`;
215
+ function pe(r) {
216
+ return `${$}/uploads/${r}/blob`;
211
217
  }
212
- async function Ee(r) {
213
- return 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 G() {
284
+ return `node_${++qe}`;
270
285
  }
271
- function oe() {
272
- const r = Date.now(), i = Math.random().toString(36).substring(2, 8);
273
- return `wf_${r}_${i}`;
286
+ function le() {
287
+ const r = Date.now(), l = Math.random().toString(36).substring(2, 8);
288
+ return `wf_${r}_${l}`;
274
289
  }
275
- const x = se()(
276
- ie(
277
- (r, i) => ({
290
+ const k = ce()(
291
+ me(
292
+ (r, l) => ({
278
293
  nodes: [],
279
294
  edges: [],
280
295
  selectedNodeId: null,
@@ -282,6 +297,8 @@ const x = se()(
282
297
  previewVisible: {},
283
298
  generators: [],
284
299
  transforms: [],
300
+ textProviders: [],
301
+ visionProviders: [],
285
302
  // Workflow persistence state
286
303
  savedWorkflows: [],
287
304
  activeWorkflowId: null,
@@ -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 = G();
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 = G();
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 = G(), m = {
458
+ ...o,
459
+ id: i,
460
+ position: {
461
+ x: o.position.x + 50,
462
+ y: o.position.y + 50
463
+ },
464
+ data: JSON.parse(JSON.stringify(o.data)),
465
+ // Deep clone
466
+ selected: !1
467
+ };
468
+ r({
469
+ nodes: [...n.nodes, m],
470
+ selectedNodeId: i
471
+ // Select the new node
472
+ });
473
+ },
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 = G();
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 = G();
739
+ n.set(p.id, u);
740
+ const h = p.nodeType.split(":"), f = h[0], w = Math.floor(c / m), y = {
741
+ x: 100 + c % m * o,
742
+ y: 100 + w * i
743
+ };
744
+ let b;
745
+ if (f === "generator")
746
+ b = {
747
+ generatorName: h.slice(1).join(":"),
748
+ params: p.parameters,
749
+ isAI: !0
750
+ // Assume AI since we're generating from AI
751
+ };
752
+ else if (f === "transform") {
753
+ const g = h[1];
754
+ b = {
755
+ operation: h.slice(2).join(":"),
756
+ providerName: g,
757
+ params: p.parameters
758
+ };
759
+ } else if (f === "input")
760
+ b = {
761
+ uploadId: void 0,
762
+ filename: void 0,
763
+ mime: void 0
764
+ };
765
+ else if (f === "vision")
766
+ b = {
767
+ providerName: h.slice(1).join(":"),
768
+ params: p.parameters
769
+ };
770
+ else if (f === "text") {
771
+ const g = h.slice(1).join(":"), N = p.parameters.jsonSchema, W = N != null && N.properties ? {
772
+ type: "object",
773
+ properties: Object.fromEntries(
774
+ Object.entries(N.properties).map(([x, C]) => [
775
+ x,
776
+ {
777
+ type: C.type || "string",
778
+ description: C.description
779
+ }
780
+ ])
781
+ )
782
+ } : void 0;
783
+ b = {
784
+ providerName: g,
785
+ params: p.parameters,
786
+ outputSchema: W
787
+ };
788
+ } else
789
+ b = {
790
+ destination: p.parameters.destination || "./output/image.png",
791
+ provider: p.parameters.provider || "filesystem"
792
+ };
793
+ return {
794
+ id: u,
795
+ type: f,
796
+ position: y,
797
+ data: b
798
+ };
799
+ }), a = t.edges.map((p) => {
800
+ const c = n.get(p.source) || p.source, u = n.get(p.target) || p.target, h = [p.sourceHandle, p.targetHandle].filter(Boolean).join("_");
801
+ return {
802
+ id: h ? `edge_${c}_${u}_${h}` : `edge_${c}_${u}`,
803
+ source: c,
804
+ target: u,
805
+ sourceHandle: p.sourceHandle ?? void 0,
806
+ targetHandle: p.targetHandle ?? void 0
807
+ };
808
+ });
809
+ r({
810
+ nodes: d,
811
+ edges: a,
812
+ selectedNodeId: null,
813
+ currentTemplateId: null,
814
+ previewVisible: {},
815
+ activeWorkflowId: null,
816
+ activeWorkflowName: "AI Generated Workflow",
817
+ hasUnsavedChanges: !0,
818
+ execution: {
819
+ status: "idle",
820
+ imageIds: [],
821
+ imageUrls: [],
822
+ previews: {},
823
+ dataOutputs: {},
824
+ nodeStatus: {}
825
+ }
826
+ });
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 Ge();
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 Ve(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 }
1629
+ });
1630
+ } else if (a.type === "transform") {
1631
+ const N = a.data;
1632
+ m(a.id, {
1633
+ params: { ...N.params, [b]: g }
1634
+ });
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 }
1276
1641
  });
1277
- } else if (m.type === "transform") {
1278
- const g = m.data;
1279
- s(m.id, {
1280
- params: { ...g.params, [b]: k }
1642
+ } else if (a.type === "vision") {
1643
+ const N = a.data;
1644
+ m(a.id, {
1645
+ params: { ...N.params, [b]: g }
1281
1646
  });
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];
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 })
1416
1793
  ] });
1417
1794
  }
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);
1795
+ function lt({ nodeId: r, outputSchema: l, updateNodeData: t }) {
1796
+ const [n, o] = I(""), i = (l == null ? void 0 : l.properties) || {}, m = Object.entries(i), d = () => {
1797
+ if (!n.trim()) return;
1798
+ const u = {
1799
+ type: "object",
1800
+ properties: {
1801
+ ...i,
1802
+ [n.trim()]: { type: "string" }
1803
+ }
1804
+ };
1805
+ t(r, { outputSchema: u }), o("");
1806
+ }, a = (u) => {
1807
+ const h = { ...i };
1808
+ delete h[u], Object.keys(h).length === 0 ? t(r, { outputSchema: void 0 }) : t(r, {
1809
+ outputSchema: { type: "object", properties: h }
1810
+ });
1811
+ }, p = (u, h) => {
1812
+ t(r, {
1813
+ outputSchema: {
1814
+ type: "object",
1815
+ properties: {
1816
+ ...i,
1817
+ [u]: { ...i[u], type: h }
1818
+ }
1819
+ }
1820
+ });
1821
+ }, c = (u, h) => {
1822
+ t(r, {
1823
+ outputSchema: {
1824
+ type: "object",
1825
+ properties: {
1826
+ ...i,
1827
+ [u]: { ...i[u], description: h || void 0 }
1828
+ }
1829
+ }
1830
+ });
1831
+ };
1832
+ return /* @__PURE__ */ s("div", { className: "mt-6 pt-4 border-t border-gray-200 dark:border-zinc-700", children: [
1833
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between mb-3", children: [
1834
+ /* @__PURE__ */ e("h3", { className: "text-sm font-medium text-gray-700 dark:text-zinc-300", children: "Output Schema" }),
1835
+ /* @__PURE__ */ e("span", { className: "text-xs text-gray-500 dark:text-zinc-500", children: m.length > 0 ? `${m.length} output${m.length > 1 ? "s" : ""}` : "No outputs defined" })
1836
+ ] }),
1837
+ /* @__PURE__ */ e("p", { className: "text-xs text-gray-500 dark:text-zinc-400 mb-3", children: "Define output properties to enable connecting individual JSON fields to other nodes." }),
1838
+ m.length > 0 && /* @__PURE__ */ e("div", { className: "space-y-2 mb-3", children: m.map(([u, h]) => /* @__PURE__ */ s(
1839
+ "div",
1840
+ {
1841
+ className: "flex items-center gap-2 p-2 bg-pink-50 dark:bg-pink-900/20 rounded border border-pink-200 dark:border-pink-800",
1842
+ children: [
1843
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
1844
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
1845
+ /* @__PURE__ */ e("span", { className: "text-sm font-medium text-pink-700 dark:text-pink-300 truncate", children: u }),
1846
+ /* @__PURE__ */ s(
1847
+ "select",
1848
+ {
1849
+ value: h.type,
1850
+ onChange: (f) => p(u, f.target.value),
1851
+ className: "text-xs px-1.5 py-0.5 rounded border border-pink-300 dark:border-pink-700 bg-white dark:bg-zinc-800 text-gray-700 dark:text-zinc-300",
1852
+ children: [
1853
+ /* @__PURE__ */ e("option", { value: "string", children: "string" }),
1854
+ /* @__PURE__ */ e("option", { value: "number", children: "number" }),
1855
+ /* @__PURE__ */ e("option", { value: "boolean", children: "boolean" }),
1856
+ /* @__PURE__ */ e("option", { value: "object", children: "object" }),
1857
+ /* @__PURE__ */ e("option", { value: "array", children: "array" })
1858
+ ]
1859
+ }
1860
+ )
1861
+ ] }),
1862
+ /* @__PURE__ */ e(
1863
+ "input",
1864
+ {
1865
+ type: "text",
1866
+ value: h.description || "",
1867
+ onChange: (f) => c(u, f.target.value),
1868
+ placeholder: "Description (optional)",
1869
+ className: "mt-1 w-full text-xs px-2 py-1 rounded border border-pink-200 dark:border-pink-700 bg-white dark:bg-zinc-800 text-gray-600 dark:text-zinc-400 placeholder-gray-400 dark:placeholder-zinc-500"
1870
+ }
1871
+ )
1872
+ ] }),
1873
+ /* @__PURE__ */ e(
1874
+ "button",
1875
+ {
1876
+ onClick: () => a(u),
1877
+ className: "text-pink-500 hover:text-pink-700 dark:text-pink-400 dark:hover:text-pink-300 p-1",
1878
+ title: "Remove property",
1879
+ children: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
1880
+ "path",
1881
+ {
1882
+ strokeLinecap: "round",
1883
+ strokeLinejoin: "round",
1884
+ strokeWidth: 2,
1885
+ d: "M6 18L18 6M6 6l12 12"
1886
+ }
1887
+ ) })
1888
+ }
1889
+ )
1890
+ ]
1891
+ },
1892
+ u
1893
+ )) }),
1894
+ /* @__PURE__ */ s("div", { className: "flex gap-2", children: [
1895
+ /* @__PURE__ */ e(
1896
+ "input",
1897
+ {
1898
+ type: "text",
1899
+ value: n,
1900
+ onChange: (u) => o(u.target.value),
1901
+ onKeyDown: (u) => u.key === "Enter" && d(),
1902
+ placeholder: "Property name...",
1903
+ className: "flex-1 px-2 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-900 text-gray-900 dark:text-zinc-100 placeholder-gray-400 dark:placeholder-zinc-500"
1904
+ }
1905
+ ),
1906
+ /* @__PURE__ */ e(
1907
+ "button",
1908
+ {
1909
+ onClick: d,
1910
+ disabled: !n.trim(),
1911
+ className: "px-3 py-1.5 text-sm font-medium text-white bg-pink-500 rounded hover:bg-pink-600 disabled:opacity-50 disabled:cursor-not-allowed",
1912
+ children: "Add"
1913
+ }
1914
+ )
1915
+ ] }),
1916
+ m.length > 0 && /* @__PURE__ */ e("p", { className: "mt-3 text-xs text-gray-500 dark:text-zinc-500", children: "Connect from the small pink handles on the right of the node to route individual properties." })
1917
+ ] });
1918
+ }
1919
+ function dt(r, l) {
1920
+ const t = new Map(r.map((d) => [d.id, d])), n = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
1921
+ for (const d of r)
1922
+ n.set(d.id, 0), o.set(d.id, []);
1923
+ for (const d of l) {
1924
+ const a = o.get(d.source) || [];
1925
+ a.push(d.target), o.set(d.source, a), n.set(d.target, (n.get(d.target) || 0) + 1);
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 V(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}: ${V(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}: ${V(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}: ${V(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}: ${V(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"}, ${V(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,64 +2606,64 @@ 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: [
2660
+ ] }) : /* @__PURE__ */ s("div", { className: "p-4 bg-gray-100 dark:bg-zinc-900 min-h-full", children: [
2661
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between mb-4", children: [
2662
+ /* @__PURE__ */ s("h2", { className: "text-lg font-semibold text-gray-800 dark:text-white", children: [
2160
2663
  "Gallery (",
2161
- a.length,
2664
+ n.length,
2162
2665
  " image",
2163
- a.length !== 1 ? "s" : "",
2666
+ n.length !== 1 ? "s" : "",
2164
2667
  ")"
2165
2668
  ] }),
2166
2669
  /* @__PURE__ */ e(
@@ -2172,32 +2675,32 @@ function st() {
2172
2675
  }
2173
2676
  )
2174
2677
  ] }),
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,
2678
+ /* @__PURE__ */ e("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: n.map((a) => /* @__PURE__ */ e(
2679
+ xt,
2177
2680
  {
2178
- image: n,
2179
- onLoadWorkflow: () => o(n.id),
2180
- isLoading: i === n.id
2681
+ image: a,
2682
+ onLoadWorkflow: () => d(a.id),
2683
+ isLoading: l === a.id
2181
2684
  },
2182
- n.id
2685
+ a.id
2183
2686
  )) })
2184
2687
  ] });
2185
2688
  }
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: [
2689
+ function xt({ image: r, onLoadWorkflow: l, isLoading: t }) {
2690
+ const n = (i) => new Date(i).toLocaleString(), o = (i) => i < 1024 ? `${i} B` : i < 1048576 ? `${(i / 1024).toFixed(1)} KB` : `${(i / 1048576).toFixed(1)} MB`;
2691
+ return /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden shadow-sm hover:shadow-md transition-shadow group", children: [
2692
+ /* @__PURE__ */ s("div", { className: "relative", children: [
2190
2693
  /* @__PURE__ */ e(
2191
2694
  "a",
2192
2695
  {
2193
- href: te(r.id),
2696
+ href: oe(r.id),
2194
2697
  target: "_blank",
2195
2698
  rel: "noopener noreferrer",
2196
2699
  className: "block aspect-square bg-gray-100 dark:bg-zinc-900",
2197
2700
  children: /* @__PURE__ */ e(
2198
2701
  "img",
2199
2702
  {
2200
- src: te(r.id),
2703
+ src: oe(r.id),
2201
2704
  alt: r.filename,
2202
2705
  className: "w-full h-full object-cover",
2203
2706
  loading: "lazy"
@@ -2208,8 +2711,8 @@ function it({ image: r, onLoadWorkflow: i, isLoading: t }) {
2208
2711
  /* @__PURE__ */ e("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center", children: /* @__PURE__ */ e(
2209
2712
  "button",
2210
2713
  {
2211
- onClick: (d) => {
2212
- d.preventDefault(), i();
2714
+ onClick: (i) => {
2715
+ i.preventDefault(), l();
2213
2716
  },
2214
2717
  disabled: t,
2215
2718
  className: "px-3 py-1.5 bg-teal-600 text-white text-sm rounded-lg hover:bg-teal-700 disabled:opacity-50",
@@ -2217,18 +2720,18 @@ function it({ image: r, onLoadWorkflow: i, isLoading: t }) {
2217
2720
  }
2218
2721
  ) })
2219
2722
  ] }),
2220
- /* @__PURE__ */ c("div", { className: "p-3", children: [
2723
+ /* @__PURE__ */ s("div", { className: "p-3", children: [
2221
2724
  /* @__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: [
2725
+ /* @__PURE__ */ s("div", { className: "text-xs text-gray-500 dark:text-zinc-400 mt-1", children: [
2223
2726
  r.mime,
2224
2727
  " • ",
2225
- s(r.size)
2728
+ o(r.size)
2226
2729
  ] }),
2227
- /* @__PURE__ */ e("div", { className: "text-xs text-gray-400 dark:text-zinc-500 mt-1", children: a(r.createdAt) })
2730
+ /* @__PURE__ */ e("div", { className: "text-xs text-gray-400 dark:text-zinc-500 mt-1", children: n(r.createdAt) })
2228
2731
  ] })
2229
2732
  ] });
2230
2733
  }
2231
- const dt = {
2734
+ const bt = {
2232
2735
  id: "sales-dashboard",
2233
2736
  name: "Sales Dashboard",
2234
2737
  description: "Quarterly revenue bar chart with gradient styling",
@@ -2278,7 +2781,7 @@ const dt = {
2278
2781
  ],
2279
2782
  edges: []
2280
2783
  }
2281
- }, lt = {
2784
+ }, ft = {
2282
2785
  id: "user-growth",
2283
2786
  name: "User Growth Line Chart",
2284
2787
  description: "Monthly user growth with smooth bezier curves",
@@ -2326,7 +2829,7 @@ const dt = {
2326
2829
  ],
2327
2830
  edges: []
2328
2831
  }
2329
- }, ct = {
2832
+ }, kt = {
2330
2833
  id: "api-flow",
2331
2834
  name: "API Request Flow",
2332
2835
  description: "Sequence diagram showing API authentication flow",
@@ -2368,7 +2871,7 @@ const dt = {
2368
2871
  ],
2369
2872
  edges: []
2370
2873
  }
2371
- }, mt = {
2874
+ }, vt = {
2372
2875
  id: "system-architecture",
2373
2876
  name: "System Architecture",
2374
2877
  description: "Microservices architecture diagram",
@@ -2426,7 +2929,7 @@ const dt = {
2426
2929
  ],
2427
2930
  edges: []
2428
2931
  }
2429
- }, ut = {
2932
+ }, yt = {
2430
2933
  id: "git-workflow",
2431
2934
  name: "Git Branch Workflow",
2432
2935
  description: "Git branching strategy with feature and release branches",
@@ -2469,7 +2972,7 @@ const dt = {
2469
2972
  ],
2470
2973
  edges: []
2471
2974
  }
2472
- }, gt = {
2975
+ }, wt = {
2473
2976
  id: "website-qr",
2474
2977
  name: "Website QR Code",
2475
2978
  description: "QR code linking to your website with custom styling",
@@ -2497,7 +3000,7 @@ const dt = {
2497
3000
  ],
2498
3001
  edges: []
2499
3002
  }
2500
- }, pt = {
3003
+ }, Nt = {
2501
3004
  id: "wifi-qr",
2502
3005
  name: "WiFi QR Code",
2503
3006
  description: "Scannable QR code for WiFi network access",
@@ -2525,7 +3028,7 @@ const dt = {
2525
3028
  ],
2526
3029
  edges: []
2527
3030
  }
2528
- }, ht = {
3031
+ }, zt = {
2529
3032
  id: "chart-watermark",
2530
3033
  name: "Chart with Watermark",
2531
3034
  description: "Bar chart with company watermark and rounded corners",
@@ -2591,7 +3094,7 @@ const dt = {
2591
3094
  { id: "e2", source: "transform-1", target: "transform-2" }
2592
3095
  ]
2593
3096
  }
2594
- }, ft = {
3097
+ }, Ct = {
2595
3098
  id: "diagram-webp",
2596
3099
  name: "Diagram to WebP",
2597
3100
  description: "Mermaid diagram converted to optimized WebP format",
@@ -2632,108 +3135,108 @@ const dt = {
2632
3135
  ],
2633
3136
  edges: [{ id: "e1", source: "gen-1", target: "transform-1" }]
2634
3137
  }
2635
- }, O = [
3138
+ }, H = [
2636
3139
  // Charts
2637
- dt,
2638
- lt,
3140
+ bt,
3141
+ ft,
2639
3142
  // Diagrams
2640
- ct,
2641
- mt,
2642
- ut,
3143
+ kt,
3144
+ vt,
3145
+ yt,
2643
3146
  // QR Codes
2644
- gt,
2645
- pt,
3147
+ wt,
3148
+ Nt,
2646
3149
  // Pipelines
2647
- ht,
2648
- ft
3150
+ zt,
3151
+ Ct
2649
3152
  ];
2650
- function bt() {
2651
- const r = new Set(O.map((i) => i.category));
3153
+ function It() {
3154
+ const r = new Set(H.map((l) => l.category));
2652
3155
  return Array.from(r).sort();
2653
3156
  }
2654
- function $t(r) {
2655
- return O.filter((i) => i.category === r);
3157
+ function Vt(r) {
3158
+ return H.filter((l) => l.category === r);
2656
3159
  }
2657
- function ne(r) {
2658
- return O.find((i) => i.id === r);
3160
+ function de(r) {
3161
+ return H.find((l) => l.id === r);
2659
3162
  }
2660
- function Mt(r) {
2661
- const i = r.toLowerCase();
2662
- return O.filter(
3163
+ function Ft(r) {
3164
+ const l = r.toLowerCase();
3165
+ return H.filter(
2663
3166
  (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)));
3167
+ var n;
3168
+ return t.name.toLowerCase().includes(l) || t.description.toLowerCase().includes(l) || t.category.toLowerCase().includes(l) || t.generator.toLowerCase().includes(l) || ((n = t.tags) == null ? void 0 : n.some((o) => o.toLowerCase().includes(l)));
2666
3169
  }
2667
3170
  );
2668
3171
  }
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)));
3172
+ function St({ onSelect: r }) {
3173
+ const [l, t] = I(null), [n, o] = I(""), i = ne(() => It(), []), m = ne(() => {
3174
+ let d = H;
3175
+ if (l && (d = d.filter((a) => a.category === l)), n) {
3176
+ const a = n.toLowerCase();
3177
+ d = d.filter(
3178
+ (p) => {
3179
+ var c;
3180
+ return p.name.toLowerCase().includes(a) || p.description.toLowerCase().includes(a) || p.generator.toLowerCase().includes(a) || ((c = p.tags) == null ? void 0 : c.some((u) => u.toLowerCase().includes(a)));
2678
3181
  }
2679
3182
  );
2680
3183
  }
2681
- return o;
2682
- }, [i, a]);
2683
- return /* @__PURE__ */ c("div", { className: "p-6", children: [
2684
- /* @__PURE__ */ c("div", { className: "mb-6", children: [
3184
+ return d;
3185
+ }, [l, n]);
3186
+ return /* @__PURE__ */ s("div", { className: "p-6", children: [
3187
+ /* @__PURE__ */ s("div", { className: "mb-6", children: [
2685
3188
  /* @__PURE__ */ e("h2", { className: "text-2xl font-bold text-gray-900 dark:text-white mb-2", children: "Templates" }),
2686
3189
  /* @__PURE__ */ e("p", { className: "text-gray-600 dark:text-zinc-400", children: "Start with a pre-built workflow. Click any template to load it into the editor." })
2687
3190
  ] }),
2688
- /* @__PURE__ */ c("div", { className: "flex flex-wrap gap-4 mb-6", children: [
3191
+ /* @__PURE__ */ s("div", { className: "flex flex-wrap gap-4 mb-6", children: [
2689
3192
  /* @__PURE__ */ e(
2690
3193
  "input",
2691
3194
  {
2692
3195
  type: "text",
2693
3196
  placeholder: "Search templates...",
2694
- value: a,
2695
- onChange: (o) => s(o.target.value),
3197
+ value: n,
3198
+ onChange: (d) => o(d.target.value),
2696
3199
  className: "px-4 py-2 border border-gray-300 dark:border-zinc-600 rounded-lg bg-white dark:bg-zinc-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-teal-500 focus:border-transparent w-64"
2697
3200
  }
2698
3201
  ),
2699
- /* @__PURE__ */ c("div", { className: "flex gap-2 flex-wrap", children: [
3202
+ /* @__PURE__ */ s("div", { className: "flex gap-2 flex-wrap", children: [
2700
3203
  /* @__PURE__ */ e(
2701
3204
  "button",
2702
3205
  {
2703
3206
  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"}`,
3207
+ className: `px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${l === null ? "bg-teal-600 text-white" : "bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600"}`,
2705
3208
  children: "All"
2706
3209
  }
2707
3210
  ),
2708
- d.map((o) => /* @__PURE__ */ e(
3211
+ i.map((d) => /* @__PURE__ */ e(
2709
3212
  "button",
2710
3213
  {
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
3214
+ onClick: () => t(d),
3215
+ className: `px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${l === d ? "bg-teal-600 text-white" : "bg-gray-200 dark:bg-zinc-700 text-gray-700 dark:text-zinc-300 hover:bg-gray-300 dark:hover:bg-zinc-600"}`,
3216
+ children: d
2714
3217
  },
2715
- o
3218
+ d
2716
3219
  ))
2717
3220
  ] })
2718
3221
  ] }),
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,
3222
+ m.length === 0 ? /* @__PURE__ */ e("div", { className: "text-center py-12 text-gray-500 dark:text-zinc-400", children: "No templates found matching your criteria." }) : /* @__PURE__ */ e("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: m.map((d) => /* @__PURE__ */ e(
3223
+ Lt,
2721
3224
  {
2722
- template: o,
2723
- onSelect: () => r(o.id)
3225
+ template: d,
3226
+ onSelect: () => r(d.id)
2724
3227
  },
2725
- o.id
3228
+ d.id
2726
3229
  )) })
2727
3230
  ] });
2728
3231
  }
2729
- function kt({ template: r, onSelect: i }) {
2730
- const t = r.workflow.nodes.length, a = r.workflow.edges.length, s = {
3232
+ function Lt({ template: r, onSelect: l }) {
3233
+ const t = r.workflow.nodes.length, n = r.workflow.edges.length, o = {
2731
3234
  quickchart: "bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300",
2732
3235
  mermaid: "bg-pink-100 text-pink-800 dark:bg-pink-900/30 dark:text-pink-300",
2733
3236
  qr: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300",
2734
3237
  d3: "bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-300"
2735
3238
  };
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: [
3239
+ return /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 overflow-hidden hover:shadow-lg transition-shadow", children: [
2737
3240
  /* @__PURE__ */ e("div", { className: "aspect-video bg-gray-100 dark:bg-zinc-900 flex items-center justify-center p-4", children: r.preview ? /* @__PURE__ */ e(
2738
3241
  "img",
2739
3242
  {
@@ -2741,7 +3244,7 @@ function kt({ template: r, onSelect: i }) {
2741
3244
  alt: r.name,
2742
3245
  className: "max-w-full max-h-full object-contain"
2743
3246
  }
2744
- ) : /* @__PURE__ */ c("div", { className: "text-center text-gray-400 dark:text-zinc-500", children: [
3247
+ ) : /* @__PURE__ */ s("div", { className: "text-center text-gray-400 dark:text-zinc-500", children: [
2745
3248
  /* @__PURE__ */ e(
2746
3249
  "svg",
2747
3250
  {
@@ -2762,20 +3265,20 @@ function kt({ template: r, onSelect: i }) {
2762
3265
  ),
2763
3266
  /* @__PURE__ */ e("span", { className: "text-sm", children: "No preview" })
2764
3267
  ] }) }),
2765
- /* @__PURE__ */ c("div", { className: "p-4", children: [
2766
- /* @__PURE__ */ c("div", { className: "flex items-start justify-between mb-2", children: [
3268
+ /* @__PURE__ */ s("div", { className: "p-4", children: [
3269
+ /* @__PURE__ */ s("div", { className: "flex items-start justify-between mb-2", children: [
2767
3270
  /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: r.name }),
2768
3271
  /* @__PURE__ */ e(
2769
3272
  "span",
2770
3273
  {
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"}`,
3274
+ className: `px-2 py-0.5 rounded text-xs font-medium ${o[r.generator] || "bg-gray-100 text-gray-800 dark:bg-zinc-700 dark:text-zinc-300"}`,
2772
3275
  children: r.generator
2773
3276
  }
2774
3277
  )
2775
3278
  ] }),
2776
3279
  /* @__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: [
3280
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-4 text-xs text-gray-500 dark:text-zinc-500 mb-4", children: [
3281
+ /* @__PURE__ */ s("span", { className: "flex items-center gap-1", children: [
2779
3282
  /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e(
2780
3283
  "path",
2781
3284
  {
@@ -2789,7 +3292,7 @@ function kt({ template: r, onSelect: i }) {
2789
3292
  " node",
2790
3293
  t !== 1 ? "s" : ""
2791
3294
  ] }),
2792
- a > 0 && /* @__PURE__ */ c("span", { className: "flex items-center gap-1", children: [
3295
+ n > 0 && /* @__PURE__ */ s("span", { className: "flex items-center gap-1", children: [
2793
3296
  /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e(
2794
3297
  "path",
2795
3298
  {
@@ -2799,23 +3302,23 @@ function kt({ template: r, onSelect: i }) {
2799
3302
  d: "M13 7l5 5m0 0l-5 5m5-5H6"
2800
3303
  }
2801
3304
  ) }),
2802
- a,
3305
+ n,
2803
3306
  " edge",
2804
- a !== 1 ? "s" : ""
3307
+ n !== 1 ? "s" : ""
2805
3308
  ] })
2806
3309
  ] }),
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(
3310
+ r.tags && r.tags.length > 0 && /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1 mb-4", children: r.tags.slice(0, 4).map((i) => /* @__PURE__ */ e(
2808
3311
  "span",
2809
3312
  {
2810
3313
  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
3314
+ children: i
2812
3315
  },
2813
- d
3316
+ i
2814
3317
  )) }),
2815
3318
  /* @__PURE__ */ e(
2816
3319
  "button",
2817
3320
  {
2818
- onClick: i,
3321
+ onClick: l,
2819
3322
  className: "w-full py-2 px-4 bg-teal-600 hover:bg-teal-700 text-white rounded-lg font-medium transition-colors",
2820
3323
  children: "Use Template"
2821
3324
  }
@@ -2823,67 +3326,67 @@ function kt({ template: r, onSelect: i }) {
2823
3326
  ] })
2824
3327
  ] });
2825
3328
  }
2826
- function wt({
3329
+ function Wt({
2827
3330
  workflow: r,
2828
- isActive: i,
3331
+ isActive: l,
2829
3332
  onLoad: t,
2830
- onDelete: a,
2831
- onRename: s,
2832
- onDuplicate: d
3333
+ onDelete: n,
3334
+ onRename: o,
3335
+ onDuplicate: i
2833
3336
  }) {
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();
3337
+ const [m, d] = I(!1), [a, p] = I(r.name), [c, u] = I(!1), h = () => {
3338
+ a.trim() && a !== r.name && o(a.trim()), d(!1);
3339
+ }, f = (w) => {
3340
+ const v = new Date(w), b = (/* @__PURE__ */ new Date()).getTime() - v.getTime(), g = Math.floor(b / 6e4), N = Math.floor(b / 36e5), W = Math.floor(b / 864e5);
3341
+ return g < 1 ? "Just now" : g < 60 ? `${g}m ago` : N < 24 ? `${N}h ago` : W < 7 ? `${W}d ago` : v.toLocaleDateString();
2839
3342
  };
2840
- return /* @__PURE__ */ c(
3343
+ return /* @__PURE__ */ s(
2841
3344
  "div",
2842
3345
  {
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"}`,
3346
+ className: `group relative p-3 rounded-lg border transition-colors ${l ? "bg-teal-50 dark:bg-teal-900/20 border-teal-200 dark:border-teal-800" : "bg-white dark:bg-zinc-800 border-zinc-200 dark:border-zinc-700 hover:border-zinc-300 dark:hover:border-zinc-600"}`,
2844
3347
  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: [
3348
+ /* @__PURE__ */ s("div", { className: "flex items-start justify-between gap-2", children: [
3349
+ /* @__PURE__ */ s("button", { onClick: t, className: "flex-1 text-left min-w-0", children: [
2847
3350
  m ? /* @__PURE__ */ e(
2848
3351
  "input",
2849
3352
  {
2850
3353
  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));
3354
+ value: a,
3355
+ onChange: (w) => p(w.target.value),
3356
+ onBlur: h,
3357
+ onKeyDown: (w) => {
3358
+ w.key === "Enter" && h(), w.key === "Escape" && (p(r.name), d(!1));
2856
3359
  },
2857
3360
  className: "w-full px-1 py-0.5 text-sm font-medium bg-white dark:bg-zinc-900 border border-teal-500 rounded focus:outline-none focus:ring-1 focus:ring-teal-500",
2858
3361
  autoFocus: !0,
2859
- onClick: (k) => k.stopPropagation()
3362
+ onClick: (w) => w.stopPropagation()
2860
3363
  }
2861
3364
  ) : /* @__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: [
3365
+ /* @__PURE__ */ s("span", { className: "block text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: [
2863
3366
  r.nodes.length,
2864
3367
  " nodes · Updated ",
2865
- b(r.updatedAt)
3368
+ f(r.updatedAt)
2866
3369
  ] })
2867
3370
  ] }),
2868
- /* @__PURE__ */ c("div", { className: "relative", children: [
3371
+ /* @__PURE__ */ s("div", { className: "relative", children: [
2869
3372
  /* @__PURE__ */ e(
2870
3373
  "button",
2871
3374
  {
2872
- onClick: (k) => {
2873
- k.stopPropagation(), p(!l);
3375
+ onClick: (w) => {
3376
+ w.stopPropagation(), u(!c);
2874
3377
  },
2875
3378
  className: "p-1 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300 rounded opacity-0 group-hover:opacity-100 transition-opacity",
2876
3379
  children: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ e("path", { d: "M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" }) })
2877
3380
  }
2878
3381
  ),
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: [
3382
+ c && /* @__PURE__ */ s(U, { children: [
3383
+ /* @__PURE__ */ e("div", { className: "fixed inset-0 z-10", onClick: () => u(!1) }),
3384
+ /* @__PURE__ */ s("div", { className: "absolute right-0 top-full mt-1 w-36 bg-white dark:bg-zinc-800 rounded-lg shadow-lg border border-zinc-200 dark:border-zinc-700 py-1 z-20", children: [
2882
3385
  /* @__PURE__ */ e(
2883
3386
  "button",
2884
3387
  {
2885
- onClick: (k) => {
2886
- k.stopPropagation(), o(!0), p(!1);
3388
+ onClick: (w) => {
3389
+ w.stopPropagation(), d(!0), u(!1);
2887
3390
  },
2888
3391
  className: "w-full px-3 py-1.5 text-left text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700",
2889
3392
  children: "Rename"
@@ -2892,8 +3395,8 @@ function wt({
2892
3395
  /* @__PURE__ */ e(
2893
3396
  "button",
2894
3397
  {
2895
- onClick: (k) => {
2896
- k.stopPropagation(), d(), p(!1);
3398
+ onClick: (w) => {
3399
+ w.stopPropagation(), i(), u(!1);
2897
3400
  },
2898
3401
  className: "w-full px-3 py-1.5 text-left text-sm text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-700",
2899
3402
  children: "Duplicate"
@@ -2902,8 +3405,8 @@ function wt({
2902
3405
  /* @__PURE__ */ e(
2903
3406
  "button",
2904
3407
  {
2905
- onClick: (k) => {
2906
- k.stopPropagation(), window.confirm("Delete this workflow?") && a(), p(!1);
3408
+ onClick: (w) => {
3409
+ w.stopPropagation(), window.confirm("Delete this workflow?") && n(), u(!1);
2907
3410
  },
2908
3411
  className: "w-full px-3 py-1.5 text-left text-sm text-red-600 dark:text-red-400 hover:bg-zinc-100 dark:hover:bg-zinc-700",
2909
3412
  children: "Delete"
@@ -2913,24 +3416,24 @@ function wt({
2913
3416
  ] })
2914
3417
  ] })
2915
3418
  ] }),
2916
- i && /* @__PURE__ */ e("span", { className: "absolute top-2 right-2 w-2 h-2 bg-teal-500 rounded-full" })
3419
+ l && /* @__PURE__ */ e("span", { className: "absolute top-2 right-2 w-2 h-2 bg-teal-500 rounded-full" })
2917
3420
  ]
2918
3421
  }
2919
3422
  );
2920
3423
  }
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);
3424
+ function At() {
3425
+ const r = k((c) => c.showLibrary), l = k((c) => c.toggleLibrary), t = k((c) => c.savedWorkflows), n = k((c) => c.activeWorkflowId), o = k((c) => c.loadWorkflow), i = k((c) => c.deleteWorkflow), m = k((c) => c.renameWorkflow), d = k((c) => c.duplicateWorkflow), a = k((c) => c.newWorkflow);
2923
3426
  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: [
3427
+ const p = [...t].sort((c, u) => u.updatedAt - c.updatedAt);
3428
+ return /* @__PURE__ */ s(U, { children: [
3429
+ /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black/20 dark:bg-black/40 z-40", onClick: l }),
3430
+ /* @__PURE__ */ s("div", { className: "fixed left-0 top-0 bottom-0 w-80 bg-zinc-50 dark:bg-zinc-900 border-r border-zinc-200 dark:border-zinc-700 z-50 flex flex-col shadow-xl", children: [
3431
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between px-4 py-3 border-b border-zinc-200 dark:border-zinc-700", children: [
2929
3432
  /* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-zinc-900 dark:text-zinc-100", children: "My Workflows" }),
2930
3433
  /* @__PURE__ */ e(
2931
3434
  "button",
2932
3435
  {
2933
- onClick: i,
3436
+ onClick: l,
2934
3437
  className: "p-1 text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300 rounded",
2935
3438
  children: /* @__PURE__ */ e("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
2936
3439
  "path",
@@ -2944,11 +3447,11 @@ function vt() {
2944
3447
  }
2945
3448
  )
2946
3449
  ] }),
2947
- /* @__PURE__ */ e("div", { className: "p-4 border-b border-zinc-200 dark:border-zinc-700", children: /* @__PURE__ */ c(
3450
+ /* @__PURE__ */ e("div", { className: "p-4 border-b border-zinc-200 dark:border-zinc-700", children: /* @__PURE__ */ s(
2948
3451
  "button",
2949
3452
  {
2950
3453
  onClick: () => {
2951
- n(), i(), window.dispatchEvent(new window.CustomEvent("new-workflow-created"));
3454
+ a(), l(), window.dispatchEvent(new window.CustomEvent("new-workflow-created"));
2952
3455
  },
2953
3456
  className: "w-full flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-lg hover:bg-teal-700 transition-colors",
2954
3457
  children: [
@@ -2965,7 +3468,7 @@ function vt() {
2965
3468
  ]
2966
3469
  }
2967
3470
  ) }),
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: [
3471
+ /* @__PURE__ */ e("div", { className: "flex-1 overflow-y-auto p-4", children: p.length === 0 ? /* @__PURE__ */ s("div", { className: "text-center py-8", children: [
2969
3472
  /* @__PURE__ */ e("div", { className: "w-12 h-12 mx-auto mb-3 rounded-full bg-zinc-200 dark:bg-zinc-700 flex items-center justify-center", children: /* @__PURE__ */ e(
2970
3473
  "svg",
2971
3474
  {
@@ -2986,21 +3489,21 @@ function vt() {
2986
3489
  ) }),
2987
3490
  /* @__PURE__ */ e("p", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No saved workflows yet" }),
2988
3491
  /* @__PURE__ */ e("p", { className: "text-xs text-zinc-400 dark:text-zinc-500 mt-1", children: "Build a workflow and save it to see it here" })
2989
- ] }) : /* @__PURE__ */ e("div", { className: "space-y-2", children: u.map((l) => /* @__PURE__ */ e(
2990
- wt,
3492
+ ] }) : /* @__PURE__ */ e("div", { className: "space-y-2", children: p.map((c) => /* @__PURE__ */ e(
3493
+ Wt,
2991
3494
  {
2992
- workflow: l,
2993
- isActive: l.id === a,
3495
+ workflow: c,
3496
+ isActive: c.id === n,
2994
3497
  onLoad: () => {
2995
- s(l.id), i();
3498
+ o(c.id), l();
2996
3499
  },
2997
- onDelete: () => d(l.id),
2998
- onRename: (p) => m(l.id, p),
2999
- onDuplicate: () => o(l.id)
3500
+ onDelete: () => i(c.id),
3501
+ onRename: (u) => m(c.id, u),
3502
+ onDuplicate: () => d(c.id)
3000
3503
  },
3001
- l.id
3504
+ c.id
3002
3505
  )) }) }),
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: [
3506
+ /* @__PURE__ */ s("div", { className: "px-4 py-3 border-t border-zinc-200 dark:border-zinc-700 text-xs text-zinc-500 dark:text-zinc-400", children: [
3004
3507
  t.length,
3005
3508
  " workflow",
3006
3509
  t.length !== 1 ? "s" : "",
@@ -3009,7 +3512,7 @@ function vt() {
3009
3512
  ] })
3010
3513
  ] });
3011
3514
  }
3012
- const yt = [
3515
+ const Pt = [
3013
3516
  {
3014
3517
  id: "openai",
3015
3518
  name: "OpenAI",
@@ -3027,10 +3530,17 @@ const yt = [
3027
3530
  {
3028
3531
  id: "gemini",
3029
3532
  name: "Google AI",
3030
- description: "Gemini Vision, Gemini Text",
3533
+ description: "Gemini Vision, Gemini Text, Gemini Edit",
3031
3534
  placeholder: "AIza...",
3032
3535
  docsUrl: "https://aistudio.google.com/apikey"
3033
3536
  },
3537
+ {
3538
+ id: "grok",
3539
+ name: "xAI (Grok)",
3540
+ description: "Grok Vision, Grok Text",
3541
+ placeholder: "xai-...",
3542
+ docsUrl: "https://console.x.ai/"
3543
+ },
3034
3544
  {
3035
3545
  id: "openrouter",
3036
3546
  name: "OpenRouter",
@@ -3038,7 +3548,7 @@ const yt = [
3038
3548
  placeholder: "sk-or-...",
3039
3549
  docsUrl: "https://openrouter.ai/keys"
3040
3550
  }
3041
- ], Nt = [
3551
+ ], $t = [
3042
3552
  {
3043
3553
  id: "ollama",
3044
3554
  name: "Ollama",
@@ -3054,21 +3564,21 @@ const yt = [
3054
3564
  docsUrl: "https://lmstudio.ai"
3055
3565
  }
3056
3566
  ];
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 = () => {
3567
+ function Mt({ provider: r }) {
3568
+ const l = O((h) => h.ai), t = O((h) => h.setAIProvider), n = l[r.id], o = (n == null ? void 0 : n.enabled) ?? !1, i = (n == null ? void 0 : n.apiKey) ?? "", [m, d] = I(i), [a, p] = I(!1), c = () => {
3059
3569
  t(r.id, {
3060
3570
  apiKey: m,
3061
- enabled: !s
3571
+ enabled: !o
3062
3572
  });
3063
- }, p = (f) => {
3064
- o(f), t(r.id, {
3065
- apiKey: f,
3066
- enabled: s
3573
+ }, u = (h) => {
3574
+ d(h), t(r.id, {
3575
+ apiKey: h,
3576
+ enabled: o
3067
3577
  });
3068
3578
  };
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: [
3579
+ return /* @__PURE__ */ s("div", { className: "flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg", children: [
3580
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
3581
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3072
3582
  /* @__PURE__ */ e("span", { className: "font-medium text-gray-900 dark:text-white", children: r.name }),
3073
3583
  /* @__PURE__ */ e(
3074
3584
  "a",
@@ -3082,13 +3592,13 @@ function zt({ provider: r }) {
3082
3592
  )
3083
3593
  ] }),
3084
3594
  /* @__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: [
3595
+ /* @__PURE__ */ e("div", { className: "mt-2 flex items-center gap-2", children: /* @__PURE__ */ s("div", { className: "relative flex-1", children: [
3086
3596
  /* @__PURE__ */ e(
3087
3597
  "input",
3088
3598
  {
3089
- type: n ? "text" : "password",
3599
+ type: a ? "text" : "password",
3090
3600
  value: m,
3091
- onChange: (f) => p(f.target.value),
3601
+ onChange: (h) => u(h.target.value),
3092
3602
  placeholder: r.placeholder,
3093
3603
  className: "w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500"
3094
3604
  }
@@ -3097,9 +3607,9 @@ function zt({ provider: r }) {
3097
3607
  "button",
3098
3608
  {
3099
3609
  type: "button",
3100
- onClick: () => u(!n),
3610
+ onClick: () => p(!a),
3101
3611
  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(
3612
+ children: /* @__PURE__ */ e("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: a ? /* @__PURE__ */ e(
3103
3613
  "path",
3104
3614
  {
3105
3615
  strokeLinecap: "round",
@@ -3123,33 +3633,33 @@ function zt({ provider: r }) {
3123
3633
  /* @__PURE__ */ e("div", { className: "flex items-center", children: /* @__PURE__ */ e(
3124
3634
  "button",
3125
3635
  {
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"}`,
3636
+ onClick: c,
3637
+ className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${o ? "bg-teal-600" : "bg-gray-300 dark:bg-zinc-600"}`,
3128
3638
  children: /* @__PURE__ */ e(
3129
3639
  "span",
3130
3640
  {
3131
- className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${s ? "translate-x-6" : "translate-x-1"}`
3641
+ className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${o ? "translate-x-6" : "translate-x-1"}`
3132
3642
  }
3133
3643
  )
3134
3644
  }
3135
3645
  ) })
3136
3646
  ] });
3137
3647
  }
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 = () => {
3648
+ function jt({ provider: r }) {
3649
+ const l = O((c) => c.ai), t = O((c) => c.setAIProvider), n = l[r.id], o = (n == null ? void 0 : n.enabled) ?? !1, i = (n == null ? void 0 : n.baseUrl) ?? r.defaultUrl, [m, d] = I(i), a = () => {
3140
3650
  t(r.id, {
3141
3651
  baseUrl: m,
3142
- enabled: !s
3652
+ enabled: !o
3143
3653
  });
3144
- }, u = (l) => {
3145
- o(l), t(r.id, {
3146
- baseUrl: l,
3147
- enabled: s
3654
+ }, p = (c) => {
3655
+ d(c), t(r.id, {
3656
+ baseUrl: c,
3657
+ enabled: o
3148
3658
  });
3149
3659
  };
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: [
3660
+ return /* @__PURE__ */ s("div", { className: "flex items-start gap-4 p-4 border border-gray-200 dark:border-zinc-700 rounded-lg", children: [
3661
+ /* @__PURE__ */ s("div", { className: "flex-1 min-w-0", children: [
3662
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3153
3663
  /* @__PURE__ */ e("span", { className: "font-medium text-gray-900 dark:text-white", children: r.name }),
3154
3664
  /* @__PURE__ */ e(
3155
3665
  "a",
@@ -3169,7 +3679,7 @@ function Ct({ provider: r }) {
3169
3679
  {
3170
3680
  type: "text",
3171
3681
  value: m,
3172
- onChange: (l) => u(l.target.value),
3682
+ onChange: (c) => p(c.target.value),
3173
3683
  placeholder: r.defaultUrl,
3174
3684
  className: "w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500"
3175
3685
  }
@@ -3178,30 +3688,30 @@ function Ct({ provider: r }) {
3178
3688
  /* @__PURE__ */ e("div", { className: "flex items-center", children: /* @__PURE__ */ e(
3179
3689
  "button",
3180
3690
  {
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"}`,
3691
+ onClick: a,
3692
+ className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${o ? "bg-teal-600" : "bg-gray-300 dark:bg-zinc-600"}`,
3183
3693
  children: /* @__PURE__ */ e(
3184
3694
  "span",
3185
3695
  {
3186
- className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${s ? "translate-x-6" : "translate-x-1"}`
3696
+ className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${o ? "translate-x-6" : "translate-x-1"}`
3187
3697
  }
3188
3698
  )
3189
3699
  }
3190
3700
  ) })
3191
3701
  ] });
3192
3702
  }
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: [
3703
+ function Dt() {
3704
+ const r = O((t) => t.showSettings), l = O((t) => t.closeSettings);
3705
+ return r ? /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl max-w-xl w-full mx-4 max-h-[85vh] flex flex-col", children: [
3706
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-zinc-700", children: [
3707
+ /* @__PURE__ */ s("div", { children: [
3198
3708
  /* @__PURE__ */ e("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "AI Provider Settings" }),
3199
3709
  /* @__PURE__ */ e("p", { className: "text-sm text-gray-500 dark:text-zinc-400 mt-0.5", children: "Configure your AI providers for vision and text generation" })
3200
3710
  ] }),
3201
3711
  /* @__PURE__ */ e(
3202
3712
  "button",
3203
3713
  {
3204
- onClick: i,
3714
+ onClick: l,
3205
3715
  className: "text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200",
3206
3716
  children: /* @__PURE__ */ e("svg", { className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
3207
3717
  "path",
@@ -3215,16 +3725,16 @@ function St() {
3215
3725
  }
3216
3726
  )
3217
3727
  ] }),
3218
- /* @__PURE__ */ c("div", { className: "flex-1 overflow-y-auto p-6 space-y-6", children: [
3219
- /* @__PURE__ */ c("section", { children: [
3728
+ /* @__PURE__ */ s("div", { className: "flex-1 overflow-y-auto p-6 space-y-6", children: [
3729
+ /* @__PURE__ */ s("section", { children: [
3220
3730
  /* @__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)) })
3731
+ /* @__PURE__ */ e("div", { className: "space-y-3", children: Pt.map((t) => /* @__PURE__ */ e(Mt, { provider: t }, t.id)) })
3222
3732
  ] }),
3223
- /* @__PURE__ */ c("section", { children: [
3733
+ /* @__PURE__ */ s("section", { children: [
3224
3734
  /* @__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)) })
3735
+ /* @__PURE__ */ e("div", { className: "space-y-3", children: $t.map((t) => /* @__PURE__ */ e(jt, { provider: t }, t.id)) })
3226
3736
  ] }),
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: [
3737
+ /* @__PURE__ */ e("div", { className: "bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4", children: /* @__PURE__ */ s("div", { className: "flex items-start gap-3", children: [
3228
3738
  /* @__PURE__ */ e(
3229
3739
  "svg",
3230
3740
  {
@@ -3243,7 +3753,7 @@ function St() {
3243
3753
  )
3244
3754
  }
3245
3755
  ),
3246
- /* @__PURE__ */ c("div", { children: [
3756
+ /* @__PURE__ */ s("div", { children: [
3247
3757
  /* @__PURE__ */ e("p", { className: "text-sm font-medium text-blue-900 dark:text-blue-300", children: "Your keys stay local" }),
3248
3758
  /* @__PURE__ */ e("p", { className: "text-sm text-blue-700 dark:text-blue-400 mt-1", children: "API keys are stored in your browser only and sent directly to providers. They never pass through our servers." })
3249
3759
  ] })
@@ -3252,116 +3762,436 @@ function St() {
3252
3762
  /* @__PURE__ */ e("div", { className: "flex justify-end px-6 py-4 border-t border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ e(
3253
3763
  "button",
3254
3764
  {
3255
- onClick: i,
3765
+ onClick: l,
3256
3766
  className: "px-4 py-2 text-sm font-medium text-white bg-teal-600 rounded-md hover:bg-teal-700",
3257
3767
  children: "Done"
3258
3768
  }
3259
3769
  ) })
3260
3770
  ] }) }) : null;
3261
3771
  }
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);
3772
+ function Tt({ isOpen: r, onClose: l, onApplyWorkflow: t }) {
3773
+ const [n, o] = I([]), [i, m] = I(""), [d, a] = I(!1), [p, c] = I(null), [u, h] = I(null), [f, w] = I(""), v = Q(null), y = Q(null);
3774
+ D(() => {
3775
+ r && u === null && Ke().then((x) => {
3776
+ h(x.available), w(x.message);
3777
+ }).catch(() => {
3778
+ h(!1), w("Failed to check AI availability");
3779
+ });
3780
+ }, [r, u]), D(() => {
3781
+ r && y.current && y.current.focus();
3782
+ }, [r]), D(() => {
3783
+ var x;
3784
+ (x = v.current) == null || x.scrollIntoView({ behavior: "smooth" });
3785
+ }, [n]);
3786
+ const b = L(async () => {
3787
+ if (!i.trim() || d) return;
3788
+ const x = {
3789
+ role: "user",
3790
+ content: i.trim(),
3791
+ timestamp: Date.now()
3276
3792
  };
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(
3793
+ o((C) => [...C, x]), m(""), a(!0), c(null);
3794
+ try {
3795
+ const C = await _e({
3796
+ prompt: x.content,
3797
+ history: n
3798
+ }), S = {
3799
+ role: "assistant",
3800
+ content: C.message,
3801
+ workflow: C.workflow,
3802
+ timestamp: Date.now()
3803
+ };
3804
+ o((T) => [...T, S]), !C.success && C.error && c(C.error);
3805
+ } catch (C) {
3806
+ c(C instanceof Error ? C.message : "Failed to generate workflow");
3807
+ } finally {
3808
+ a(!1);
3809
+ }
3810
+ }, [i, d, n]), g = (x) => {
3811
+ x.key === "Enter" && !x.shiftKey && (x.preventDefault(), b());
3812
+ }, N = (x) => {
3813
+ t(x), l();
3814
+ }, W = () => {
3815
+ o([]), c(null);
3816
+ };
3817
+ return r ? /* @__PURE__ */ e("div", { className: "fixed inset-0 bg-black/50 flex items-center justify-center z-50", children: /* @__PURE__ */ s("div", { className: "bg-white dark:bg-zinc-800 rounded-lg shadow-xl w-full max-w-2xl mx-4 h-[80vh] flex flex-col", children: [
3818
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-zinc-700", children: [
3819
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-3", children: [
3820
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3821
+ /* @__PURE__ */ e(
3822
+ "svg",
3823
+ {
3824
+ className: "h-5 w-5 text-teal-600",
3825
+ fill: "none",
3826
+ viewBox: "0 0 24 24",
3827
+ stroke: "currentColor",
3828
+ children: /* @__PURE__ */ e(
3829
+ "path",
3830
+ {
3831
+ strokeLinecap: "round",
3832
+ strokeLinejoin: "round",
3833
+ strokeWidth: 2,
3834
+ d: "M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
3835
+ }
3836
+ )
3837
+ }
3838
+ ),
3839
+ /* @__PURE__ */ e("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "AI Workflow Generator" })
3840
+ ] }),
3841
+ /* @__PURE__ */ e("span", { className: "text-xs bg-teal-100 dark:bg-teal-900 text-teal-700 dark:text-teal-300 px-2 py-0.5 rounded", children: "Gemini 3 Pro" })
3842
+ ] }),
3843
+ /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3844
+ n.length > 0 && /* @__PURE__ */ e(
3313
3845
  "button",
3314
3846
  {
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"
3847
+ onClick: W,
3848
+ className: "p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded",
3849
+ title: "New Chat",
3850
+ children: /* @__PURE__ */ e("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
3851
+ "path",
3852
+ {
3853
+ strokeLinecap: "round",
3854
+ strokeLinejoin: "round",
3855
+ strokeWidth: 2,
3856
+ d: "M12 4v16m8-8H4"
3857
+ }
3858
+ ) })
3318
3859
  }
3319
3860
  ),
3320
3861
  /* @__PURE__ */ e(
3321
3862
  "button",
3322
3863
  {
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"
3864
+ onClick: l,
3865
+ className: "p-2 text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded",
3866
+ children: /* @__PURE__ */ e("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
3867
+ "path",
3868
+ {
3869
+ strokeLinecap: "round",
3870
+ strokeLinejoin: "round",
3871
+ strokeWidth: 2,
3872
+ d: "M6 18L18 6M6 6l12 12"
3873
+ }
3874
+ ) })
3875
+ }
3876
+ )
3877
+ ] })
3878
+ ] }),
3879
+ /* @__PURE__ */ s("div", { className: "flex-1 overflow-auto p-4 space-y-4", children: [
3880
+ u === !1 && /* @__PURE__ */ e("div", { className: "bg-amber-50 dark:bg-amber-900/30 border border-amber-200 dark:border-amber-800 rounded-lg p-4", children: /* @__PURE__ */ s("div", { className: "flex items-start gap-3", children: [
3881
+ /* @__PURE__ */ e(
3882
+ "svg",
3883
+ {
3884
+ className: "h-5 w-5 text-amber-600 dark:text-amber-400 mt-0.5",
3885
+ fill: "none",
3886
+ viewBox: "0 0 24 24",
3887
+ stroke: "currentColor",
3888
+ children: /* @__PURE__ */ e(
3889
+ "path",
3890
+ {
3891
+ strokeLinecap: "round",
3892
+ strokeLinejoin: "round",
3893
+ strokeWidth: 2,
3894
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
3895
+ }
3896
+ )
3897
+ }
3898
+ ),
3899
+ /* @__PURE__ */ s("div", { children: [
3900
+ /* @__PURE__ */ e("p", { className: "font-medium text-amber-800 dark:text-amber-200", children: "AI Generation Not Available" }),
3901
+ /* @__PURE__ */ e("p", { className: "text-sm text-amber-700 dark:text-amber-300 mt-1", children: f }),
3902
+ /* @__PURE__ */ e("p", { className: "text-xs text-amber-600 dark:text-amber-400 mt-2", children: "Set GEMINI_API_KEY in your environment to enable this feature." })
3903
+ ] })
3904
+ ] }) }),
3905
+ n.length === 0 && u !== !1 && /* @__PURE__ */ s("div", { className: "text-center py-8", children: [
3906
+ /* @__PURE__ */ e("div", { className: "inline-flex items-center justify-center w-16 h-16 bg-teal-100 dark:bg-teal-900/50 rounded-full mb-4", children: /* @__PURE__ */ e(
3907
+ "svg",
3908
+ {
3909
+ className: "h-8 w-8 text-teal-600 dark:text-teal-400",
3910
+ fill: "none",
3911
+ viewBox: "0 0 24 24",
3912
+ stroke: "currentColor",
3913
+ children: /* @__PURE__ */ e(
3914
+ "path",
3915
+ {
3916
+ strokeLinecap: "round",
3917
+ strokeLinejoin: "round",
3918
+ strokeWidth: 2,
3919
+ d: "M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"
3920
+ }
3921
+ )
3922
+ }
3923
+ ) }),
3924
+ /* @__PURE__ */ e("h4", { className: "text-lg font-medium text-gray-900 dark:text-white mb-2", children: "Describe your workflow" }),
3925
+ /* @__PURE__ */ e("p", { className: "text-sm text-gray-500 dark:text-zinc-400 max-w-md mx-auto", children: "Tell me what you want to create and I'll generate a workflow for you. For example:" }),
3926
+ /* @__PURE__ */ e("div", { className: "mt-4 space-y-2", children: [
3927
+ "Generate an image of a sunset and resize it to 800x600",
3928
+ "Use Gemini text to generate 3 creative image prompts about space exploration, then generate images from each prompt",
3929
+ "Generate an image with Gemini, then use it as a reference to create a variation with different lighting",
3930
+ "Create a product mockup: generate a minimalist logo, then composite it onto a t-shirt image",
3931
+ "Build an AI art pipeline: generate a base image, apply artistic style transfer, then upscale to 4K"
3932
+ ].map((x, C) => /* @__PURE__ */ s(
3933
+ "button",
3934
+ {
3935
+ onClick: () => m(x),
3936
+ className: "block w-full text-left text-sm px-4 py-2 bg-gray-100 dark:bg-zinc-700 hover:bg-gray-200 dark:hover:bg-zinc-600 rounded-lg text-gray-700 dark:text-zinc-300 transition-colors",
3937
+ children: [
3938
+ '"',
3939
+ x,
3940
+ '"'
3941
+ ]
3942
+ },
3943
+ C
3944
+ )) })
3945
+ ] }),
3946
+ n.map((x, C) => /* @__PURE__ */ e(
3947
+ "div",
3948
+ {
3949
+ className: `flex ${x.role === "user" ? "justify-end" : "justify-start"}`,
3950
+ children: /* @__PURE__ */ s(
3951
+ "div",
3952
+ {
3953
+ className: `max-w-[80%] rounded-lg px-4 py-3 ${x.role === "user" ? "bg-teal-600 text-white" : "bg-gray-100 dark:bg-zinc-700 text-gray-900 dark:text-white"}`,
3954
+ children: [
3955
+ /* @__PURE__ */ e("p", { className: "text-sm whitespace-pre-wrap", children: x.content }),
3956
+ x.role === "assistant" && x.workflow && /* @__PURE__ */ s("div", { className: "mt-3 pt-3 border-t border-gray-200 dark:border-zinc-600", children: [
3957
+ /* @__PURE__ */ s("div", { className: "flex items-center justify-between mb-2", children: [
3958
+ /* @__PURE__ */ e("span", { className: "text-xs font-medium text-gray-500 dark:text-zinc-400", children: "Generated Workflow" }),
3959
+ /* @__PURE__ */ e(
3960
+ "button",
3961
+ {
3962
+ onClick: () => N(x.workflow),
3963
+ className: "text-xs px-3 py-1 bg-teal-600 hover:bg-teal-700 text-white rounded transition-colors",
3964
+ children: "Apply to Canvas"
3965
+ }
3966
+ )
3967
+ ] }),
3968
+ /* @__PURE__ */ e("div", { className: "bg-white dark:bg-zinc-800 rounded p-2 text-xs", children: /* @__PURE__ */ s("div", { className: "space-y-1", children: [
3969
+ x.workflow.nodes.map((S, T) => /* @__PURE__ */ s(
3970
+ "div",
3971
+ {
3972
+ className: "flex items-center gap-2 text-gray-600 dark:text-zinc-300",
3973
+ children: [
3974
+ /* @__PURE__ */ e("span", { className: "font-mono bg-gray-100 dark:bg-zinc-700 px-1.5 py-0.5 rounded", children: S.nodeType.split(":").pop() }),
3975
+ S.label && /* @__PURE__ */ s("span", { className: "text-gray-400", children: [
3976
+ "(",
3977
+ S.label,
3978
+ ")"
3979
+ ] })
3980
+ ]
3981
+ },
3982
+ T
3983
+ )),
3984
+ x.workflow.edges.length > 0 && /* @__PURE__ */ s("div", { className: "text-gray-400 dark:text-zinc-500 pt-1", children: [
3985
+ x.workflow.edges.length,
3986
+ " connection",
3987
+ x.workflow.edges.length !== 1 ? "s" : ""
3988
+ ] })
3989
+ ] }) })
3990
+ ] })
3991
+ ]
3992
+ }
3993
+ )
3994
+ },
3995
+ C
3996
+ )),
3997
+ d && /* @__PURE__ */ e("div", { className: "flex justify-start", children: /* @__PURE__ */ e("div", { className: "bg-gray-100 dark:bg-zinc-700 rounded-lg px-4 py-3", children: /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
3998
+ /* @__PURE__ */ s("div", { className: "flex space-x-1", children: [
3999
+ /* @__PURE__ */ e("div", { className: "w-2 h-2 bg-gray-400 dark:bg-zinc-500 rounded-full animate-bounce" }),
4000
+ /* @__PURE__ */ e(
4001
+ "div",
4002
+ {
4003
+ className: "w-2 h-2 bg-gray-400 dark:bg-zinc-500 rounded-full animate-bounce",
4004
+ style: { animationDelay: "0.1s" }
4005
+ }
4006
+ ),
4007
+ /* @__PURE__ */ e(
4008
+ "div",
4009
+ {
4010
+ className: "w-2 h-2 bg-gray-400 dark:bg-zinc-500 rounded-full animate-bounce",
4011
+ style: { animationDelay: "0.2s" }
4012
+ }
4013
+ )
4014
+ ] }),
4015
+ /* @__PURE__ */ e("span", { className: "text-sm text-gray-500 dark:text-zinc-400", children: "Generating workflow..." })
4016
+ ] }) }) }),
4017
+ p && /* @__PURE__ */ e("div", { className: "bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg p-3", children: /* @__PURE__ */ e("p", { className: "text-sm text-red-700 dark:text-red-300", children: p }) }),
4018
+ /* @__PURE__ */ e("div", { ref: v })
4019
+ ] }),
4020
+ /* @__PURE__ */ s("div", { className: "border-t border-gray-200 dark:border-zinc-700 p-4", children: [
4021
+ /* @__PURE__ */ s("div", { className: "flex gap-2", children: [
4022
+ /* @__PURE__ */ e(
4023
+ "textarea",
4024
+ {
4025
+ ref: y,
4026
+ value: i,
4027
+ onChange: (x) => m(x.target.value),
4028
+ onKeyDown: g,
4029
+ placeholder: u === !1 ? "AI generation not available" : "Describe what workflow you want to create...",
4030
+ disabled: d || u === !1,
4031
+ rows: 2,
4032
+ className: "flex-1 resize-none rounded-lg border border-gray-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 px-4 py-2 text-sm text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-zinc-500 focus:border-teal-500 focus:outline-none focus:ring-1 focus:ring-teal-500 disabled:opacity-50 disabled:cursor-not-allowed"
3326
4033
  }
3327
4034
  ),
3328
4035
  /* @__PURE__ */ e(
3329
4036
  "button",
3330
4037
  {
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"
4038
+ onClick: b,
4039
+ disabled: !i.trim() || d || u === !1,
4040
+ className: "self-end px-4 py-2 bg-teal-600 hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed text-white rounded-lg transition-colors",
4041
+ children: /* @__PURE__ */ e("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
4042
+ "path",
4043
+ {
4044
+ strokeLinecap: "round",
4045
+ strokeLinejoin: "round",
4046
+ strokeWidth: 2,
4047
+ d: "M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
4048
+ }
4049
+ ) })
4050
+ }
4051
+ )
4052
+ ] }),
4053
+ /* @__PURE__ */ e("p", { className: "text-xs text-gray-400 dark:text-zinc-500 mt-2", children: "Press Enter to send, Shift+Enter for new line" })
4054
+ ] })
4055
+ ] }) }) : null;
4056
+ }
4057
+ function Ut() {
4058
+ const { screenToFlowPosition: r } = Ae(), l = k((o) => o.addNode), t = L(
4059
+ (o) => {
4060
+ o.preventDefault();
4061
+ const i = o.dataTransfer.getData("application/json");
4062
+ if (i)
4063
+ try {
4064
+ const m = JSON.parse(i), d = r({
4065
+ x: o.clientX,
4066
+ y: o.clientY
4067
+ });
4068
+ l(m, d);
4069
+ } catch (m) {
4070
+ console.error("Failed to parse dropped node:", m);
4071
+ }
4072
+ },
4073
+ [l, r]
4074
+ ), n = L((o) => {
4075
+ o.preventDefault(), o.dataTransfer.dropEffect = "move";
4076
+ }, []);
4077
+ return /* @__PURE__ */ e("div", { className: "flex-1", onDrop: t, onDragOver: n, children: /* @__PURE__ */ e(at, {}) });
4078
+ }
4079
+ function Ht() {
4080
+ const [r, l] = I("editor"), [t, n] = I(!1), o = k((a) => a.loadTemplate), i = k((a) => a.loadGeneratedWorkflow);
4081
+ D(() => {
4082
+ const p = new URLSearchParams(window.location.search).get("template");
4083
+ if (p) {
4084
+ const c = de(p);
4085
+ c && (o(c), window.history.replaceState({}, "", window.location.pathname));
4086
+ }
4087
+ }, [o]), D(() => {
4088
+ const a = () => {
4089
+ l("editor");
4090
+ };
4091
+ return window.addEventListener("workflow-loaded", a), () => {
4092
+ window.removeEventListener("workflow-loaded", a);
4093
+ };
4094
+ }, []);
4095
+ const m = L(
4096
+ (a) => {
4097
+ const p = de(a);
4098
+ p && (o(p), l("editor"));
4099
+ },
4100
+ [o]
4101
+ ), d = L(
4102
+ (a) => {
4103
+ i(a), l("editor");
4104
+ },
4105
+ [i]
4106
+ );
4107
+ return /* @__PURE__ */ s(We, { children: [
4108
+ /* @__PURE__ */ e(Dt, {}),
4109
+ /* @__PURE__ */ e(
4110
+ Tt,
4111
+ {
4112
+ isOpen: t,
4113
+ onClose: () => n(!1),
4114
+ onApplyWorkflow: d
4115
+ }
4116
+ ),
4117
+ /* @__PURE__ */ e(At, {}),
4118
+ /* @__PURE__ */ s("div", { className: "h-screen flex flex-col bg-gray-100 dark:bg-zinc-900", children: [
4119
+ /* @__PURE__ */ e(gt, {}),
4120
+ /* @__PURE__ */ e("div", { className: "bg-white dark:bg-zinc-800 border-b border-gray-200 dark:border-zinc-700", children: /* @__PURE__ */ s("div", { className: "flex items-center justify-between", children: [
4121
+ /* @__PURE__ */ s("div", { className: "flex", children: [
4122
+ /* @__PURE__ */ e(
4123
+ "button",
4124
+ {
4125
+ onClick: () => l("editor"),
4126
+ className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "editor" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
4127
+ children: "Editor"
4128
+ }
4129
+ ),
4130
+ /* @__PURE__ */ e(
4131
+ "button",
4132
+ {
4133
+ onClick: () => l("gallery"),
4134
+ className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "gallery" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
4135
+ children: "Gallery"
4136
+ }
4137
+ ),
4138
+ /* @__PURE__ */ e(
4139
+ "button",
4140
+ {
4141
+ onClick: () => l("templates"),
4142
+ className: `px-6 py-3 text-sm font-medium border-b-2 transition-colors ${r === "templates" ? "border-teal-500 text-teal-600 dark:text-teal-400" : "border-transparent text-gray-500 dark:text-zinc-400 hover:text-gray-700 dark:hover:text-zinc-200"}`,
4143
+ children: "Templates"
4144
+ }
4145
+ )
4146
+ ] }),
4147
+ /* @__PURE__ */ s(
4148
+ "button",
4149
+ {
4150
+ onClick: () => n(!0),
4151
+ className: "mr-4 px-4 py-1.5 text-sm font-medium text-white bg-gradient-to-r from-teal-500 to-cyan-500 hover:from-teal-600 hover:to-cyan-600 rounded-full flex items-center gap-2 transition-all shadow-sm hover:shadow",
4152
+ children: [
4153
+ /* @__PURE__ */ e("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e(
4154
+ "path",
4155
+ {
4156
+ strokeLinecap: "round",
4157
+ strokeLinejoin: "round",
4158
+ strokeWidth: 2,
4159
+ d: "M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
4160
+ }
4161
+ ) }),
4162
+ "AI Generate"
4163
+ ]
3334
4164
  }
3335
4165
  )
3336
4166
  ] }) }),
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, {})
4167
+ /* @__PURE__ */ s("div", { className: "flex-1 flex overflow-hidden", children: [
4168
+ r === "editor" && /* @__PURE__ */ s(U, { children: [
4169
+ /* @__PURE__ */ e(ot, {}),
4170
+ /* @__PURE__ */ e(Ut, {}),
4171
+ /* @__PURE__ */ e(st, {})
3342
4172
  ] }),
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 }) })
4173
+ r === "gallery" && /* @__PURE__ */ e("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ e(ht, {}) }),
4174
+ r === "templates" && /* @__PURE__ */ e("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ e(St, { onSelect: m }) })
3345
4175
  ] })
3346
4176
  ] })
3347
4177
  ] });
3348
4178
  }
3349
4179
  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
4180
+ Dt as AISettings,
4181
+ Ht as App,
4182
+ ht as Gallery,
4183
+ st as NodeInspector,
4184
+ ot as NodePalette,
4185
+ St as TemplateGallery,
4186
+ gt as Toolbar,
4187
+ nt as UploadGallery,
4188
+ at as WorkflowEditor,
4189
+ At as WorkflowLibrary,
4190
+ It as getCategories,
4191
+ de as getTemplateById,
4192
+ Vt as getTemplatesByCategory,
4193
+ Ft as searchTemplates,
4194
+ H as templates,
4195
+ k as useWorkflowStore
3366
4196
  };
3367
4197
  //# sourceMappingURL=index.js.map