@meissa_a/meissa 0.1.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.
Files changed (65) hide show
  1. package/README.md +350 -0
  2. package/dist/apps/app-generator.d.ts +30 -0
  3. package/dist/apps/index.d.ts +25 -0
  4. package/dist/apps/postmessage.d.ts +24 -0
  5. package/dist/apps/template.d.ts +10 -0
  6. package/dist/apps/types.d.ts +107 -0
  7. package/dist/apps.cjs +687 -0
  8. package/dist/apps.js +645 -0
  9. package/dist/client/component.d.ts +17 -0
  10. package/dist/client/content.d.ts +12 -0
  11. package/dist/client/index.d.ts +7 -0
  12. package/dist/client/patch.d.ts +6 -0
  13. package/dist/client/renderer.d.ts +43 -0
  14. package/dist/client/types.d.ts +52 -0
  15. package/dist/client.cjs +3558 -0
  16. package/dist/client.js +3524 -0
  17. package/dist/renderer/ComponentRenderer.d.ts +11 -0
  18. package/dist/renderer/MeissaRenderer.d.ts +8 -0
  19. package/dist/renderer/components/Alert.d.ts +2 -0
  20. package/dist/renderer/components/Badge.d.ts +2 -0
  21. package/dist/renderer/components/Btn.d.ts +2 -0
  22. package/dist/renderer/components/Card.d.ts +2 -0
  23. package/dist/renderer/components/Chart.d.ts +2 -0
  24. package/dist/renderer/components/Code.d.ts +2 -0
  25. package/dist/renderer/components/Col.d.ts +2 -0
  26. package/dist/renderer/components/Divider.d.ts +2 -0
  27. package/dist/renderer/components/Form.d.ts +2 -0
  28. package/dist/renderer/components/Grid.d.ts +2 -0
  29. package/dist/renderer/components/Heading.d.ts +2 -0
  30. package/dist/renderer/components/Img.d.ts +2 -0
  31. package/dist/renderer/components/Input.d.ts +2 -0
  32. package/dist/renderer/components/List.d.ts +2 -0
  33. package/dist/renderer/components/Progress.d.ts +2 -0
  34. package/dist/renderer/components/Row.d.ts +2 -0
  35. package/dist/renderer/components/Select.d.ts +2 -0
  36. package/dist/renderer/components/Split.d.ts +2 -0
  37. package/dist/renderer/components/Stat.d.ts +2 -0
  38. package/dist/renderer/components/Table.d.ts +2 -0
  39. package/dist/renderer/components/Tabs.d.ts +2 -0
  40. package/dist/renderer/components/Text.d.ts +2 -0
  41. package/dist/renderer/components/index.d.ts +2 -0
  42. package/dist/renderer/context/ActionContext.d.ts +3 -0
  43. package/dist/renderer/context/DataContext.d.ts +3 -0
  44. package/dist/renderer/context/FormContext.d.ts +10 -0
  45. package/dist/renderer/core/binder.d.ts +17 -0
  46. package/dist/renderer/core/evaluator.d.ts +13 -0
  47. package/dist/renderer/core/iterator.d.ts +10 -0
  48. package/dist/renderer/core/normalizer.d.ts +5 -0
  49. package/dist/renderer/core/parser.d.ts +8 -0
  50. package/dist/renderer/core/resolver.d.ts +6 -0
  51. package/dist/renderer/core/types.d.ts +68 -0
  52. package/dist/renderer/index.d.ts +7 -0
  53. package/dist/renderer/utils/cn.d.ts +2 -0
  54. package/dist/renderer/utils/filters.d.ts +8 -0
  55. package/dist/renderer/utils/sanitize.d.ts +9 -0
  56. package/dist/renderer.cjs +3273 -0
  57. package/dist/renderer.js +3239 -0
  58. package/dist/server/index.d.ts +4 -0
  59. package/dist/server/markdown.d.ts +9 -0
  60. package/dist/server/server.d.ts +39 -0
  61. package/dist/server/types.d.ts +56 -0
  62. package/dist/server/validator.d.ts +5 -0
  63. package/dist/server.cjs +345 -0
  64. package/dist/server.js +303 -0
  65. package/package.json +84 -0
@@ -0,0 +1,3558 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ function __accessProp(key) {
6
+ return this[key];
7
+ }
8
+ var __toCommonJS = (from) => {
9
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
10
+ if (entry)
11
+ return entry;
12
+ entry = __defProp({}, "__esModule", { value: true });
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (var key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(entry, key))
16
+ __defProp(entry, key, {
17
+ get: __accessProp.bind(from, key),
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
21
+ __moduleCache.set(from, entry);
22
+ return entry;
23
+ };
24
+ var __moduleCache;
25
+ var __returnValue = (v) => v;
26
+ function __exportSetter(name, newValue) {
27
+ this[name] = __returnValue.bind(null, newValue);
28
+ }
29
+ var __export = (target, all) => {
30
+ for (var name in all)
31
+ __defProp(target, name, {
32
+ get: all[name],
33
+ enumerable: true,
34
+ configurable: true,
35
+ set: __exportSetter.bind(all, name)
36
+ });
37
+ };
38
+
39
+ // src/client/index.ts
40
+ var exports_client = {};
41
+ __export(exports_client, {
42
+ handleMcpContent: () => handleMcpContent,
43
+ applyPatches: () => applyPatches,
44
+ MeissaContentWithRef: () => MeissaContentWithRef,
45
+ MeissaContent: () => MeissaContent,
46
+ MeissaClientRenderer: () => MeissaClientRenderer
47
+ });
48
+ module.exports = __toCommonJS(exports_client);
49
+
50
+ // src/client/renderer.ts
51
+ var import_react14 = require("react");
52
+ var import_client = require("react-dom/client");
53
+
54
+ // src/renderer/MeissaRenderer.tsx
55
+ var import_react13 = require("react");
56
+
57
+ // src/renderer/core/normalizer.ts
58
+ var PRIMARY_PROPS = {
59
+ text: "content",
60
+ heading: "content",
61
+ code: "content",
62
+ btn: "label",
63
+ badge: "content",
64
+ alert: "content",
65
+ img: "src",
66
+ progress: "value",
67
+ list: "items",
68
+ stat: "value",
69
+ input: "name",
70
+ select: "options",
71
+ table: "data",
72
+ chart: "data",
73
+ card: "title",
74
+ tabs: "items",
75
+ form: "submit"
76
+ };
77
+ var DEFAULTS = {
78
+ text: { variant: "default", bold: false, align: "left" },
79
+ heading: { level: 2, align: "left" },
80
+ btn: { variant: "primary", size: "md", disabled: false },
81
+ input: { type: "text", required: false, disabled: false },
82
+ table: { sortable: true },
83
+ chart: { type: "line", legend: true, h: 256 },
84
+ stat: { variant: "default" },
85
+ alert: { variant: "info", dismissible: false },
86
+ badge: { variant: "default" },
87
+ progress: { value: 0, indeterminate: false },
88
+ card: { variant: "default", padding: 4 },
89
+ row: { gap: 4, align: "center", wrap: true },
90
+ col: { gap: 4, align: "stretch" },
91
+ grid: { cols: 2, gap: 4 },
92
+ split: { ratio: "1:1", gap: 4 }
93
+ };
94
+ var CONTAINERS = new Set(["row", "col", "grid", "split", "card", "form", "fragment"]);
95
+ function normalize(input) {
96
+ if (Array.isArray(input)) {
97
+ return normalizeTuple(input);
98
+ }
99
+ if (typeof input === "object" && input !== null) {
100
+ return normalizeObject(input);
101
+ }
102
+ return { type: "text", content: `[Invalid node]` };
103
+ }
104
+ function normalizeTuple(tuple) {
105
+ const type = tuple[0];
106
+ if (!type || typeof type !== "string") {
107
+ return { type: "text", content: "[Invalid: missing type]" };
108
+ }
109
+ if (type === "switch") {
110
+ return normalizeSwitch(tuple);
111
+ }
112
+ if (type === "each") {
113
+ return normalizeEach(tuple);
114
+ }
115
+ if (type === "ref") {
116
+ return { type: "ref", name: tuple[1] };
117
+ }
118
+ const node = { type };
119
+ const second = tuple[1];
120
+ const third = tuple[2];
121
+ if (tuple.length === 1) {} else if (tuple.length === 2) {
122
+ assignSecond(node, type, second);
123
+ } else if (tuple.length >= 3) {
124
+ assignSecond(node, type, second);
125
+ if (Array.isArray(third)) {
126
+ node.children = normalizeChildren(third);
127
+ }
128
+ }
129
+ applyDefaults(node);
130
+ return node;
131
+ }
132
+ function assignSecond(node, type, second) {
133
+ if (second === null || second === undefined) {
134
+ const primaryProp = PRIMARY_PROPS[type];
135
+ if (primaryProp) {
136
+ node[primaryProp] = null;
137
+ }
138
+ } else if (typeof second === "string" || typeof second === "number" || typeof second === "boolean") {
139
+ const primaryProp = PRIMARY_PROPS[type];
140
+ if (primaryProp) {
141
+ node[primaryProp] = second;
142
+ }
143
+ } else if (Array.isArray(second)) {
144
+ if (second.length > 0 && Array.isArray(second[0])) {
145
+ node.children = normalizeChildren(second);
146
+ } else {
147
+ const primaryProp = PRIMARY_PROPS[type];
148
+ if (primaryProp) {
149
+ node[primaryProp] = second;
150
+ }
151
+ }
152
+ } else if (typeof second === "object") {
153
+ const obj = second;
154
+ if ("type" in obj && typeof obj.type === "string") {
155
+ Object.assign(node, obj);
156
+ node.type = type;
157
+ } else {
158
+ if (type === "tabs" && !("items" in obj)) {
159
+ const hasTabContent = Object.values(obj).some((v) => Array.isArray(v));
160
+ if (hasTabContent) {
161
+ node.items = obj;
162
+ return;
163
+ }
164
+ }
165
+ Object.assign(node, obj);
166
+ }
167
+ }
168
+ }
169
+ function normalizeSwitch(tuple) {
170
+ const binding = tuple[1];
171
+ const cases = tuple[2];
172
+ const normalizedCases = {};
173
+ if (cases && typeof cases === "object") {
174
+ for (const [key, value] of Object.entries(cases)) {
175
+ normalizedCases[key] = normalize(value);
176
+ }
177
+ }
178
+ return { type: "switch", binding, cases: normalizedCases };
179
+ }
180
+ function normalizeEach(tuple) {
181
+ const binding = tuple[1];
182
+ const template = tuple[2];
183
+ return {
184
+ type: "each",
185
+ binding,
186
+ template: normalize(template)
187
+ };
188
+ }
189
+ function normalizeChildren(arr) {
190
+ const result = [];
191
+ for (const item of arr) {
192
+ if (item === null || item === undefined)
193
+ continue;
194
+ result.push(normalize(item));
195
+ }
196
+ return result;
197
+ }
198
+ function normalizeObject(obj) {
199
+ const node = { type: obj.type };
200
+ for (const [key, value] of Object.entries(obj)) {
201
+ if (key === "children" && Array.isArray(value)) {
202
+ node.children = normalizeChildren(value);
203
+ } else {
204
+ node[key] = value;
205
+ }
206
+ }
207
+ applyDefaults(node);
208
+ return node;
209
+ }
210
+ function applyDefaults(node) {
211
+ const defaults = DEFAULTS[node.type];
212
+ if (!defaults)
213
+ return;
214
+ for (const [key, value] of Object.entries(defaults)) {
215
+ if (!(key in node)) {
216
+ node[key] = value;
217
+ }
218
+ }
219
+ }
220
+
221
+ // src/renderer/core/resolver.ts
222
+ function resolveRefs(nodes, defs) {
223
+ if (Object.keys(defs).length === 0)
224
+ return nodes;
225
+ return nodes.map((node) => resolveNode(node, defs));
226
+ }
227
+ function resolveNode(node, defs) {
228
+ if (node.type === "ref") {
229
+ const name = node.name;
230
+ const def = defs[name];
231
+ if (def) {
232
+ return structuredClone(def);
233
+ }
234
+ return { type: "text", content: `[Unknown ref: ${name}]` };
235
+ }
236
+ if (node.children) {
237
+ node.children = node.children.map((child) => resolveNode(child, defs));
238
+ }
239
+ if (node.type === "each" && node.template) {
240
+ node.template = resolveNode(node.template, defs);
241
+ }
242
+ if (node.type === "switch" && node.cases) {
243
+ const cases = node.cases;
244
+ for (const key of Object.keys(cases)) {
245
+ cases[key] = resolveNode(cases[key], defs);
246
+ }
247
+ }
248
+ return node;
249
+ }
250
+
251
+ // src/renderer/core/parser.ts
252
+ function parse(input) {
253
+ if (isDocument(input)) {
254
+ const doc = input;
255
+ const defs = normalizeDefs(doc.defs);
256
+ const nodes = normalizeArray(doc.ui);
257
+ const resolved = resolveRefs(nodes, defs);
258
+ return {
259
+ nodes: resolved,
260
+ defs,
261
+ data: doc.data ?? {},
262
+ theme: doc.theme
263
+ };
264
+ }
265
+ if (Array.isArray(input) && input.length > 0) {
266
+ if (typeof input[0] === "string" && !Array.isArray(input[1]?.constructor === Array ? input[1] : null)) {
267
+ if (input.length <= 3 && isComponentType(input[0])) {
268
+ const node = normalize(input);
269
+ return { nodes: [node], defs: {}, data: {} };
270
+ }
271
+ }
272
+ const nodes = normalizeArray(input);
273
+ return { nodes, defs: {}, data: {} };
274
+ }
275
+ if (typeof input === "object" && input !== null && "type" in input) {
276
+ const node = normalize(input);
277
+ return { nodes: [node], defs: {}, data: {} };
278
+ }
279
+ return { nodes: [], defs: {}, data: {} };
280
+ }
281
+ function isDocument(input) {
282
+ return typeof input === "object" && input !== null && !Array.isArray(input) && "ui" in input && Array.isArray(input.ui);
283
+ }
284
+ function isComponentType(value) {
285
+ const types = new Set([
286
+ "text",
287
+ "heading",
288
+ "code",
289
+ "img",
290
+ "btn",
291
+ "input",
292
+ "select",
293
+ "form",
294
+ "table",
295
+ "list",
296
+ "chart",
297
+ "stat",
298
+ "card",
299
+ "tabs",
300
+ "alert",
301
+ "badge",
302
+ "progress",
303
+ "divider",
304
+ "row",
305
+ "col",
306
+ "grid",
307
+ "split",
308
+ "each",
309
+ "switch",
310
+ "ref",
311
+ "fragment"
312
+ ]);
313
+ return types.has(value);
314
+ }
315
+ function normalizeArray(arr) {
316
+ const result = [];
317
+ for (const item of arr) {
318
+ if (item === null || item === undefined)
319
+ continue;
320
+ if (Array.isArray(item)) {
321
+ if (typeof item[0] === "string") {
322
+ result.push(normalize(item));
323
+ }
324
+ } else if (typeof item === "object" && "type" in item) {
325
+ result.push(normalize(item));
326
+ }
327
+ }
328
+ return result;
329
+ }
330
+ function normalizeDefs(defs) {
331
+ if (!defs)
332
+ return {};
333
+ const result = {};
334
+ for (const [name, def] of Object.entries(defs)) {
335
+ result[name] = normalize(def);
336
+ }
337
+ return result;
338
+ }
339
+
340
+ // src/renderer/context/DataContext.tsx
341
+ var import_react = require("react");
342
+ var DataContext = import_react.createContext({
343
+ data: {},
344
+ root: {}
345
+ });
346
+ var DataProvider = DataContext.Provider;
347
+ function useData() {
348
+ return import_react.useContext(DataContext);
349
+ }
350
+
351
+ // src/renderer/context/ActionContext.tsx
352
+ var import_react2 = require("react");
353
+ var noop = () => {};
354
+ var ActionContext = import_react2.createContext({
355
+ onAction: noop,
356
+ onNavigate: noop
357
+ });
358
+ var ActionProvider = ActionContext.Provider;
359
+ function useAction() {
360
+ return import_react2.useContext(ActionContext);
361
+ }
362
+
363
+ // src/renderer/ComponentRenderer.tsx
364
+ var import_react12 = require("react");
365
+
366
+ // src/renderer/utils/filters.ts
367
+ var filters = {
368
+ currency(value) {
369
+ const num = Number(value);
370
+ if (isNaN(num))
371
+ return value;
372
+ return new Intl.NumberFormat("en-US", {
373
+ style: "currency",
374
+ currency: "USD"
375
+ }).format(num);
376
+ },
377
+ percent(value) {
378
+ const num = Number(value);
379
+ if (isNaN(num))
380
+ return value;
381
+ const pct = num <= 1 && num >= 0 ? num * 100 : num;
382
+ return `${Math.round(pct)}%`;
383
+ },
384
+ number(value) {
385
+ const num = Number(value);
386
+ if (isNaN(num))
387
+ return value;
388
+ return new Intl.NumberFormat("en-US").format(num);
389
+ },
390
+ relative(value) {
391
+ if (!value)
392
+ return "";
393
+ const date = new Date(value);
394
+ if (isNaN(date.getTime()))
395
+ return String(value);
396
+ const now = Date.now();
397
+ const diff = now - date.getTime();
398
+ const seconds = Math.floor(diff / 1000);
399
+ const minutes = Math.floor(seconds / 60);
400
+ const hours = Math.floor(minutes / 60);
401
+ const days = Math.floor(hours / 24);
402
+ const months = Math.floor(days / 30);
403
+ const years = Math.floor(days / 365);
404
+ if (seconds < 60)
405
+ return "just now";
406
+ if (minutes < 60)
407
+ return `${minutes} minute${minutes > 1 ? "s" : ""} ago`;
408
+ if (hours < 24)
409
+ return `${hours} hour${hours > 1 ? "s" : ""} ago`;
410
+ if (days < 30)
411
+ return `${days} day${days > 1 ? "s" : ""} ago`;
412
+ if (months < 12)
413
+ return `${months} month${months > 1 ? "s" : ""} ago`;
414
+ return `${years} year${years > 1 ? "s" : ""} ago`;
415
+ },
416
+ date(value, format) {
417
+ if (!value)
418
+ return "";
419
+ const date = new Date(value);
420
+ if (isNaN(date.getTime()))
421
+ return String(value);
422
+ switch (format) {
423
+ case "short":
424
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
425
+ case "long":
426
+ return date.toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" });
427
+ case "iso":
428
+ return date.toISOString().split("T")[0];
429
+ case "time":
430
+ return date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
431
+ case "datetime":
432
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) + " " + date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
433
+ default:
434
+ return date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
435
+ }
436
+ },
437
+ uppercase(value) {
438
+ return typeof value === "string" ? value.toUpperCase() : value;
439
+ },
440
+ lowercase(value) {
441
+ return typeof value === "string" ? value.toLowerCase() : value;
442
+ },
443
+ truncate(value, arg) {
444
+ if (typeof value !== "string")
445
+ return value;
446
+ const max = parseInt(arg || "50", 10);
447
+ if (value.length <= max)
448
+ return value;
449
+ return value.slice(0, max) + "...";
450
+ },
451
+ default(value, arg) {
452
+ if (value === null || value === undefined || value === "") {
453
+ if (arg && arg.startsWith('"') && arg.endsWith('"')) {
454
+ return arg.slice(1, -1);
455
+ }
456
+ if (arg && /^-?\d+(\.\d+)?$/.test(arg)) {
457
+ return Number(arg);
458
+ }
459
+ return arg ?? "";
460
+ }
461
+ return value;
462
+ }
463
+ };
464
+ function applyFilter(filterExpr, value) {
465
+ const colonIdx = filterExpr.indexOf(":");
466
+ const name = colonIdx >= 0 ? filterExpr.slice(0, colonIdx) : filterExpr;
467
+ const arg = colonIdx >= 0 ? filterExpr.slice(colonIdx + 1) : undefined;
468
+ const fn = filters[name];
469
+ if (!fn)
470
+ return value;
471
+ return fn(value, arg);
472
+ }
473
+
474
+ // src/renderer/core/binder.ts
475
+ function resolveBindings(template, data) {
476
+ if (typeof template !== "string")
477
+ return template;
478
+ if (!template.includes("{{"))
479
+ return template;
480
+ const exactMatch = template.match(/^\{\{(.+?)\}\}$/);
481
+ if (exactMatch) {
482
+ return resolveExpression(exactMatch[1], data);
483
+ }
484
+ return template.replace(/\{\{(.+?)\}\}/g, (_, expr) => {
485
+ const result = resolveExpression(expr, data);
486
+ return result == null ? "" : String(result);
487
+ });
488
+ }
489
+ function resolveExpression(expr, data) {
490
+ const parts = expr.split("|").map((s) => s.trim());
491
+ const path = parts[0];
492
+ const filters2 = parts.slice(1);
493
+ if (hasComparison(path)) {
494
+ return evaluateComparison(path, data);
495
+ }
496
+ let value = resolvePath(path, data);
497
+ for (const filter of filters2) {
498
+ value = applyFilter(filter, value);
499
+ }
500
+ return value;
501
+ }
502
+ function resolvePath(path, data) {
503
+ if (!path)
504
+ return;
505
+ if (path.startsWith("!")) {
506
+ const value = resolvePath(path.slice(1), data);
507
+ return !isTruthy(value);
508
+ }
509
+ const segments = parsePath(path);
510
+ let current = data;
511
+ for (const segment of segments) {
512
+ if (current === null || current === undefined)
513
+ return;
514
+ if (typeof current === "object") {
515
+ current = current[segment];
516
+ } else {
517
+ return;
518
+ }
519
+ }
520
+ return current;
521
+ }
522
+ function parsePath(path) {
523
+ const segments = [];
524
+ let current = "";
525
+ for (let i = 0;i < path.length; i++) {
526
+ const char = path[i];
527
+ if (char === ".") {
528
+ if (current)
529
+ segments.push(current);
530
+ current = "";
531
+ } else if (char === "[") {
532
+ if (current)
533
+ segments.push(current);
534
+ current = "";
535
+ } else if (char === "]") {
536
+ if (current)
537
+ segments.push(current);
538
+ current = "";
539
+ } else {
540
+ current += char;
541
+ }
542
+ }
543
+ if (current)
544
+ segments.push(current);
545
+ return segments;
546
+ }
547
+ function hasComparison(expr) {
548
+ return /\s*(==|!=|<=|>=|<|>)\s*/.test(expr);
549
+ }
550
+ function evaluateComparison(expr, data) {
551
+ const match = expr.match(/^(.+?)\s*(==|!=|<=|>=|<|>)\s*(.+)$/);
552
+ if (!match)
553
+ return false;
554
+ const [, leftExpr, op, rightExpr] = match;
555
+ const left = resolveOperand(leftExpr.trim(), data);
556
+ const right = resolveOperand(rightExpr.trim(), data);
557
+ switch (op) {
558
+ case "==":
559
+ return left == right;
560
+ case "!=":
561
+ return left != right;
562
+ case "<":
563
+ return Number(left) < Number(right);
564
+ case ">":
565
+ return Number(left) > Number(right);
566
+ case "<=":
567
+ return Number(left) <= Number(right);
568
+ case ">=":
569
+ return Number(left) >= Number(right);
570
+ default:
571
+ return false;
572
+ }
573
+ }
574
+ function resolveOperand(expr, data) {
575
+ if (expr.startsWith("'") && expr.endsWith("'") || expr.startsWith('"') && expr.endsWith('"')) {
576
+ return expr.slice(1, -1);
577
+ }
578
+ if (/^-?\d+(\.\d+)?$/.test(expr)) {
579
+ return Number(expr);
580
+ }
581
+ if (expr === "true")
582
+ return true;
583
+ if (expr === "false")
584
+ return false;
585
+ if (expr === "null")
586
+ return null;
587
+ return resolvePath(expr, data);
588
+ }
589
+ function isTruthy(value) {
590
+ if (value === null || value === undefined)
591
+ return false;
592
+ if (value === false)
593
+ return false;
594
+ if (value === 0)
595
+ return false;
596
+ if (value === "")
597
+ return false;
598
+ if (Array.isArray(value) && value.length === 0)
599
+ return false;
600
+ return true;
601
+ }
602
+
603
+ // src/renderer/core/evaluator.ts
604
+ function evaluate(node, data) {
605
+ if (node.type === "switch") {
606
+ return evaluateSwitch(node, data);
607
+ }
608
+ if (node.if !== undefined) {
609
+ const value = resolveBindings(node.if, data);
610
+ const negated = typeof node.if === "string" && node.if.startsWith("!{{");
611
+ const truthy = negated ? value : isTruthy(value);
612
+ if (!truthy) {
613
+ return { node: null, hidden: false };
614
+ }
615
+ }
616
+ let hidden = false;
617
+ if (node.show !== undefined) {
618
+ const value = resolveBindings(node.show, data);
619
+ if (!isTruthy(value)) {
620
+ hidden = true;
621
+ }
622
+ }
623
+ return { node, hidden };
624
+ }
625
+ function evaluateSwitch(node, data) {
626
+ const binding = node.binding;
627
+ const cases = node.cases;
628
+ if (!binding || !cases) {
629
+ return { node: null, hidden: false };
630
+ }
631
+ const value = resolveBindings(binding, data);
632
+ const key = String(value);
633
+ if (key in cases) {
634
+ return { node: cases[key], hidden: false };
635
+ }
636
+ if ("_" in cases) {
637
+ return { node: cases["_"], hidden: false };
638
+ }
639
+ return { node: null, hidden: false };
640
+ }
641
+
642
+ // src/renderer/core/iterator.ts
643
+ function expandEach(node, data) {
644
+ const binding = node.binding;
645
+ const template = node.template;
646
+ if (!binding || !template)
647
+ return [];
648
+ const items = resolveBindings(binding, data);
649
+ if (!Array.isArray(items))
650
+ return [];
651
+ return items.map((item, index) => ({
652
+ node: template,
653
+ data: {
654
+ ...data,
655
+ $: item,
656
+ $i: index,
657
+ $first: index === 0,
658
+ $last: index === items.length - 1
659
+ }
660
+ }));
661
+ }
662
+
663
+ // ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
664
+ function r(e) {
665
+ var t, f, n = "";
666
+ if (typeof e == "string" || typeof e == "number")
667
+ n += e;
668
+ else if (typeof e == "object")
669
+ if (Array.isArray(e)) {
670
+ var o = e.length;
671
+ for (t = 0;t < o; t++)
672
+ e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
673
+ } else
674
+ for (f in e)
675
+ e[f] && (n && (n += " "), n += f);
676
+ return n;
677
+ }
678
+ function clsx() {
679
+ for (var e, t, f = 0, n = "", o = arguments.length;f < o; f++)
680
+ (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
681
+ return n;
682
+ }
683
+
684
+ // ../../node_modules/.bun/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
685
+ var CLASS_PART_SEPARATOR = "-";
686
+ var createClassGroupUtils = (config) => {
687
+ const classMap = createClassMap(config);
688
+ const {
689
+ conflictingClassGroups,
690
+ conflictingClassGroupModifiers
691
+ } = config;
692
+ const getClassGroupId = (className) => {
693
+ const classParts = className.split(CLASS_PART_SEPARATOR);
694
+ if (classParts[0] === "" && classParts.length !== 1) {
695
+ classParts.shift();
696
+ }
697
+ return getGroupRecursive(classParts, classMap) || getGroupIdForArbitraryProperty(className);
698
+ };
699
+ const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
700
+ const conflicts = conflictingClassGroups[classGroupId] || [];
701
+ if (hasPostfixModifier && conflictingClassGroupModifiers[classGroupId]) {
702
+ return [...conflicts, ...conflictingClassGroupModifiers[classGroupId]];
703
+ }
704
+ return conflicts;
705
+ };
706
+ return {
707
+ getClassGroupId,
708
+ getConflictingClassGroupIds
709
+ };
710
+ };
711
+ var getGroupRecursive = (classParts, classPartObject) => {
712
+ if (classParts.length === 0) {
713
+ return classPartObject.classGroupId;
714
+ }
715
+ const currentClassPart = classParts[0];
716
+ const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
717
+ const classGroupFromNextClassPart = nextClassPartObject ? getGroupRecursive(classParts.slice(1), nextClassPartObject) : undefined;
718
+ if (classGroupFromNextClassPart) {
719
+ return classGroupFromNextClassPart;
720
+ }
721
+ if (classPartObject.validators.length === 0) {
722
+ return;
723
+ }
724
+ const classRest = classParts.join(CLASS_PART_SEPARATOR);
725
+ return classPartObject.validators.find(({
726
+ validator
727
+ }) => validator(classRest))?.classGroupId;
728
+ };
729
+ var arbitraryPropertyRegex = /^\[(.+)\]$/;
730
+ var getGroupIdForArbitraryProperty = (className) => {
731
+ if (arbitraryPropertyRegex.test(className)) {
732
+ const arbitraryPropertyClassName = arbitraryPropertyRegex.exec(className)[1];
733
+ const property = arbitraryPropertyClassName?.substring(0, arbitraryPropertyClassName.indexOf(":"));
734
+ if (property) {
735
+ return "arbitrary.." + property;
736
+ }
737
+ }
738
+ };
739
+ var createClassMap = (config) => {
740
+ const {
741
+ theme,
742
+ prefix
743
+ } = config;
744
+ const classMap = {
745
+ nextPart: new Map,
746
+ validators: []
747
+ };
748
+ const prefixedClassGroupEntries = getPrefixedClassGroupEntries(Object.entries(config.classGroups), prefix);
749
+ prefixedClassGroupEntries.forEach(([classGroupId, classGroup]) => {
750
+ processClassesRecursively(classGroup, classMap, classGroupId, theme);
751
+ });
752
+ return classMap;
753
+ };
754
+ var processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
755
+ classGroup.forEach((classDefinition) => {
756
+ if (typeof classDefinition === "string") {
757
+ const classPartObjectToEdit = classDefinition === "" ? classPartObject : getPart(classPartObject, classDefinition);
758
+ classPartObjectToEdit.classGroupId = classGroupId;
759
+ return;
760
+ }
761
+ if (typeof classDefinition === "function") {
762
+ if (isThemeGetter(classDefinition)) {
763
+ processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
764
+ return;
765
+ }
766
+ classPartObject.validators.push({
767
+ validator: classDefinition,
768
+ classGroupId
769
+ });
770
+ return;
771
+ }
772
+ Object.entries(classDefinition).forEach(([key, classGroup2]) => {
773
+ processClassesRecursively(classGroup2, getPart(classPartObject, key), classGroupId, theme);
774
+ });
775
+ });
776
+ };
777
+ var getPart = (classPartObject, path) => {
778
+ let currentClassPartObject = classPartObject;
779
+ path.split(CLASS_PART_SEPARATOR).forEach((pathPart) => {
780
+ if (!currentClassPartObject.nextPart.has(pathPart)) {
781
+ currentClassPartObject.nextPart.set(pathPart, {
782
+ nextPart: new Map,
783
+ validators: []
784
+ });
785
+ }
786
+ currentClassPartObject = currentClassPartObject.nextPart.get(pathPart);
787
+ });
788
+ return currentClassPartObject;
789
+ };
790
+ var isThemeGetter = (func) => func.isThemeGetter;
791
+ var getPrefixedClassGroupEntries = (classGroupEntries, prefix) => {
792
+ if (!prefix) {
793
+ return classGroupEntries;
794
+ }
795
+ return classGroupEntries.map(([classGroupId, classGroup]) => {
796
+ const prefixedClassGroup = classGroup.map((classDefinition) => {
797
+ if (typeof classDefinition === "string") {
798
+ return prefix + classDefinition;
799
+ }
800
+ if (typeof classDefinition === "object") {
801
+ return Object.fromEntries(Object.entries(classDefinition).map(([key, value]) => [prefix + key, value]));
802
+ }
803
+ return classDefinition;
804
+ });
805
+ return [classGroupId, prefixedClassGroup];
806
+ });
807
+ };
808
+ var createLruCache = (maxCacheSize) => {
809
+ if (maxCacheSize < 1) {
810
+ return {
811
+ get: () => {
812
+ return;
813
+ },
814
+ set: () => {}
815
+ };
816
+ }
817
+ let cacheSize = 0;
818
+ let cache = new Map;
819
+ let previousCache = new Map;
820
+ const update = (key, value) => {
821
+ cache.set(key, value);
822
+ cacheSize++;
823
+ if (cacheSize > maxCacheSize) {
824
+ cacheSize = 0;
825
+ previousCache = cache;
826
+ cache = new Map;
827
+ }
828
+ };
829
+ return {
830
+ get(key) {
831
+ let value = cache.get(key);
832
+ if (value !== undefined) {
833
+ return value;
834
+ }
835
+ if ((value = previousCache.get(key)) !== undefined) {
836
+ update(key, value);
837
+ return value;
838
+ }
839
+ },
840
+ set(key, value) {
841
+ if (cache.has(key)) {
842
+ cache.set(key, value);
843
+ } else {
844
+ update(key, value);
845
+ }
846
+ }
847
+ };
848
+ };
849
+ var IMPORTANT_MODIFIER = "!";
850
+ var createParseClassName = (config) => {
851
+ const {
852
+ separator,
853
+ experimentalParseClassName
854
+ } = config;
855
+ const isSeparatorSingleCharacter = separator.length === 1;
856
+ const firstSeparatorCharacter = separator[0];
857
+ const separatorLength = separator.length;
858
+ const parseClassName = (className) => {
859
+ const modifiers = [];
860
+ let bracketDepth = 0;
861
+ let modifierStart = 0;
862
+ let postfixModifierPosition;
863
+ for (let index = 0;index < className.length; index++) {
864
+ let currentCharacter = className[index];
865
+ if (bracketDepth === 0) {
866
+ if (currentCharacter === firstSeparatorCharacter && (isSeparatorSingleCharacter || className.slice(index, index + separatorLength) === separator)) {
867
+ modifiers.push(className.slice(modifierStart, index));
868
+ modifierStart = index + separatorLength;
869
+ continue;
870
+ }
871
+ if (currentCharacter === "/") {
872
+ postfixModifierPosition = index;
873
+ continue;
874
+ }
875
+ }
876
+ if (currentCharacter === "[") {
877
+ bracketDepth++;
878
+ } else if (currentCharacter === "]") {
879
+ bracketDepth--;
880
+ }
881
+ }
882
+ const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.substring(modifierStart);
883
+ const hasImportantModifier = baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER);
884
+ const baseClassName = hasImportantModifier ? baseClassNameWithImportantModifier.substring(1) : baseClassNameWithImportantModifier;
885
+ const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : undefined;
886
+ return {
887
+ modifiers,
888
+ hasImportantModifier,
889
+ baseClassName,
890
+ maybePostfixModifierPosition
891
+ };
892
+ };
893
+ if (experimentalParseClassName) {
894
+ return (className) => experimentalParseClassName({
895
+ className,
896
+ parseClassName
897
+ });
898
+ }
899
+ return parseClassName;
900
+ };
901
+ var sortModifiers = (modifiers) => {
902
+ if (modifiers.length <= 1) {
903
+ return modifiers;
904
+ }
905
+ const sortedModifiers = [];
906
+ let unsortedModifiers = [];
907
+ modifiers.forEach((modifier) => {
908
+ const isArbitraryVariant = modifier[0] === "[";
909
+ if (isArbitraryVariant) {
910
+ sortedModifiers.push(...unsortedModifiers.sort(), modifier);
911
+ unsortedModifiers = [];
912
+ } else {
913
+ unsortedModifiers.push(modifier);
914
+ }
915
+ });
916
+ sortedModifiers.push(...unsortedModifiers.sort());
917
+ return sortedModifiers;
918
+ };
919
+ var createConfigUtils = (config) => ({
920
+ cache: createLruCache(config.cacheSize),
921
+ parseClassName: createParseClassName(config),
922
+ ...createClassGroupUtils(config)
923
+ });
924
+ var SPLIT_CLASSES_REGEX = /\s+/;
925
+ var mergeClassList = (classList, configUtils) => {
926
+ const {
927
+ parseClassName,
928
+ getClassGroupId,
929
+ getConflictingClassGroupIds
930
+ } = configUtils;
931
+ const classGroupsInConflict = [];
932
+ const classNames = classList.trim().split(SPLIT_CLASSES_REGEX);
933
+ let result = "";
934
+ for (let index = classNames.length - 1;index >= 0; index -= 1) {
935
+ const originalClassName = classNames[index];
936
+ const {
937
+ modifiers,
938
+ hasImportantModifier,
939
+ baseClassName,
940
+ maybePostfixModifierPosition
941
+ } = parseClassName(originalClassName);
942
+ let hasPostfixModifier = Boolean(maybePostfixModifierPosition);
943
+ let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
944
+ if (!classGroupId) {
945
+ if (!hasPostfixModifier) {
946
+ result = originalClassName + (result.length > 0 ? " " + result : result);
947
+ continue;
948
+ }
949
+ classGroupId = getClassGroupId(baseClassName);
950
+ if (!classGroupId) {
951
+ result = originalClassName + (result.length > 0 ? " " + result : result);
952
+ continue;
953
+ }
954
+ hasPostfixModifier = false;
955
+ }
956
+ const variantModifier = sortModifiers(modifiers).join(":");
957
+ const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier;
958
+ const classId = modifierId + classGroupId;
959
+ if (classGroupsInConflict.includes(classId)) {
960
+ continue;
961
+ }
962
+ classGroupsInConflict.push(classId);
963
+ const conflictGroups = getConflictingClassGroupIds(classGroupId, hasPostfixModifier);
964
+ for (let i = 0;i < conflictGroups.length; ++i) {
965
+ const group = conflictGroups[i];
966
+ classGroupsInConflict.push(modifierId + group);
967
+ }
968
+ result = originalClassName + (result.length > 0 ? " " + result : result);
969
+ }
970
+ return result;
971
+ };
972
+ function twJoin() {
973
+ let index = 0;
974
+ let argument;
975
+ let resolvedValue;
976
+ let string = "";
977
+ while (index < arguments.length) {
978
+ if (argument = arguments[index++]) {
979
+ if (resolvedValue = toValue(argument)) {
980
+ string && (string += " ");
981
+ string += resolvedValue;
982
+ }
983
+ }
984
+ }
985
+ return string;
986
+ }
987
+ var toValue = (mix) => {
988
+ if (typeof mix === "string") {
989
+ return mix;
990
+ }
991
+ let resolvedValue;
992
+ let string = "";
993
+ for (let k = 0;k < mix.length; k++) {
994
+ if (mix[k]) {
995
+ if (resolvedValue = toValue(mix[k])) {
996
+ string && (string += " ");
997
+ string += resolvedValue;
998
+ }
999
+ }
1000
+ }
1001
+ return string;
1002
+ };
1003
+ function createTailwindMerge(createConfigFirst, ...createConfigRest) {
1004
+ let configUtils;
1005
+ let cacheGet;
1006
+ let cacheSet;
1007
+ let functionToCall = initTailwindMerge;
1008
+ function initTailwindMerge(classList) {
1009
+ const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst());
1010
+ configUtils = createConfigUtils(config);
1011
+ cacheGet = configUtils.cache.get;
1012
+ cacheSet = configUtils.cache.set;
1013
+ functionToCall = tailwindMerge;
1014
+ return tailwindMerge(classList);
1015
+ }
1016
+ function tailwindMerge(classList) {
1017
+ const cachedResult = cacheGet(classList);
1018
+ if (cachedResult) {
1019
+ return cachedResult;
1020
+ }
1021
+ const result = mergeClassList(classList, configUtils);
1022
+ cacheSet(classList, result);
1023
+ return result;
1024
+ }
1025
+ return function callTailwindMerge() {
1026
+ return functionToCall(twJoin.apply(null, arguments));
1027
+ };
1028
+ }
1029
+ var fromTheme = (key) => {
1030
+ const themeGetter = (theme) => theme[key] || [];
1031
+ themeGetter.isThemeGetter = true;
1032
+ return themeGetter;
1033
+ };
1034
+ var arbitraryValueRegex = /^\[(?:([a-z-]+):)?(.+)\]$/i;
1035
+ var fractionRegex = /^\d+\/\d+$/;
1036
+ var stringLengths = /* @__PURE__ */ new Set(["px", "full", "screen"]);
1037
+ var tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
1038
+ var lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
1039
+ var colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
1040
+ var shadowRegex = /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/;
1041
+ var imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/;
1042
+ var isLength = (value) => isNumber(value) || stringLengths.has(value) || fractionRegex.test(value);
1043
+ var isArbitraryLength = (value) => getIsArbitraryValue(value, "length", isLengthOnly);
1044
+ var isNumber = (value) => Boolean(value) && !Number.isNaN(Number(value));
1045
+ var isArbitraryNumber = (value) => getIsArbitraryValue(value, "number", isNumber);
1046
+ var isInteger = (value) => Boolean(value) && Number.isInteger(Number(value));
1047
+ var isPercent = (value) => value.endsWith("%") && isNumber(value.slice(0, -1));
1048
+ var isArbitraryValue = (value) => arbitraryValueRegex.test(value);
1049
+ var isTshirtSize = (value) => tshirtUnitRegex.test(value);
1050
+ var sizeLabels = /* @__PURE__ */ new Set(["length", "size", "percentage"]);
1051
+ var isArbitrarySize = (value) => getIsArbitraryValue(value, sizeLabels, isNever);
1052
+ var isArbitraryPosition = (value) => getIsArbitraryValue(value, "position", isNever);
1053
+ var imageLabels = /* @__PURE__ */ new Set(["image", "url"]);
1054
+ var isArbitraryImage = (value) => getIsArbitraryValue(value, imageLabels, isImage);
1055
+ var isArbitraryShadow = (value) => getIsArbitraryValue(value, "", isShadow);
1056
+ var isAny = () => true;
1057
+ var getIsArbitraryValue = (value, label, testValue) => {
1058
+ const result = arbitraryValueRegex.exec(value);
1059
+ if (result) {
1060
+ if (result[1]) {
1061
+ return typeof label === "string" ? result[1] === label : label.has(result[1]);
1062
+ }
1063
+ return testValue(result[2]);
1064
+ }
1065
+ return false;
1066
+ };
1067
+ var isLengthOnly = (value) => lengthUnitRegex.test(value) && !colorFunctionRegex.test(value);
1068
+ var isNever = () => false;
1069
+ var isShadow = (value) => shadowRegex.test(value);
1070
+ var isImage = (value) => imageRegex.test(value);
1071
+ var getDefaultConfig = () => {
1072
+ const colors = fromTheme("colors");
1073
+ const spacing = fromTheme("spacing");
1074
+ const blur = fromTheme("blur");
1075
+ const brightness = fromTheme("brightness");
1076
+ const borderColor = fromTheme("borderColor");
1077
+ const borderRadius = fromTheme("borderRadius");
1078
+ const borderSpacing = fromTheme("borderSpacing");
1079
+ const borderWidth = fromTheme("borderWidth");
1080
+ const contrast = fromTheme("contrast");
1081
+ const grayscale = fromTheme("grayscale");
1082
+ const hueRotate = fromTheme("hueRotate");
1083
+ const invert = fromTheme("invert");
1084
+ const gap = fromTheme("gap");
1085
+ const gradientColorStops = fromTheme("gradientColorStops");
1086
+ const gradientColorStopPositions = fromTheme("gradientColorStopPositions");
1087
+ const inset = fromTheme("inset");
1088
+ const margin = fromTheme("margin");
1089
+ const opacity = fromTheme("opacity");
1090
+ const padding = fromTheme("padding");
1091
+ const saturate = fromTheme("saturate");
1092
+ const scale = fromTheme("scale");
1093
+ const sepia = fromTheme("sepia");
1094
+ const skew = fromTheme("skew");
1095
+ const space = fromTheme("space");
1096
+ const translate = fromTheme("translate");
1097
+ const getOverscroll = () => ["auto", "contain", "none"];
1098
+ const getOverflow = () => ["auto", "hidden", "clip", "visible", "scroll"];
1099
+ const getSpacingWithAutoAndArbitrary = () => ["auto", isArbitraryValue, spacing];
1100
+ const getSpacingWithArbitrary = () => [isArbitraryValue, spacing];
1101
+ const getLengthWithEmptyAndArbitrary = () => ["", isLength, isArbitraryLength];
1102
+ const getNumberWithAutoAndArbitrary = () => ["auto", isNumber, isArbitraryValue];
1103
+ const getPositions = () => ["bottom", "center", "left", "left-bottom", "left-top", "right", "right-bottom", "right-top", "top"];
1104
+ const getLineStyles = () => ["solid", "dashed", "dotted", "double", "none"];
1105
+ const getBlendModes = () => ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"];
1106
+ const getAlign = () => ["start", "end", "center", "between", "around", "evenly", "stretch"];
1107
+ const getZeroAndEmpty = () => ["", "0", isArbitraryValue];
1108
+ const getBreaks = () => ["auto", "avoid", "all", "avoid-page", "page", "left", "right", "column"];
1109
+ const getNumberAndArbitrary = () => [isNumber, isArbitraryValue];
1110
+ return {
1111
+ cacheSize: 500,
1112
+ separator: ":",
1113
+ theme: {
1114
+ colors: [isAny],
1115
+ spacing: [isLength, isArbitraryLength],
1116
+ blur: ["none", "", isTshirtSize, isArbitraryValue],
1117
+ brightness: getNumberAndArbitrary(),
1118
+ borderColor: [colors],
1119
+ borderRadius: ["none", "", "full", isTshirtSize, isArbitraryValue],
1120
+ borderSpacing: getSpacingWithArbitrary(),
1121
+ borderWidth: getLengthWithEmptyAndArbitrary(),
1122
+ contrast: getNumberAndArbitrary(),
1123
+ grayscale: getZeroAndEmpty(),
1124
+ hueRotate: getNumberAndArbitrary(),
1125
+ invert: getZeroAndEmpty(),
1126
+ gap: getSpacingWithArbitrary(),
1127
+ gradientColorStops: [colors],
1128
+ gradientColorStopPositions: [isPercent, isArbitraryLength],
1129
+ inset: getSpacingWithAutoAndArbitrary(),
1130
+ margin: getSpacingWithAutoAndArbitrary(),
1131
+ opacity: getNumberAndArbitrary(),
1132
+ padding: getSpacingWithArbitrary(),
1133
+ saturate: getNumberAndArbitrary(),
1134
+ scale: getNumberAndArbitrary(),
1135
+ sepia: getZeroAndEmpty(),
1136
+ skew: getNumberAndArbitrary(),
1137
+ space: getSpacingWithArbitrary(),
1138
+ translate: getSpacingWithArbitrary()
1139
+ },
1140
+ classGroups: {
1141
+ aspect: [{
1142
+ aspect: ["auto", "square", "video", isArbitraryValue]
1143
+ }],
1144
+ container: ["container"],
1145
+ columns: [{
1146
+ columns: [isTshirtSize]
1147
+ }],
1148
+ "break-after": [{
1149
+ "break-after": getBreaks()
1150
+ }],
1151
+ "break-before": [{
1152
+ "break-before": getBreaks()
1153
+ }],
1154
+ "break-inside": [{
1155
+ "break-inside": ["auto", "avoid", "avoid-page", "avoid-column"]
1156
+ }],
1157
+ "box-decoration": [{
1158
+ "box-decoration": ["slice", "clone"]
1159
+ }],
1160
+ box: [{
1161
+ box: ["border", "content"]
1162
+ }],
1163
+ display: ["block", "inline-block", "inline", "flex", "inline-flex", "table", "inline-table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row-group", "table-row", "flow-root", "grid", "inline-grid", "contents", "list-item", "hidden"],
1164
+ float: [{
1165
+ float: ["right", "left", "none", "start", "end"]
1166
+ }],
1167
+ clear: [{
1168
+ clear: ["left", "right", "both", "none", "start", "end"]
1169
+ }],
1170
+ isolation: ["isolate", "isolation-auto"],
1171
+ "object-fit": [{
1172
+ object: ["contain", "cover", "fill", "none", "scale-down"]
1173
+ }],
1174
+ "object-position": [{
1175
+ object: [...getPositions(), isArbitraryValue]
1176
+ }],
1177
+ overflow: [{
1178
+ overflow: getOverflow()
1179
+ }],
1180
+ "overflow-x": [{
1181
+ "overflow-x": getOverflow()
1182
+ }],
1183
+ "overflow-y": [{
1184
+ "overflow-y": getOverflow()
1185
+ }],
1186
+ overscroll: [{
1187
+ overscroll: getOverscroll()
1188
+ }],
1189
+ "overscroll-x": [{
1190
+ "overscroll-x": getOverscroll()
1191
+ }],
1192
+ "overscroll-y": [{
1193
+ "overscroll-y": getOverscroll()
1194
+ }],
1195
+ position: ["static", "fixed", "absolute", "relative", "sticky"],
1196
+ inset: [{
1197
+ inset: [inset]
1198
+ }],
1199
+ "inset-x": [{
1200
+ "inset-x": [inset]
1201
+ }],
1202
+ "inset-y": [{
1203
+ "inset-y": [inset]
1204
+ }],
1205
+ start: [{
1206
+ start: [inset]
1207
+ }],
1208
+ end: [{
1209
+ end: [inset]
1210
+ }],
1211
+ top: [{
1212
+ top: [inset]
1213
+ }],
1214
+ right: [{
1215
+ right: [inset]
1216
+ }],
1217
+ bottom: [{
1218
+ bottom: [inset]
1219
+ }],
1220
+ left: [{
1221
+ left: [inset]
1222
+ }],
1223
+ visibility: ["visible", "invisible", "collapse"],
1224
+ z: [{
1225
+ z: ["auto", isInteger, isArbitraryValue]
1226
+ }],
1227
+ basis: [{
1228
+ basis: getSpacingWithAutoAndArbitrary()
1229
+ }],
1230
+ "flex-direction": [{
1231
+ flex: ["row", "row-reverse", "col", "col-reverse"]
1232
+ }],
1233
+ "flex-wrap": [{
1234
+ flex: ["wrap", "wrap-reverse", "nowrap"]
1235
+ }],
1236
+ flex: [{
1237
+ flex: ["1", "auto", "initial", "none", isArbitraryValue]
1238
+ }],
1239
+ grow: [{
1240
+ grow: getZeroAndEmpty()
1241
+ }],
1242
+ shrink: [{
1243
+ shrink: getZeroAndEmpty()
1244
+ }],
1245
+ order: [{
1246
+ order: ["first", "last", "none", isInteger, isArbitraryValue]
1247
+ }],
1248
+ "grid-cols": [{
1249
+ "grid-cols": [isAny]
1250
+ }],
1251
+ "col-start-end": [{
1252
+ col: ["auto", {
1253
+ span: ["full", isInteger, isArbitraryValue]
1254
+ }, isArbitraryValue]
1255
+ }],
1256
+ "col-start": [{
1257
+ "col-start": getNumberWithAutoAndArbitrary()
1258
+ }],
1259
+ "col-end": [{
1260
+ "col-end": getNumberWithAutoAndArbitrary()
1261
+ }],
1262
+ "grid-rows": [{
1263
+ "grid-rows": [isAny]
1264
+ }],
1265
+ "row-start-end": [{
1266
+ row: ["auto", {
1267
+ span: [isInteger, isArbitraryValue]
1268
+ }, isArbitraryValue]
1269
+ }],
1270
+ "row-start": [{
1271
+ "row-start": getNumberWithAutoAndArbitrary()
1272
+ }],
1273
+ "row-end": [{
1274
+ "row-end": getNumberWithAutoAndArbitrary()
1275
+ }],
1276
+ "grid-flow": [{
1277
+ "grid-flow": ["row", "col", "dense", "row-dense", "col-dense"]
1278
+ }],
1279
+ "auto-cols": [{
1280
+ "auto-cols": ["auto", "min", "max", "fr", isArbitraryValue]
1281
+ }],
1282
+ "auto-rows": [{
1283
+ "auto-rows": ["auto", "min", "max", "fr", isArbitraryValue]
1284
+ }],
1285
+ gap: [{
1286
+ gap: [gap]
1287
+ }],
1288
+ "gap-x": [{
1289
+ "gap-x": [gap]
1290
+ }],
1291
+ "gap-y": [{
1292
+ "gap-y": [gap]
1293
+ }],
1294
+ "justify-content": [{
1295
+ justify: ["normal", ...getAlign()]
1296
+ }],
1297
+ "justify-items": [{
1298
+ "justify-items": ["start", "end", "center", "stretch"]
1299
+ }],
1300
+ "justify-self": [{
1301
+ "justify-self": ["auto", "start", "end", "center", "stretch"]
1302
+ }],
1303
+ "align-content": [{
1304
+ content: ["normal", ...getAlign(), "baseline"]
1305
+ }],
1306
+ "align-items": [{
1307
+ items: ["start", "end", "center", "baseline", "stretch"]
1308
+ }],
1309
+ "align-self": [{
1310
+ self: ["auto", "start", "end", "center", "stretch", "baseline"]
1311
+ }],
1312
+ "place-content": [{
1313
+ "place-content": [...getAlign(), "baseline"]
1314
+ }],
1315
+ "place-items": [{
1316
+ "place-items": ["start", "end", "center", "baseline", "stretch"]
1317
+ }],
1318
+ "place-self": [{
1319
+ "place-self": ["auto", "start", "end", "center", "stretch"]
1320
+ }],
1321
+ p: [{
1322
+ p: [padding]
1323
+ }],
1324
+ px: [{
1325
+ px: [padding]
1326
+ }],
1327
+ py: [{
1328
+ py: [padding]
1329
+ }],
1330
+ ps: [{
1331
+ ps: [padding]
1332
+ }],
1333
+ pe: [{
1334
+ pe: [padding]
1335
+ }],
1336
+ pt: [{
1337
+ pt: [padding]
1338
+ }],
1339
+ pr: [{
1340
+ pr: [padding]
1341
+ }],
1342
+ pb: [{
1343
+ pb: [padding]
1344
+ }],
1345
+ pl: [{
1346
+ pl: [padding]
1347
+ }],
1348
+ m: [{
1349
+ m: [margin]
1350
+ }],
1351
+ mx: [{
1352
+ mx: [margin]
1353
+ }],
1354
+ my: [{
1355
+ my: [margin]
1356
+ }],
1357
+ ms: [{
1358
+ ms: [margin]
1359
+ }],
1360
+ me: [{
1361
+ me: [margin]
1362
+ }],
1363
+ mt: [{
1364
+ mt: [margin]
1365
+ }],
1366
+ mr: [{
1367
+ mr: [margin]
1368
+ }],
1369
+ mb: [{
1370
+ mb: [margin]
1371
+ }],
1372
+ ml: [{
1373
+ ml: [margin]
1374
+ }],
1375
+ "space-x": [{
1376
+ "space-x": [space]
1377
+ }],
1378
+ "space-x-reverse": ["space-x-reverse"],
1379
+ "space-y": [{
1380
+ "space-y": [space]
1381
+ }],
1382
+ "space-y-reverse": ["space-y-reverse"],
1383
+ w: [{
1384
+ w: ["auto", "min", "max", "fit", "svw", "lvw", "dvw", isArbitraryValue, spacing]
1385
+ }],
1386
+ "min-w": [{
1387
+ "min-w": [isArbitraryValue, spacing, "min", "max", "fit"]
1388
+ }],
1389
+ "max-w": [{
1390
+ "max-w": [isArbitraryValue, spacing, "none", "full", "min", "max", "fit", "prose", {
1391
+ screen: [isTshirtSize]
1392
+ }, isTshirtSize]
1393
+ }],
1394
+ h: [{
1395
+ h: [isArbitraryValue, spacing, "auto", "min", "max", "fit", "svh", "lvh", "dvh"]
1396
+ }],
1397
+ "min-h": [{
1398
+ "min-h": [isArbitraryValue, spacing, "min", "max", "fit", "svh", "lvh", "dvh"]
1399
+ }],
1400
+ "max-h": [{
1401
+ "max-h": [isArbitraryValue, spacing, "min", "max", "fit", "svh", "lvh", "dvh"]
1402
+ }],
1403
+ size: [{
1404
+ size: [isArbitraryValue, spacing, "auto", "min", "max", "fit"]
1405
+ }],
1406
+ "font-size": [{
1407
+ text: ["base", isTshirtSize, isArbitraryLength]
1408
+ }],
1409
+ "font-smoothing": ["antialiased", "subpixel-antialiased"],
1410
+ "font-style": ["italic", "not-italic"],
1411
+ "font-weight": [{
1412
+ font: ["thin", "extralight", "light", "normal", "medium", "semibold", "bold", "extrabold", "black", isArbitraryNumber]
1413
+ }],
1414
+ "font-family": [{
1415
+ font: [isAny]
1416
+ }],
1417
+ "fvn-normal": ["normal-nums"],
1418
+ "fvn-ordinal": ["ordinal"],
1419
+ "fvn-slashed-zero": ["slashed-zero"],
1420
+ "fvn-figure": ["lining-nums", "oldstyle-nums"],
1421
+ "fvn-spacing": ["proportional-nums", "tabular-nums"],
1422
+ "fvn-fraction": ["diagonal-fractions", "stacked-fractions"],
1423
+ tracking: [{
1424
+ tracking: ["tighter", "tight", "normal", "wide", "wider", "widest", isArbitraryValue]
1425
+ }],
1426
+ "line-clamp": [{
1427
+ "line-clamp": ["none", isNumber, isArbitraryNumber]
1428
+ }],
1429
+ leading: [{
1430
+ leading: ["none", "tight", "snug", "normal", "relaxed", "loose", isLength, isArbitraryValue]
1431
+ }],
1432
+ "list-image": [{
1433
+ "list-image": ["none", isArbitraryValue]
1434
+ }],
1435
+ "list-style-type": [{
1436
+ list: ["none", "disc", "decimal", isArbitraryValue]
1437
+ }],
1438
+ "list-style-position": [{
1439
+ list: ["inside", "outside"]
1440
+ }],
1441
+ "placeholder-color": [{
1442
+ placeholder: [colors]
1443
+ }],
1444
+ "placeholder-opacity": [{
1445
+ "placeholder-opacity": [opacity]
1446
+ }],
1447
+ "text-alignment": [{
1448
+ text: ["left", "center", "right", "justify", "start", "end"]
1449
+ }],
1450
+ "text-color": [{
1451
+ text: [colors]
1452
+ }],
1453
+ "text-opacity": [{
1454
+ "text-opacity": [opacity]
1455
+ }],
1456
+ "text-decoration": ["underline", "overline", "line-through", "no-underline"],
1457
+ "text-decoration-style": [{
1458
+ decoration: [...getLineStyles(), "wavy"]
1459
+ }],
1460
+ "text-decoration-thickness": [{
1461
+ decoration: ["auto", "from-font", isLength, isArbitraryLength]
1462
+ }],
1463
+ "underline-offset": [{
1464
+ "underline-offset": ["auto", isLength, isArbitraryValue]
1465
+ }],
1466
+ "text-decoration-color": [{
1467
+ decoration: [colors]
1468
+ }],
1469
+ "text-transform": ["uppercase", "lowercase", "capitalize", "normal-case"],
1470
+ "text-overflow": ["truncate", "text-ellipsis", "text-clip"],
1471
+ "text-wrap": [{
1472
+ text: ["wrap", "nowrap", "balance", "pretty"]
1473
+ }],
1474
+ indent: [{
1475
+ indent: getSpacingWithArbitrary()
1476
+ }],
1477
+ "vertical-align": [{
1478
+ align: ["baseline", "top", "middle", "bottom", "text-top", "text-bottom", "sub", "super", isArbitraryValue]
1479
+ }],
1480
+ whitespace: [{
1481
+ whitespace: ["normal", "nowrap", "pre", "pre-line", "pre-wrap", "break-spaces"]
1482
+ }],
1483
+ break: [{
1484
+ break: ["normal", "words", "all", "keep"]
1485
+ }],
1486
+ hyphens: [{
1487
+ hyphens: ["none", "manual", "auto"]
1488
+ }],
1489
+ content: [{
1490
+ content: ["none", isArbitraryValue]
1491
+ }],
1492
+ "bg-attachment": [{
1493
+ bg: ["fixed", "local", "scroll"]
1494
+ }],
1495
+ "bg-clip": [{
1496
+ "bg-clip": ["border", "padding", "content", "text"]
1497
+ }],
1498
+ "bg-opacity": [{
1499
+ "bg-opacity": [opacity]
1500
+ }],
1501
+ "bg-origin": [{
1502
+ "bg-origin": ["border", "padding", "content"]
1503
+ }],
1504
+ "bg-position": [{
1505
+ bg: [...getPositions(), isArbitraryPosition]
1506
+ }],
1507
+ "bg-repeat": [{
1508
+ bg: ["no-repeat", {
1509
+ repeat: ["", "x", "y", "round", "space"]
1510
+ }]
1511
+ }],
1512
+ "bg-size": [{
1513
+ bg: ["auto", "cover", "contain", isArbitrarySize]
1514
+ }],
1515
+ "bg-image": [{
1516
+ bg: ["none", {
1517
+ "gradient-to": ["t", "tr", "r", "br", "b", "bl", "l", "tl"]
1518
+ }, isArbitraryImage]
1519
+ }],
1520
+ "bg-color": [{
1521
+ bg: [colors]
1522
+ }],
1523
+ "gradient-from-pos": [{
1524
+ from: [gradientColorStopPositions]
1525
+ }],
1526
+ "gradient-via-pos": [{
1527
+ via: [gradientColorStopPositions]
1528
+ }],
1529
+ "gradient-to-pos": [{
1530
+ to: [gradientColorStopPositions]
1531
+ }],
1532
+ "gradient-from": [{
1533
+ from: [gradientColorStops]
1534
+ }],
1535
+ "gradient-via": [{
1536
+ via: [gradientColorStops]
1537
+ }],
1538
+ "gradient-to": [{
1539
+ to: [gradientColorStops]
1540
+ }],
1541
+ rounded: [{
1542
+ rounded: [borderRadius]
1543
+ }],
1544
+ "rounded-s": [{
1545
+ "rounded-s": [borderRadius]
1546
+ }],
1547
+ "rounded-e": [{
1548
+ "rounded-e": [borderRadius]
1549
+ }],
1550
+ "rounded-t": [{
1551
+ "rounded-t": [borderRadius]
1552
+ }],
1553
+ "rounded-r": [{
1554
+ "rounded-r": [borderRadius]
1555
+ }],
1556
+ "rounded-b": [{
1557
+ "rounded-b": [borderRadius]
1558
+ }],
1559
+ "rounded-l": [{
1560
+ "rounded-l": [borderRadius]
1561
+ }],
1562
+ "rounded-ss": [{
1563
+ "rounded-ss": [borderRadius]
1564
+ }],
1565
+ "rounded-se": [{
1566
+ "rounded-se": [borderRadius]
1567
+ }],
1568
+ "rounded-ee": [{
1569
+ "rounded-ee": [borderRadius]
1570
+ }],
1571
+ "rounded-es": [{
1572
+ "rounded-es": [borderRadius]
1573
+ }],
1574
+ "rounded-tl": [{
1575
+ "rounded-tl": [borderRadius]
1576
+ }],
1577
+ "rounded-tr": [{
1578
+ "rounded-tr": [borderRadius]
1579
+ }],
1580
+ "rounded-br": [{
1581
+ "rounded-br": [borderRadius]
1582
+ }],
1583
+ "rounded-bl": [{
1584
+ "rounded-bl": [borderRadius]
1585
+ }],
1586
+ "border-w": [{
1587
+ border: [borderWidth]
1588
+ }],
1589
+ "border-w-x": [{
1590
+ "border-x": [borderWidth]
1591
+ }],
1592
+ "border-w-y": [{
1593
+ "border-y": [borderWidth]
1594
+ }],
1595
+ "border-w-s": [{
1596
+ "border-s": [borderWidth]
1597
+ }],
1598
+ "border-w-e": [{
1599
+ "border-e": [borderWidth]
1600
+ }],
1601
+ "border-w-t": [{
1602
+ "border-t": [borderWidth]
1603
+ }],
1604
+ "border-w-r": [{
1605
+ "border-r": [borderWidth]
1606
+ }],
1607
+ "border-w-b": [{
1608
+ "border-b": [borderWidth]
1609
+ }],
1610
+ "border-w-l": [{
1611
+ "border-l": [borderWidth]
1612
+ }],
1613
+ "border-opacity": [{
1614
+ "border-opacity": [opacity]
1615
+ }],
1616
+ "border-style": [{
1617
+ border: [...getLineStyles(), "hidden"]
1618
+ }],
1619
+ "divide-x": [{
1620
+ "divide-x": [borderWidth]
1621
+ }],
1622
+ "divide-x-reverse": ["divide-x-reverse"],
1623
+ "divide-y": [{
1624
+ "divide-y": [borderWidth]
1625
+ }],
1626
+ "divide-y-reverse": ["divide-y-reverse"],
1627
+ "divide-opacity": [{
1628
+ "divide-opacity": [opacity]
1629
+ }],
1630
+ "divide-style": [{
1631
+ divide: getLineStyles()
1632
+ }],
1633
+ "border-color": [{
1634
+ border: [borderColor]
1635
+ }],
1636
+ "border-color-x": [{
1637
+ "border-x": [borderColor]
1638
+ }],
1639
+ "border-color-y": [{
1640
+ "border-y": [borderColor]
1641
+ }],
1642
+ "border-color-s": [{
1643
+ "border-s": [borderColor]
1644
+ }],
1645
+ "border-color-e": [{
1646
+ "border-e": [borderColor]
1647
+ }],
1648
+ "border-color-t": [{
1649
+ "border-t": [borderColor]
1650
+ }],
1651
+ "border-color-r": [{
1652
+ "border-r": [borderColor]
1653
+ }],
1654
+ "border-color-b": [{
1655
+ "border-b": [borderColor]
1656
+ }],
1657
+ "border-color-l": [{
1658
+ "border-l": [borderColor]
1659
+ }],
1660
+ "divide-color": [{
1661
+ divide: [borderColor]
1662
+ }],
1663
+ "outline-style": [{
1664
+ outline: ["", ...getLineStyles()]
1665
+ }],
1666
+ "outline-offset": [{
1667
+ "outline-offset": [isLength, isArbitraryValue]
1668
+ }],
1669
+ "outline-w": [{
1670
+ outline: [isLength, isArbitraryLength]
1671
+ }],
1672
+ "outline-color": [{
1673
+ outline: [colors]
1674
+ }],
1675
+ "ring-w": [{
1676
+ ring: getLengthWithEmptyAndArbitrary()
1677
+ }],
1678
+ "ring-w-inset": ["ring-inset"],
1679
+ "ring-color": [{
1680
+ ring: [colors]
1681
+ }],
1682
+ "ring-opacity": [{
1683
+ "ring-opacity": [opacity]
1684
+ }],
1685
+ "ring-offset-w": [{
1686
+ "ring-offset": [isLength, isArbitraryLength]
1687
+ }],
1688
+ "ring-offset-color": [{
1689
+ "ring-offset": [colors]
1690
+ }],
1691
+ shadow: [{
1692
+ shadow: ["", "inner", "none", isTshirtSize, isArbitraryShadow]
1693
+ }],
1694
+ "shadow-color": [{
1695
+ shadow: [isAny]
1696
+ }],
1697
+ opacity: [{
1698
+ opacity: [opacity]
1699
+ }],
1700
+ "mix-blend": [{
1701
+ "mix-blend": [...getBlendModes(), "plus-lighter", "plus-darker"]
1702
+ }],
1703
+ "bg-blend": [{
1704
+ "bg-blend": getBlendModes()
1705
+ }],
1706
+ filter: [{
1707
+ filter: ["", "none"]
1708
+ }],
1709
+ blur: [{
1710
+ blur: [blur]
1711
+ }],
1712
+ brightness: [{
1713
+ brightness: [brightness]
1714
+ }],
1715
+ contrast: [{
1716
+ contrast: [contrast]
1717
+ }],
1718
+ "drop-shadow": [{
1719
+ "drop-shadow": ["", "none", isTshirtSize, isArbitraryValue]
1720
+ }],
1721
+ grayscale: [{
1722
+ grayscale: [grayscale]
1723
+ }],
1724
+ "hue-rotate": [{
1725
+ "hue-rotate": [hueRotate]
1726
+ }],
1727
+ invert: [{
1728
+ invert: [invert]
1729
+ }],
1730
+ saturate: [{
1731
+ saturate: [saturate]
1732
+ }],
1733
+ sepia: [{
1734
+ sepia: [sepia]
1735
+ }],
1736
+ "backdrop-filter": [{
1737
+ "backdrop-filter": ["", "none"]
1738
+ }],
1739
+ "backdrop-blur": [{
1740
+ "backdrop-blur": [blur]
1741
+ }],
1742
+ "backdrop-brightness": [{
1743
+ "backdrop-brightness": [brightness]
1744
+ }],
1745
+ "backdrop-contrast": [{
1746
+ "backdrop-contrast": [contrast]
1747
+ }],
1748
+ "backdrop-grayscale": [{
1749
+ "backdrop-grayscale": [grayscale]
1750
+ }],
1751
+ "backdrop-hue-rotate": [{
1752
+ "backdrop-hue-rotate": [hueRotate]
1753
+ }],
1754
+ "backdrop-invert": [{
1755
+ "backdrop-invert": [invert]
1756
+ }],
1757
+ "backdrop-opacity": [{
1758
+ "backdrop-opacity": [opacity]
1759
+ }],
1760
+ "backdrop-saturate": [{
1761
+ "backdrop-saturate": [saturate]
1762
+ }],
1763
+ "backdrop-sepia": [{
1764
+ "backdrop-sepia": [sepia]
1765
+ }],
1766
+ "border-collapse": [{
1767
+ border: ["collapse", "separate"]
1768
+ }],
1769
+ "border-spacing": [{
1770
+ "border-spacing": [borderSpacing]
1771
+ }],
1772
+ "border-spacing-x": [{
1773
+ "border-spacing-x": [borderSpacing]
1774
+ }],
1775
+ "border-spacing-y": [{
1776
+ "border-spacing-y": [borderSpacing]
1777
+ }],
1778
+ "table-layout": [{
1779
+ table: ["auto", "fixed"]
1780
+ }],
1781
+ caption: [{
1782
+ caption: ["top", "bottom"]
1783
+ }],
1784
+ transition: [{
1785
+ transition: ["none", "all", "", "colors", "opacity", "shadow", "transform", isArbitraryValue]
1786
+ }],
1787
+ duration: [{
1788
+ duration: getNumberAndArbitrary()
1789
+ }],
1790
+ ease: [{
1791
+ ease: ["linear", "in", "out", "in-out", isArbitraryValue]
1792
+ }],
1793
+ delay: [{
1794
+ delay: getNumberAndArbitrary()
1795
+ }],
1796
+ animate: [{
1797
+ animate: ["none", "spin", "ping", "pulse", "bounce", isArbitraryValue]
1798
+ }],
1799
+ transform: [{
1800
+ transform: ["", "gpu", "none"]
1801
+ }],
1802
+ scale: [{
1803
+ scale: [scale]
1804
+ }],
1805
+ "scale-x": [{
1806
+ "scale-x": [scale]
1807
+ }],
1808
+ "scale-y": [{
1809
+ "scale-y": [scale]
1810
+ }],
1811
+ rotate: [{
1812
+ rotate: [isInteger, isArbitraryValue]
1813
+ }],
1814
+ "translate-x": [{
1815
+ "translate-x": [translate]
1816
+ }],
1817
+ "translate-y": [{
1818
+ "translate-y": [translate]
1819
+ }],
1820
+ "skew-x": [{
1821
+ "skew-x": [skew]
1822
+ }],
1823
+ "skew-y": [{
1824
+ "skew-y": [skew]
1825
+ }],
1826
+ "transform-origin": [{
1827
+ origin: ["center", "top", "top-right", "right", "bottom-right", "bottom", "bottom-left", "left", "top-left", isArbitraryValue]
1828
+ }],
1829
+ accent: [{
1830
+ accent: ["auto", colors]
1831
+ }],
1832
+ appearance: [{
1833
+ appearance: ["none", "auto"]
1834
+ }],
1835
+ cursor: [{
1836
+ cursor: ["auto", "default", "pointer", "wait", "text", "move", "help", "not-allowed", "none", "context-menu", "progress", "cell", "crosshair", "vertical-text", "alias", "copy", "no-drop", "grab", "grabbing", "all-scroll", "col-resize", "row-resize", "n-resize", "e-resize", "s-resize", "w-resize", "ne-resize", "nw-resize", "se-resize", "sw-resize", "ew-resize", "ns-resize", "nesw-resize", "nwse-resize", "zoom-in", "zoom-out", isArbitraryValue]
1837
+ }],
1838
+ "caret-color": [{
1839
+ caret: [colors]
1840
+ }],
1841
+ "pointer-events": [{
1842
+ "pointer-events": ["none", "auto"]
1843
+ }],
1844
+ resize: [{
1845
+ resize: ["none", "y", "x", ""]
1846
+ }],
1847
+ "scroll-behavior": [{
1848
+ scroll: ["auto", "smooth"]
1849
+ }],
1850
+ "scroll-m": [{
1851
+ "scroll-m": getSpacingWithArbitrary()
1852
+ }],
1853
+ "scroll-mx": [{
1854
+ "scroll-mx": getSpacingWithArbitrary()
1855
+ }],
1856
+ "scroll-my": [{
1857
+ "scroll-my": getSpacingWithArbitrary()
1858
+ }],
1859
+ "scroll-ms": [{
1860
+ "scroll-ms": getSpacingWithArbitrary()
1861
+ }],
1862
+ "scroll-me": [{
1863
+ "scroll-me": getSpacingWithArbitrary()
1864
+ }],
1865
+ "scroll-mt": [{
1866
+ "scroll-mt": getSpacingWithArbitrary()
1867
+ }],
1868
+ "scroll-mr": [{
1869
+ "scroll-mr": getSpacingWithArbitrary()
1870
+ }],
1871
+ "scroll-mb": [{
1872
+ "scroll-mb": getSpacingWithArbitrary()
1873
+ }],
1874
+ "scroll-ml": [{
1875
+ "scroll-ml": getSpacingWithArbitrary()
1876
+ }],
1877
+ "scroll-p": [{
1878
+ "scroll-p": getSpacingWithArbitrary()
1879
+ }],
1880
+ "scroll-px": [{
1881
+ "scroll-px": getSpacingWithArbitrary()
1882
+ }],
1883
+ "scroll-py": [{
1884
+ "scroll-py": getSpacingWithArbitrary()
1885
+ }],
1886
+ "scroll-ps": [{
1887
+ "scroll-ps": getSpacingWithArbitrary()
1888
+ }],
1889
+ "scroll-pe": [{
1890
+ "scroll-pe": getSpacingWithArbitrary()
1891
+ }],
1892
+ "scroll-pt": [{
1893
+ "scroll-pt": getSpacingWithArbitrary()
1894
+ }],
1895
+ "scroll-pr": [{
1896
+ "scroll-pr": getSpacingWithArbitrary()
1897
+ }],
1898
+ "scroll-pb": [{
1899
+ "scroll-pb": getSpacingWithArbitrary()
1900
+ }],
1901
+ "scroll-pl": [{
1902
+ "scroll-pl": getSpacingWithArbitrary()
1903
+ }],
1904
+ "snap-align": [{
1905
+ snap: ["start", "end", "center", "align-none"]
1906
+ }],
1907
+ "snap-stop": [{
1908
+ snap: ["normal", "always"]
1909
+ }],
1910
+ "snap-type": [{
1911
+ snap: ["none", "x", "y", "both"]
1912
+ }],
1913
+ "snap-strictness": [{
1914
+ snap: ["mandatory", "proximity"]
1915
+ }],
1916
+ touch: [{
1917
+ touch: ["auto", "none", "manipulation"]
1918
+ }],
1919
+ "touch-x": [{
1920
+ "touch-pan": ["x", "left", "right"]
1921
+ }],
1922
+ "touch-y": [{
1923
+ "touch-pan": ["y", "up", "down"]
1924
+ }],
1925
+ "touch-pz": ["touch-pinch-zoom"],
1926
+ select: [{
1927
+ select: ["none", "text", "all", "auto"]
1928
+ }],
1929
+ "will-change": [{
1930
+ "will-change": ["auto", "scroll", "contents", "transform", isArbitraryValue]
1931
+ }],
1932
+ fill: [{
1933
+ fill: [colors, "none"]
1934
+ }],
1935
+ "stroke-w": [{
1936
+ stroke: [isLength, isArbitraryLength, isArbitraryNumber]
1937
+ }],
1938
+ stroke: [{
1939
+ stroke: [colors, "none"]
1940
+ }],
1941
+ sr: ["sr-only", "not-sr-only"],
1942
+ "forced-color-adjust": [{
1943
+ "forced-color-adjust": ["auto", "none"]
1944
+ }]
1945
+ },
1946
+ conflictingClassGroups: {
1947
+ overflow: ["overflow-x", "overflow-y"],
1948
+ overscroll: ["overscroll-x", "overscroll-y"],
1949
+ inset: ["inset-x", "inset-y", "start", "end", "top", "right", "bottom", "left"],
1950
+ "inset-x": ["right", "left"],
1951
+ "inset-y": ["top", "bottom"],
1952
+ flex: ["basis", "grow", "shrink"],
1953
+ gap: ["gap-x", "gap-y"],
1954
+ p: ["px", "py", "ps", "pe", "pt", "pr", "pb", "pl"],
1955
+ px: ["pr", "pl"],
1956
+ py: ["pt", "pb"],
1957
+ m: ["mx", "my", "ms", "me", "mt", "mr", "mb", "ml"],
1958
+ mx: ["mr", "ml"],
1959
+ my: ["mt", "mb"],
1960
+ size: ["w", "h"],
1961
+ "font-size": ["leading"],
1962
+ "fvn-normal": ["fvn-ordinal", "fvn-slashed-zero", "fvn-figure", "fvn-spacing", "fvn-fraction"],
1963
+ "fvn-ordinal": ["fvn-normal"],
1964
+ "fvn-slashed-zero": ["fvn-normal"],
1965
+ "fvn-figure": ["fvn-normal"],
1966
+ "fvn-spacing": ["fvn-normal"],
1967
+ "fvn-fraction": ["fvn-normal"],
1968
+ "line-clamp": ["display", "overflow"],
1969
+ rounded: ["rounded-s", "rounded-e", "rounded-t", "rounded-r", "rounded-b", "rounded-l", "rounded-ss", "rounded-se", "rounded-ee", "rounded-es", "rounded-tl", "rounded-tr", "rounded-br", "rounded-bl"],
1970
+ "rounded-s": ["rounded-ss", "rounded-es"],
1971
+ "rounded-e": ["rounded-se", "rounded-ee"],
1972
+ "rounded-t": ["rounded-tl", "rounded-tr"],
1973
+ "rounded-r": ["rounded-tr", "rounded-br"],
1974
+ "rounded-b": ["rounded-br", "rounded-bl"],
1975
+ "rounded-l": ["rounded-tl", "rounded-bl"],
1976
+ "border-spacing": ["border-spacing-x", "border-spacing-y"],
1977
+ "border-w": ["border-w-s", "border-w-e", "border-w-t", "border-w-r", "border-w-b", "border-w-l"],
1978
+ "border-w-x": ["border-w-r", "border-w-l"],
1979
+ "border-w-y": ["border-w-t", "border-w-b"],
1980
+ "border-color": ["border-color-s", "border-color-e", "border-color-t", "border-color-r", "border-color-b", "border-color-l"],
1981
+ "border-color-x": ["border-color-r", "border-color-l"],
1982
+ "border-color-y": ["border-color-t", "border-color-b"],
1983
+ "scroll-m": ["scroll-mx", "scroll-my", "scroll-ms", "scroll-me", "scroll-mt", "scroll-mr", "scroll-mb", "scroll-ml"],
1984
+ "scroll-mx": ["scroll-mr", "scroll-ml"],
1985
+ "scroll-my": ["scroll-mt", "scroll-mb"],
1986
+ "scroll-p": ["scroll-px", "scroll-py", "scroll-ps", "scroll-pe", "scroll-pt", "scroll-pr", "scroll-pb", "scroll-pl"],
1987
+ "scroll-px": ["scroll-pr", "scroll-pl"],
1988
+ "scroll-py": ["scroll-pt", "scroll-pb"],
1989
+ touch: ["touch-x", "touch-y", "touch-pz"],
1990
+ "touch-x": ["touch"],
1991
+ "touch-y": ["touch"],
1992
+ "touch-pz": ["touch"]
1993
+ },
1994
+ conflictingClassGroupModifiers: {
1995
+ "font-size": ["leading"]
1996
+ }
1997
+ };
1998
+ };
1999
+ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
2000
+
2001
+ // src/renderer/utils/cn.ts
2002
+ function cn(...inputs) {
2003
+ return twMerge(clsx(inputs));
2004
+ }
2005
+
2006
+ // src/renderer/components/Text.tsx
2007
+ var jsx_dev_runtime = require("react/jsx-dev-runtime");
2008
+ var variantClasses = {
2009
+ default: "text-meissa-fg",
2010
+ muted: "text-meissa-muted",
2011
+ success: "text-meissa-success",
2012
+ warning: "text-meissa-warning",
2013
+ error: "text-meissa-destructive"
2014
+ };
2015
+ var alignClasses = {
2016
+ left: "text-left",
2017
+ center: "text-center",
2018
+ right: "text-right"
2019
+ };
2020
+ function Text({ node }) {
2021
+ const variant = node.variant || "default";
2022
+ const bold = node.bold;
2023
+ const align = node.align || "left";
2024
+ const content = node.content;
2025
+ return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("p", {
2026
+ className: cn(variantClasses[variant], alignClasses[align], bold && "font-semibold", node.class),
2027
+ children: content
2028
+ }, undefined, false, undefined, this);
2029
+ }
2030
+
2031
+ // src/renderer/components/Heading.tsx
2032
+ var jsx_dev_runtime2 = require("react/jsx-dev-runtime");
2033
+ var levelClasses = {
2034
+ 1: "text-3xl font-bold",
2035
+ 2: "text-2xl font-semibold",
2036
+ 3: "text-xl font-semibold",
2037
+ 4: "text-lg font-medium",
2038
+ 5: "text-base font-medium",
2039
+ 6: "text-sm font-medium"
2040
+ };
2041
+ var alignClasses2 = {
2042
+ left: "text-left",
2043
+ center: "text-center",
2044
+ right: "text-right"
2045
+ };
2046
+ function Heading({ node }) {
2047
+ const level = node.level || 2;
2048
+ const align = node.align || "left";
2049
+ const content = node.content;
2050
+ const Tag = `h${level}`;
2051
+ return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Tag, {
2052
+ className: cn(levelClasses[level], alignClasses2[align], "text-meissa-fg", node.class),
2053
+ children: content
2054
+ }, undefined, false, undefined, this);
2055
+ }
2056
+
2057
+ // src/renderer/components/Code.tsx
2058
+ var jsx_dev_runtime3 = require("react/jsx-dev-runtime");
2059
+ function Code({ node }) {
2060
+ const content = node.content;
2061
+ const lang = node.lang;
2062
+ const inline = node.inline;
2063
+ if (inline) {
2064
+ return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV("code", {
2065
+ className: cn("bg-meissa-fg/10 rounded px-1.5 py-0.5 text-sm font-mono text-meissa-fg", node.class),
2066
+ children: content
2067
+ }, undefined, false, undefined, this);
2068
+ }
2069
+ return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV("pre", {
2070
+ className: cn("bg-meissa-fg/10 rounded-lg p-4 overflow-x-auto", node.class),
2071
+ children: /* @__PURE__ */ jsx_dev_runtime3.jsxDEV("code", {
2072
+ className: "text-sm font-mono text-meissa-fg",
2073
+ "data-lang": lang,
2074
+ children: content
2075
+ }, undefined, false, undefined, this)
2076
+ }, undefined, false, undefined, this);
2077
+ }
2078
+
2079
+ // src/renderer/utils/sanitize.ts
2080
+ function sanitizeUrl(url) {
2081
+ const trimmed = url.trim().toLowerCase();
2082
+ if (trimmed.startsWith("javascript:") || trimmed.startsWith("data:text/html")) {
2083
+ return "about:blank";
2084
+ }
2085
+ return url;
2086
+ }
2087
+
2088
+ // src/renderer/components/Img.tsx
2089
+ var jsx_dev_runtime4 = require("react/jsx-dev-runtime");
2090
+ var fitClasses = {
2091
+ cover: "object-cover",
2092
+ contain: "object-contain",
2093
+ fill: "object-fill"
2094
+ };
2095
+ function Img({ node }) {
2096
+ const src = sanitizeUrl(node.src);
2097
+ const alt = node.alt || "";
2098
+ const w = node.w;
2099
+ const h = node.h;
2100
+ const fit = node.fit || "cover";
2101
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV("img", {
2102
+ src,
2103
+ alt,
2104
+ width: w,
2105
+ height: h,
2106
+ className: cn("rounded", fitClasses[fit], node.class)
2107
+ }, undefined, false, undefined, this);
2108
+ }
2109
+
2110
+ // src/renderer/components/Btn.tsx
2111
+ var import_react4 = require("react");
2112
+
2113
+ // src/renderer/context/FormContext.tsx
2114
+ var import_react3 = require("react");
2115
+ var jsx_dev_runtime5 = require("react/jsx-dev-runtime");
2116
+ var FormContext = import_react3.createContext(null);
2117
+ function useForm() {
2118
+ return import_react3.useContext(FormContext);
2119
+ }
2120
+ function FormProvider({ submitAction, onSubmit, children }) {
2121
+ const [values, setValues] = import_react3.useState({});
2122
+ const setValue = import_react3.useCallback((name, value) => {
2123
+ setValues((prev) => ({ ...prev, [name]: value }));
2124
+ }, []);
2125
+ const submit = import_react3.useCallback((action, extraArgs) => {
2126
+ onSubmit(action || submitAction, { ...values, ...extraArgs });
2127
+ }, [submitAction, onSubmit, values]);
2128
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(FormContext.Provider, {
2129
+ value: { values, setValue, submit },
2130
+ children
2131
+ }, undefined, false, undefined, this);
2132
+ }
2133
+
2134
+ // src/renderer/components/Btn.tsx
2135
+ var jsx_dev_runtime6 = require("react/jsx-dev-runtime");
2136
+ var variantClasses2 = {
2137
+ primary: "bg-meissa-primary text-white hover:opacity-90",
2138
+ secondary: "bg-meissa-fg/10 text-meissa-fg hover:bg-meissa-fg/15",
2139
+ destructive: "bg-meissa-destructive text-white hover:opacity-90",
2140
+ ghost: "hover:bg-meissa-fg/10 text-meissa-fg",
2141
+ outline: "border border-meissa-border text-meissa-fg hover:bg-meissa-fg/5"
2142
+ };
2143
+ var sizeClasses = {
2144
+ sm: "px-2.5 py-1 text-xs",
2145
+ md: "px-4 py-2 text-sm",
2146
+ lg: "px-6 py-3 text-base"
2147
+ };
2148
+ function Btn({ node }) {
2149
+ const { onAction, onNavigate } = useAction();
2150
+ const form = useForm();
2151
+ const label = node.label;
2152
+ const variant = node.variant || "primary";
2153
+ const size = node.size || "md";
2154
+ const disabled = node.disabled;
2155
+ const action = node.action;
2156
+ const args = node.args;
2157
+ const confirm = node.confirm;
2158
+ const navigate = node.navigate;
2159
+ const handleClick = import_react4.useCallback(() => {
2160
+ if (disabled)
2161
+ return;
2162
+ if (confirm) {
2163
+ if (!window.confirm(confirm))
2164
+ return;
2165
+ }
2166
+ if (navigate) {
2167
+ onNavigate(navigate);
2168
+ } else if (action) {
2169
+ onAction(action, args);
2170
+ } else if (form) {
2171
+ form.submit(undefined, args);
2172
+ }
2173
+ }, [disabled, confirm, navigate, action, args, form, onAction, onNavigate]);
2174
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV("button", {
2175
+ type: "button",
2176
+ disabled,
2177
+ onClick: handleClick,
2178
+ className: cn("inline-flex items-center justify-center rounded-md font-medium transition-colors", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-meissa-primary", "disabled:opacity-50 disabled:pointer-events-none", variantClasses2[variant], sizeClasses[size], node.class),
2179
+ children: label
2180
+ }, undefined, false, undefined, this);
2181
+ }
2182
+
2183
+ // src/renderer/components/Input.tsx
2184
+ var import_react5 = require("react");
2185
+ var jsx_dev_runtime7 = require("react/jsx-dev-runtime");
2186
+ function Input({ node }) {
2187
+ const form = useForm();
2188
+ const name = node.name;
2189
+ const type = node.type || "text";
2190
+ const label = node.label;
2191
+ const placeholder = node.placeholder;
2192
+ const required = node.required;
2193
+ const disabled = node.disabled;
2194
+ const value = form?.values[name] ?? node.value ?? "";
2195
+ const handleChange = import_react5.useCallback((e) => {
2196
+ form?.setValue(name, e.target.value);
2197
+ }, [form, name]);
2198
+ const inputClasses = cn("w-full rounded-md border border-meissa-border bg-meissa-bg px-3 py-2 text-sm", "placeholder:text-meissa-muted", "focus:outline-none focus:ring-2 focus:ring-meissa-primary focus:border-transparent", "disabled:opacity-50 disabled:cursor-not-allowed", node.class);
2199
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("div", {
2200
+ className: "flex flex-col gap-1.5",
2201
+ children: [
2202
+ label && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("label", {
2203
+ className: "text-sm font-medium text-meissa-fg",
2204
+ children: [
2205
+ label,
2206
+ required && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("span", {
2207
+ className: "text-meissa-destructive ml-1",
2208
+ children: "*"
2209
+ }, undefined, false, undefined, this)
2210
+ ]
2211
+ }, undefined, true, undefined, this),
2212
+ type === "textarea" ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("textarea", {
2213
+ name,
2214
+ placeholder,
2215
+ required,
2216
+ disabled,
2217
+ value,
2218
+ onChange: handleChange,
2219
+ className: cn(inputClasses, "min-h-[80px] resize-y"),
2220
+ rows: 4
2221
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV("input", {
2222
+ name,
2223
+ type,
2224
+ placeholder,
2225
+ required,
2226
+ disabled,
2227
+ value,
2228
+ onChange: handleChange,
2229
+ className: inputClasses
2230
+ }, undefined, false, undefined, this)
2231
+ ]
2232
+ }, undefined, true, undefined, this);
2233
+ }
2234
+
2235
+ // src/renderer/components/Select.tsx
2236
+ var import_react6 = require("react");
2237
+ var jsx_dev_runtime8 = require("react/jsx-dev-runtime");
2238
+ function normalizeOptions(raw) {
2239
+ return raw.map((item) => {
2240
+ if (typeof item === "string")
2241
+ return { label: item, value: item };
2242
+ const obj = item;
2243
+ return { label: obj.label || obj.value, value: obj.value || obj.label };
2244
+ });
2245
+ }
2246
+ function Select({ node }) {
2247
+ const form = useForm();
2248
+ const name = node.name;
2249
+ const label = node.label;
2250
+ const placeholder = node.placeholder || "Select...";
2251
+ const required = node.required;
2252
+ const multiple = node.multiple;
2253
+ const rawOptions = node.options || [];
2254
+ const options = normalizeOptions(rawOptions);
2255
+ const value = form?.values[name] ?? node.value ?? "";
2256
+ const handleChange = import_react6.useCallback((e) => {
2257
+ form?.setValue(name, e.target.value);
2258
+ }, [form, name]);
2259
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("div", {
2260
+ className: "flex flex-col gap-1.5",
2261
+ children: [
2262
+ label && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("label", {
2263
+ className: "text-sm font-medium text-meissa-fg",
2264
+ children: [
2265
+ label,
2266
+ required && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("span", {
2267
+ className: "text-meissa-destructive ml-1",
2268
+ children: "*"
2269
+ }, undefined, false, undefined, this)
2270
+ ]
2271
+ }, undefined, true, undefined, this),
2272
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("select", {
2273
+ name,
2274
+ required,
2275
+ multiple,
2276
+ value,
2277
+ onChange: handleChange,
2278
+ className: cn("w-full rounded-md border border-meissa-border bg-meissa-bg px-3 py-2 text-sm", "focus:outline-none focus:ring-2 focus:ring-meissa-primary focus:border-transparent", "disabled:opacity-50 disabled:cursor-not-allowed", node.class),
2279
+ children: [
2280
+ !multiple && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("option", {
2281
+ value: "",
2282
+ children: placeholder
2283
+ }, undefined, false, undefined, this),
2284
+ options.map((opt) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV("option", {
2285
+ value: opt.value,
2286
+ children: opt.label
2287
+ }, opt.value, false, undefined, this))
2288
+ ]
2289
+ }, undefined, true, undefined, this)
2290
+ ]
2291
+ }, undefined, true, undefined, this);
2292
+ }
2293
+
2294
+ // src/renderer/components/Form.tsx
2295
+ var import_react7 = require("react");
2296
+ var jsx_dev_runtime9 = require("react/jsx-dev-runtime");
2297
+ function Form({ node, children }) {
2298
+ const { onAction } = useAction();
2299
+ const submit = node.submit;
2300
+ const args = node.args || {};
2301
+ const handleSubmit = import_react7.useCallback((action, formValues) => {
2302
+ onAction(action || submit, { ...args, ...formValues });
2303
+ }, [onAction, submit, args]);
2304
+ const onFormSubmit = import_react7.useCallback((e) => {
2305
+ e.preventDefault();
2306
+ }, []);
2307
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(FormProvider, {
2308
+ submitAction: submit,
2309
+ onSubmit: handleSubmit,
2310
+ children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV("form", {
2311
+ onSubmit: onFormSubmit,
2312
+ className: cn("flex flex-col gap-4", node.class),
2313
+ children
2314
+ }, undefined, false, undefined, this)
2315
+ }, undefined, false, undefined, this);
2316
+ }
2317
+
2318
+ // src/renderer/components/Table.tsx
2319
+ var import_react8 = require("react");
2320
+ var jsx_dev_runtime10 = require("react/jsx-dev-runtime");
2321
+ function toTitleCase(key) {
2322
+ return key.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
2323
+ }
2324
+ function isNumeric(val) {
2325
+ return typeof val === "number" || typeof val === "string" && !isNaN(Number(val)) && val.trim() !== "";
2326
+ }
2327
+ function Table({ node }) {
2328
+ const { onAction } = useAction();
2329
+ const data = node.data || [];
2330
+ const customColumns = node.columns;
2331
+ const headers = node.headers || {};
2332
+ const sortable = node.sortable !== false;
2333
+ const paginate = node.paginate;
2334
+ const actions = node.actions;
2335
+ const [sortKey, setSortKey] = import_react8.useState(null);
2336
+ const [sortDir, setSortDir] = import_react8.useState("asc");
2337
+ const [page, setPage] = import_react8.useState(0);
2338
+ const columns = import_react8.useMemo(() => {
2339
+ if (customColumns)
2340
+ return customColumns;
2341
+ if (data.length === 0)
2342
+ return [];
2343
+ return Object.keys(data[0]);
2344
+ }, [customColumns, data]);
2345
+ const numericCols = import_react8.useMemo(() => {
2346
+ if (data.length === 0)
2347
+ return new Set;
2348
+ const set = new Set;
2349
+ for (const col of columns) {
2350
+ if (data.every((row) => row[col] == null || isNumeric(row[col]))) {
2351
+ set.add(col);
2352
+ }
2353
+ }
2354
+ return set;
2355
+ }, [columns, data]);
2356
+ const sortedData = import_react8.useMemo(() => {
2357
+ if (!sortKey)
2358
+ return data;
2359
+ return [...data].sort((a, b) => {
2360
+ const av = a[sortKey];
2361
+ const bv = b[sortKey];
2362
+ if (av == null && bv == null)
2363
+ return 0;
2364
+ if (av == null)
2365
+ return 1;
2366
+ if (bv == null)
2367
+ return -1;
2368
+ const cmp = numericCols.has(sortKey) ? Number(av) - Number(bv) : String(av).localeCompare(String(bv));
2369
+ return sortDir === "asc" ? cmp : -cmp;
2370
+ });
2371
+ }, [data, sortKey, sortDir, numericCols]);
2372
+ const paginatedData = import_react8.useMemo(() => {
2373
+ if (!paginate)
2374
+ return sortedData;
2375
+ const start = page * paginate;
2376
+ return sortedData.slice(start, start + paginate);
2377
+ }, [sortedData, page, paginate]);
2378
+ const totalPages = paginate ? Math.ceil(data.length / paginate) : 1;
2379
+ const handleSort = import_react8.useCallback((col) => {
2380
+ if (!sortable)
2381
+ return;
2382
+ if (sortKey === col) {
2383
+ setSortDir((d) => d === "asc" ? "desc" : "asc");
2384
+ } else {
2385
+ setSortKey(col);
2386
+ setSortDir("asc");
2387
+ }
2388
+ }, [sortable, sortKey]);
2389
+ const handleAction = import_react8.useCallback((action, row) => {
2390
+ const resolvedArgs = {};
2391
+ if (action.args) {
2392
+ for (const [k, v] of Object.entries(action.args)) {
2393
+ if (typeof v === "string" && v.startsWith("{{$.") && v.endsWith("}}")) {
2394
+ const path = v.slice(4, -2);
2395
+ resolvedArgs[k] = row[path];
2396
+ } else {
2397
+ resolvedArgs[k] = v;
2398
+ }
2399
+ }
2400
+ }
2401
+ onAction(action.action, resolvedArgs);
2402
+ }, [onAction]);
2403
+ return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
2404
+ className: cn("w-full overflow-x-auto", node.class),
2405
+ children: [
2406
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("table", {
2407
+ className: "w-full text-sm",
2408
+ children: [
2409
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("thead", {
2410
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("tr", {
2411
+ className: "border-b border-meissa-border",
2412
+ children: [
2413
+ columns.map((col) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("th", {
2414
+ onClick: () => handleSort(col),
2415
+ className: cn("px-3 py-2 font-medium text-meissa-muted", numericCols.has(col) ? "text-right" : "text-left", sortable && "cursor-pointer select-none hover:text-meissa-fg"),
2416
+ children: [
2417
+ headers[col] || toTitleCase(col),
2418
+ sortKey === col && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
2419
+ className: "ml-1",
2420
+ children: sortDir === "asc" ? "↑" : "↓"
2421
+ }, undefined, false, undefined, this)
2422
+ ]
2423
+ }, col, true, undefined, this)),
2424
+ actions && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("th", {
2425
+ className: "px-3 py-2"
2426
+ }, undefined, false, undefined, this)
2427
+ ]
2428
+ }, undefined, true, undefined, this)
2429
+ }, undefined, false, undefined, this),
2430
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("tbody", {
2431
+ children: paginatedData.map((row, i) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("tr", {
2432
+ className: cn("border-b border-meissa-border last:border-0", i % 2 === 1 && "bg-meissa-fg/[0.03]"),
2433
+ children: [
2434
+ columns.map((col) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("td", {
2435
+ className: cn("px-3 py-2 text-meissa-fg", numericCols.has(col) ? "text-right" : "text-left"),
2436
+ children: row[col] != null ? String(row[col]) : ""
2437
+ }, col, false, undefined, this)),
2438
+ actions && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("td", {
2439
+ className: "px-3 py-2 text-right",
2440
+ children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
2441
+ className: "flex justify-end gap-1",
2442
+ children: actions.map((action, ai) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("button", {
2443
+ type: "button",
2444
+ onClick: () => handleAction(action, row),
2445
+ className: cn("px-2 py-1 text-xs rounded font-medium", action.variant === "destructive" ? "text-meissa-destructive hover:bg-meissa-destructive/10" : "text-meissa-primary hover:bg-meissa-primary/10"),
2446
+ children: action.label
2447
+ }, ai, false, undefined, this))
2448
+ }, undefined, false, undefined, this)
2449
+ }, undefined, false, undefined, this)
2450
+ ]
2451
+ }, i, true, undefined, this))
2452
+ }, undefined, false, undefined, this)
2453
+ ]
2454
+ }, undefined, true, undefined, this),
2455
+ paginate && totalPages > 1 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
2456
+ className: "flex items-center justify-between px-3 py-2 border-t border-meissa-border",
2457
+ children: [
2458
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
2459
+ className: "text-xs text-meissa-muted",
2460
+ children: [
2461
+ "Page ",
2462
+ page + 1,
2463
+ " of ",
2464
+ totalPages
2465
+ ]
2466
+ }, undefined, true, undefined, this),
2467
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
2468
+ className: "flex gap-1",
2469
+ children: [
2470
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("button", {
2471
+ type: "button",
2472
+ disabled: page === 0,
2473
+ onClick: () => setPage((p) => p - 1),
2474
+ className: "px-2 py-1 text-xs rounded border border-meissa-border disabled:opacity-50",
2475
+ children: "Prev"
2476
+ }, undefined, false, undefined, this),
2477
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("button", {
2478
+ type: "button",
2479
+ disabled: page >= totalPages - 1,
2480
+ onClick: () => setPage((p) => p + 1),
2481
+ className: "px-2 py-1 text-xs rounded border border-meissa-border disabled:opacity-50",
2482
+ children: "Next"
2483
+ }, undefined, false, undefined, this)
2484
+ ]
2485
+ }, undefined, true, undefined, this)
2486
+ ]
2487
+ }, undefined, true, undefined, this)
2488
+ ]
2489
+ }, undefined, true, undefined, this);
2490
+ }
2491
+
2492
+ // src/renderer/components/List.tsx
2493
+ var jsx_dev_runtime11 = require("react/jsx-dev-runtime");
2494
+ var variantClasses3 = {
2495
+ default: "space-y-1",
2496
+ compact: "space-y-0.5",
2497
+ spaced: "space-y-3"
2498
+ };
2499
+ function List({ node }) {
2500
+ const items = node.items || [];
2501
+ const ordered = node.ordered;
2502
+ const variant = node.variant || "default";
2503
+ const Tag = ordered ? "ol" : "ul";
2504
+ return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Tag, {
2505
+ className: cn(ordered ? "list-decimal" : "list-disc", "pl-5 text-sm text-meissa-fg", variantClasses3[variant], node.class),
2506
+ children: items.map((item, i) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV("li", {
2507
+ children: String(item)
2508
+ }, i, false, undefined, this))
2509
+ }, undefined, false, undefined, this);
2510
+ }
2511
+
2512
+ // src/renderer/components/Chart.tsx
2513
+ var import_react9 = require("react");
2514
+ var jsx_dev_runtime12 = require("react/jsx-dev-runtime");
2515
+ var rechartsPromise = import("recharts");
2516
+ var COLORS = ["#6366f1", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#06b6d4"];
2517
+ function ChartInner({ node }) {
2518
+ const data = node.data || [];
2519
+ const type = node.type || "line";
2520
+ const x = node.x;
2521
+ const y = node.y;
2522
+ const title = node.title;
2523
+ const legend = node.legend !== false;
2524
+ const h = node.h || 256;
2525
+ const colors = node.colors || COLORS;
2526
+ const { xKey, yKeys } = import_react9.useMemo(() => {
2527
+ if (data.length === 0)
2528
+ return { xKey: "", yKeys: [] };
2529
+ const keys = Object.keys(data[0]);
2530
+ const resolvedX = x || keys[0];
2531
+ const resolvedY = y ? Array.isArray(y) ? y : [y] : keys.filter((k) => k !== resolvedX);
2532
+ return { xKey: resolvedX, yKeys: resolvedY };
2533
+ }, [data, x, y]);
2534
+ if (data.length === 0) {
2535
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
2536
+ className: "text-sm text-meissa-muted italic",
2537
+ children: "No data"
2538
+ }, undefined, false, undefined, this);
2539
+ }
2540
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
2541
+ className: cn("w-full", node.class),
2542
+ style: { height: h },
2543
+ children: [
2544
+ title && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("p", {
2545
+ className: "text-sm font-medium text-meissa-fg mb-2",
2546
+ children: title
2547
+ }, undefined, false, undefined, this),
2548
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(import_react9.Suspense, {
2549
+ fallback: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV("div", {
2550
+ className: "animate-pulse bg-meissa-fg/10 rounded w-full h-full"
2551
+ }, undefined, false, undefined, this),
2552
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(RechartsChart, {
2553
+ data,
2554
+ type,
2555
+ xKey,
2556
+ yKeys,
2557
+ colors,
2558
+ legend,
2559
+ h: h - (title ? 28 : 0)
2560
+ }, undefined, false, undefined, this)
2561
+ }, undefined, false, undefined, this)
2562
+ ]
2563
+ }, undefined, true, undefined, this);
2564
+ }
2565
+ function RechartsChart({ data, type, xKey, yKeys, colors, legend, h }) {
2566
+ const recharts = import_react9.use(rechartsPromise);
2567
+ const {
2568
+ ResponsiveContainer,
2569
+ LineChart,
2570
+ Line,
2571
+ BarChart,
2572
+ Bar,
2573
+ AreaChart,
2574
+ Area,
2575
+ PieChart,
2576
+ Pie,
2577
+ Cell,
2578
+ XAxis,
2579
+ YAxis,
2580
+ CartesianGrid,
2581
+ Tooltip,
2582
+ Legend
2583
+ } = recharts;
2584
+ if (type === "sparkline") {
2585
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ResponsiveContainer, {
2586
+ width: "100%",
2587
+ height: h,
2588
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(LineChart, {
2589
+ data,
2590
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Line, {
2591
+ type: "monotone",
2592
+ dataKey: yKeys[0],
2593
+ stroke: colors[0],
2594
+ strokeWidth: 2,
2595
+ dot: false
2596
+ }, undefined, false, undefined, this)
2597
+ }, undefined, false, undefined, this)
2598
+ }, undefined, false, undefined, this);
2599
+ }
2600
+ if (type === "pie" || type === "donut") {
2601
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ResponsiveContainer, {
2602
+ width: "100%",
2603
+ height: h,
2604
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(PieChart, {
2605
+ children: [
2606
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Pie, {
2607
+ data,
2608
+ dataKey: yKeys[0],
2609
+ nameKey: xKey,
2610
+ innerRadius: type === "donut" ? "60%" : 0,
2611
+ outerRadius: "80%",
2612
+ children: data.map((_, i) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Cell, {
2613
+ fill: colors[i % colors.length]
2614
+ }, i, false, undefined, this))
2615
+ }, undefined, false, undefined, this),
2616
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Tooltip, {}, undefined, false, undefined, this),
2617
+ legend && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Legend, {}, undefined, false, undefined, this)
2618
+ ]
2619
+ }, undefined, true, undefined, this)
2620
+ }, undefined, false, undefined, this);
2621
+ }
2622
+ const ChartComponent = type === "bar" ? BarChart : type === "area" ? AreaChart : LineChart;
2623
+ const SeriesComponent = type === "bar" ? Bar : type === "area" ? Area : Line;
2624
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ResponsiveContainer, {
2625
+ width: "100%",
2626
+ height: h,
2627
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ChartComponent, {
2628
+ data,
2629
+ children: [
2630
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(CartesianGrid, {
2631
+ strokeDasharray: "3 3"
2632
+ }, undefined, false, undefined, this),
2633
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(XAxis, {
2634
+ dataKey: xKey,
2635
+ tick: { fontSize: 12 }
2636
+ }, undefined, false, undefined, this),
2637
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(YAxis, {
2638
+ tick: { fontSize: 12 }
2639
+ }, undefined, false, undefined, this),
2640
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Tooltip, {}, undefined, false, undefined, this),
2641
+ legend && yKeys.length > 1 && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Legend, {}, undefined, false, undefined, this),
2642
+ yKeys.map((key, i) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(SeriesComponent, {
2643
+ type: "monotone",
2644
+ dataKey: key,
2645
+ stroke: colors[i % colors.length],
2646
+ fill: colors[i % colors.length],
2647
+ ...type === "area" ? { fillOpacity: 0.3 } : {}
2648
+ }, key, false, undefined, this))
2649
+ ]
2650
+ }, undefined, true, undefined, this)
2651
+ }, undefined, false, undefined, this);
2652
+ }
2653
+ function Chart({ node }) {
2654
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(ChartInner, {
2655
+ node
2656
+ }, undefined, false, undefined, this);
2657
+ }
2658
+
2659
+ // src/renderer/components/Stat.tsx
2660
+ var jsx_dev_runtime13 = require("react/jsx-dev-runtime");
2661
+ var variantClasses4 = {
2662
+ default: "",
2663
+ success: "text-green-600",
2664
+ warning: "text-yellow-600",
2665
+ destructive: "text-red-600"
2666
+ };
2667
+ function Stat({ node }) {
2668
+ const value = node.value;
2669
+ const label = node.label;
2670
+ const trend = node.trend;
2671
+ const variant = node.variant || "default";
2672
+ const trendPositive = trend?.startsWith("+");
2673
+ const trendNegative = trend?.startsWith("-");
2674
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
2675
+ className: cn("flex flex-col gap-1", node.class),
2676
+ children: [
2677
+ label && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
2678
+ className: "text-sm text-meissa-muted",
2679
+ children: label
2680
+ }, undefined, false, undefined, this),
2681
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("div", {
2682
+ className: "flex items-baseline gap-2",
2683
+ children: [
2684
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
2685
+ className: cn("text-2xl font-semibold", variantClasses4[variant] || "text-meissa-fg"),
2686
+ children: value
2687
+ }, undefined, false, undefined, this),
2688
+ trend && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV("span", {
2689
+ className: cn("text-sm font-medium", trendPositive && "text-green-600", trendNegative && "text-red-600", !trendPositive && !trendNegative && "text-meissa-muted"),
2690
+ children: [
2691
+ trendPositive && "↑",
2692
+ trendNegative && "↓",
2693
+ trend
2694
+ ]
2695
+ }, undefined, true, undefined, this)
2696
+ ]
2697
+ }, undefined, true, undefined, this)
2698
+ ]
2699
+ }, undefined, true, undefined, this);
2700
+ }
2701
+
2702
+ // src/renderer/components/Card.tsx
2703
+ var jsx_dev_runtime14 = require("react/jsx-dev-runtime");
2704
+ var variantClasses5 = {
2705
+ default: "border border-meissa-border bg-meissa-bg",
2706
+ outline: "border-2 border-meissa-border bg-transparent",
2707
+ elevated: "border border-meissa-border bg-meissa-bg shadow-md"
2708
+ };
2709
+ var paddingClasses = {
2710
+ 0: "p-0",
2711
+ 1: "p-1",
2712
+ 2: "p-2",
2713
+ 3: "p-3",
2714
+ 4: "p-4",
2715
+ 6: "p-6",
2716
+ 8: "p-8"
2717
+ };
2718
+ function Card({ node, children }) {
2719
+ const title = node.title;
2720
+ const subtitle = node.subtitle;
2721
+ const variant = node.variant || "default";
2722
+ const padding = node.padding ?? 4;
2723
+ return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
2724
+ className: cn("rounded-lg", variantClasses5[variant], node.class),
2725
+ children: [
2726
+ (title || subtitle) && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
2727
+ className: cn("border-b border-meissa-border", paddingClasses[padding] || "p-4"),
2728
+ children: [
2729
+ title && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("h3", {
2730
+ className: "font-semibold text-meissa-fg",
2731
+ children: title
2732
+ }, undefined, false, undefined, this),
2733
+ subtitle && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("p", {
2734
+ className: "text-sm text-meissa-muted mt-0.5",
2735
+ children: subtitle
2736
+ }, undefined, false, undefined, this)
2737
+ ]
2738
+ }, undefined, true, undefined, this),
2739
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV("div", {
2740
+ className: cn("flex flex-col gap-4", paddingClasses[padding] || "p-4"),
2741
+ children
2742
+ }, undefined, false, undefined, this)
2743
+ ]
2744
+ }, undefined, true, undefined, this);
2745
+ }
2746
+
2747
+ // src/renderer/components/Tabs.tsx
2748
+ var import_react10 = require("react");
2749
+ var jsx_dev_runtime15 = require("react/jsx-dev-runtime");
2750
+ var tabVariantClasses = {
2751
+ default: "border-b-2 border-transparent data-[active=true]:border-meissa-primary data-[active=true]:text-meissa-primary",
2752
+ pills: "rounded-md data-[active=true]:bg-meissa-primary data-[active=true]:text-white",
2753
+ underline: "border-b-2 border-transparent data-[active=true]:border-meissa-fg data-[active=true]:text-meissa-fg"
2754
+ };
2755
+ function Tabs({ node, children }) {
2756
+ const items = node.items || {};
2757
+ const defaultTab = node.default || Object.keys(items)[0];
2758
+ const variant = node.variant || "default";
2759
+ const [activeTab, setActiveTab] = import_react10.useState(defaultTab);
2760
+ const tabKeys = Object.keys(items);
2761
+ return /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
2762
+ className: cn("w-full", node.class),
2763
+ children: [
2764
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
2765
+ className: cn("flex", variant === "default" || variant === "underline" ? "border-b border-meissa-border" : "gap-1"),
2766
+ role: "tablist",
2767
+ children: tabKeys.map((key) => /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("button", {
2768
+ type: "button",
2769
+ role: "tab",
2770
+ "aria-selected": activeTab === key,
2771
+ "data-active": activeTab === key,
2772
+ onClick: () => setActiveTab(key),
2773
+ className: cn("px-4 py-2 text-sm font-medium text-meissa-muted transition-colors", "hover:text-meissa-fg", tabVariantClasses[variant]),
2774
+ children: key
2775
+ }, key, false, undefined, this))
2776
+ }, undefined, false, undefined, this),
2777
+ /* @__PURE__ */ jsx_dev_runtime15.jsxDEV("div", {
2778
+ className: "pt-4",
2779
+ role: "tabpanel",
2780
+ children
2781
+ }, undefined, false, undefined, this)
2782
+ ]
2783
+ }, undefined, true, undefined, this);
2784
+ }
2785
+
2786
+ // src/renderer/components/Alert.tsx
2787
+ var import_react11 = require("react");
2788
+ var jsx_dev_runtime16 = require("react/jsx-dev-runtime");
2789
+ var variantClasses6 = {
2790
+ info: "bg-meissa-primary/10 border-meissa-primary/20 text-meissa-primary",
2791
+ success: "bg-meissa-success/10 border-meissa-success/20 text-meissa-success",
2792
+ warning: "bg-meissa-warning/10 border-meissa-warning/20 text-meissa-warning",
2793
+ error: "bg-meissa-destructive/10 border-meissa-destructive/20 text-meissa-destructive"
2794
+ };
2795
+ function Alert({ node }) {
2796
+ const [dismissed, setDismissed] = import_react11.useState(false);
2797
+ const content = node.content;
2798
+ const variant = node.variant || "info";
2799
+ const title = node.title;
2800
+ const dismissible = node.dismissible;
2801
+ const handleDismiss = import_react11.useCallback(() => setDismissed(true), []);
2802
+ if (dismissed)
2803
+ return null;
2804
+ return /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
2805
+ role: "alert",
2806
+ className: cn("rounded-md border p-4", variantClasses6[variant], node.class),
2807
+ children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
2808
+ className: "flex items-start justify-between",
2809
+ children: [
2810
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("div", {
2811
+ className: "flex-1",
2812
+ children: [
2813
+ title && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("p", {
2814
+ className: "font-medium mb-1",
2815
+ children: title
2816
+ }, undefined, false, undefined, this),
2817
+ /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("p", {
2818
+ className: "text-sm",
2819
+ children: content
2820
+ }, undefined, false, undefined, this)
2821
+ ]
2822
+ }, undefined, true, undefined, this),
2823
+ dismissible && /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("button", {
2824
+ type: "button",
2825
+ onClick: handleDismiss,
2826
+ className: "ml-3 inline-flex shrink-0 rounded p-1 opacity-70 hover:opacity-100",
2827
+ "aria-label": "Dismiss",
2828
+ children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("svg", {
2829
+ className: "h-4 w-4",
2830
+ fill: "none",
2831
+ viewBox: "0 0 24 24",
2832
+ stroke: "currentColor",
2833
+ children: /* @__PURE__ */ jsx_dev_runtime16.jsxDEV("path", {
2834
+ strokeLinecap: "round",
2835
+ strokeLinejoin: "round",
2836
+ strokeWidth: 2,
2837
+ d: "M6 18L18 6M6 6l12 12"
2838
+ }, undefined, false, undefined, this)
2839
+ }, undefined, false, undefined, this)
2840
+ }, undefined, false, undefined, this)
2841
+ ]
2842
+ }, undefined, true, undefined, this)
2843
+ }, undefined, false, undefined, this);
2844
+ }
2845
+
2846
+ // src/renderer/components/Badge.tsx
2847
+ var jsx_dev_runtime17 = require("react/jsx-dev-runtime");
2848
+ var variantClasses7 = {
2849
+ default: "bg-meissa-fg/10 text-meissa-fg",
2850
+ primary: "bg-meissa-primary/10 text-meissa-primary",
2851
+ success: "bg-meissa-success/10 text-meissa-success",
2852
+ warning: "bg-meissa-warning/10 text-meissa-warning",
2853
+ error: "bg-meissa-destructive/10 text-meissa-destructive",
2854
+ outline: "border border-meissa-border text-meissa-fg"
2855
+ };
2856
+ function Badge({ node }) {
2857
+ const content = node.content;
2858
+ const variant = node.variant || "default";
2859
+ return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV("span", {
2860
+ className: cn("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium", variantClasses7[variant], node.class),
2861
+ children: content
2862
+ }, undefined, false, undefined, this);
2863
+ }
2864
+
2865
+ // src/renderer/components/Progress.tsx
2866
+ var jsx_dev_runtime18 = require("react/jsx-dev-runtime");
2867
+ var variantClasses8 = {
2868
+ default: "bg-meissa-primary",
2869
+ success: "bg-green-500",
2870
+ warning: "bg-yellow-500",
2871
+ error: "bg-red-500"
2872
+ };
2873
+ function Progress({ node }) {
2874
+ const value = node.value ?? 0;
2875
+ const label = node.label;
2876
+ const showValue = node.showValue;
2877
+ const variant = node.variant || "default";
2878
+ const indeterminate = node.indeterminate;
2879
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
2880
+ className: cn("w-full", node.class),
2881
+ children: [
2882
+ (label || showValue) && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
2883
+ className: "flex justify-between mb-1",
2884
+ children: [
2885
+ label && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
2886
+ className: "text-sm text-meissa-fg",
2887
+ children: label
2888
+ }, undefined, false, undefined, this),
2889
+ showValue && !indeterminate && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("span", {
2890
+ className: "text-sm text-meissa-muted",
2891
+ children: [
2892
+ Math.round(value),
2893
+ "%"
2894
+ ]
2895
+ }, undefined, true, undefined, this)
2896
+ ]
2897
+ }, undefined, true, undefined, this),
2898
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
2899
+ className: "w-full h-2 bg-meissa-fg/10 rounded-full overflow-hidden",
2900
+ children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV("div", {
2901
+ className: cn("h-full rounded-full transition-all duration-300", variantClasses8[variant], indeterminate && "animate-pulse w-full"),
2902
+ style: !indeterminate ? { width: `${Math.min(100, Math.max(0, value))}%` } : undefined,
2903
+ role: "progressbar",
2904
+ "aria-valuenow": indeterminate ? undefined : value,
2905
+ "aria-valuemin": 0,
2906
+ "aria-valuemax": 100
2907
+ }, undefined, false, undefined, this)
2908
+ }, undefined, false, undefined, this)
2909
+ ]
2910
+ }, undefined, true, undefined, this);
2911
+ }
2912
+
2913
+ // src/renderer/components/Divider.tsx
2914
+ var jsx_dev_runtime19 = require("react/jsx-dev-runtime");
2915
+ var spacingClasses = {
2916
+ 0: "my-0",
2917
+ 1: "my-1",
2918
+ 2: "my-2",
2919
+ 3: "my-3",
2920
+ 4: "my-4",
2921
+ 6: "my-6",
2922
+ 8: "my-8",
2923
+ 10: "my-10",
2924
+ 12: "my-12",
2925
+ 16: "my-16"
2926
+ };
2927
+ function Divider({ node }) {
2928
+ const label = node.label;
2929
+ const spacing = node.spacing ?? 4;
2930
+ if (label) {
2931
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
2932
+ className: cn("flex items-center", spacingClasses[spacing] || "my-4", node.class),
2933
+ children: [
2934
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
2935
+ className: "flex-1 border-t border-meissa-border"
2936
+ }, undefined, false, undefined, this),
2937
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("span", {
2938
+ className: "px-3 text-sm text-meissa-muted",
2939
+ children: label
2940
+ }, undefined, false, undefined, this),
2941
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("div", {
2942
+ className: "flex-1 border-t border-meissa-border"
2943
+ }, undefined, false, undefined, this)
2944
+ ]
2945
+ }, undefined, true, undefined, this);
2946
+ }
2947
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV("hr", {
2948
+ className: cn("border-t border-meissa-border", spacingClasses[spacing] || "my-4", node.class)
2949
+ }, undefined, false, undefined, this);
2950
+ }
2951
+
2952
+ // src/renderer/components/Row.tsx
2953
+ var jsx_dev_runtime20 = require("react/jsx-dev-runtime");
2954
+ var alignClasses3 = {
2955
+ start: "items-start",
2956
+ center: "items-center",
2957
+ end: "items-end",
2958
+ stretch: "items-stretch"
2959
+ };
2960
+ var justifyClasses = {
2961
+ start: "justify-start",
2962
+ center: "justify-center",
2963
+ end: "justify-end",
2964
+ between: "justify-between",
2965
+ around: "justify-around"
2966
+ };
2967
+ var gapClasses = {
2968
+ 0: "gap-0",
2969
+ 1: "gap-1",
2970
+ 2: "gap-2",
2971
+ 3: "gap-3",
2972
+ 4: "gap-4",
2973
+ 6: "gap-6",
2974
+ 8: "gap-8",
2975
+ 10: "gap-10",
2976
+ 12: "gap-12",
2977
+ 16: "gap-16"
2978
+ };
2979
+ function Row({ node, children }) {
2980
+ const gap = node.gap ?? 4;
2981
+ const align = node.align || "center";
2982
+ const justify = node.justify || "start";
2983
+ const wrap = node.wrap;
2984
+ return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV("div", {
2985
+ className: cn("flex flex-row", gapClasses[gap] || "gap-4", alignClasses3[align], justifyClasses[justify], wrap && "flex-wrap", "max-sm:flex-wrap", node.class),
2986
+ children
2987
+ }, undefined, false, undefined, this);
2988
+ }
2989
+
2990
+ // src/renderer/components/Col.tsx
2991
+ var jsx_dev_runtime21 = require("react/jsx-dev-runtime");
2992
+ var alignClasses4 = {
2993
+ start: "items-start",
2994
+ center: "items-center",
2995
+ end: "items-end",
2996
+ stretch: "items-stretch"
2997
+ };
2998
+ var justifyClasses2 = {
2999
+ start: "justify-start",
3000
+ center: "justify-center",
3001
+ end: "justify-end",
3002
+ between: "justify-between",
3003
+ around: "justify-around"
3004
+ };
3005
+ var gapClasses2 = {
3006
+ 0: "gap-0",
3007
+ 1: "gap-1",
3008
+ 2: "gap-2",
3009
+ 3: "gap-3",
3010
+ 4: "gap-4",
3011
+ 6: "gap-6",
3012
+ 8: "gap-8",
3013
+ 10: "gap-10",
3014
+ 12: "gap-12",
3015
+ 16: "gap-16"
3016
+ };
3017
+ function Col({ node, children }) {
3018
+ const gap = node.gap ?? 4;
3019
+ const align = node.align || "stretch";
3020
+ const justify = node.justify || "start";
3021
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV("div", {
3022
+ className: cn("flex flex-col", gapClasses2[gap] || "gap-4", alignClasses4[align], justifyClasses2[justify], node.class),
3023
+ children
3024
+ }, undefined, false, undefined, this);
3025
+ }
3026
+
3027
+ // src/renderer/components/Grid.tsx
3028
+ var jsx_dev_runtime22 = require("react/jsx-dev-runtime");
3029
+ var colsClasses = {
3030
+ 1: "grid-cols-1",
3031
+ 2: "grid-cols-2",
3032
+ 3: "grid-cols-3",
3033
+ 4: "grid-cols-4",
3034
+ 5: "grid-cols-5",
3035
+ 6: "grid-cols-6"
3036
+ };
3037
+ var gapClasses3 = {
3038
+ 0: "gap-0",
3039
+ 1: "gap-1",
3040
+ 2: "gap-2",
3041
+ 3: "gap-3",
3042
+ 4: "gap-4",
3043
+ 6: "gap-6",
3044
+ 8: "gap-8",
3045
+ 10: "gap-10",
3046
+ 12: "gap-12",
3047
+ 16: "gap-16"
3048
+ };
3049
+ var alignClasses5 = {
3050
+ start: "items-start",
3051
+ center: "items-center",
3052
+ end: "items-end",
3053
+ stretch: "items-stretch"
3054
+ };
3055
+ function Grid({ node, children }) {
3056
+ const cols = node.cols ?? 3;
3057
+ const gap = node.gap ?? 4;
3058
+ const align = node.align || "stretch";
3059
+ return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV("div", {
3060
+ className: cn("grid", colsClasses[cols] || `grid-cols-${cols}`, gapClasses3[gap] || "gap-4", alignClasses5[align], "max-sm:grid-cols-1 max-md:grid-cols-2", node.class),
3061
+ children
3062
+ }, undefined, false, undefined, this);
3063
+ }
3064
+
3065
+ // src/renderer/components/Split.tsx
3066
+ var jsx_dev_runtime23 = require("react/jsx-dev-runtime");
3067
+ var ratioMap = {
3068
+ "1/4": ["w-1/4", "w-3/4"],
3069
+ "1/3": ["w-1/3", "w-2/3"],
3070
+ "1/2": ["w-1/2", "w-1/2"],
3071
+ "2/3": ["w-2/3", "w-1/3"],
3072
+ "3/4": ["w-3/4", "w-1/4"]
3073
+ };
3074
+ var gapClasses4 = {
3075
+ 0: "gap-0",
3076
+ 1: "gap-1",
3077
+ 2: "gap-2",
3078
+ 3: "gap-3",
3079
+ 4: "gap-4",
3080
+ 6: "gap-6",
3081
+ 8: "gap-8",
3082
+ 10: "gap-10",
3083
+ 12: "gap-12",
3084
+ 16: "gap-16"
3085
+ };
3086
+ function Split({ node, children }) {
3087
+ const ratio = node.ratio || "1/3";
3088
+ const gap = node.gap ?? 4;
3089
+ const dir = node.dir || "row";
3090
+ const isCol = dir === "col";
3091
+ const [firstSize, secondSize] = ratioMap[ratio] || ["w-1/3", "w-2/3"];
3092
+ const childArray = Array.isArray(children) ? children : [children];
3093
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
3094
+ className: cn("flex", isCol ? "flex-col" : "flex-row", gapClasses4[gap] || "gap-4", "max-sm:flex-col", node.class),
3095
+ children: [
3096
+ childArray[0] && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
3097
+ className: cn(!isCol && firstSize, "max-sm:w-full"),
3098
+ children: childArray[0]
3099
+ }, undefined, false, undefined, this),
3100
+ childArray[1] && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV("div", {
3101
+ className: cn(!isCol && secondSize, "max-sm:w-full"),
3102
+ children: childArray[1]
3103
+ }, undefined, false, undefined, this)
3104
+ ]
3105
+ }, undefined, true, undefined, this);
3106
+ }
3107
+
3108
+ // src/renderer/components/index.ts
3109
+ var COMPONENT_REGISTRY = {
3110
+ text: Text,
3111
+ heading: Heading,
3112
+ code: Code,
3113
+ img: Img,
3114
+ btn: Btn,
3115
+ input: Input,
3116
+ select: Select,
3117
+ form: Form,
3118
+ table: Table,
3119
+ list: List,
3120
+ chart: Chart,
3121
+ stat: Stat,
3122
+ card: Card,
3123
+ tabs: Tabs,
3124
+ alert: Alert,
3125
+ badge: Badge,
3126
+ progress: Progress,
3127
+ divider: Divider,
3128
+ row: Row,
3129
+ col: Col,
3130
+ grid: Grid,
3131
+ split: Split
3132
+ };
3133
+
3134
+ // src/renderer/ComponentRenderer.tsx
3135
+ var jsx_dev_runtime24 = require("react/jsx-dev-runtime");
3136
+ function ComponentRenderer({ node }) {
3137
+ const { data } = useData();
3138
+ const evalResult = import_react12.useMemo(() => evaluate(node, data), [node, data]);
3139
+ if (!evalResult.node)
3140
+ return null;
3141
+ const evaluatedNode = evalResult.node;
3142
+ if (evaluatedNode.type === "each") {
3143
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(EachRenderer, {
3144
+ node: evaluatedNode
3145
+ }, undefined, false, undefined, this);
3146
+ }
3147
+ if (evaluatedNode.type === "fragment") {
3148
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(FragmentRenderer, {
3149
+ node: evaluatedNode
3150
+ }, undefined, false, undefined, this);
3151
+ }
3152
+ const boundNode = import_react12.useMemo(() => bindNode(evaluatedNode, data), [evaluatedNode, data]);
3153
+ const Component = COMPONENT_REGISTRY[boundNode.type];
3154
+ if (!Component) {
3155
+ if (typeof globalThis !== "undefined" && globalThis.process?.env?.NODE_ENV !== "production") {
3156
+ console.warn(`[Meissa] Unknown component type: "${boundNode.type}"`);
3157
+ }
3158
+ return null;
3159
+ }
3160
+ const children = boundNode.children?.map((child, i) => /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ComponentRenderer, {
3161
+ node: child
3162
+ }, child.id || i, false, undefined, this));
3163
+ const element = /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Component, {
3164
+ node: boundNode,
3165
+ children
3166
+ }, undefined, false, undefined, this);
3167
+ if (evalResult.hidden) {
3168
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV("div", {
3169
+ style: { display: "none" },
3170
+ children: element
3171
+ }, undefined, false, undefined, this);
3172
+ }
3173
+ return element;
3174
+ }
3175
+ function EachRenderer({ node }) {
3176
+ const { data, root } = useData();
3177
+ const items = import_react12.useMemo(() => expandEach(node, data), [node, data]);
3178
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(jsx_dev_runtime24.Fragment, {
3179
+ children: items.map((item, i) => /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(DataProvider, {
3180
+ value: { data: item.data, root },
3181
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ComponentRenderer, {
3182
+ node: item.node
3183
+ }, undefined, false, undefined, this)
3184
+ }, i, false, undefined, this))
3185
+ }, undefined, false, undefined, this);
3186
+ }
3187
+ function FragmentRenderer({ node }) {
3188
+ if (!node.children)
3189
+ return null;
3190
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(jsx_dev_runtime24.Fragment, {
3191
+ children: node.children.map((child, i) => /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ComponentRenderer, {
3192
+ node: child
3193
+ }, child.id || i, false, undefined, this))
3194
+ }, undefined, false, undefined, this);
3195
+ }
3196
+ function bindNode(node, data) {
3197
+ const bound = { type: node.type };
3198
+ for (const [key, value] of Object.entries(node)) {
3199
+ if (key === "type")
3200
+ continue;
3201
+ if (key === "children") {
3202
+ bound.children = node.children;
3203
+ continue;
3204
+ }
3205
+ bound[key] = bindValue(value, data);
3206
+ }
3207
+ return bound;
3208
+ }
3209
+ function bindValue(value, data) {
3210
+ if (typeof value === "string") {
3211
+ return resolveBindings(value, data);
3212
+ }
3213
+ if (Array.isArray(value)) {
3214
+ return value.map((item) => bindValue(item, data));
3215
+ }
3216
+ if (value !== null && typeof value === "object") {
3217
+ const result = {};
3218
+ for (const [k, v] of Object.entries(value)) {
3219
+ result[k] = bindValue(v, data);
3220
+ }
3221
+ return result;
3222
+ }
3223
+ return value;
3224
+ }
3225
+
3226
+ // src/renderer/MeissaRenderer.tsx
3227
+ var jsx_dev_runtime25 = require("react/jsx-dev-runtime");
3228
+ var noop2 = () => {};
3229
+ function MeissaRenderer({
3230
+ schema,
3231
+ data: externalData,
3232
+ theme,
3233
+ onAction = noop2,
3234
+ onNavigate = noop2,
3235
+ className
3236
+ }) {
3237
+ const parsed = import_react13.useMemo(() => parse(schema), [schema]);
3238
+ const mergedData = import_react13.useMemo(() => ({ ...parsed.data, ...externalData }), [parsed.data, externalData]);
3239
+ const themeStyles = import_react13.useMemo(() => {
3240
+ const mergedTheme = { ...parsed.theme, ...theme };
3241
+ if (!mergedTheme?.colors)
3242
+ return;
3243
+ const vars = {};
3244
+ const { colors } = mergedTheme;
3245
+ if (colors.primary)
3246
+ vars["--meissa-primary"] = colors.primary;
3247
+ if (colors.destructive)
3248
+ vars["--meissa-destructive"] = colors.destructive;
3249
+ if (colors.success)
3250
+ vars["--meissa-success"] = colors.success;
3251
+ if (colors.warning)
3252
+ vars["--meissa-warning"] = colors.warning;
3253
+ if (colors.bg)
3254
+ vars["--meissa-bg"] = colors.bg;
3255
+ if (colors.fg)
3256
+ vars["--meissa-fg"] = colors.fg;
3257
+ if (colors.muted)
3258
+ vars["--meissa-muted"] = colors.muted;
3259
+ if (colors.border)
3260
+ vars["--meissa-border"] = colors.border;
3261
+ return vars;
3262
+ }, [parsed.theme, theme]);
3263
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV("div", {
3264
+ className: cn("flex flex-col gap-4", className),
3265
+ style: themeStyles,
3266
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(ActionProvider, {
3267
+ value: { onAction, onNavigate },
3268
+ children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(DataProvider, {
3269
+ value: { data: mergedData, root: mergedData },
3270
+ children: parsed.nodes.map((node, i) => /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(ComponentRenderer, {
3271
+ node
3272
+ }, node.id || i, false, undefined, this))
3273
+ }, undefined, false, undefined, this)
3274
+ }, undefined, false, undefined, this)
3275
+ }, undefined, false, undefined, this);
3276
+ }
3277
+ // src/client/patch.ts
3278
+ function parsePointer(pointer) {
3279
+ if (pointer === "" || pointer === "/")
3280
+ return [];
3281
+ if (!pointer.startsWith("/")) {
3282
+ throw new Error(`Invalid JSON Pointer: "${pointer}" — must start with "/"`);
3283
+ }
3284
+ return pointer.slice(1).split("/").map((seg) => seg.replace(/~1/g, "/").replace(/~0/g, "~"));
3285
+ }
3286
+ function traverse(obj, segments) {
3287
+ if (segments.length === 0) {
3288
+ throw new Error("Cannot operate on root with empty path");
3289
+ }
3290
+ let current = obj;
3291
+ for (let i = 0;i < segments.length - 1; i++) {
3292
+ const seg = segments[i];
3293
+ if (Array.isArray(current)) {
3294
+ const idx = parseInt(seg, 10);
3295
+ if (isNaN(idx))
3296
+ throw new Error(`Invalid array index: "${seg}"`);
3297
+ current = current[idx];
3298
+ } else if (current !== null && typeof current === "object") {
3299
+ current = current[seg];
3300
+ } else {
3301
+ throw new Error(`Cannot traverse into ${typeof current} at segment "${seg}"`);
3302
+ }
3303
+ }
3304
+ return [current, segments[segments.length - 1]];
3305
+ }
3306
+ function applyOp(data, op) {
3307
+ const segments = parsePointer(op.path);
3308
+ if (segments.length === 0) {
3309
+ if (op.op === "replace") {
3310
+ throw new Error("Cannot replace root — use update() instead");
3311
+ }
3312
+ throw new Error(`Cannot ${op.op} at root path`);
3313
+ }
3314
+ const [parent, lastKey] = traverse(data, segments);
3315
+ if (Array.isArray(parent)) {
3316
+ const isAppend = lastKey === "-";
3317
+ const idx = isAppend ? parent.length : parseInt(lastKey, 10);
3318
+ switch (op.op) {
3319
+ case "add":
3320
+ if (isAppend) {
3321
+ parent.push(op.value);
3322
+ } else {
3323
+ if (isNaN(idx))
3324
+ throw new Error(`Invalid array index: "${lastKey}"`);
3325
+ parent.splice(idx, 0, op.value);
3326
+ }
3327
+ break;
3328
+ case "replace":
3329
+ if (isNaN(idx))
3330
+ throw new Error(`Invalid array index: "${lastKey}"`);
3331
+ parent[idx] = op.value;
3332
+ break;
3333
+ case "remove":
3334
+ if (isNaN(idx))
3335
+ throw new Error(`Invalid array index: "${lastKey}"`);
3336
+ parent.splice(idx, 1);
3337
+ break;
3338
+ }
3339
+ } else if (parent !== null && typeof parent === "object") {
3340
+ const obj = parent;
3341
+ switch (op.op) {
3342
+ case "add":
3343
+ case "replace":
3344
+ obj[lastKey] = op.value;
3345
+ break;
3346
+ case "remove":
3347
+ delete obj[lastKey];
3348
+ break;
3349
+ }
3350
+ } else {
3351
+ throw new Error(`Cannot apply patch at "${op.path}" — parent is not an object or array`);
3352
+ }
3353
+ }
3354
+ function applyPatches(data, patches) {
3355
+ const cloned = structuredClone(data);
3356
+ for (const patch of patches) {
3357
+ applyOp(cloned, patch);
3358
+ }
3359
+ return cloned;
3360
+ }
3361
+
3362
+ // src/client/renderer.ts
3363
+ class MeissaClientRenderer {
3364
+ root;
3365
+ container;
3366
+ theme;
3367
+ onAction;
3368
+ onNavigate;
3369
+ currentSchema = null;
3370
+ currentData = {};
3371
+ destroyed = false;
3372
+ constructor(options) {
3373
+ this.container = options.container;
3374
+ this.theme = options.theme;
3375
+ this.onAction = options.onAction;
3376
+ this.onNavigate = options.onNavigate;
3377
+ this.root = import_client.createRoot(this.container);
3378
+ }
3379
+ render(schema, data) {
3380
+ if (this.destroyed) {
3381
+ throw new Error("MeissaClientRenderer has been destroyed");
3382
+ }
3383
+ this.currentSchema = schema;
3384
+ if (data !== undefined) {
3385
+ this.currentData = data;
3386
+ }
3387
+ this.commitRender();
3388
+ }
3389
+ patch(patches) {
3390
+ if (this.destroyed) {
3391
+ throw new Error("MeissaClientRenderer has been destroyed");
3392
+ }
3393
+ if (!this.currentSchema) {
3394
+ throw new Error("Cannot patch before initial render");
3395
+ }
3396
+ this.currentData = applyPatches(this.currentData, patches);
3397
+ this.commitRender();
3398
+ }
3399
+ update(data) {
3400
+ if (this.destroyed) {
3401
+ throw new Error("MeissaClientRenderer has been destroyed");
3402
+ }
3403
+ if (!this.currentSchema) {
3404
+ throw new Error("Cannot update before initial render");
3405
+ }
3406
+ this.currentData = data;
3407
+ this.commitRender();
3408
+ }
3409
+ destroy() {
3410
+ if (this.destroyed)
3411
+ return;
3412
+ this.destroyed = true;
3413
+ this.root.unmount();
3414
+ this.currentSchema = null;
3415
+ this.currentData = {};
3416
+ }
3417
+ commitRender() {
3418
+ if (!this.currentSchema)
3419
+ return;
3420
+ const handleAction = (name, args) => {
3421
+ if (this.onAction) {
3422
+ this.onAction(name, args ?? {});
3423
+ }
3424
+ };
3425
+ const handleNavigate = (uri) => {
3426
+ if (this.onNavigate) {
3427
+ this.onNavigate(uri);
3428
+ }
3429
+ };
3430
+ this.root.render(import_react14.createElement(MeissaRenderer, {
3431
+ schema: this.currentSchema,
3432
+ data: this.currentData,
3433
+ theme: this.theme,
3434
+ onAction: handleAction,
3435
+ onNavigate: handleNavigate
3436
+ }));
3437
+ }
3438
+ }
3439
+ // src/client/component.tsx
3440
+ var import_react15 = require("react");
3441
+ var import_react16 = require("react");
3442
+ var jsx_dev_runtime26 = require("react/jsx-dev-runtime");
3443
+ function MeissaContent({
3444
+ schema,
3445
+ data: externalData,
3446
+ theme,
3447
+ onAction,
3448
+ onNavigate,
3449
+ className
3450
+ }) {
3451
+ const [patchedData, setPatchedData] = import_react15.useState(externalData);
3452
+ const dataRef = import_react15.useRef(patchedData);
3453
+ dataRef.current = patchedData;
3454
+ const prevExternalRef = import_react15.useRef(externalData);
3455
+ if (externalData !== prevExternalRef.current) {
3456
+ prevExternalRef.current = externalData;
3457
+ setPatchedData(externalData);
3458
+ dataRef.current = externalData;
3459
+ }
3460
+ const applyPatch = import_react15.useCallback((patches) => {
3461
+ setPatchedData((current) => {
3462
+ const base = current ?? {};
3463
+ return applyPatches(base, patches);
3464
+ });
3465
+ }, []);
3466
+ const handleAction = import_react15.useCallback((name, args) => {
3467
+ if (onAction) {
3468
+ onAction(name, args ?? {});
3469
+ }
3470
+ }, [onAction]);
3471
+ const handleNavigate = import_react15.useCallback((uri) => {
3472
+ if (onNavigate) {
3473
+ onNavigate(uri);
3474
+ }
3475
+ }, [onNavigate]);
3476
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(MeissaRenderer, {
3477
+ schema,
3478
+ data: patchedData,
3479
+ theme,
3480
+ onAction: handleAction,
3481
+ onNavigate: handleNavigate,
3482
+ className
3483
+ }, undefined, false, undefined, this);
3484
+ }
3485
+ var MeissaContentWithRef = import_react16.forwardRef(function MeissaContentWithRef2(props, ref) {
3486
+ const [patchedData, setPatchedData] = import_react15.useState(props.data);
3487
+ const dataRef = import_react15.useRef(patchedData);
3488
+ dataRef.current = patchedData;
3489
+ const prevExternalRef = import_react15.useRef(props.data);
3490
+ if (props.data !== prevExternalRef.current) {
3491
+ prevExternalRef.current = props.data;
3492
+ setPatchedData(props.data);
3493
+ dataRef.current = props.data;
3494
+ }
3495
+ const applyPatchFn = import_react15.useCallback((patches) => {
3496
+ setPatchedData((current) => {
3497
+ const base = current ?? {};
3498
+ return applyPatches(base, patches);
3499
+ });
3500
+ }, []);
3501
+ import_react16.useImperativeHandle(ref, () => ({
3502
+ applyPatch: applyPatchFn
3503
+ }), [applyPatchFn]);
3504
+ const handleAction = import_react15.useCallback((name, args) => {
3505
+ if (props.onAction) {
3506
+ props.onAction(name, args ?? {});
3507
+ }
3508
+ }, [props.onAction]);
3509
+ const handleNavigate = import_react15.useCallback((uri) => {
3510
+ if (props.onNavigate) {
3511
+ props.onNavigate(uri);
3512
+ }
3513
+ }, [props.onNavigate]);
3514
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(MeissaRenderer, {
3515
+ schema: props.schema,
3516
+ data: patchedData,
3517
+ theme: props.theme,
3518
+ onAction: handleAction,
3519
+ onNavigate: handleNavigate,
3520
+ className: props.className
3521
+ }, undefined, false, undefined, this);
3522
+ });
3523
+ // src/client/content.ts
3524
+ function handleMcpContent(contentBlocks) {
3525
+ for (const block of contentBlocks) {
3526
+ if (block.type === "meissa/patch") {
3527
+ const patchBlock = block;
3528
+ return {
3529
+ type: "meissa/patch",
3530
+ target: patchBlock.target,
3531
+ patches: patchBlock.patches
3532
+ };
3533
+ }
3534
+ }
3535
+ for (const block of contentBlocks) {
3536
+ if (block.type === "meissa") {
3537
+ const meissaBlock = block;
3538
+ return {
3539
+ type: "meissa",
3540
+ schema: meissaBlock.schema,
3541
+ data: meissaBlock.data,
3542
+ theme: meissaBlock.theme,
3543
+ fallback: meissaBlock.fallback
3544
+ };
3545
+ }
3546
+ }
3547
+ const textParts = [];
3548
+ for (const block of contentBlocks) {
3549
+ if (block.type === "text") {
3550
+ textParts.push(block.text);
3551
+ }
3552
+ }
3553
+ return {
3554
+ type: "text",
3555
+ text: textParts.join(`
3556
+ `)
3557
+ };
3558
+ }