@utilix-tech/sdk 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 (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +199 -0
  3. package/dist/api-8aZtWhSj.d.cts +308 -0
  4. package/dist/api-8aZtWhSj.d.ts +308 -0
  5. package/dist/chunk-2CJSLYWI.js +520 -0
  6. package/dist/chunk-3BAHSW4C.js +1385 -0
  7. package/dist/chunk-6YPV2AB5.js +1246 -0
  8. package/dist/chunk-BPVAB4P2.js +1126 -0
  9. package/dist/chunk-FL53T24A.js +257 -0
  10. package/dist/chunk-L6KCTHUW.js +1086 -0
  11. package/dist/chunk-MLKGABMK.js +7 -0
  12. package/dist/chunk-ROTPLW7T.js +265 -0
  13. package/dist/chunk-TSAGO3XP.js +1253 -0
  14. package/dist/chunk-UC656APA.js +1080 -0
  15. package/dist/chunk-W4UBLYFU.js +1219 -0
  16. package/dist/chunk-XST6X3HT.js +896 -0
  17. package/dist/chunk-XXYZLLHI.js +2227 -0
  18. package/dist/chunk-ZKL2VX2G.js +2215 -0
  19. package/dist/chunk-ZPQZEIXP.js +685 -0
  20. package/dist/code-QNrdLIR3.d.cts +327 -0
  21. package/dist/code-QNrdLIR3.d.ts +327 -0
  22. package/dist/color-tPwZCr9H.d.cts +229 -0
  23. package/dist/color-tPwZCr9H.d.ts +229 -0
  24. package/dist/css-Cf7AMGM-.d.cts +318 -0
  25. package/dist/css-Cf7AMGM-.d.ts +318 -0
  26. package/dist/data-rMjWNiOJ.d.cts +215 -0
  27. package/dist/data-rMjWNiOJ.d.ts +215 -0
  28. package/dist/encoding-7gmq-vkV.d.cts +108 -0
  29. package/dist/encoding-7gmq-vkV.d.ts +108 -0
  30. package/dist/generators-BGtRGpJZ.d.cts +118 -0
  31. package/dist/generators-BGtRGpJZ.d.ts +118 -0
  32. package/dist/hashing-CnetQFD_.d.cts +76 -0
  33. package/dist/hashing-CnetQFD_.d.ts +76 -0
  34. package/dist/index.cjs +15466 -0
  35. package/dist/index.d.cts +18 -0
  36. package/dist/index.d.ts +18 -0
  37. package/dist/index.js +20 -0
  38. package/dist/json-BjSoIS1h.d.cts +198 -0
  39. package/dist/json-BjSoIS1h.d.ts +198 -0
  40. package/dist/misc-DcVBManm.d.cts +201 -0
  41. package/dist/misc-DcVBManm.d.ts +201 -0
  42. package/dist/network-CNtmrDeN.d.cts +170 -0
  43. package/dist/network-CNtmrDeN.d.ts +170 -0
  44. package/dist/text-DqAjPtQ0.d.cts +319 -0
  45. package/dist/text-DqAjPtQ0.d.ts +319 -0
  46. package/dist/time-DbT8fjaF.d.cts +145 -0
  47. package/dist/time-DbT8fjaF.d.ts +145 -0
  48. package/dist/tools/api.cjs +1216 -0
  49. package/dist/tools/api.d.cts +1 -0
  50. package/dist/tools/api.d.ts +1 -0
  51. package/dist/tools/api.js +2 -0
  52. package/dist/tools/code.cjs +2212 -0
  53. package/dist/tools/code.d.cts +1 -0
  54. package/dist/tools/code.d.ts +1 -0
  55. package/dist/tools/code.js +2 -0
  56. package/dist/tools/color.cjs +1122 -0
  57. package/dist/tools/color.d.cts +1 -0
  58. package/dist/tools/color.d.ts +1 -0
  59. package/dist/tools/color.js +2 -0
  60. package/dist/tools/css.cjs +1242 -0
  61. package/dist/tools/css.d.cts +1 -0
  62. package/dist/tools/css.d.ts +1 -0
  63. package/dist/tools/css.js +2 -0
  64. package/dist/tools/data.cjs +1097 -0
  65. package/dist/tools/data.d.cts +1 -0
  66. package/dist/tools/data.d.ts +1 -0
  67. package/dist/tools/data.js +2 -0
  68. package/dist/tools/encoding.cjs +261 -0
  69. package/dist/tools/encoding.d.cts +1 -0
  70. package/dist/tools/encoding.d.ts +1 -0
  71. package/dist/tools/encoding.js +2 -0
  72. package/dist/tools/generators.cjs +521 -0
  73. package/dist/tools/generators.d.cts +1 -0
  74. package/dist/tools/generators.d.ts +1 -0
  75. package/dist/tools/generators.js +2 -0
  76. package/dist/tools/hashing.cjs +259 -0
  77. package/dist/tools/hashing.d.cts +1 -0
  78. package/dist/tools/hashing.d.ts +1 -0
  79. package/dist/tools/hashing.js +2 -0
  80. package/dist/tools/json.cjs +1270 -0
  81. package/dist/tools/json.d.cts +1 -0
  82. package/dist/tools/json.d.ts +1 -0
  83. package/dist/tools/json.js +2 -0
  84. package/dist/tools/misc.cjs +1082 -0
  85. package/dist/tools/misc.d.cts +1 -0
  86. package/dist/tools/misc.d.ts +1 -0
  87. package/dist/tools/misc.js +2 -0
  88. package/dist/tools/network.cjs +1381 -0
  89. package/dist/tools/network.d.cts +1 -0
  90. package/dist/tools/network.d.ts +1 -0
  91. package/dist/tools/network.js +2 -0
  92. package/dist/tools/text.cjs +2224 -0
  93. package/dist/tools/text.d.cts +1 -0
  94. package/dist/tools/text.d.ts +1 -0
  95. package/dist/tools/text.js +2 -0
  96. package/dist/tools/time.cjs +681 -0
  97. package/dist/tools/time.d.cts +1 -0
  98. package/dist/tools/time.d.ts +1 -0
  99. package/dist/tools/time.js +2 -0
  100. package/dist/tools/units.cjs +892 -0
  101. package/dist/tools/units.d.cts +1 -0
  102. package/dist/tools/units.d.ts +1 -0
  103. package/dist/tools/units.js +2 -0
  104. package/dist/units-6lwDYBvX.d.cts +302 -0
  105. package/dist/units-6lwDYBvX.d.ts +302 -0
  106. package/package.json +148 -0
@@ -0,0 +1,1242 @@
1
+ 'use strict';
2
+
3
+ // src/tools/css.ts
4
+ function generateGradient(config) {
5
+ const stops = config.stops.map((s) => `${s.color} ${s.position}%`).join(", ");
6
+ if (config.type === "linear") {
7
+ return `linear-gradient(${config.angle}deg, ${stops})`;
8
+ }
9
+ if (config.type === "radial") {
10
+ const shape = config.radialShape ?? "ellipse";
11
+ return `radial-gradient(${shape} at center, ${stops})`;
12
+ }
13
+ return `conic-gradient(from ${config.angle}deg, ${stops})`;
14
+ }
15
+ function generateCssProperty(config) {
16
+ return `background: ${generateGradient(config)};`;
17
+ }
18
+ function parseGradient(css) {
19
+ const trimmed = css.trim();
20
+ const linearMatch = trimmed.match(/^linear-gradient\((.+)\)$/);
21
+ if (linearMatch) {
22
+ const inner = linearMatch[1];
23
+ const parts = inner.split(",").map((p) => p.trim());
24
+ const angleMatch = parts[0].match(/^(-?\d+(?:\.\d+)?)deg$/);
25
+ const angle = angleMatch ? parseFloat(angleMatch[1]) : 0;
26
+ const stopParts = angleMatch ? parts.slice(1) : parts;
27
+ const stops = parseStops(stopParts);
28
+ if (!stops) return { error: "Could not parse color stops" };
29
+ return { type: "linear", angle, stops };
30
+ }
31
+ const radialMatch = trimmed.match(/^radial-gradient\((.+)\)$/);
32
+ if (radialMatch) {
33
+ const inner = radialMatch[1];
34
+ const parts = inner.split(",").map((p) => p.trim());
35
+ const shapeMatch = parts[0].match(/^(circle|ellipse)/);
36
+ const radialShape = shapeMatch && (shapeMatch[1] === "circle" || shapeMatch[1] === "ellipse") ? shapeMatch[1] : "ellipse";
37
+ const stopParts = shapeMatch ? parts.slice(1) : parts;
38
+ const stops = parseStops(stopParts);
39
+ if (!stops) return { error: "Could not parse color stops" };
40
+ return { type: "radial", angle: 0, stops, radialShape };
41
+ }
42
+ const conicMatch = trimmed.match(/^conic-gradient\((.+)\)$/);
43
+ if (conicMatch) {
44
+ const inner = conicMatch[1];
45
+ const parts = inner.split(",").map((p) => p.trim());
46
+ const fromMatch = parts[0].match(/^from\s+(-?\d+(?:\.\d+)?)deg$/);
47
+ const angle = fromMatch ? parseFloat(fromMatch[1]) : 0;
48
+ const stopParts = fromMatch ? parts.slice(1) : parts;
49
+ const stops = parseStops(stopParts);
50
+ if (!stops) return { error: "Could not parse color stops" };
51
+ return { type: "conic", angle, stops };
52
+ }
53
+ return { error: "Unrecognized gradient format" };
54
+ }
55
+ function parseStops(parts) {
56
+ const stops = [];
57
+ for (let i = 0; i < parts.length; i++) {
58
+ const part = parts[i].trim();
59
+ const match = part.match(/^(.+?)\s+(\d+(?:\.\d+)?)%$/);
60
+ if (match) {
61
+ stops.push({ color: match[1].trim(), position: parseFloat(match[2]) });
62
+ } else {
63
+ const pos = parts.length === 1 ? 0 : Math.round(i / (parts.length - 1) * 100);
64
+ stops.push({ color: part, position: pos });
65
+ }
66
+ }
67
+ return stops.length > 0 ? stops : null;
68
+ }
69
+ var GRADIENT_PRESETS = [
70
+ {
71
+ name: "Sunset",
72
+ config: {
73
+ type: "linear",
74
+ angle: 135,
75
+ stops: [
76
+ { color: "#ff6b6b", position: 0 },
77
+ { color: "#feca57", position: 100 }
78
+ ]
79
+ }
80
+ },
81
+ {
82
+ name: "Ocean",
83
+ config: {
84
+ type: "linear",
85
+ angle: 180,
86
+ stops: [
87
+ { color: "#0099f7", position: 0 },
88
+ { color: "#f11712", position: 100 }
89
+ ]
90
+ }
91
+ },
92
+ {
93
+ name: "Purple Haze",
94
+ config: {
95
+ type: "radial",
96
+ angle: 0,
97
+ radialShape: "ellipse",
98
+ stops: [
99
+ { color: "#da8cff", position: 0 },
100
+ { color: "#9a55ff", position: 100 }
101
+ ]
102
+ }
103
+ },
104
+ {
105
+ name: "Mint",
106
+ config: {
107
+ type: "linear",
108
+ angle: 90,
109
+ stops: [
110
+ { color: "#00b09b", position: 0 },
111
+ { color: "#96c93d", position: 100 }
112
+ ]
113
+ }
114
+ },
115
+ {
116
+ name: "Rainbow Conic",
117
+ config: {
118
+ type: "conic",
119
+ angle: 0,
120
+ stops: [
121
+ { color: "red", position: 0 },
122
+ { color: "yellow", position: 17 },
123
+ { color: "lime", position: 33 },
124
+ { color: "cyan", position: 50 },
125
+ { color: "blue", position: 67 },
126
+ { color: "magenta", position: 83 },
127
+ { color: "red", position: 100 }
128
+ ]
129
+ }
130
+ }
131
+ ];
132
+ function generateBoxShadow(layers) {
133
+ if (layers.length === 0) return "none";
134
+ return layers.map((l) => {
135
+ const parts = [];
136
+ if (l.inset) parts.push("inset");
137
+ parts.push(`${l.offsetX}px`, `${l.offsetY}px`, `${l.blur}px`, `${l.spread}px`, l.color);
138
+ return parts.join(" ");
139
+ }).join(", ");
140
+ }
141
+ function parseBoxShadow(css) {
142
+ const trimmed = css.trim();
143
+ if (trimmed === "" || trimmed === "none") return [];
144
+ const layerStrings = splitShadowLayers(trimmed);
145
+ const layers = [];
146
+ for (const layerStr of layerStrings) {
147
+ const parsed = parseSingleShadowLayer(layerStr.trim());
148
+ if (!parsed) return { error: `Could not parse layer: "${layerStr.trim()}"` };
149
+ layers.push(parsed);
150
+ }
151
+ return layers;
152
+ }
153
+ function splitShadowLayers(css) {
154
+ const layers = [];
155
+ let depth = 0;
156
+ let current = "";
157
+ for (const char of css) {
158
+ if (char === "(") depth++;
159
+ else if (char === ")") depth--;
160
+ if (char === "," && depth === 0) {
161
+ layers.push(current);
162
+ current = "";
163
+ } else {
164
+ current += char;
165
+ }
166
+ }
167
+ if (current.trim()) layers.push(current);
168
+ return layers;
169
+ }
170
+ function parseSingleShadowLayer(str) {
171
+ let inset = false;
172
+ let s = str;
173
+ if (/^inset\b/i.test(s)) {
174
+ inset = true;
175
+ s = s.replace(/^inset\s+/i, "");
176
+ }
177
+ const colorPattern = /(rgba?\([^)]+\)|hsla?\([^)]+\)|#[0-9a-fA-F]{3,8}|[a-zA-Z]+)$/;
178
+ const colorMatch = s.match(colorPattern);
179
+ const color = colorMatch ? colorMatch[1] : "rgba(0,0,0,0.5)";
180
+ if (colorMatch) s = s.slice(0, colorMatch.index).trim();
181
+ const nums = s.split(/\s+/).map((v) => parseFloat(v)).filter((n) => !isNaN(n));
182
+ if (nums.length < 2) return null;
183
+ return {
184
+ offsetX: nums[0] ?? 0,
185
+ offsetY: nums[1] ?? 0,
186
+ blur: nums[2] ?? 0,
187
+ spread: nums[3] ?? 0,
188
+ color,
189
+ inset
190
+ };
191
+ }
192
+ var DEFAULT_SHADOW = {
193
+ offsetX: 0,
194
+ offsetY: 4,
195
+ blur: 6,
196
+ spread: -1,
197
+ color: "rgba(0, 0, 0, 0.1)",
198
+ inset: false
199
+ };
200
+ var SHADOW_PRESETS = [
201
+ {
202
+ name: "Soft",
203
+ layers: [
204
+ { offsetX: 0, offsetY: 2, blur: 8, spread: 0, color: "rgba(0,0,0,0.1)", inset: false }
205
+ ]
206
+ },
207
+ {
208
+ name: "Medium",
209
+ layers: [
210
+ { offsetX: 0, offsetY: 4, blur: 12, spread: 0, color: "rgba(0,0,0,0.15)", inset: false }
211
+ ]
212
+ },
213
+ {
214
+ name: "Hard",
215
+ layers: [
216
+ { offsetX: 4, offsetY: 4, blur: 0, spread: 0, color: "rgba(0,0,0,0.8)", inset: false }
217
+ ]
218
+ },
219
+ {
220
+ name: "Inset",
221
+ layers: [
222
+ { offsetX: 0, offsetY: 2, blur: 4, spread: 0, color: "rgba(0,0,0,0.2)", inset: true }
223
+ ]
224
+ },
225
+ {
226
+ name: "Layered",
227
+ layers: [
228
+ { offsetX: 0, offsetY: 1, blur: 3, spread: 0, color: "rgba(0,0,0,0.12)", inset: false },
229
+ { offsetX: 0, offsetY: 4, blur: 6, spread: 0, color: "rgba(0,0,0,0.08)", inset: false },
230
+ { offsetX: 0, offsetY: 8, blur: 16, spread: 0, color: "rgba(0,0,0,0.06)", inset: false }
231
+ ]
232
+ },
233
+ {
234
+ name: "Neon Blue",
235
+ layers: [
236
+ { offsetX: 0, offsetY: 0, blur: 8, spread: 2, color: "#00d4ff", inset: false },
237
+ { offsetX: 0, offsetY: 0, blur: 20, spread: 4, color: "#0099bb", inset: false }
238
+ ]
239
+ }
240
+ ];
241
+ function generateBorderRadius(config) {
242
+ const { topLeft, topRight, bottomRight, bottomLeft, unit } = config;
243
+ if (topLeft === topRight && topRight === bottomRight && bottomRight === bottomLeft) {
244
+ return `${topLeft}${unit}`;
245
+ }
246
+ if (topLeft === bottomRight && topRight === bottomLeft) {
247
+ return `${topLeft}${unit} ${topRight}${unit}`;
248
+ }
249
+ if (topRight === bottomLeft) {
250
+ return `${topLeft}${unit} ${topRight}${unit} ${bottomRight}${unit}`;
251
+ }
252
+ return `${topLeft}${unit} ${topRight}${unit} ${bottomRight}${unit} ${bottomLeft}${unit}`;
253
+ }
254
+ function parseBorderRadius(css) {
255
+ const trimmed = css.trim();
256
+ if (!trimmed) {
257
+ return { error: "Empty input" };
258
+ }
259
+ const tokenRe = /^(\d+(?:\.\d+)?)(px|%|rem)?$/;
260
+ const parts = trimmed.split(/\s+/);
261
+ if (parts.length < 1 || parts.length > 4) {
262
+ return { error: "Invalid border-radius format" };
263
+ }
264
+ const parsed = [];
265
+ let detectedUnit = "px";
266
+ for (const part of parts) {
267
+ const match = tokenRe.exec(part);
268
+ if (!match) {
269
+ return { error: `Invalid token: ${part}` };
270
+ }
271
+ const value = parseFloat(match[1]);
272
+ const unit = match[2] || "px";
273
+ if (parsed.length > 0 && unit !== detectedUnit && match[2]) {
274
+ return { error: "Mixed units are not supported" };
275
+ }
276
+ if (match[2]) {
277
+ detectedUnit = unit;
278
+ }
279
+ parsed.push({ value, unit });
280
+ }
281
+ const u = detectedUnit;
282
+ if (parsed.length === 1) {
283
+ const v = parsed[0].value;
284
+ return { topLeft: v, topRight: v, bottomRight: v, bottomLeft: v, unit: u };
285
+ }
286
+ if (parsed.length === 2) {
287
+ return { topLeft: parsed[0].value, topRight: parsed[1].value, bottomRight: parsed[0].value, bottomLeft: parsed[1].value, unit: u };
288
+ }
289
+ if (parsed.length === 3) {
290
+ return { topLeft: parsed[0].value, topRight: parsed[1].value, bottomRight: parsed[2].value, bottomLeft: parsed[1].value, unit: u };
291
+ }
292
+ return { topLeft: parsed[0].value, topRight: parsed[1].value, bottomRight: parsed[2].value, bottomLeft: parsed[3].value, unit: u };
293
+ }
294
+ function isUniform(config) {
295
+ return config.topLeft === config.topRight && config.topRight === config.bottomRight && config.bottomRight === config.bottomLeft;
296
+ }
297
+ var BORDER_PRESETS = [
298
+ {
299
+ name: "Sharp",
300
+ config: { topLeft: 0, topRight: 0, bottomRight: 0, bottomLeft: 0, unit: "px" }
301
+ },
302
+ {
303
+ name: "Rounded",
304
+ config: { topLeft: 8, topRight: 8, bottomRight: 8, bottomLeft: 8, unit: "px" }
305
+ },
306
+ {
307
+ name: "Pill",
308
+ config: { topLeft: 9999, topRight: 9999, bottomRight: 9999, bottomLeft: 9999, unit: "px" }
309
+ },
310
+ {
311
+ name: "Circle",
312
+ config: { topLeft: 50, topRight: 50, bottomRight: 50, bottomLeft: 50, unit: "%" }
313
+ },
314
+ {
315
+ name: "Squircle",
316
+ config: { topLeft: 30, topRight: 30, bottomRight: 30, bottomLeft: 30, unit: "%" }
317
+ },
318
+ {
319
+ name: "Asymmetric",
320
+ config: { topLeft: 16, topRight: 4, bottomRight: 16, bottomLeft: 4, unit: "px" }
321
+ }
322
+ ];
323
+ var ANIMATION_PRESETS = {
324
+ fadeIn: {
325
+ keyframes: [
326
+ { stop: 0, properties: { opacity: "0" } },
327
+ { stop: 100, properties: { opacity: "1" } }
328
+ ],
329
+ config: {
330
+ name: "fadeIn",
331
+ duration: "0.5s",
332
+ timingFunction: "ease",
333
+ fillMode: "both"
334
+ }
335
+ },
336
+ fadeOut: {
337
+ keyframes: [
338
+ { stop: 0, properties: { opacity: "1" } },
339
+ { stop: 100, properties: { opacity: "0" } }
340
+ ],
341
+ config: {
342
+ name: "fadeOut",
343
+ duration: "0.5s",
344
+ timingFunction: "ease",
345
+ fillMode: "both"
346
+ }
347
+ },
348
+ slideInLeft: {
349
+ keyframes: [
350
+ { stop: 0, properties: { transform: "translateX(-100%)", opacity: "0" } },
351
+ { stop: 100, properties: { transform: "translateX(0)", opacity: "1" } }
352
+ ],
353
+ config: {
354
+ name: "slideInLeft",
355
+ duration: "0.4s",
356
+ timingFunction: "ease-out",
357
+ fillMode: "both"
358
+ }
359
+ },
360
+ slideInRight: {
361
+ keyframes: [
362
+ { stop: 0, properties: { transform: "translateX(100%)", opacity: "0" } },
363
+ { stop: 100, properties: { transform: "translateX(0)", opacity: "1" } }
364
+ ],
365
+ config: {
366
+ name: "slideInRight",
367
+ duration: "0.4s",
368
+ timingFunction: "ease-out",
369
+ fillMode: "both"
370
+ }
371
+ },
372
+ bounceIn: {
373
+ keyframes: [
374
+ { stop: 0, properties: { transform: "scale(0.3)", opacity: "0" } },
375
+ { stop: 50, properties: { transform: "scale(1.05)", opacity: "0.8" } },
376
+ { stop: 70, properties: { transform: "scale(0.9)", opacity: "0.9" } },
377
+ { stop: 100, properties: { transform: "scale(1)", opacity: "1" } }
378
+ ],
379
+ config: {
380
+ name: "bounceIn",
381
+ duration: "0.6s",
382
+ timingFunction: "cubic-bezier(0.215, 0.61, 0.355, 1)",
383
+ fillMode: "both"
384
+ }
385
+ },
386
+ pulse: {
387
+ keyframes: [
388
+ { stop: 0, properties: { transform: "scale(1)" } },
389
+ { stop: 50, properties: { transform: "scale(1.05)" } },
390
+ { stop: 100, properties: { transform: "scale(1)" } }
391
+ ],
392
+ config: {
393
+ name: "pulse",
394
+ duration: "1s",
395
+ timingFunction: "ease-in-out",
396
+ iterationCount: "infinite"
397
+ }
398
+ },
399
+ spin: {
400
+ keyframes: [
401
+ { stop: 0, properties: { transform: "rotate(0deg)" } },
402
+ { stop: 100, properties: { transform: "rotate(360deg)" } }
403
+ ],
404
+ config: {
405
+ name: "spin",
406
+ duration: "1s",
407
+ timingFunction: "linear",
408
+ iterationCount: "infinite"
409
+ }
410
+ },
411
+ shake: {
412
+ keyframes: [
413
+ { stop: 0, properties: { transform: "translateX(0)" } },
414
+ { stop: 10, properties: { transform: "translateX(-10px)" } },
415
+ { stop: 30, properties: { transform: "translateX(10px)" } },
416
+ { stop: 50, properties: { transform: "translateX(-10px)" } },
417
+ { stop: 70, properties: { transform: "translateX(10px)" } },
418
+ { stop: 90, properties: { transform: "translateX(-10px)" } },
419
+ { stop: 100, properties: { transform: "translateX(0)" } }
420
+ ],
421
+ config: {
422
+ name: "shake",
423
+ duration: "0.6s",
424
+ timingFunction: "ease-in-out"
425
+ }
426
+ },
427
+ zoomIn: {
428
+ keyframes: [
429
+ { stop: 0, properties: { transform: "scale(0)", opacity: "0" } },
430
+ { stop: 100, properties: { transform: "scale(1)", opacity: "1" } }
431
+ ],
432
+ config: {
433
+ name: "zoomIn",
434
+ duration: "0.4s",
435
+ timingFunction: "ease-out",
436
+ fillMode: "both"
437
+ }
438
+ },
439
+ zoomOut: {
440
+ keyframes: [
441
+ { stop: 0, properties: { transform: "scale(1)", opacity: "1" } },
442
+ { stop: 100, properties: { transform: "scale(0)", opacity: "0" } }
443
+ ],
444
+ config: {
445
+ name: "zoomOut",
446
+ duration: "0.4s",
447
+ timingFunction: "ease-in",
448
+ fillMode: "both"
449
+ }
450
+ }
451
+ };
452
+ function generateKeyframesCSS(name, keyframes) {
453
+ const stops = keyframes.slice().sort((a, b) => a.stop - b.stop).map((kf) => {
454
+ const props = Object.entries(kf.properties).map(([prop, value]) => ` ${prop}: ${value};`).join("\n");
455
+ return ` ${kf.stop}% {
456
+ ${props}
457
+ }`;
458
+ }).join("\n");
459
+ return `@keyframes ${name} {
460
+ ${stops}
461
+ }`;
462
+ }
463
+ function generateAnimationCSS(config) {
464
+ const {
465
+ name,
466
+ duration,
467
+ timingFunction,
468
+ delay,
469
+ iterationCount,
470
+ direction,
471
+ fillMode
472
+ } = config;
473
+ return `animation: ${name} ${duration} ${timingFunction} ${delay} ${iterationCount} ${direction} ${fillMode};`;
474
+ }
475
+ function generateFullCSS(selector, config, keyframes) {
476
+ const keyframesBlock = generateKeyframesCSS(config.name, keyframes);
477
+ const animationProp = generateAnimationCSS(config);
478
+ const selectorBlock = `${selector} {
479
+ ${animationProp}
480
+ }`;
481
+ return `${keyframesBlock}
482
+
483
+ ${selectorBlock}`;
484
+ }
485
+ function parseKeyframesCSS(css) {
486
+ const nameMatch = css.match(/@keyframes\s+([\w-]+)\s*\{/);
487
+ if (!nameMatch) {
488
+ return { error: "No @keyframes rule found in the provided CSS." };
489
+ }
490
+ const name = nameMatch[1];
491
+ const outerStart = css.indexOf("{", css.indexOf("@keyframes"));
492
+ if (outerStart === -1) {
493
+ return { error: "Malformed @keyframes block: missing opening brace." };
494
+ }
495
+ let depth = 0;
496
+ let outerEnd = -1;
497
+ for (let i = outerStart; i < css.length; i++) {
498
+ if (css[i] === "{") depth++;
499
+ else if (css[i] === "}") {
500
+ depth--;
501
+ if (depth === 0) {
502
+ outerEnd = i;
503
+ break;
504
+ }
505
+ }
506
+ }
507
+ if (outerEnd === -1) {
508
+ return { error: "Malformed @keyframes block: missing closing brace." };
509
+ }
510
+ const innerContent = css.slice(outerStart + 1, outerEnd);
511
+ const stopPattern = /([\d]+%|from|to)\s*\{([^}]*)\}/g;
512
+ const parsedKeyframes = [];
513
+ let match;
514
+ while ((match = stopPattern.exec(innerContent)) !== null) {
515
+ const stopStr = match[1].trim();
516
+ let stop;
517
+ if (stopStr === "from") {
518
+ stop = 0;
519
+ } else if (stopStr === "to") {
520
+ stop = 100;
521
+ } else {
522
+ stop = parseInt(stopStr, 10);
523
+ }
524
+ const propsStr = match[2];
525
+ const properties = {};
526
+ const propLines = propsStr.split(";");
527
+ for (const line of propLines) {
528
+ const trimmed = line.trim();
529
+ if (!trimmed) continue;
530
+ const colonIdx = trimmed.indexOf(":");
531
+ if (colonIdx === -1) continue;
532
+ const prop = trimmed.slice(0, colonIdx).trim();
533
+ const value = trimmed.slice(colonIdx + 1).trim();
534
+ if (prop && value) {
535
+ properties[prop] = value;
536
+ }
537
+ }
538
+ parsedKeyframes.push({ stop, properties });
539
+ }
540
+ if (parsedKeyframes.length === 0) {
541
+ return { error: "No keyframe stops found inside the @keyframes block." };
542
+ }
543
+ return { name, keyframes: parsedKeyframes };
544
+ }
545
+ function validateKeyframes(keyframes) {
546
+ if (keyframes.length < 2) {
547
+ return "At least 2 keyframes are required.";
548
+ }
549
+ const seenStops = /* @__PURE__ */ new Set();
550
+ for (const kf of keyframes) {
551
+ if (kf.stop < 0 || kf.stop > 100) {
552
+ return `Keyframe stop ${kf.stop} is out of range. Stops must be between 0 and 100.`;
553
+ }
554
+ if (seenStops.has(kf.stop)) {
555
+ return `Duplicate keyframe stop: ${kf.stop}%.`;
556
+ }
557
+ seenStops.add(kf.stop);
558
+ }
559
+ return null;
560
+ }
561
+ var CUBIC_BEZIER_PRESETS = {
562
+ "ease": { x1: 0.25, y1: 0.1, x2: 0.25, y2: 1 },
563
+ "ease-in": { x1: 0.42, y1: 0, x2: 1, y2: 1 },
564
+ "ease-out": { x1: 0, y1: 0, x2: 0.58, y2: 1 },
565
+ "ease-in-out": { x1: 0.42, y1: 0, x2: 0.58, y2: 1 },
566
+ "linear": { x1: 0, y1: 0, x2: 1, y2: 1 },
567
+ "bounce-in": { x1: 0.215, y1: 0.61, x2: 0.355, y2: 1 },
568
+ "bounce-out": { x1: 0.55, y1: 0.055, x2: 0.675, y2: 0.19 }
569
+ };
570
+ var PRESETS = CUBIC_BEZIER_PRESETS;
571
+ function parseCubicBezier(input) {
572
+ const trimmed = input.trim().toLowerCase();
573
+ if (trimmed in CUBIC_BEZIER_PRESETS) {
574
+ return { ...CUBIC_BEZIER_PRESETS[trimmed] };
575
+ }
576
+ const inner = trimmed.startsWith("cubic-bezier(") ? trimmed.slice("cubic-bezier(".length).replace(/\)$/, "") : trimmed;
577
+ const parts = inner.split(",").map((p) => p.trim());
578
+ if (parts.length !== 4) {
579
+ return { error: `Expected 4 values, got ${parts.length}` };
580
+ }
581
+ const nums = parts.map(Number);
582
+ if (nums.some(isNaN)) {
583
+ return { error: "All values must be numeric" };
584
+ }
585
+ const params = {
586
+ x1: nums[0],
587
+ y1: nums[1],
588
+ x2: nums[2],
589
+ y2: nums[3]
590
+ };
591
+ const validationError = validateCubicBezierParams(params);
592
+ if (validationError) {
593
+ return { error: validationError };
594
+ }
595
+ return params;
596
+ }
597
+ function toCssValue(params) {
598
+ const fmt = (n) => {
599
+ const s = n.toString();
600
+ return s.includes(".") ? s.replace(/\.?0+$/, "") || "0" : s;
601
+ };
602
+ return `cubic-bezier(${fmt(params.x1)}, ${fmt(params.y1)}, ${fmt(params.x2)}, ${fmt(params.y2)})`;
603
+ }
604
+ function sampleCurve(params, t) {
605
+ const { y1, y2 } = params;
606
+ const mt = 1 - t;
607
+ return 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t;
608
+ }
609
+ function getCurvePoints(params, steps = 50) {
610
+ const { x1, y1, x2, y2 } = params;
611
+ const points = [];
612
+ for (let i = 0; i <= steps; i++) {
613
+ const t = i / steps;
614
+ const mt = 1 - t;
615
+ const x = 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t;
616
+ const y = 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t;
617
+ points.push({ t, x, y });
618
+ }
619
+ return points;
620
+ }
621
+ function validateCubicBezierParams(params) {
622
+ if (params.x1 < 0 || params.x1 > 1) {
623
+ return `x1 must be between 0 and 1, got ${params.x1}`;
624
+ }
625
+ if (params.x2 < 0 || params.x2 > 1) {
626
+ return `x2 must be between 0 and 1, got ${params.x2}`;
627
+ }
628
+ return null;
629
+ }
630
+ var validateParams = validateCubicBezierParams;
631
+ function toClampUnit(px, unit, rootFontSize) {
632
+ if (unit === "rem") {
633
+ const rem = px / rootFontSize;
634
+ return `${+rem.toFixed(4).replace(/\.?0+$/, "")}rem`;
635
+ }
636
+ return `${px}px`;
637
+ }
638
+ function formatVwRem(slopeVw, interceptRem) {
639
+ const vwStr = `${+slopeVw.toFixed(4).replace(/\.?0+$/, "")}vw`;
640
+ if (interceptRem === 0) return vwStr;
641
+ const sign = interceptRem >= 0 ? "+" : "-";
642
+ const absIntercept = Math.abs(interceptRem);
643
+ const remStr = `${+absIntercept.toFixed(4).replace(/\.?0+$/, "")}rem`;
644
+ return `${vwStr} ${sign} ${remStr}`;
645
+ }
646
+ function calcClamp(config) {
647
+ const { minSize, maxSize, minViewport, maxViewport, unit } = config;
648
+ const rootFontSize = config.rootFontSize ?? 16;
649
+ if (minSize >= maxSize) {
650
+ return { error: "minSize must be less than maxSize" };
651
+ }
652
+ if (minViewport >= maxViewport) {
653
+ return { error: "minViewport must be less than maxViewport" };
654
+ }
655
+ if (rootFontSize <= 0) {
656
+ return { error: "rootFontSize must be positive" };
657
+ }
658
+ const slope = (maxSize - minSize) / (maxViewport - minViewport);
659
+ const interceptPx = minSize - slope * minViewport;
660
+ const slopeVw = slope * 100;
661
+ const interceptRem = interceptPx / rootFontSize;
662
+ const preferredOutput = formatVwRem(slopeVw, interceptRem);
663
+ const minOutput = toClampUnit(minSize, unit, rootFontSize);
664
+ const maxOutput = toClampUnit(maxSize, unit, rootFontSize);
665
+ const clampValue = `clamp(${minOutput}, ${preferredOutput}, ${maxOutput})`;
666
+ return {
667
+ clampValue,
668
+ slope,
669
+ intercept: interceptPx,
670
+ minOutput,
671
+ maxOutput,
672
+ preferredOutput
673
+ };
674
+ }
675
+ function previewClamp(config, viewportWidth) {
676
+ const { minSize, maxSize, minViewport, maxViewport } = config;
677
+ const slope = (maxSize - minSize) / (maxViewport - minViewport);
678
+ const interceptPx = minSize - slope * minViewport;
679
+ const preferred = slope * viewportWidth + interceptPx;
680
+ return Math.min(Math.max(preferred, minSize), maxSize);
681
+ }
682
+ function parseClampString(clamp) {
683
+ const trimmed = clamp.trim();
684
+ const clampMatch = trimmed.match(/^clamp\(\s*(.+?)\s*,\s*(.+?)\s*,\s*(.+?)\s*\)$/);
685
+ if (!clampMatch) {
686
+ return { error: "Input does not look like a clamp() function" };
687
+ }
688
+ const [, minStr, preferredStr, maxStr] = clampMatch;
689
+ const minMatch = minStr.match(/^([\d.]+)(px|rem)$/);
690
+ if (!minMatch) return { error: `Cannot parse min value: ${minStr}` };
691
+ const maxMatch = maxStr.match(/^([\d.]+)(px|rem)$/);
692
+ if (!maxMatch) return { error: `Cannot parse max value: ${maxStr}` };
693
+ const unit = minMatch[2];
694
+ const rootFontSize = 16;
695
+ const minSize = unit === "rem" ? parseFloat(minMatch[1]) * rootFontSize : parseFloat(minMatch[1]);
696
+ const maxSize = unit === "rem" ? parseFloat(maxMatch[1]) * rootFontSize : parseFloat(maxMatch[1]);
697
+ const prefMatch = preferredStr.match(/^([\d.]+)vw\s*([+-]\s*[\d.]+rem)?$/);
698
+ if (!prefMatch) return { error: `Cannot parse preferred value: ${preferredStr}` };
699
+ const slopeVw = parseFloat(prefMatch[1]);
700
+ const slope = slopeVw / 100;
701
+ let interceptRem = 0;
702
+ if (prefMatch[2]) {
703
+ const interceptMatch = prefMatch[2].match(/([+-])\s*([\d.]+)rem/);
704
+ if (interceptMatch) {
705
+ interceptRem = parseFloat(interceptMatch[2]) * (interceptMatch[1] === "-" ? -1 : 1);
706
+ }
707
+ }
708
+ const interceptPx = interceptRem * rootFontSize;
709
+ if (slope === 0) {
710
+ return { error: "Cannot determine viewports from zero slope" };
711
+ }
712
+ const minViewport = (minSize - interceptPx) / slope;
713
+ const maxViewport = (maxSize - interceptPx) / slope;
714
+ return {
715
+ minSize,
716
+ maxSize,
717
+ minViewport: Math.round(minViewport),
718
+ maxViewport: Math.round(maxViewport),
719
+ unit,
720
+ rootFontSize
721
+ };
722
+ }
723
+ function makeSpecificityResult(inline, id, classAttr, element) {
724
+ return {
725
+ inline,
726
+ id,
727
+ classAttr,
728
+ element,
729
+ value: [inline, id, classAttr, element],
730
+ notation: `(${inline},${id},${classAttr},${element})`
731
+ };
732
+ }
733
+ function addTuples(a, b) {
734
+ return [a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]];
735
+ }
736
+ function tokenizeSelector(selector) {
737
+ const tokens = [];
738
+ let i = 0;
739
+ const s = selector.trim();
740
+ while (i < s.length) {
741
+ if (/[\s>+~]/.test(s[i])) {
742
+ i++;
743
+ continue;
744
+ }
745
+ if (s[i] === "*") {
746
+ tokens.push({ token: "*", type: "universal", contribution: [0, 0, 0, 0] });
747
+ i++;
748
+ continue;
749
+ }
750
+ if (s[i] === "#") {
751
+ let j = i + 1;
752
+ while (j < s.length && /[a-zA-Z0-9_-]/.test(s[j])) j++;
753
+ const token = s.slice(i, j);
754
+ tokens.push({ token, type: "id", contribution: [0, 1, 0, 0] });
755
+ i = j;
756
+ continue;
757
+ }
758
+ if (s[i] === ".") {
759
+ let j = i + 1;
760
+ while (j < s.length && /[a-zA-Z0-9_-]/.test(s[j])) j++;
761
+ const token = s.slice(i, j);
762
+ tokens.push({ token, type: "class", contribution: [0, 0, 1, 0] });
763
+ i = j;
764
+ continue;
765
+ }
766
+ if (s[i] === "[") {
767
+ let j = i + 1;
768
+ while (j < s.length && s[j] !== "]") j++;
769
+ const token = s.slice(i, j + 1);
770
+ tokens.push({ token, type: "attribute", contribution: [0, 0, 1, 0] });
771
+ i = j + 1;
772
+ continue;
773
+ }
774
+ if (s[i] === ":") {
775
+ const isPseudoElement = s[i + 1] === ":";
776
+ const start = i;
777
+ i += isPseudoElement ? 2 : 1;
778
+ let j = i;
779
+ while (j < s.length && /[a-zA-Z0-9_-]/.test(s[j])) j++;
780
+ const pseudoName = s.slice(i, j).toLowerCase();
781
+ i = j;
782
+ if (i < s.length && s[i] === "(") {
783
+ let depth = 1;
784
+ let k = i + 1;
785
+ while (k < s.length && depth > 0) {
786
+ if (s[k] === "(") depth++;
787
+ else if (s[k] === ")") depth--;
788
+ k++;
789
+ }
790
+ const argStr = s.slice(i + 1, k - 1);
791
+ const token = s.slice(start, k);
792
+ i = k;
793
+ if (pseudoName === "where") {
794
+ tokens.push({ token, type: "pseudo-class-where", contribution: [0, 0, 0, 0] });
795
+ } else if (pseudoName === "not" || pseudoName === "is" || pseudoName === "has") {
796
+ const argTokens = tokenizeSelector(argStr);
797
+ const argContrib = argTokens.reduce(
798
+ (acc, t) => addTuples(acc, t.contribution),
799
+ [0, 0, 0, 0]
800
+ );
801
+ tokens.push({ token, type: `pseudo-class-${pseudoName}`, contribution: argContrib });
802
+ } else if (pseudoName === "nth-child" || pseudoName === "nth-last-child" || pseudoName === "nth-of-type" || pseudoName === "nth-last-of-type") {
803
+ tokens.push({ token, type: "pseudo-class", contribution: [0, 0, 1, 0] });
804
+ } else {
805
+ tokens.push({ token, type: "pseudo-class-fn", contribution: [0, 0, 1, 0] });
806
+ }
807
+ } else {
808
+ const token = s.slice(start, i);
809
+ if (isPseudoElement) {
810
+ tokens.push({ token, type: "pseudo-element", contribution: [0, 0, 0, 1] });
811
+ } else {
812
+ tokens.push({ token, type: "pseudo-class", contribution: [0, 0, 1, 0] });
813
+ }
814
+ }
815
+ continue;
816
+ }
817
+ if (/[a-zA-Z_-]/.test(s[i])) {
818
+ let j = i;
819
+ while (j < s.length && /[a-zA-Z0-9_-]/.test(s[j])) j++;
820
+ const token = s.slice(i, j);
821
+ tokens.push({ token, type: "element", contribution: [0, 0, 0, 1] });
822
+ i = j;
823
+ continue;
824
+ }
825
+ i++;
826
+ }
827
+ return tokens;
828
+ }
829
+ function calcSpecificity(selector) {
830
+ const tokens = tokenizeSelector(selector);
831
+ const total = tokens.reduce(
832
+ (acc, t) => addTuples(acc, t.contribution),
833
+ [0, 0, 0, 0]
834
+ );
835
+ return makeSpecificityResult(total[0], total[1], total[2], total[3]);
836
+ }
837
+ function compareSpecificity(a, b) {
838
+ for (let i = 0; i < 4; i++) {
839
+ if (a.value[i] < b.value[i]) return -1;
840
+ if (a.value[i] > b.value[i]) return 1;
841
+ }
842
+ return 0;
843
+ }
844
+ function explainSelector(selector) {
845
+ return tokenizeSelector(selector);
846
+ }
847
+ function multipleSelectors(css) {
848
+ let selectorPart = css.trim();
849
+ const braceIdx = selectorPart.indexOf("{");
850
+ if (braceIdx !== -1) {
851
+ selectorPart = selectorPart.slice(0, braceIdx).trim();
852
+ }
853
+ return selectorPart.split(",").map((s) => s.trim()).filter(Boolean).map((selector) => ({
854
+ selector,
855
+ specificity: calcSpecificity(selector)
856
+ }));
857
+ }
858
+ function calcCssResult(input, output) {
859
+ const originalSize = input.length;
860
+ const outputSize = output.length;
861
+ const savingsPercent = originalSize === 0 ? 0 : Math.round((originalSize - outputSize) / originalSize * 100 * 100) / 100;
862
+ return { output, originalSize, outputSize, savingsPercent };
863
+ }
864
+ function minifyCss(input) {
865
+ let output = input;
866
+ output = output.replace(/\/\*[\s\S]*?\*\//g, "");
867
+ output = output.replace(/\s+/g, " ");
868
+ output = output.replace(/\s*{\s*/g, "{");
869
+ output = output.replace(/\s*}\s*/g, "}");
870
+ output = output.replace(/\s*:\s*/g, ":");
871
+ output = output.replace(/\s*;\s*/g, ";");
872
+ output = output.replace(/\s*,\s*/g, ",");
873
+ output = output.replace(/;}/g, "}");
874
+ output = output.trim();
875
+ return calcCssResult(input, output);
876
+ }
877
+ function formatCss(input, indentSize = 2) {
878
+ const indent = " ".repeat(indentSize);
879
+ const { output: minified } = minifyCss(input);
880
+ let result = "";
881
+ let insideBlock = false;
882
+ let i = 0;
883
+ while (i < minified.length) {
884
+ const char = minified[i];
885
+ if (char === "{") {
886
+ result += " {\n";
887
+ insideBlock = true;
888
+ i++;
889
+ } else if (char === "}") {
890
+ result = result.trimEnd() + "\n";
891
+ result += "}\n\n";
892
+ insideBlock = false;
893
+ i++;
894
+ } else if (char === ";" && insideBlock) {
895
+ result += ";\n";
896
+ if (i + 1 < minified.length && minified[i + 1] !== "}") {
897
+ result += indent;
898
+ }
899
+ i++;
900
+ } else {
901
+ if (insideBlock && result.endsWith("{\n")) {
902
+ result += indent;
903
+ }
904
+ result += char;
905
+ i++;
906
+ }
907
+ }
908
+ const output = result.trimEnd();
909
+ return calcCssResult(input, output);
910
+ }
911
+ function countRules(css) {
912
+ const matches = css.match(/{/g);
913
+ return matches ? matches.length : 0;
914
+ }
915
+ function countProperties(css) {
916
+ let count = 0;
917
+ let insideBlock = false;
918
+ for (let i = 0; i < css.length; i++) {
919
+ const char = css[i];
920
+ if (char === "{") {
921
+ insideBlock = true;
922
+ } else if (char === "}") {
923
+ insideBlock = false;
924
+ } else if (char === ";" && insideBlock) {
925
+ count++;
926
+ }
927
+ }
928
+ css.replace(/{[^{}]*}/g, (block) => {
929
+ const innerContent = block.slice(1, -1).trim();
930
+ if (!innerContent) return block;
931
+ const lastDecl = innerContent.split(";").pop()?.trim();
932
+ if (lastDecl && lastDecl.includes(":")) {
933
+ count++;
934
+ }
935
+ return block;
936
+ });
937
+ return count;
938
+ }
939
+ var DEFAULT_CONTAINER = {
940
+ flexDirection: "row",
941
+ flexWrap: "nowrap",
942
+ justifyContent: "flex-start",
943
+ alignItems: "stretch",
944
+ alignContent: "stretch",
945
+ gap: 0
946
+ };
947
+ var DEFAULT_ITEM = {
948
+ flexGrow: 0,
949
+ flexShrink: 1,
950
+ flexBasis: "auto",
951
+ alignSelf: "auto",
952
+ order: 0
953
+ };
954
+ function generateFlexContainerCss(config) {
955
+ const lines = ["display: flex;"];
956
+ if (config.flexDirection !== "row") {
957
+ lines.push(`flex-direction: ${config.flexDirection};`);
958
+ }
959
+ if (config.flexWrap !== "nowrap") {
960
+ lines.push(`flex-wrap: ${config.flexWrap};`);
961
+ }
962
+ if (config.justifyContent !== "flex-start") {
963
+ lines.push(`justify-content: ${config.justifyContent};`);
964
+ }
965
+ if (config.alignItems !== "stretch") {
966
+ lines.push(`align-items: ${config.alignItems};`);
967
+ }
968
+ if (config.alignContent !== "stretch") {
969
+ lines.push(`align-content: ${config.alignContent};`);
970
+ }
971
+ if (config.rowGap !== void 0 || config.columnGap !== void 0) {
972
+ const rg = config.rowGap !== void 0 ? config.rowGap : config.gap;
973
+ const cg = config.columnGap !== void 0 ? config.columnGap : config.gap;
974
+ if (rg === cg) {
975
+ lines.push(`gap: ${rg}px;`);
976
+ } else {
977
+ lines.push(`row-gap: ${rg}px;`);
978
+ lines.push(`column-gap: ${cg}px;`);
979
+ }
980
+ } else if (config.gap !== 0) {
981
+ lines.push(`gap: ${config.gap}px;`);
982
+ }
983
+ return lines.join("\n");
984
+ }
985
+ function generateFlexItemCss(config) {
986
+ const lines = [];
987
+ const flexShorthand = `${config.flexGrow} ${config.flexShrink} ${config.flexBasis}`;
988
+ lines.push(`flex: ${flexShorthand};`);
989
+ if (config.alignSelf !== "auto") {
990
+ lines.push(`align-self: ${config.alignSelf};`);
991
+ }
992
+ if (config.order !== 0) {
993
+ lines.push(`order: ${config.order};`);
994
+ }
995
+ return lines.join("\n");
996
+ }
997
+ var FLEX_PRESETS = [
998
+ {
999
+ name: "Horizontal Stack",
1000
+ description: "Items laid out in a row from left to right",
1001
+ container: {
1002
+ ...DEFAULT_CONTAINER,
1003
+ flexDirection: "row",
1004
+ alignItems: "center",
1005
+ gap: 8
1006
+ }
1007
+ },
1008
+ {
1009
+ name: "Vertical Stack",
1010
+ description: "Items stacked vertically from top to bottom",
1011
+ container: {
1012
+ ...DEFAULT_CONTAINER,
1013
+ flexDirection: "column",
1014
+ alignItems: "stretch",
1015
+ gap: 8
1016
+ }
1017
+ },
1018
+ {
1019
+ name: "Centered",
1020
+ description: "Items centered both horizontally and vertically",
1021
+ container: {
1022
+ ...DEFAULT_CONTAINER,
1023
+ justifyContent: "center",
1024
+ alignItems: "center"
1025
+ }
1026
+ },
1027
+ {
1028
+ name: "Space Between",
1029
+ description: "Items spread out with equal space between them",
1030
+ container: {
1031
+ ...DEFAULT_CONTAINER,
1032
+ justifyContent: "space-between",
1033
+ alignItems: "center"
1034
+ }
1035
+ },
1036
+ {
1037
+ name: "Grid-like",
1038
+ description: "Wrapping layout that resembles a grid",
1039
+ container: {
1040
+ ...DEFAULT_CONTAINER,
1041
+ flexWrap: "wrap",
1042
+ justifyContent: "flex-start",
1043
+ alignItems: "flex-start",
1044
+ gap: 16
1045
+ }
1046
+ },
1047
+ {
1048
+ name: "Space Evenly",
1049
+ description: "Items distributed with equal space around each item",
1050
+ container: {
1051
+ ...DEFAULT_CONTAINER,
1052
+ justifyContent: "space-evenly",
1053
+ alignItems: "center"
1054
+ }
1055
+ },
1056
+ {
1057
+ name: "Right-aligned",
1058
+ description: "Items aligned to the right end of the container",
1059
+ container: {
1060
+ ...DEFAULT_CONTAINER,
1061
+ justifyContent: "flex-end",
1062
+ alignItems: "center",
1063
+ gap: 8
1064
+ }
1065
+ }
1066
+ ];
1067
+ var DEFAULT_CONFIG = {
1068
+ templateColumns: "repeat(3, 1fr)",
1069
+ templateRows: "auto",
1070
+ gap: 16,
1071
+ justifyItems: "stretch",
1072
+ alignItems: "stretch",
1073
+ justifyContent: "start",
1074
+ alignContent: "start"
1075
+ };
1076
+ var GRID_PRESETS = [
1077
+ {
1078
+ name: "3-Column",
1079
+ description: "Equal three-column layout",
1080
+ config: {
1081
+ templateColumns: "repeat(3, 1fr)",
1082
+ templateRows: "auto",
1083
+ gap: 16,
1084
+ justifyItems: "stretch",
1085
+ alignItems: "stretch",
1086
+ justifyContent: "start",
1087
+ alignContent: "start"
1088
+ }
1089
+ },
1090
+ {
1091
+ name: "12-Column Layout",
1092
+ description: "Classic 12-column grid system",
1093
+ config: {
1094
+ templateColumns: "repeat(12, 1fr)",
1095
+ templateRows: "auto",
1096
+ gap: 24,
1097
+ justifyItems: "stretch",
1098
+ alignItems: "stretch",
1099
+ justifyContent: "start",
1100
+ alignContent: "start"
1101
+ }
1102
+ },
1103
+ {
1104
+ name: "Holy Grail",
1105
+ description: "Header, two sidebars, content, footer",
1106
+ config: {
1107
+ templateColumns: "200px 1fr 200px",
1108
+ templateRows: "auto 1fr auto",
1109
+ gap: 0,
1110
+ justifyItems: "stretch",
1111
+ alignItems: "stretch",
1112
+ justifyContent: "stretch",
1113
+ alignContent: "stretch"
1114
+ }
1115
+ },
1116
+ {
1117
+ name: "Mosaic",
1118
+ description: "Asymmetric mosaic grid",
1119
+ config: {
1120
+ templateColumns: "2fr 1fr 1fr",
1121
+ templateRows: "repeat(2, 200px)",
1122
+ gap: 8,
1123
+ justifyItems: "stretch",
1124
+ alignItems: "stretch",
1125
+ justifyContent: "start",
1126
+ alignContent: "start"
1127
+ }
1128
+ },
1129
+ {
1130
+ name: "Card Grid",
1131
+ description: "Responsive auto-fit card grid",
1132
+ config: {
1133
+ templateColumns: "repeat(auto-fit, minmax(250px, 1fr))",
1134
+ templateRows: "auto",
1135
+ gap: 20,
1136
+ justifyItems: "stretch",
1137
+ alignItems: "start",
1138
+ justifyContent: "start",
1139
+ alignContent: "start"
1140
+ }
1141
+ }
1142
+ ];
1143
+ function generateGridContainerCss(config) {
1144
+ const lines = ["display: grid;"];
1145
+ lines.push(`grid-template-columns: ${config.templateColumns};`);
1146
+ lines.push(`grid-template-rows: ${config.templateRows};`);
1147
+ const colGap = config.columnGap !== void 0 ? config.columnGap : config.gap;
1148
+ const rowGap = config.rowGap !== void 0 ? config.rowGap : config.gap;
1149
+ if (colGap === rowGap) {
1150
+ lines.push(`gap: ${colGap}px;`);
1151
+ } else {
1152
+ lines.push(`column-gap: ${colGap}px;`);
1153
+ lines.push(`row-gap: ${rowGap}px;`);
1154
+ }
1155
+ lines.push(`justify-items: ${config.justifyItems};`);
1156
+ lines.push(`align-items: ${config.alignItems};`);
1157
+ lines.push(`justify-content: ${config.justifyContent};`);
1158
+ lines.push(`align-content: ${config.alignContent};`);
1159
+ return lines.join("\n");
1160
+ }
1161
+ function generateGridItemCss(config) {
1162
+ const lines = [];
1163
+ if (config.columnStart !== void 0) lines.push(`grid-column-start: ${config.columnStart};`);
1164
+ if (config.columnEnd !== void 0) lines.push(`grid-column-end: ${config.columnEnd};`);
1165
+ if (config.rowStart !== void 0) lines.push(`grid-row-start: ${config.rowStart};`);
1166
+ if (config.rowEnd !== void 0) lines.push(`grid-row-end: ${config.rowEnd};`);
1167
+ if (config.justifySelf !== void 0) lines.push(`justify-self: ${config.justifySelf};`);
1168
+ if (config.alignSelf !== void 0) lines.push(`align-self: ${config.alignSelf};`);
1169
+ return lines.join("\n");
1170
+ }
1171
+ function parseRepeat(expr) {
1172
+ const trimmed = expr.trim();
1173
+ const match = trimmed.match(/^repeat\(\s*([^,]+?)\s*,\s*(.+?)\s*\)$/i);
1174
+ if (!match) {
1175
+ return { error: "Invalid repeat() expression" };
1176
+ }
1177
+ const count = match[1].trim();
1178
+ const size = match[2].trim();
1179
+ if (count !== "auto-fit" && count !== "auto-fill") {
1180
+ const n = parseInt(count, 10);
1181
+ if (isNaN(n) || n <= 0) {
1182
+ return { error: `Invalid repeat count: ${count}` };
1183
+ }
1184
+ if (!size) {
1185
+ return { error: "Repeat size cannot be empty" };
1186
+ }
1187
+ return Array(n).fill(size).join(" ");
1188
+ }
1189
+ return `${count}(${size})`;
1190
+ }
1191
+ function buildRepeat(count, size) {
1192
+ return `repeat(${count}, ${size})`;
1193
+ }
1194
+
1195
+ exports.ANIMATION_PRESETS = ANIMATION_PRESETS;
1196
+ exports.BORDER_PRESETS = BORDER_PRESETS;
1197
+ exports.CUBIC_BEZIER_PRESETS = CUBIC_BEZIER_PRESETS;
1198
+ exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
1199
+ exports.DEFAULT_CONTAINER = DEFAULT_CONTAINER;
1200
+ exports.DEFAULT_ITEM = DEFAULT_ITEM;
1201
+ exports.DEFAULT_SHADOW = DEFAULT_SHADOW;
1202
+ exports.FLEX_PRESETS = FLEX_PRESETS;
1203
+ exports.GRADIENT_PRESETS = GRADIENT_PRESETS;
1204
+ exports.GRID_PRESETS = GRID_PRESETS;
1205
+ exports.PRESETS = PRESETS;
1206
+ exports.SHADOW_PRESETS = SHADOW_PRESETS;
1207
+ exports.buildRepeat = buildRepeat;
1208
+ exports.calcClamp = calcClamp;
1209
+ exports.calcSpecificity = calcSpecificity;
1210
+ exports.compareSpecificity = compareSpecificity;
1211
+ exports.countProperties = countProperties;
1212
+ exports.countRules = countRules;
1213
+ exports.explainSelector = explainSelector;
1214
+ exports.formatCss = formatCss;
1215
+ exports.generateAnimationCSS = generateAnimationCSS;
1216
+ exports.generateBorderRadius = generateBorderRadius;
1217
+ exports.generateBoxShadow = generateBoxShadow;
1218
+ exports.generateCssProperty = generateCssProperty;
1219
+ exports.generateFlexContainerCss = generateFlexContainerCss;
1220
+ exports.generateFlexItemCss = generateFlexItemCss;
1221
+ exports.generateFullCSS = generateFullCSS;
1222
+ exports.generateGradient = generateGradient;
1223
+ exports.generateGridContainerCss = generateGridContainerCss;
1224
+ exports.generateGridItemCss = generateGridItemCss;
1225
+ exports.generateKeyframesCSS = generateKeyframesCSS;
1226
+ exports.getCurvePoints = getCurvePoints;
1227
+ exports.isUniform = isUniform;
1228
+ exports.minifyCss = minifyCss;
1229
+ exports.multipleSelectors = multipleSelectors;
1230
+ exports.parseBorderRadius = parseBorderRadius;
1231
+ exports.parseBoxShadow = parseBoxShadow;
1232
+ exports.parseClampString = parseClampString;
1233
+ exports.parseCubicBezier = parseCubicBezier;
1234
+ exports.parseGradient = parseGradient;
1235
+ exports.parseKeyframesCSS = parseKeyframesCSS;
1236
+ exports.parseRepeat = parseRepeat;
1237
+ exports.previewClamp = previewClamp;
1238
+ exports.sampleCurve = sampleCurve;
1239
+ exports.toCssValue = toCssValue;
1240
+ exports.validateCubicBezierParams = validateCubicBezierParams;
1241
+ exports.validateKeyframes = validateKeyframes;
1242
+ exports.validateParams = validateParams;