wizards 0.2.15 → 0.2.17

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.
Files changed (66) hide show
  1. package/apps/runtime/dist/credits/estimate.js +14 -8
  2. package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
  3. package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
  4. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
  5. package/apps/runtime/dist/db/schema.js +2 -0
  6. package/apps/runtime/dist/engine/events.js +14 -2
  7. package/apps/runtime/dist/engine/prepare.js +5 -2
  8. package/apps/runtime/dist/engine/requirements.js +248 -12
  9. package/apps/runtime/dist/engine/runner.js +28 -5
  10. package/apps/runtime/dist/engine/steps.js +18 -10
  11. package/apps/runtime/dist/engine/template.js +13 -10
  12. package/apps/runtime/dist/routes/studio.js +2 -2
  13. package/apps/runtime/dist/services/marketplace.js +34 -7
  14. package/apps/runtime/dist/tools/browser.js +12 -6
  15. package/apps/runtime/dist/tools/index.js +12 -6
  16. package/apps/runtime/dist/tools/mail.js +5 -2
  17. package/apps/runtime/dist/tools/pages.js +1 -1
  18. package/apps/runtime/dist/tools/project.js +5 -2
  19. package/apps/runtime/dist/tools/store.js +4 -4
  20. package/apps/runtime/dist/widgets/step.js +10 -4
  21. package/apps/web/dist/assets/{Account-B_FCuidz.js → Account-LVXhagaS.js} +1 -1
  22. package/apps/web/dist/assets/{ChangelogDialog-BKvNJIrA.js → ChangelogDialog-DM0KAoy6.js} +1 -1
  23. package/apps/web/dist/assets/ChatPanel-CxOQmtv-.js +1 -0
  24. package/apps/web/dist/assets/CreditsDialog-DkW3YT44.js +1 -0
  25. package/apps/web/dist/assets/EditorPage-hbisE1Wf.js +2 -0
  26. package/apps/web/dist/assets/{FlowPreview-De3ZyIer.js → FlowPreview-v7or29ku.js} +1 -1
  27. package/apps/web/dist/assets/{Harness-3kuJaJoj.js → Harness-RZF-bBmb.js} +2 -2
  28. package/apps/web/dist/assets/{HomePage-DWDT64vg.js → HomePage-mxG-a_KU.js} +1 -1
  29. package/apps/web/dist/assets/{ImportWizard-CTGmBDI8.js → ImportWizard-CiPyUt3E.js} +1 -1
  30. package/apps/web/dist/assets/LocalRuntime-Dqp9wkN3.js +1 -0
  31. package/apps/web/dist/assets/NewWizardPage-DHwRsi0_.js +2 -0
  32. package/apps/web/dist/assets/ProjectPage-Bb7jN_6n.js +4 -0
  33. package/apps/web/dist/assets/PublicRunner-TGkOwbAP.js +1 -0
  34. package/apps/web/dist/assets/RunnerView-DzHGshZj.js +70 -0
  35. package/apps/web/dist/assets/SettingsPage-CG3Xtfej.js +1 -0
  36. package/apps/web/dist/assets/{SetupPage-DHQYO7zB.js → SetupPage-O1GfPlqX.js} +1 -1
  37. package/apps/web/dist/assets/SharePage-CCNUhtry.js +1 -0
  38. package/apps/web/dist/assets/{api-RJbFM_oc.js → api-DB22_B7G.js} +2 -2
  39. package/apps/web/dist/assets/changelog-BkIJdZ7M.js +1 -0
  40. package/apps/web/dist/assets/{esm-CgnVZhIQ.js → esm-3TT9i_rv.js} +1 -1
  41. package/apps/web/dist/assets/{index-9maLuK9R.css → index-BPpKz65x.css} +1 -1
  42. package/apps/web/dist/assets/index-CLe9Wrpu.js +10 -0
  43. package/apps/web/dist/assets/{meta-CchZXdWH.js → meta-CEsBCPfA.js} +1 -1
  44. package/apps/web/dist/assets/{settings-menu-CrRWSrNL.js → settings-menu-pOcjznGJ.js} +1 -1
  45. package/apps/web/dist/assets/ui-I7QYMX0F.js +1 -0
  46. package/apps/web/dist/index.html +4 -4
  47. package/apps/web/dist/mcp/flow.html +54 -54
  48. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +11 -0
  49. package/node_modules/@engenty-wizards/shared/dist/definition.js +27 -2
  50. package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +2 -0
  51. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +150 -0
  52. package/node_modules/@engenty-wizards/shared/dist/run.js +72 -1
  53. package/package.json +1 -1
  54. package/apps/web/dist/assets/ChatPanel-CPgh0skF.js +0 -1
  55. package/apps/web/dist/assets/CreditsDialog-CbFq_7-m.js +0 -1
  56. package/apps/web/dist/assets/EditorPage-8liZwYCK.js +0 -2
  57. package/apps/web/dist/assets/LocalRuntime-CVdU8RtD.js +0 -1
  58. package/apps/web/dist/assets/NewWizardPage-CqFlo0b-.js +0 -2
  59. package/apps/web/dist/assets/ProjectPage-CDw2Jcxx.js +0 -4
  60. package/apps/web/dist/assets/PublicRunner-BYnX2OmB.js +0 -1
  61. package/apps/web/dist/assets/RunnerView-Civq59Tk.js +0 -70
  62. package/apps/web/dist/assets/SettingsPage-Bj0TxbiM.js +0 -1
  63. package/apps/web/dist/assets/SharePage-CY6bwfTI.js +0 -1
  64. package/apps/web/dist/assets/changelog-BWtvjeKs.js +0 -1
  65. package/apps/web/dist/assets/index-LmRYEd-y.js +0 -10
  66. package/apps/web/dist/assets/ui-HV_XbHjw.js +0 -1
@@ -1418,6 +1418,7 @@ export declare function branchValues(values: Record<string, unknown>, outputs: R
1418
1418
  }>): Record<string, unknown>;
1419
1419
  /** The step after `step`, honouring its branch rules. `null` = the end. */
1420
1420
  export declare function nextStepId(def: WizardDefinition, stepId: string, values: Record<string, unknown>): string | null;
1421
+ export declare function ruleMatches(rule: NextRule, values: Record<string, unknown>): boolean;
1421
1422
  export interface ItemsTotals {
1422
1423
  rows: Record<string, unknown>[];
1423
1424
  net: number;
@@ -1428,5 +1429,15 @@ export interface ItemsTotals {
1428
1429
  }
1429
1430
  export declare function itemsTotals(field: Field, value: unknown, values: Record<string, unknown>): ItemsTotals;
1430
1431
  export declare function allFields(def: WizardDefinition): Field[];
1432
+ /**
1433
+ * The language a wizard speaks to people, read from its own words (titles, labels, intro).
1434
+ * A definition carries none; German where it is not clearly English.
1435
+ */
1436
+ export declare function wizardLang(def: WizardDefinition): "de" | "en";
1437
+ /** The locale amounts and dates are written in for a wizard's language. */
1438
+ export declare const LOCALES: {
1439
+ readonly de: "de-DE";
1440
+ readonly en: "en-GB";
1441
+ };
1431
1442
  /** True when this app's schema reads the definition without losing anything of it. */
1432
1443
  export declare function readable(definition: unknown): boolean;
@@ -735,7 +735,7 @@ export function nextStepId(def, stepId, values) {
735
735
  return null;
736
736
  }
737
737
  for (const rule of step.next ?? []) {
738
- if (matches(rule, values)) {
738
+ if (ruleMatches(rule, values)) {
739
739
  return rule.goto === "end" ? null : rule.goto;
740
740
  }
741
741
  }
@@ -744,7 +744,7 @@ export function nextStepId(def, stepId, values) {
744
744
  function isEmptyValue(v) {
745
745
  return v === undefined || v === null || v === "" || (Array.isArray(v) && v.length === 0);
746
746
  }
747
- function matches(rule, values) {
747
+ export function ruleMatches(rule, values) {
748
748
  const v = values[rule.when.field];
749
749
  switch (rule.when.op) {
750
750
  case "empty":
@@ -796,6 +796,31 @@ function round2(n) {
796
796
  export function allFields(def) {
797
797
  return def.steps.flatMap((s) => (s.type === "page" ? s.fields : []));
798
798
  }
799
+ const GERMAN = /\b(und|der|die|das|ist|nicht|für|mit|ein|eine|wird|zu|dein|deine|ihr|wir|was|wie|oder)\b|[äöüß]/gi;
800
+ const ENGLISH = /\b(and|the|is|not|for|with|a|an|your|you|we|what|how|or|to|of)\b/gi;
801
+ /**
802
+ * The language a wizard speaks to people, read from its own words (titles, labels, intro).
803
+ * A definition carries none; German where it is not clearly English.
804
+ */
805
+ export function wizardLang(def) {
806
+ const text = [
807
+ def.title,
808
+ def.description,
809
+ def.intro,
810
+ ...def.steps.flatMap((s) => [
811
+ s.title,
812
+ s.description,
813
+ ...(s.type === "page" ? s.fields.flatMap((f) => [f.label, f.help, f.placeholder]) : []),
814
+ ]),
815
+ ]
816
+ .filter(Boolean)
817
+ .join(" ");
818
+ const de = text.match(GERMAN)?.length ?? 0;
819
+ const en = text.match(ENGLISH)?.length ?? 0;
820
+ return en > de ? "en" : "de";
821
+ }
822
+ /** The locale amounts and dates are written in for a wizard's language. */
823
+ export const LOCALES = { de: "de-DE", en: "en-GB" };
799
824
  // --- can this app read a definition? ---------------------------------------------------------
800
825
  // The schema drops what it does not know. A definition written for a newer app would be read
801
826
  // without complaint and run wrongly, so it counts only when nothing of it is lost.
@@ -295,4 +295,6 @@ export interface MarketplaceEntry extends MarketplaceSummary {
295
295
  starred: boolean;
296
296
  /** What it needs that this runtime has no model for: a wizard made from it would not start. */
297
297
  missing: Capability[];
298
+ /** What only some of its paths need and this runtime has no model for: it runs the other ways. */
299
+ optional: Capability[];
298
300
  }
@@ -112,12 +112,153 @@ export interface ShownList {
112
112
  formats: Format[];
113
113
  label: string | null;
114
114
  }
115
+ /**
116
+ * What a step reports while it works, in words for each language: the runtime writes the German
117
+ * line into the run's log, a runner shows it in the language the person reads.
118
+ */
119
+ export declare const RUN_NOTES: {
120
+ readonly batchDone: {
121
+ readonly de: "{done} von {total} fertig";
122
+ readonly en: "{done} of {total} done";
123
+ };
124
+ readonly editing: {
125
+ readonly de: "Bearbeitet {n} von {total}";
126
+ readonly en: "Editing {n} of {total}";
127
+ };
128
+ readonly filming: {
129
+ readonly de: "Dreht {n} von {total}";
130
+ readonly en: "Filming {n} of {total}";
131
+ };
132
+ readonly clipsRendering: {
133
+ readonly de: "{count} Clips werden gerendert – das dauert einige Minuten.";
134
+ readonly en: "Rendering {count} clips – this takes a few minutes.";
135
+ };
136
+ readonly videoRendering: {
137
+ readonly de: "Das Video wird gerendert – das dauert meist 1–3 Minuten.";
138
+ readonly en: "Rendering the video – this usually takes 1–3 minutes.";
139
+ };
140
+ readonly photo: {
141
+ readonly de: "Sieht sich Foto {n} von {total} an";
142
+ readonly en: "Looking at photo {n} of {total}";
143
+ };
144
+ readonly listen: {
145
+ readonly de: "Hört „{label}“ an …";
146
+ readonly en: "Listening to “{label}” …";
147
+ };
148
+ readonly listenFailed: {
149
+ readonly de: "„{label}“ konnte nicht verschriftlicht werden.";
150
+ readonly en: "“{label}” could not be written down.";
151
+ };
152
+ readonly filmCutting: {
153
+ readonly de: "Der Film wird geschnitten – das dauert etwa eine Minute.";
154
+ readonly en: "Cutting the film – this takes about a minute.";
155
+ };
156
+ readonly filmProgress: {
157
+ readonly de: "{pct} % geschnitten";
158
+ readonly en: "{pct} % cut";
159
+ };
160
+ readonly filmError: {
161
+ readonly de: "Der Film meldet: {detail}";
162
+ readonly en: "The film reports: {detail}";
163
+ };
164
+ readonly widgetError: {
165
+ readonly de: "Das Widget meldet einen Fehler: {detail}";
166
+ readonly en: "The widget reports an error: {detail}";
167
+ };
168
+ readonly mcpConnected: {
169
+ readonly de: "Verbunden mit {names}";
170
+ readonly en: "Connected to {names}";
171
+ };
172
+ readonly mcpUnreachable: {
173
+ readonly de: "MCP-Server nicht erreichbar: {detail}";
174
+ readonly en: "MCP server unreachable: {detail}";
175
+ };
176
+ readonly reads: {
177
+ readonly de: "Liest {name}";
178
+ readonly en: "Reading {name}";
179
+ };
180
+ readonly readsMany: {
181
+ readonly de: "Liest {count} Dokumente";
182
+ readonly en: "Reading {count} documents";
183
+ };
184
+ readonly opens: {
185
+ readonly de: "Öffnet {name}";
186
+ readonly en: "Opening {name}";
187
+ };
188
+ readonly clicks: {
189
+ readonly de: "Klickt im Browser";
190
+ readonly en: "Clicking in the browser";
191
+ };
192
+ readonly types: {
193
+ readonly de: "Tippt im Browser";
194
+ readonly en: "Typing in the browser";
195
+ };
196
+ readonly looksAtPage: {
197
+ readonly de: "Sieht sich die Seite an";
198
+ readonly en: "Looking at the page";
199
+ };
200
+ readonly waitsForSignIn: {
201
+ readonly de: "Wartet auf deine Anmeldung bei {name}";
202
+ readonly en: "Waiting for you to sign in at {name}";
203
+ };
204
+ readonly downloads: {
205
+ readonly de: "Lädt {name} herunter";
206
+ readonly en: "Downloading {name}";
207
+ };
208
+ readonly runs: {
209
+ readonly de: "Führt aus: {command}";
210
+ readonly en: "Running: {command}";
211
+ };
212
+ readonly python: {
213
+ readonly de: "Führt Python aus";
214
+ readonly en: "Running Python";
215
+ };
216
+ readonly drawing: {
217
+ readonly de: "Zeichnet ein Bild";
218
+ readonly en: "Drawing an image";
219
+ };
220
+ readonly writesPage: {
221
+ readonly de: "Schreibt die Seite „{title}“";
222
+ readonly en: "Writing the page “{title}”";
223
+ };
224
+ readonly searchesDocuments: {
225
+ readonly de: "Sucht in den Dokumenten: {query}";
226
+ readonly en: "Searching the documents: {query}";
227
+ };
228
+ readonly searchesMail: {
229
+ readonly de: "Durchsucht {label}";
230
+ readonly en: "Searching {label}";
231
+ };
232
+ readonly savesReceipts: {
233
+ readonly de: "Speichert {count} Belege aus {label}";
234
+ readonly en: "Saving {count} receipts from {label}";
235
+ };
236
+ readonly remembers: {
237
+ readonly de: "Merkt sich {title}";
238
+ readonly en: "Remembering {title}";
239
+ };
240
+ readonly files: {
241
+ readonly de: "Legt {count} Dateien ab";
242
+ readonly en: "Filing {count} files";
243
+ };
244
+ };
245
+ export type RunNoteCode = keyof typeof RUN_NOTES;
246
+ /** A line of `RUN_NOTES` with what goes into its gaps. */
247
+ export interface RunNote {
248
+ code: RunNoteCode;
249
+ params?: Record<string, string | number>;
250
+ }
251
+ /** A note in a language, its gaps filled. */
252
+ export declare function noteText(note: RunNote, lang: "de" | "en"): string;
115
253
  export interface RunEvent {
116
254
  id: number;
117
255
  at: string;
118
256
  stepId: string | null;
119
257
  type: "step_started" | "step_done" | "tool" | "info" | "error";
258
+ /** In German, as the run's log keeps it. */
120
259
  message: string;
260
+ /** The same as a note a runner shows in the person's language; null for free text. */
261
+ note?: RunNote | null;
121
262
  /** A picture of the run this is about (a photo being looked at, an image just made). */
122
263
  asset?: string | null;
123
264
  }
@@ -131,6 +272,8 @@ export interface RunView {
131
272
  values: Record<string, unknown>;
132
273
  /** What fields of the current page start with, from earlier steps (`prefill`). */
133
274
  prefill: Record<string, unknown>;
275
+ /** Choices of the current page that lead to a step without a model here, by field id. */
276
+ closed: Record<string, ClosedChoice>;
134
277
  outputs: Record<string, StepOutput>;
135
278
  /** Steps whose outputs the current step shows, with their definitions. */
136
279
  shown: {
@@ -209,6 +352,13 @@ export interface MissingModel {
209
352
  /** A step that needs it lies on every path: the run cannot start. */
210
353
  blocking: boolean;
211
354
  }
355
+ /** A page's choice whose values lead to a step this runtime has no model for. */
356
+ export interface ClosedChoice {
357
+ /** The options (or a toggle's true / false) that lead there; empty = the field as a whole. */
358
+ values: (string | boolean)[];
359
+ /** What is missing on the way. */
360
+ classes: ModelClass[];
361
+ }
212
362
  export interface RunEstimate {
213
363
  available: boolean;
214
364
  credits: number;
@@ -1 +1,72 @@
1
- export {};
1
+ /**
2
+ * What a step reports while it works, in words for each language: the runtime writes the German
3
+ * line into the run's log, a runner shows it in the language the person reads.
4
+ */
5
+ export const RUN_NOTES = {
6
+ batchDone: { de: "{done} von {total} fertig", en: "{done} of {total} done" },
7
+ editing: { de: "Bearbeitet {n} von {total}", en: "Editing {n} of {total}" },
8
+ filming: { de: "Dreht {n} von {total}", en: "Filming {n} of {total}" },
9
+ clipsRendering: {
10
+ de: "{count} Clips werden gerendert – das dauert einige Minuten.",
11
+ en: "Rendering {count} clips – this takes a few minutes.",
12
+ },
13
+ videoRendering: {
14
+ de: "Das Video wird gerendert – das dauert meist 1–3 Minuten.",
15
+ en: "Rendering the video – this usually takes 1–3 minutes.",
16
+ },
17
+ photo: { de: "Sieht sich Foto {n} von {total} an", en: "Looking at photo {n} of {total}" },
18
+ listen: { de: "Hört „{label}“ an …", en: "Listening to “{label}” …" },
19
+ listenFailed: {
20
+ de: "„{label}“ konnte nicht verschriftlicht werden.",
21
+ en: "“{label}” could not be written down.",
22
+ },
23
+ filmCutting: {
24
+ de: "Der Film wird geschnitten – das dauert etwa eine Minute.",
25
+ en: "Cutting the film – this takes about a minute.",
26
+ },
27
+ filmProgress: { de: "{pct} % geschnitten", en: "{pct} % cut" },
28
+ filmError: { de: "Der Film meldet: {detail}", en: "The film reports: {detail}" },
29
+ widgetError: {
30
+ de: "Das Widget meldet einen Fehler: {detail}",
31
+ en: "The widget reports an error: {detail}",
32
+ },
33
+ mcpConnected: { de: "Verbunden mit {names}", en: "Connected to {names}" },
34
+ mcpUnreachable: {
35
+ de: "MCP-Server nicht erreichbar: {detail}",
36
+ en: "MCP server unreachable: {detail}",
37
+ },
38
+ reads: { de: "Liest {name}", en: "Reading {name}" },
39
+ readsMany: { de: "Liest {count} Dokumente", en: "Reading {count} documents" },
40
+ opens: { de: "Öffnet {name}", en: "Opening {name}" },
41
+ clicks: { de: "Klickt im Browser", en: "Clicking in the browser" },
42
+ types: { de: "Tippt im Browser", en: "Typing in the browser" },
43
+ looksAtPage: { de: "Sieht sich die Seite an", en: "Looking at the page" },
44
+ waitsForSignIn: {
45
+ de: "Wartet auf deine Anmeldung bei {name}",
46
+ en: "Waiting for you to sign in at {name}",
47
+ },
48
+ downloads: { de: "Lädt {name} herunter", en: "Downloading {name}" },
49
+ runs: { de: "Führt aus: {command}", en: "Running: {command}" },
50
+ python: { de: "Führt Python aus", en: "Running Python" },
51
+ drawing: { de: "Zeichnet ein Bild", en: "Drawing an image" },
52
+ writesPage: { de: "Schreibt die Seite „{title}“", en: "Writing the page “{title}”" },
53
+ searchesDocuments: {
54
+ de: "Sucht in den Dokumenten: {query}",
55
+ en: "Searching the documents: {query}",
56
+ },
57
+ searchesMail: { de: "Durchsucht {label}", en: "Searching {label}" },
58
+ savesReceipts: {
59
+ de: "Speichert {count} Belege aus {label}",
60
+ en: "Saving {count} receipts from {label}",
61
+ },
62
+ remembers: { de: "Merkt sich {title}", en: "Remembering {title}" },
63
+ files: { de: "Legt {count} Dateien ab", en: "Filing {count} files" },
64
+ };
65
+ /** A note in a language, its gaps filled. */
66
+ export function noteText(note, lang) {
67
+ const line = RUN_NOTES[note.code];
68
+ if (!line) {
69
+ return "";
70
+ }
71
+ return line[lang].replace(/\{(\w+)\}/g, (gap, key) => note.params?.[key] === undefined ? gap : String(note.params[key]));
72
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wizards",
3
- "version": "0.2.15",
3
+ "version": "0.2.17",
4
4
  "description": "Make a wish. Get your wizard. It guides you step by step. Let AI do the work. Runs on your machine, on the AI subscription you already have.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "homepage": "https://engenty.ai",
@@ -1 +0,0 @@
1
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{c as r,d as i,i as a,n as o,nt as s}from"./api-RJbFM_oc.js";import{t as c}from"./createLucideIcon-q3MZMmnf.js";import{g as l,i as u,l as d,p as f,u as p}from"./RunnerView-Civq59Tk.js";import{t as m}from"./chevron-down-DymW-2BP.js";import{t as h}from"./plus-Du-Jx8aI.js";import{n as g}from"./video-9fDPRPCv.js";import{_,d as v,h as y,o as b,y as x}from"./ui-HV_XbHjw.js";import{j as S,k as C}from"./index-LmRYEd-y.js";var w={name:`chevron-up`,size:24,node:[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]};w.node;var T=c(w),E=e(t(),1),D=!1;function O(){if(!(typeof window>`u`||D))return window.SpeechRecognition??window.webkitSpeechRecognition}var k=typeof navigator<`u`&&!!navigator.mediaDevices?.getUserMedia&&typeof MediaRecorder<`u`;function A(e,t){let n=e.trimEnd(),r=t.trim();return n&&r?`${n} ${r}`:n||r}function j(e,t){let[n,r]=(0,E.useState)(!1),[i,a]=(0,E.useState)(!1),[s,c]=(0,E.useState)(null),l=(0,E.useRef)(e);l.current=e;let u=(0,E.useRef)(t);u.current=t;let d=(0,E.useRef)(null);(0,E.useEffect)(()=>()=>d.current?.stop(),[]);let f=async()=>{let e=l.current,t;try{t=await navigator.mediaDevices.getUserMedia({audio:!0})}catch{c(`denied`);return}let n=[],i=new MediaRecorder(t);i.ondataavailable=e=>e.data.size&&n.push(e.data),i.onstop=async()=>{for(let e of t.getTracks())e.stop();d.current=null,r(!1);let s=(i.mimeType||`audio/webm`).split(`;`)[0],l=new File(n,`dictation`,{type:s});if(l.size){a(!0);try{let{text:t}=await o.upload(`/api/studio/transcribe`,l);t.trim()&&u.current(A(e,t))}catch(e){c(e.message)}finally{a(!1)}}},d.current={stop:()=>i.state!==`inactive`&&i.stop()},i.start(),r(!0)},p=e=>{let t=l.current,n=``,i=new e;i.continuous=!0,i.interimResults=!0,i.lang=_===`de`?`de-DE`:`en-US`,i.onresult=e=>{let r=``;for(let t=Math.max(0,e.resultIndex);t<e.results.length;t++){let i=e.results[t],a=i[0]?.transcript??``;i.isFinal?n=A(n,a):r+=a}u.current(A(t,A(n,r)))},i.onerror=e=>{if(e.error!==`aborted`&&e.error!==`no-speech`){if(e.error===`not-allowed`){c(`denied`);return}D=!0,k&&!n?(i.onend=null,d.current=null,f()):c(e.error)}},i.onend=()=>{d.current=null,r(!1)},d.current={stop:()=>i.stop()},i.start(),r(!0)};return{supported:!!O()||k,listening:n,processing:i,error:s,toggle:()=>{if(i)return;if(d.current){d.current.stop();return}c(null);let e=O();e?p(e):f()}}}var M=e(n(),1),N=/\.(png|jpe?g|gif|webp|avif|svg)$/i;function P(e){let t=e.filter(e=>e.type.startsWith(`image/`));return t.length?Object.fromEntries(t.map(e=>[e.name,URL.createObjectURL(e)])):void 0}function F(e){let t=e.match(/(?:^|\n\n)(?:Angehängt|Attached): ([^\n]+)$/);return t?{text:e.slice(0,t.index).trim(),names:t[1].split(`, `).filter(Boolean)}:{text:e,names:[]}}function I(e,t){if(e.name&&e.name!==`image.png`)return e;let n=e.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`,r=new Date().toISOString().slice(0,19).replace(/[-:]/g,``).replace(`T`,`-`);return new File([e],`paste-${r}${t?`-${t+1}`:``}.${n}`,{type:e.type})}function L({url:e,label:t,children:n}){return(0,M.jsxs)(`div`,{className:`group relative`,title:t,children:[(0,M.jsx)(`img`,{src:e,alt:t,width:64,height:64,className:`size-16 rounded-lg bg-paper-2 object-cover ring-1 ring-border`}),n]})}function R({names:e,previews:t,fileUrl:n}){let r=e.filter(e=>t?.[e]||n&&N.test(e)),i=e.filter(e=>!r.includes(e));return(0,M.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5`,children:[r.map(e=>{let r=t?.[e]??n?.(e)??``;return(0,M.jsx)(`a`,{href:r,target:`_blank`,rel:`noreferrer`,title:e,children:(0,M.jsx)(`img`,{src:r,alt:e,className:`max-h-60 w-auto max-w-full rounded-xl bg-paper-2 object-contain ring-1 ring-border`})},e)}),i.length?(0,M.jsx)(`div`,{className:`flex flex-wrap justify-end gap-1.5`,children:i.map(e=>(0,M.jsxs)(`span`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 px-2.5 py-1 text-[0.75rem] text-ink-2`,children:[(0,M.jsx)(f,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e})]},e))}):null]})}function z(e,t){let n=s(),[i,o]=(0,E.useState)([]),[c,l]=(0,E.useState)(`idle`),[u,d]=(0,E.useState)(null),[f,p]=(0,E.useState)(null),[m,h]=(0,E.useState)(null),[g,_]=(0,E.useState)(null),v=(0,E.useRef)(null);return(0,E.useEffect)(()=>{if(e){if(v.current!==e.id){v.current=e.id,o(e.messages);return}c===`idle`&&o(t=>e.messages.length>=t.length?e.messages:t)}},[e,c]),{messages:i,phase:c,activity:f,thought:m,startedAt:g,error:u,send:async(i,s=[])=>{if(!e||!(i.trim()||s.length)||c!==`idle`)return!1;if(d(null),_(Date.now()),h(null),s.length){l(`thinking`);try{for(let t of s){let n=await fetch(r(`/api/studio/wizards/${e.id}/files/${encodeURIComponent(t.name)}`),{method:`PUT`,credentials:`include`,headers:{"content-type":t.type||`application/octet-stream`},body:t});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??n.statusText)}}}catch(t){return d(t.message),l(`idle`),_(null),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),!1}let t=`${x(`editor.attached`)}: ${s.map(e=>e.name).join(`, `)}`;i=i.trim()?`${i}\n\n${t}`:t}let u=`p-${Date.now()}`;o(e=>[...e,{id:`u-${Date.now()}`,role:`user`,content:i,previews:P(s)},{id:u,role:`assistant`,content:``,pending:!0}]),l(`thinking`),p(null);let f=!1;try{await a(`/api/studio/wizards/${e.id}/chat`,{message:i},(e,n)=>{if(e===`text`){let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:t.content+e}:t))}else if(e===`activity`)p(JSON.parse(n));else if(e===`thought`)h(JSON.parse(n));else if(e===`building`)l(`building`);else if(e===`done`){f=!0;let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:e.reply,changed:e.changed,pending:!1}:t)),e.changed&&t(e.draft,e.revision)}else e===`error`&&(f=!0,d(JSON.parse(n).message))}),f||d(x(`editor.chatBroken`))}catch(e){d(e.message)}finally{p(null),h(null),_(null),o(e=>e.filter(e=>!(e.id===u&&!e.content)).map(e=>({...e,pending:!1}))),l(`idle`),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),await n.invalidateQueries({queryKey:[`me`]})}return!0},fileUrl:t=>r(`/api/studio/wizards/${e?.id}/files/${encodeURIComponent(t)}`)}}function B(e){let[t,n]=(0,E.useState)(()=>Date.now());return(0,E.useEffect)(()=>{if(e===null)return;n(Date.now());let t=setInterval(()=>n(Date.now()),1e3);return()=>clearInterval(t)},[e]),e===null?null:Math.max(0,Math.floor((t-e)/1e3))}function V(e){return e<60?`${e} s`:`${Math.floor(e/60)}:${String(e%60).padStart(2,`0`)} min`}function H({chat:e,thought:t,className:n,spinner:r=`size-3.5`}){let i=B(e.startedAt);return(0,M.jsxs)(`div`,{className:y(`min-w-0`,n),children:[(0,M.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,M.jsx)(v,{className:y(`shrink-0`,r)}),(0,M.jsx)(`span`,{className:`min-w-0 truncate`,children:e.activity??(e.phase===`building`?x(`editor.building`):x(`editor.thinking`))}),i===null?null:(0,M.jsx)(`span`,{className:`shrink-0 text-ink-4 tabular-nums`,children:V(i)})]}),t&&e.thought?(0,M.jsx)(`p`,{className:`mt-0.5 truncate pl-5.5 text-[0.75rem] text-ink-4`,children:e.thought}):null]})}function U({message:e,fileUrl:t}){let{text:n,names:r}=F(e.content);return(0,M.jsxs)(`div`,{className:`ml-8 flex flex-col items-end gap-1.5 self-end`,children:[r.length?(0,M.jsx)(R,{names:r,previews:e.previews,fileUrl:t}):null,n?(0,M.jsx)(`div`,{className:`rounded-xl rounded-br-md bg-paper-2 px-4 py-2.5 text-[0.875rem] leading-relaxed`,children:(0,M.jsx)(`span`,{className:`whitespace-pre-wrap`,children:n})}):null]})}function W({chat:e,avatar:t,hello:n=x(`editor.chatHello`),placeholder:r=x(`editor.composer`),changedLabel:a=`Ablauf aktualisiert`,compact:o,intro:s,closed:c,card:_}){let[w,D]=(0,E.useState)(!1),[O,k]=(0,E.useState)(``),[A,N]=(0,E.useState)([]),P=(0,E.useRef)(null),F=(0,E.useRef)(null),R=(0,E.useRef)(null),z=j(O,k);(0,E.useEffect)(()=>{P.current?.scrollTo({top:P.current.scrollHeight,behavior:`smooth`})},[e.messages,e.phase]),(0,E.useEffect)(()=>{let e=F.current;if(!e)return;let t=()=>{e.style.height=`auto`,e.style.height=O?`${Math.min(e.scrollHeight,200)}px`:``};t();let n=e.clientWidth,r=new ResizeObserver(()=>{e.clientWidth!==n&&(n=e.clientWidth,t())});return r.observe(e),()=>r.disconnect()},[O]);let B=(O.trim()||A.length>0)&&e.phase===`idle`,V=e=>N(t=>[...t.filter(t=>!e.some(e=>e.name===t.name)),...e]),[W,G]=(0,E.useState)(new Map);(0,E.useEffect)(()=>{let e=new Map(A.filter(e=>e.type.startsWith(`image/`)).map(e=>[e,URL.createObjectURL(e)]));return G(e),()=>{for(let t of e.values())URL.revokeObjectURL(t)}},[A]);let K=async()=>{if(!B)return;z.listening&&z.toggle();let t={text:O,files:A};k(``),N([]),await e.send(t.text.trim(),t.files)||(k(t.text),N(t.files))},q=!o||w,J=e.messages.at(-1);return(0,M.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[o&&(J||e.error)?(0,M.jsxs)(`button`,{type:`button`,"aria-expanded":w,"aria-label":x(`editor.thread`),onClick:()=>D(e=>!e),className:`flex items-center gap-2 px-4 pt-2.5 pb-0.5 text-left text-[0.8125rem] text-ink-3 transition hover:text-ink`,children:[!(e.error||w)&&J?.pending?(0,M.jsx)(H,{chat:e,className:`flex-1`}):(0,M.jsx)(`span`,{className:y(`min-w-0 flex-1 truncate`,e.error&&`text-rose`),children:e.error??(w?x(`editor.thread`):J?.content)}),w?(0,M.jsx)(m,{className:`size-4 shrink-0`}):(0,M.jsx)(T,{className:`size-4 shrink-0`})]}):null,(0,M.jsxs)(`div`,{ref:P,className:y(`min-h-0 flex-1 overflow-y-auto px-5 py-5`,!q&&`hidden`),children:[e.messages.length===0&&!c?s??(0,M.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,M.jsx)(i,{kind:t,size:32,interactive:!1}),(0,M.jsx)(`p`,{className:`pt-1 text-[0.875rem] text-ink-2 leading-relaxed`,children:n})]}):null,(0,M.jsx)(`div`,{className:`flex flex-col gap-4`,children:e.messages.map(n=>n.role===`user`?(0,M.jsx)(U,{message:n,fileUrl:e.fileUrl},n.id):(0,M.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,M.jsx)(`div`,{className:`shrink-0`,children:(0,M.jsx)(i,{kind:t,size:28,interactive:!1})}),(0,M.jsxs)(`div`,{className:`min-w-0 pt-0.5 text-[0.875rem]`,children:[n.source===`mcp`?(0,M.jsxs)(`div`,{className:`mb-1 inline-flex items-center gap-1.5 text-[0.75rem] text-ink-3`,children:[(0,M.jsx)(S,{className:`size-3`}),` `,x(`editor.viaClient`,{client:n.client??`MCP`})]}):null,n.content?(0,M.jsx)(u,{text:n.content,className:`text-[0.875rem]`}):null,_&&n.cards?.length?(0,M.jsx)(`div`,{className:`mt-2 flex flex-col gap-2`,children:n.cards.map(e=>(0,M.jsx)(E.Fragment,{children:_(e)},e.id))}):null,n.pending?(0,M.jsx)(H,{chat:e,thought:!0,className:`mt-1 text-[0.8125rem] text-ink-3`}):null,n.changed?(0,M.jsxs)(`div`,{className:`mt-2 inline-flex items-center gap-1.5 rounded-full bg-ember-tint px-2.5 py-0.5 text-[0.75rem] text-ember-strong`,children:[(0,M.jsx)(p,{className:`size-3`}),` `,a]}):null]})]},n.id))}),e.error?(0,M.jsx)(`div`,{className:`mt-4 rounded-lg bg-rose-tint px-3 py-2 text-[0.8125rem] text-rose`,children:e.error}):null]}),c?(0,M.jsx)(`p`,{className:`m-3 rounded-xl bg-paper-2 px-4 py-3 text-[0.8125rem] text-ink-2 leading-relaxed`,children:c}):(0,M.jsxs)(`div`,{className:o?`p-2`:`p-3`,children:[(0,M.jsxs)(`div`,{className:`rounded-xl bg-card p-1.5 shadow-soft ring-1 ring-border focus-within:ring-focus`,children:[W.size?(0,M.jsx)(`div`,{className:`flex flex-wrap gap-2 px-1 pt-1 pb-1.5`,children:A.map((e,t)=>{let n=W.get(e);return n?(0,M.jsx)(L,{url:n,label:e.name,children:(0,M.jsx)(`button`,{type:`button`,"aria-label":x(`editor.detach`),onClick:()=>N(e=>e.filter((e,n)=>n!==t)),className:`-top-1.5 -right-1.5 absolute flex size-5 items-center justify-center rounded-full bg-ink text-paper opacity-0 shadow-soft transition focus-visible:opacity-100 group-hover:opacity-100`,children:(0,M.jsx)(C,{className:`size-3`})})},`${e.name}-${t}`):null})}):null,A.some(e=>!W.has(e))?(0,M.jsx)(`ul`,{className:`flex flex-wrap gap-1.5 px-1 pt-1 pb-1.5`,children:A.map((e,t)=>W.has(e)?null:(0,M.jsxs)(`li`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 py-1 pr-1 pl-2.5 text-[0.75rem] text-ink-2`,children:[(0,M.jsx)(f,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e.name}),(0,M.jsx)(`button`,{type:`button`,"aria-label":x(`editor.detach`),onClick:()=>N(e=>e.filter((e,n)=>n!==t)),className:`inline-flex size-5 shrink-0 items-center justify-center rounded-full text-ink-3 hover:bg-paper-3 hover:text-ink`,children:(0,M.jsx)(C,{className:`size-3`})})]},`${e.name}-${t}`))}):null,(0,M.jsxs)(`div`,{className:`flex items-end gap-1`,children:[(0,M.jsx)(b,{label:x(`editor.attach`),onClick:()=>R.current?.click(),children:(0,M.jsx)(h,{className:`size-4`})}),(0,M.jsx)(`input`,{ref:R,type:`file`,multiple:!0,hidden:!0,onChange:e=>{let t=Array.from(e.target.files??[]);e.target.value=``,V(t)}}),(0,M.jsx)(`textarea`,{ref:F,rows:1,value:O,onChange:e=>k(e.target.value),onPaste:e=>{let t=Array.from(e.clipboardData.files);t.length&&(e.preventDefault(),V(t.map(I)))},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),K())},placeholder:z.listening?x(`editor.listening`):r,className:`max-h-[200px] min-h-[40px] flex-1 resize-none bg-transparent px-1.5 py-2 text-[0.875rem] outline-none placeholder:truncate placeholder:text-ink-4`}),z.supported?(0,M.jsx)(b,{label:z.processing?x(`editor.transcribing`):z.listening?x(`editor.voiceStop`):x(`editor.voice`),"aria-pressed":z.listening,disabled:z.processing,onClick:z.toggle,className:y(z.listening&&`bg-rose-tint text-rose hover:bg-rose-tint hover:text-rose`),children:z.processing?(0,M.jsx)(v,{className:`size-4`}):z.listening?(0,M.jsx)(d,{className:`size-3.5 animate-pulse-dot fill-current`}):(0,M.jsx)(g,{className:`size-4`})}):null,(0,M.jsx)(`button`,{type:`button`,onClick:()=>void K(),disabled:!B,className:y(`inline-flex size-9 shrink-0 items-center justify-center rounded-full transition`,B?`bg-primary text-primary-foreground`:`bg-paper-2 text-ink-4`),"aria-label":`Send`,children:(0,M.jsx)(l,{className:`size-4`})})]})]}),z.error?(0,M.jsx)(`p`,{className:`mt-2 px-1 text-[0.75rem] text-rose`,children:z.error===`denied`?x(`editor.micDenied`):z.error}):null]})]})}export{z as i,H as n,P as r,W as t};
@@ -1 +0,0 @@
1
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{t as r}from"./preload-helper-CNEI7N0N.js";import{t as i}from"./external-link-MAL7vJYj.js";import{_ as a,a as o,d as s,i as c,s as l,y as u}from"./ui-HV_XbHjw.js";var d=e(t(),1),f=[{name:`engenty wizards`,description:{de:`KI-Wizards aus einer Beschreibung, mit einem Link geteilt.`,en:`AI wizards built from a description, shared with a link.`},homepage:`https://github.com/engenty/engenty-wizards`,license:`FSL-1.1-MIT`},{name:`engenty`,description:{de:`Konnektoren, Datentabellen, Suche und die Engenties stammen aus dem engenty-Framework.`,en:`Connectors, data tables, search and the engenties come from the engenty framework.`},homepage:`https://github.com/engenty/engenty`,license:`FSL-1.1-MIT`}],p=[{name:`Mastra`,description:{de:`Agent-Framework hinter den KI-Schritten.`,en:`Agent framework behind the AI steps.`},homepage:`https://github.com/mastra-ai/mastra`,license:`Apache-2.0`},{name:`AI SDK`,description:{de:`Modell-Aufrufe für Text, Bild, Video und Sprache.`,en:`Model calls for text, image, video and speech.`},homepage:`https://github.com/vercel/ai`,license:`Apache-2.0`},{name:`Model Context Protocol`,description:{de:`MCP-Server zum Bauen von Wizards, MCP-Client für Werkzeuge der Schritte.`,en:`MCP server for building wizards, MCP client for the steps' tools.`},homepage:`https://github.com/modelcontextprotocol/typescript-sdk`,license:`MIT`},{name:`Hono`,description:{de:`HTTP-API der Runtime.`,en:`The runtime's HTTP API.`},homepage:`https://github.com/honojs/hono`,license:`MIT`},{name:`Drizzle ORM`,description:{de:`Schema und Migrationen der Datenbanken.`,en:`Schema and migrations of the databases.`},homepage:`https://github.com/drizzle-team/drizzle-orm`,license:`Apache-2.0`},{name:`libSQL`,description:{de:`Eine Datenbank je Mandant, lokal als Datei oder bei Turso.`,en:`One database per tenant, a local file or at Turso.`},homepage:`https://github.com/tursodatabase/libsql`,license:`MIT`},{name:`Playwright`,description:{de:`Browser-Schritte sowie PDF- und PNG-Export.`,en:`Browser steps and the PDF and PNG export.`},homepage:`https://github.com/microsoft/playwright`,license:`Apache-2.0`},{name:`agentOS`,description:{de:`Sandbox für Code-Schritte ohne Docker.`,en:`Sandbox for code steps without Docker.`},homepage:`https://github.com/rivet-dev/agentos`,license:`Apache-2.0`},{name:`React`,description:{de:`UI-Bibliothek der Web-App.`,en:`UI library of the web app.`},homepage:`https://github.com/facebook/react`,license:`MIT`},{name:`Vite`,description:{de:`Build-Werkzeug der Web-App.`,en:`Build tool of the web app.`},homepage:`https://github.com/vitejs/vite`,license:`MIT`},{name:`Tailwind CSS`,description:{de:`Styling der Oberfläche.`,en:`Styling of the interface.`},homepage:`https://github.com/tailwindlabs/tailwindcss`,license:`MIT`},{name:`React Flow`,description:{de:`Das Diagramm der Schritte im Editor.`,en:`The diagram of steps in the editor.`},homepage:`https://github.com/xyflow/xyflow`,license:`MIT`},{name:`TanStack Query`,description:{de:`Server-Daten in der Web-App.`,en:`Server data in the web app.`},homepage:`https://github.com/TanStack/query`,license:`MIT`},{name:`xterm.js`,description:{de:`Das Terminal auf der Seite, in dem sich KI-Clients anmelden.`,en:`The terminal on the page where AI clients sign in.`},homepage:`https://github.com/xtermjs/xterm.js`,license:`MIT`},{name:`Lucide`,description:{de:`Icons.`,en:`Icons.`},homepage:`https://github.com/lucide-icons/lucide`,license:`ISC`},{name:`Geist & Geist Mono`,description:{de:`Schrift der Oberfläche.`,en:`Typeface of the interface.`},homepage:`https://github.com/vercel/geist-font`,license:`OFL-1.1`},{name:`Space Grotesk`,description:{de:`Schrift der Überschriften.`,en:`Typeface of the headings.`},homepage:`https://github.com/floriankarsten/space-grotesk`,license:`OFL-1.1`},{name:`git-cliff`,description:{de:`Erzeugt den Changelog aus den Commits.`,en:`Generates the changelog from the commits.`},homepage:`https://github.com/orhun/git-cliff`,license:`MIT OR Apache-2.0`}],m=e(n(),1),h=(e,...t)=>t.some(t=>t?.toLowerCase().includes(e));function g({name:e,homepage:t,version:n,license:r,description:a}){return(0,m.jsxs)(`li`,{className:`py-2.5`,children:[(0,m.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-2.5 gap-y-0.5`,children:[t?(0,m.jsxs)(`a`,{href:t,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 font-medium text-[0.875rem] text-ink underline-offset-4 hover:underline`,children:[e,(0,m.jsx)(i,{"aria-hidden":!0,className:`size-3 text-ink-4`})]}):(0,m.jsx)(`span`,{className:`font-medium text-[0.875rem] text-ink`,children:e}),n?(0,m.jsx)(`span`,{className:`text-[0.75rem] text-ink-3 tabular-nums`,children:n}):null,(0,m.jsx)(`span`,{className:`text-[0.75rem] text-ink-3`,children:r})]}),a?(0,m.jsx)(`p`,{className:`mt-0.5 text-[0.8125rem] text-ink-3`,children:a}):null]})}function _({title:e,hint:t,children:n}){return(0,m.jsxs)(`section`,{className:`mt-6`,children:[(0,m.jsx)(`h3`,{className:`border-border-soft border-b pb-2 font-display font-semibold text-[1rem]`,children:e}),t?(0,m.jsx)(`p`,{className:`mt-2 text-[0.8125rem] text-ink-3`,children:t}):null,n]})}function v({credits:e}){return(0,m.jsx)(`ul`,{className:`divide-y divide-border-soft`,children:e.map(e=>(0,m.jsx)(g,{name:e.name,homepage:e.homepage,license:e.license,description:e.description[a]},e.name))})}function y({label:e,packages:t}){return(0,m.jsxs)(`div`,{className:`mt-4`,children:[(0,m.jsx)(`h4`,{className:`font-medium text-[0.75rem] text-ink-3 tracking-wide`,children:e}),(0,m.jsx)(`ul`,{className:`divide-y divide-border-soft`,children:t.map(e=>(0,m.jsx)(g,{...e},e.name))})]})}function b({open:e,onClose:t}){let[n,i]=(0,d.useState)(null),[a,g]=(0,d.useState)(``);(0,d.useEffect)(()=>{if(!e||n)return;let t=!1;return r(()=>import(`./oss-credits-CIxnNZor.js`).then(e=>{t||i(e.default)}),[]),()=>{t=!0}},[e,n]),(0,d.useEffect)(()=>{e||g(``)},[e]);let b=a.trim().toLowerCase(),x=e=>b?e.filter(e=>h(b,e.name,e.license,e.description.de,e.description.en)):e,S=e=>b?e.filter(e=>h(b,e.name,e.license,e.version)):e,C=x(f),w=x(p),T=n?[{id:`shared`,label:u(`about.creditsShared`),packages:S(n.shared)},...n.groups.map(e=>({id:e.id,label:e.label,packages:S(e.packages)}))].filter(e=>e.packages.length>0):[],E=C.length===0&&w.length===0&&T.length===0;return(0,m.jsxs)(c,{open:e,onClose:t,title:u(`about.credits`),wide:!0,children:[(0,m.jsx)(`p`,{className:`-mt-3 mb-4 text-[0.875rem] text-ink-3`,children:u(`about.creditsHint`)}),(0,m.jsx)(l,{type:`search`,value:a,placeholder:u(`about.search`),onChange:e=>g(e.target.value)}),C.length>0?(0,m.jsx)(_,{title:u(`about.creditsProduct`),children:(0,m.jsx)(v,{credits:C})}):null,w.length>0?(0,m.jsx)(_,{title:u(`about.creditsBuiltWith`),children:(0,m.jsx)(v,{credits:w})}):null,n===null?(0,m.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,m.jsx)(s,{})}):T.length>0?(0,m.jsx)(_,{title:u(`about.creditsDeps`),hint:b?void 0:u(`about.creditsDepsHint`),children:T.map(e=>(0,m.jsx)(y,{label:e.label,packages:e.packages},e.id))}):null,n!==null&&E?(0,m.jsx)(o,{children:u(`about.noMatches`)}):null]})}export{b as CreditsDialog};