dispersa 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -186,10 +186,55 @@ var init_errors = __esm({
186
186
  }
187
187
  });
188
188
 
189
- // src/lib/validation/dtcg-schemas/2025.10/format/group.json
189
+ // src/shared/utils/validation-handler.ts
190
+ var ValidationHandler;
191
+ var init_validation_handler = __esm({
192
+ "src/shared/utils/validation-handler.ts"() {
193
+ ValidationHandler = class {
194
+ mode;
195
+ constructor(options) {
196
+ this.mode = options?.mode ?? "error";
197
+ }
198
+ /**
199
+ * Whether validation checks should run (mode is not 'off')
200
+ */
201
+ shouldValidate() {
202
+ return this.mode !== "off";
203
+ }
204
+ /**
205
+ * Whether the current mode is 'error' (strictest)
206
+ */
207
+ isStrict() {
208
+ return this.mode === "error";
209
+ }
210
+ /**
211
+ * Handle a validation issue: throw in 'error' mode, warn in 'warn' mode, ignore in 'off' mode
212
+ */
213
+ handleIssue(error) {
214
+ if (this.mode === "error") {
215
+ throw error;
216
+ }
217
+ if (this.mode === "warn") {
218
+ console.warn(error.message);
219
+ }
220
+ }
221
+ /**
222
+ * Emit a warning (in 'error' and 'warn' modes, skip in 'off')
223
+ */
224
+ warn(message) {
225
+ if (this.mode === "off") {
226
+ return;
227
+ }
228
+ console.warn(message);
229
+ }
230
+ };
231
+ }
232
+ });
233
+
234
+ // src/validation/dtcg-schemas/2025.10/format/group.json
190
235
  var group_default;
191
236
  var init_group = __esm({
192
- "src/lib/validation/dtcg-schemas/2025.10/format/group.json"() {
237
+ "src/validation/dtcg-schemas/2025.10/format/group.json"() {
193
238
  group_default = {
194
239
  $schema: "http://json-schema.org/draft-07/schema#",
195
240
  $id: "https://www.designtokens.org/schemas/2025.10/format/group.json",
@@ -247,10 +292,10 @@ var init_group = __esm({
247
292
  }
248
293
  });
249
294
 
250
- // src/lib/validation/dtcg-schemas/2025.10/format/groupOrToken.json
295
+ // src/validation/dtcg-schemas/2025.10/format/groupOrToken.json
251
296
  var groupOrToken_default;
252
297
  var init_groupOrToken = __esm({
253
- "src/lib/validation/dtcg-schemas/2025.10/format/groupOrToken.json"() {
298
+ "src/validation/dtcg-schemas/2025.10/format/groupOrToken.json"() {
254
299
  groupOrToken_default = {
255
300
  $schema: "http://json-schema.org/draft-07/schema#",
256
301
  $id: "https://www.designtokens.org/schemas/2025.10/format/groupOrToken.json",
@@ -268,10 +313,10 @@ var init_groupOrToken = __esm({
268
313
  }
269
314
  });
270
315
 
271
- // src/lib/validation/dtcg-schemas/2025.10/format/token.json
316
+ // src/validation/dtcg-schemas/2025.10/format/token.json
272
317
  var token_default;
273
318
  var init_token = __esm({
274
- "src/lib/validation/dtcg-schemas/2025.10/format/token.json"() {
319
+ "src/validation/dtcg-schemas/2025.10/format/token.json"() {
275
320
  token_default = {
276
321
  $schema: "http://json-schema.org/draft-07/schema#",
277
322
  $id: "https://www.designtokens.org/schemas/2025.10/format/token.json",
@@ -699,10 +744,10 @@ var init_token = __esm({
699
744
  }
700
745
  });
701
746
 
702
- // src/lib/validation/dtcg-schemas/2025.10/format/tokenType.json
747
+ // src/validation/dtcg-schemas/2025.10/format/tokenType.json
703
748
  var tokenType_default;
704
749
  var init_tokenType = __esm({
705
- "src/lib/validation/dtcg-schemas/2025.10/format/tokenType.json"() {
750
+ "src/validation/dtcg-schemas/2025.10/format/tokenType.json"() {
706
751
  tokenType_default = {
707
752
  $schema: "http://json-schema.org/draft-07/schema#",
708
753
  $id: "https://www.designtokens.org/schemas/2025.10/format/tokenType.json",
@@ -728,10 +773,10 @@ var init_tokenType = __esm({
728
773
  }
729
774
  });
730
775
 
731
- // src/lib/validation/dtcg-schemas/2025.10/format/values/border.json
776
+ // src/validation/dtcg-schemas/2025.10/format/values/border.json
732
777
  var border_default;
733
778
  var init_border = __esm({
734
- "src/lib/validation/dtcg-schemas/2025.10/format/values/border.json"() {
779
+ "src/validation/dtcg-schemas/2025.10/format/values/border.json"() {
735
780
  border_default = {
736
781
  $schema: "http://json-schema.org/draft-07/schema#",
737
782
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/border.json",
@@ -779,10 +824,10 @@ var init_border = __esm({
779
824
  }
780
825
  });
781
826
 
782
- // src/lib/validation/dtcg-schemas/2025.10/format/values/color.json
827
+ // src/validation/dtcg-schemas/2025.10/format/values/color.json
783
828
  var color_default;
784
829
  var init_color = __esm({
785
- "src/lib/validation/dtcg-schemas/2025.10/format/values/color.json"() {
830
+ "src/validation/dtcg-schemas/2025.10/format/values/color.json"() {
786
831
  color_default = {
787
832
  $schema: "http://json-schema.org/draft-07/schema#",
788
833
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/color.json",
@@ -1300,10 +1345,10 @@ var init_color = __esm({
1300
1345
  }
1301
1346
  });
1302
1347
 
1303
- // src/lib/validation/dtcg-schemas/2025.10/format/values/cubicBezier.json
1348
+ // src/validation/dtcg-schemas/2025.10/format/values/cubicBezier.json
1304
1349
  var cubicBezier_default;
1305
1350
  var init_cubicBezier = __esm({
1306
- "src/lib/validation/dtcg-schemas/2025.10/format/values/cubicBezier.json"() {
1351
+ "src/validation/dtcg-schemas/2025.10/format/values/cubicBezier.json"() {
1307
1352
  cubicBezier_default = {
1308
1353
  $schema: "http://json-schema.org/draft-07/schema#",
1309
1354
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/cubicBezier.json",
@@ -1363,10 +1408,10 @@ var init_cubicBezier = __esm({
1363
1408
  }
1364
1409
  });
1365
1410
 
1366
- // src/lib/validation/dtcg-schemas/2025.10/format/values/dimension.json
1411
+ // src/validation/dtcg-schemas/2025.10/format/values/dimension.json
1367
1412
  var dimension_default;
1368
1413
  var init_dimension = __esm({
1369
- "src/lib/validation/dtcg-schemas/2025.10/format/values/dimension.json"() {
1414
+ "src/validation/dtcg-schemas/2025.10/format/values/dimension.json"() {
1370
1415
  dimension_default = {
1371
1416
  $schema: "http://json-schema.org/draft-07/schema#",
1372
1417
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/dimension.json",
@@ -1404,10 +1449,10 @@ var init_dimension = __esm({
1404
1449
  }
1405
1450
  });
1406
1451
 
1407
- // src/lib/validation/dtcg-schemas/2025.10/format/values/duration.json
1452
+ // src/validation/dtcg-schemas/2025.10/format/values/duration.json
1408
1453
  var duration_default;
1409
1454
  var init_duration = __esm({
1410
- "src/lib/validation/dtcg-schemas/2025.10/format/values/duration.json"() {
1455
+ "src/validation/dtcg-schemas/2025.10/format/values/duration.json"() {
1411
1456
  duration_default = {
1412
1457
  $schema: "http://json-schema.org/draft-07/schema#",
1413
1458
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/duration.json",
@@ -1445,10 +1490,10 @@ var init_duration = __esm({
1445
1490
  }
1446
1491
  });
1447
1492
 
1448
- // src/lib/validation/dtcg-schemas/2025.10/format/values/fontFamily.json
1493
+ // src/validation/dtcg-schemas/2025.10/format/values/fontFamily.json
1449
1494
  var fontFamily_default;
1450
1495
  var init_fontFamily = __esm({
1451
- "src/lib/validation/dtcg-schemas/2025.10/format/values/fontFamily.json"() {
1496
+ "src/validation/dtcg-schemas/2025.10/format/values/fontFamily.json"() {
1452
1497
  fontFamily_default = {
1453
1498
  $schema: "http://json-schema.org/draft-07/schema#",
1454
1499
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/fontFamily.json",
@@ -1485,10 +1530,10 @@ var init_fontFamily = __esm({
1485
1530
  }
1486
1531
  });
1487
1532
 
1488
- // src/lib/validation/dtcg-schemas/2025.10/format/values/fontWeight.json
1533
+ // src/validation/dtcg-schemas/2025.10/format/values/fontWeight.json
1489
1534
  var fontWeight_default;
1490
1535
  var init_fontWeight = __esm({
1491
- "src/lib/validation/dtcg-schemas/2025.10/format/values/fontWeight.json"() {
1536
+ "src/validation/dtcg-schemas/2025.10/format/values/fontWeight.json"() {
1492
1537
  fontWeight_default = {
1493
1538
  $schema: "http://json-schema.org/draft-07/schema#",
1494
1539
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/fontWeight.json",
@@ -1530,10 +1575,10 @@ var init_fontWeight = __esm({
1530
1575
  }
1531
1576
  });
1532
1577
 
1533
- // src/lib/validation/dtcg-schemas/2025.10/format/values/gradient.json
1578
+ // src/validation/dtcg-schemas/2025.10/format/values/gradient.json
1534
1579
  var gradient_default;
1535
1580
  var init_gradient = __esm({
1536
- "src/lib/validation/dtcg-schemas/2025.10/format/values/gradient.json"() {
1581
+ "src/validation/dtcg-schemas/2025.10/format/values/gradient.json"() {
1537
1582
  gradient_default = {
1538
1583
  $schema: "http://json-schema.org/draft-07/schema#",
1539
1584
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/gradient.json",
@@ -1589,10 +1634,10 @@ var init_gradient = __esm({
1589
1634
  }
1590
1635
  });
1591
1636
 
1592
- // src/lib/validation/dtcg-schemas/2025.10/format/values/number.json
1637
+ // src/validation/dtcg-schemas/2025.10/format/values/number.json
1593
1638
  var number_default;
1594
1639
  var init_number = __esm({
1595
- "src/lib/validation/dtcg-schemas/2025.10/format/values/number.json"() {
1640
+ "src/validation/dtcg-schemas/2025.10/format/values/number.json"() {
1596
1641
  number_default = {
1597
1642
  $schema: "http://json-schema.org/draft-07/schema#",
1598
1643
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/number.json",
@@ -1603,10 +1648,10 @@ var init_number = __esm({
1603
1648
  }
1604
1649
  });
1605
1650
 
1606
- // src/lib/validation/dtcg-schemas/2025.10/format/values/shadow.json
1651
+ // src/validation/dtcg-schemas/2025.10/format/values/shadow.json
1607
1652
  var shadow_default;
1608
1653
  var init_shadow = __esm({
1609
- "src/lib/validation/dtcg-schemas/2025.10/format/values/shadow.json"() {
1654
+ "src/validation/dtcg-schemas/2025.10/format/values/shadow.json"() {
1610
1655
  shadow_default = {
1611
1656
  $schema: "http://json-schema.org/draft-07/schema#",
1612
1657
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/shadow.json",
@@ -1712,10 +1757,10 @@ var init_shadow = __esm({
1712
1757
  }
1713
1758
  });
1714
1759
 
1715
- // src/lib/validation/dtcg-schemas/2025.10/format/values/strokeStyle.json
1760
+ // src/validation/dtcg-schemas/2025.10/format/values/strokeStyle.json
1716
1761
  var strokeStyle_default;
1717
1762
  var init_strokeStyle = __esm({
1718
- "src/lib/validation/dtcg-schemas/2025.10/format/values/strokeStyle.json"() {
1763
+ "src/validation/dtcg-schemas/2025.10/format/values/strokeStyle.json"() {
1719
1764
  strokeStyle_default = {
1720
1765
  $schema: "http://json-schema.org/draft-07/schema#",
1721
1766
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/strokeStyle.json",
@@ -1773,10 +1818,10 @@ var init_strokeStyle = __esm({
1773
1818
  }
1774
1819
  });
1775
1820
 
1776
- // src/lib/validation/dtcg-schemas/2025.10/format/values/transition.json
1821
+ // src/validation/dtcg-schemas/2025.10/format/values/transition.json
1777
1822
  var transition_default;
1778
1823
  var init_transition = __esm({
1779
- "src/lib/validation/dtcg-schemas/2025.10/format/values/transition.json"() {
1824
+ "src/validation/dtcg-schemas/2025.10/format/values/transition.json"() {
1780
1825
  transition_default = {
1781
1826
  $schema: "http://json-schema.org/draft-07/schema#",
1782
1827
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/transition.json",
@@ -1824,10 +1869,10 @@ var init_transition = __esm({
1824
1869
  }
1825
1870
  });
1826
1871
 
1827
- // src/lib/validation/dtcg-schemas/2025.10/format/values/typography.json
1872
+ // src/validation/dtcg-schemas/2025.10/format/values/typography.json
1828
1873
  var typography_default;
1829
1874
  var init_typography = __esm({
1830
- "src/lib/validation/dtcg-schemas/2025.10/format/values/typography.json"() {
1875
+ "src/validation/dtcg-schemas/2025.10/format/values/typography.json"() {
1831
1876
  typography_default = {
1832
1877
  $schema: "http://json-schema.org/draft-07/schema#",
1833
1878
  $id: "https://www.designtokens.org/schemas/2025.10/format/values/typography.json",
@@ -1897,10 +1942,10 @@ var init_typography = __esm({
1897
1942
  }
1898
1943
  });
1899
1944
 
1900
- // src/lib/validation/dtcg-schemas/2025.10/format.json
1945
+ // src/validation/dtcg-schemas/2025.10/format.json
1901
1946
  var format_default;
1902
1947
  var init_format = __esm({
1903
- "src/lib/validation/dtcg-schemas/2025.10/format.json"() {
1948
+ "src/validation/dtcg-schemas/2025.10/format.json"() {
1904
1949
  format_default = {
1905
1950
  $schema: "http://json-schema.org/draft-07/schema#",
1906
1951
  $id: "https://www.designtokens.org/schemas/2025.10/format.json",
@@ -2009,10 +2054,10 @@ var init_format = __esm({
2009
2054
  }
2010
2055
  });
2011
2056
 
2012
- // src/lib/validation/dtcg-schemas/2025.10/resolver/modifier.json
2057
+ // src/validation/dtcg-schemas/2025.10/resolver/modifier.json
2013
2058
  var modifier_default;
2014
2059
  var init_modifier = __esm({
2015
- "src/lib/validation/dtcg-schemas/2025.10/resolver/modifier.json"() {
2060
+ "src/validation/dtcg-schemas/2025.10/resolver/modifier.json"() {
2016
2061
  modifier_default = {
2017
2062
  $schema: "http://json-schema.org/draft-07/schema#",
2018
2063
  $id: "https://www.designtokens.org/schemas/2025.10/resolver/modifier.json",
@@ -2100,10 +2145,10 @@ var init_modifier = __esm({
2100
2145
  }
2101
2146
  });
2102
2147
 
2103
- // src/lib/validation/dtcg-schemas/2025.10/resolver/resolutionOrder.json
2148
+ // src/validation/dtcg-schemas/2025.10/resolver/resolutionOrder.json
2104
2149
  var resolutionOrder_default;
2105
2150
  var init_resolutionOrder = __esm({
2106
- "src/lib/validation/dtcg-schemas/2025.10/resolver/resolutionOrder.json"() {
2151
+ "src/validation/dtcg-schemas/2025.10/resolver/resolutionOrder.json"() {
2107
2152
  resolutionOrder_default = {
2108
2153
  $schema: "http://json-schema.org/draft-07/schema#",
2109
2154
  $id: "https://www.designtokens.org/schemas/2025.10/resolver/resolutionOrder.json",
@@ -2223,10 +2268,10 @@ var init_resolutionOrder = __esm({
2223
2268
  }
2224
2269
  });
2225
2270
 
2226
- // src/lib/validation/dtcg-schemas/2025.10/resolver/set.json
2271
+ // src/validation/dtcg-schemas/2025.10/resolver/set.json
2227
2272
  var set_default;
2228
2273
  var init_set = __esm({
2229
- "src/lib/validation/dtcg-schemas/2025.10/resolver/set.json"() {
2274
+ "src/validation/dtcg-schemas/2025.10/resolver/set.json"() {
2230
2275
  set_default = {
2231
2276
  $schema: "http://json-schema.org/draft-07/schema#",
2232
2277
  $id: "https://www.designtokens.org/schemas/2025.10/resolver/set.json",
@@ -2300,10 +2345,10 @@ var init_set = __esm({
2300
2345
  }
2301
2346
  });
2302
2347
 
2303
- // src/lib/validation/dtcg-schemas/2025.10/resolver.json
2348
+ // src/validation/dtcg-schemas/2025.10/resolver.json
2304
2349
  var resolver_default;
2305
2350
  var init_resolver = __esm({
2306
- "src/lib/validation/dtcg-schemas/2025.10/resolver.json"() {
2351
+ "src/validation/dtcg-schemas/2025.10/resolver.json"() {
2307
2352
  resolver_default = {
2308
2353
  $schema: "http://json-schema.org/draft-07/schema#",
2309
2354
  $id: "https://www.designtokens.org/schemas/2025.10/resolver.json",
@@ -2368,10 +2413,10 @@ var init_resolver = __esm({
2368
2413
  }
2369
2414
  });
2370
2415
 
2371
- // src/lib/validation/schemas.ts
2416
+ // src/validation/schemas.ts
2372
2417
  var formatSchema, tokenSchema, tokenTypeSchema, groupSchema, groupOrTokenSchema, colorValueSchema, dimensionValueSchema, fontFamilyValueSchema, fontWeightValueSchema, durationValueSchema, cubicBezierValueSchema, numberValueSchema, strokeStyleValueSchema, borderValueSchema, transitionValueSchema, shadowValueSchema, gradientValueSchema, typographyValueSchema, resolverSchema, resolverSetSchema, resolverModifierSchema, resolverResolutionOrderSchema, dtcgSchemaRegistry;
2373
2418
  var init_schemas = __esm({
2374
- "src/lib/validation/schemas.ts"() {
2419
+ "src/validation/schemas.ts"() {
2375
2420
  init_group();
2376
2421
  init_groupOrToken();
2377
2422
  init_token();
@@ -2443,10 +2488,10 @@ var init_schemas = __esm({
2443
2488
  }
2444
2489
  });
2445
2490
 
2446
- // src/lib/validation/config-schemas.ts
2491
+ // src/validation/config-schemas.ts
2447
2492
  var resolverSchemaRef, basePluginProperties, commonRendererOptionsProperties, transformPluginSchema, rendererPluginSchema, filterPluginSchema, preprocessorPluginSchema, outputConfigSchema, dispersaOptionsSchema, buildConfigSchema;
2448
2493
  var init_config_schemas = __esm({
2449
- "src/lib/validation/config-schemas.ts"() {
2494
+ "src/validation/config-schemas.ts"() {
2450
2495
  init_schemas();
2451
2496
  resolverSchemaRef = resolverSchema;
2452
2497
  basePluginProperties = {
@@ -2500,6 +2545,25 @@ var init_config_schemas = __esm({
2500
2545
  additionalProperties: true
2501
2546
  // Allow custom properties for extended renderers
2502
2547
  });
2548
+ ({
2549
+ $schema: "http://json-schema.org/draft-07/schema#",
2550
+ type: "object",
2551
+ properties: {
2552
+ preset: { type: "string", enum: ["bundle", "standalone"] },
2553
+ includeImport: {
2554
+ type: "boolean",
2555
+ description: 'Prepend @import "tailwindcss" to the output'
2556
+ },
2557
+ namespace: {
2558
+ type: "string",
2559
+ description: "Optional Tailwind namespace prefix for @theme"
2560
+ },
2561
+ selector: { type: "string" },
2562
+ mediaQuery: { type: "string" },
2563
+ ...commonRendererOptionsProperties
2564
+ },
2565
+ additionalProperties: true
2566
+ });
2503
2567
  transformPluginSchema = {
2504
2568
  $schema: "http://json-schema.org/draft-07/schema#",
2505
2569
  type: "object",
@@ -2705,7 +2769,7 @@ var init_config_schemas = __esm({
2705
2769
  });
2706
2770
  var SchemaValidator;
2707
2771
  var init_validator = __esm({
2708
- "src/lib/validation/validator.ts"() {
2772
+ "src/validation/validator.ts"() {
2709
2773
  init_errors();
2710
2774
  init_token_utils();
2711
2775
  init_config_schemas();
@@ -2957,63 +3021,18 @@ var init_validator = __esm({
2957
3021
  }
2958
3022
  });
2959
3023
 
2960
- // src/lib/validation/index.ts
3024
+ // src/validation/index.ts
2961
3025
  var init_validation = __esm({
2962
- "src/lib/validation/index.ts"() {
3026
+ "src/validation/index.ts"() {
2963
3027
  init_validator();
2964
3028
  }
2965
3029
  });
2966
-
2967
- // src/shared/utils/validation-handler.ts
2968
- var ValidationHandler;
2969
- var init_validation_handler = __esm({
2970
- "src/shared/utils/validation-handler.ts"() {
2971
- ValidationHandler = class {
2972
- mode;
2973
- constructor(options) {
2974
- this.mode = options?.mode ?? "error";
2975
- }
2976
- /**
2977
- * Whether validation checks should run (mode is not 'off')
2978
- */
2979
- shouldValidate() {
2980
- return this.mode !== "off";
2981
- }
2982
- /**
2983
- * Whether the current mode is 'error' (strictest)
2984
- */
2985
- isStrict() {
2986
- return this.mode === "error";
2987
- }
2988
- /**
2989
- * Handle a validation issue: throw in 'error' mode, warn in 'warn' mode, ignore in 'off' mode
2990
- */
2991
- handleIssue(error) {
2992
- if (this.mode === "error") {
2993
- throw error;
2994
- }
2995
- if (this.mode === "warn") {
2996
- console.warn(error.message);
2997
- }
2998
- }
2999
- /**
3000
- * Emit a warning (in 'error' and 'warn' modes, skip in 'off')
3001
- */
3002
- warn(message) {
3003
- if (this.mode === "off") {
3004
- return;
3005
- }
3006
- console.warn(message);
3007
- }
3008
- };
3009
- }
3010
- });
3011
3030
  var ResolverParser;
3012
3031
  var init_resolver_parser = __esm({
3013
3032
  "src/adapters/filesystem/resolver-parser.ts"() {
3014
- init_validation();
3015
3033
  init_errors();
3016
3034
  init_validation_handler();
3035
+ init_validation();
3017
3036
  ResolverParser = class {
3018
3037
  validator;
3019
3038
  options;
@@ -3595,7 +3614,7 @@ var init_json = __esm({
3595
3614
  }
3596
3615
  });
3597
3616
 
3598
- // src/lib/codegen/type-generator.ts
3617
+ // src/codegen/type-generator.ts
3599
3618
  var TypeGenerator = class {
3600
3619
  /**
3601
3620
  * Generates complete TypeScript type definitions from resolved tokens
@@ -3727,8 +3746,8 @@ var TypeGenerator = class {
3727
3746
  /**
3728
3747
  * Add structure properties to lines
3729
3748
  */
3730
- addStructureProperties(lines, structure, indent) {
3731
- const indentStr = " ".repeat(indent);
3749
+ addStructureProperties(lines, structure, indent2) {
3750
+ const indentStr = " ".repeat(indent2);
3732
3751
  for (const [key, value] of Object.entries(structure)) {
3733
3752
  if (this.isToken(value)) {
3734
3753
  const token = value;
@@ -3739,7 +3758,7 @@ var TypeGenerator = class {
3739
3758
  lines.push(`${indentStr}${this.quoteKey(key)}: ${valueType}`);
3740
3759
  } else {
3741
3760
  lines.push(`${indentStr}${this.quoteKey(key)}: {`);
3742
- this.addStructureProperties(lines, value, indent + 1);
3761
+ this.addStructureProperties(lines, value, indent2 + 1);
3743
3762
  lines.push(`${indentStr}}`);
3744
3763
  }
3745
3764
  }
@@ -4084,7 +4103,7 @@ async function writeOutputFile(fileName, content, encoding = "utf-8") {
4084
4103
  }
4085
4104
  }
4086
4105
 
4087
- // src/lib/processing/token-modifier.ts
4106
+ // src/processing/token-modifier.ts
4088
4107
  function applyTransforms(tokens, transformList) {
4089
4108
  const result = {};
4090
4109
  for (const [name, token] of Object.entries(tokens)) {
@@ -4216,7 +4235,7 @@ init_validation_handler();
4216
4235
  // src/shared/constants.ts
4217
4236
  var DEFAULT_MAX_ALIAS_DEPTH = 10;
4218
4237
 
4219
- // src/lib/resolution/alias-resolver.ts
4238
+ // src/resolution/alias-resolver.ts
4220
4239
  init_errors();
4221
4240
 
4222
4241
  // src/shared/utils/string-similarity.ts
@@ -4267,7 +4286,7 @@ function findSimilar(target, candidates, maxDistance, maxResults = 3) {
4267
4286
  return scored.slice(0, maxResults).map((entry) => entry.value);
4268
4287
  }
4269
4288
 
4270
- // src/lib/resolution/alias-resolver.ts
4289
+ // src/resolution/alias-resolver.ts
4271
4290
  init_token_utils();
4272
4291
  init_validation_handler();
4273
4292
  var AliasResolver = class _AliasResolver {
@@ -4525,7 +4544,7 @@ var AliasResolver = class _AliasResolver {
4525
4544
  }
4526
4545
  };
4527
4546
 
4528
- // src/lib/resolution/reference-resolver.ts
4547
+ // src/resolution/reference-resolver.ts
4529
4548
  init_errors();
4530
4549
  init_validation_handler();
4531
4550
  var ReferenceResolver = class _ReferenceResolver {
@@ -4832,7 +4851,7 @@ var ReferenceResolver = class _ReferenceResolver {
4832
4851
  }
4833
4852
  };
4834
4853
 
4835
- // src/lib/resolution/resolution-engine.ts
4854
+ // src/resolution/resolution-engine.ts
4836
4855
  init_errors();
4837
4856
 
4838
4857
  // src/shared/utils/case-insensitive-map.ts
@@ -4934,10 +4953,10 @@ var CaseInsensitiveMap = class {
4934
4953
  }
4935
4954
  };
4936
4955
 
4937
- // src/lib/resolution/resolution-engine.ts
4956
+ // src/resolution/resolution-engine.ts
4938
4957
  init_validation_handler();
4939
4958
 
4940
- // src/lib/resolution/modifier-input-processor.ts
4959
+ // src/resolution/modifier-input-processor.ts
4941
4960
  init_errors();
4942
4961
  var ModifierInputProcessor = class {
4943
4962
  modifiers;
@@ -5120,7 +5139,7 @@ var ModifierInputProcessor = class {
5120
5139
  }
5121
5140
  };
5122
5141
 
5123
- // src/lib/resolution/resolution-engine.ts
5142
+ // src/resolution/resolution-engine.ts
5124
5143
  var JSON_POINTER_SETS_PREFIX = "#/sets/";
5125
5144
  var JSON_POINTER_MODIFIERS_PREFIX = "#/modifiers/";
5126
5145
  var ResolutionEngine = class {
@@ -5405,7 +5424,6 @@ var ResolutionEngine = class {
5405
5424
  return typeof obj === "object" && obj !== null && "contexts" in obj && typeof obj.contexts === "object";
5406
5425
  }
5407
5426
  };
5408
- init_validator();
5409
5427
  init_errors();
5410
5428
 
5411
5429
  // src/shared/utils/path-utils.ts
@@ -5416,11 +5434,12 @@ function formatTokenPath(parentPath, name) {
5416
5434
  return parentPath.length > 0 ? `${parentPath.join(".")}.${name}` : name;
5417
5435
  }
5418
5436
 
5419
- // src/lib/tokens/token-parser.ts
5437
+ // src/tokens/token-parser.ts
5420
5438
  init_token_utils();
5421
5439
  init_validation_handler();
5440
+ init_validator();
5422
5441
 
5423
- // src/lib/tokens/group-extension-resolver.ts
5442
+ // src/tokens/group-extension-resolver.ts
5424
5443
  init_errors();
5425
5444
  init_token_utils();
5426
5445
  var GroupExtensionResolver = class {
@@ -5582,7 +5601,7 @@ var GroupExtensionResolver = class {
5582
5601
  }
5583
5602
  };
5584
5603
 
5585
- // src/lib/tokens/token-parser.ts
5604
+ // src/tokens/token-parser.ts
5586
5605
  var INVALID_NAME_CHARS_REGEX = /[{}.]/;
5587
5606
  var TokenParser = class {
5588
5607
  validator;
@@ -6095,9 +6114,9 @@ var TokenPipeline = class {
6095
6114
  };
6096
6115
 
6097
6116
  // src/dispersa.ts
6098
- init_validator();
6099
6117
  init_errors();
6100
6118
  init_token_utils();
6119
+ init_validator();
6101
6120
  var Dispersa = class {
6102
6121
  validator;
6103
6122
  pipeline;
@@ -6379,7 +6398,7 @@ var Dispersa = class {
6379
6398
  }
6380
6399
  };
6381
6400
 
6382
- // src/lib/tokens/types.ts
6401
+ // src/tokens/types.ts
6383
6402
  function isColorToken(token) {
6384
6403
  return token.$type === "color";
6385
6404
  }
@@ -6461,7 +6480,7 @@ function colorObjectToHex(color) {
6461
6480
  return culori.formatHex(culoriColor);
6462
6481
  }
6463
6482
 
6464
- // src/lib/processing/processors/transforms/built-in/dimension-converter.ts
6483
+ // src/processing/processors/transforms/built-in/dimension-converter.ts
6465
6484
  function isDimensionObject(value) {
6466
6485
  return typeof value === "object" && value !== null && "value" in value && "unit" in value;
6467
6486
  }
@@ -6469,127 +6488,868 @@ function dimensionObjectToString(dimension) {
6469
6488
  return `${dimension.value}${dimension.unit}`;
6470
6489
  }
6471
6490
 
6472
- // src/renderers/css.ts
6491
+ // src/renderers/android.ts
6473
6492
  init_errors();
6474
6493
  init_token_utils();
6475
-
6476
- // src/renderers/bundlers/css.ts
6477
- init_errors();
6478
6494
  init_utils();
6479
- var getSourceSet = (token) => {
6480
- if (typeof token !== "object" || token === null) {
6481
- return void 0;
6482
- }
6483
- const maybe = token;
6484
- return typeof maybe._sourceSet === "string" ? maybe._sourceSet : void 0;
6495
+ var toSRGB = culori.converter("rgb");
6496
+ var toP3 = culori.converter("p3");
6497
+ var KOTLIN_KEYWORDS = /* @__PURE__ */ new Set([
6498
+ "val",
6499
+ "var",
6500
+ "fun",
6501
+ "class",
6502
+ "object",
6503
+ "when",
6504
+ "is",
6505
+ "in",
6506
+ "return",
6507
+ "break",
6508
+ "continue",
6509
+ "do",
6510
+ "while",
6511
+ "for",
6512
+ "if",
6513
+ "else",
6514
+ "try",
6515
+ "catch",
6516
+ "throw",
6517
+ "as",
6518
+ "this",
6519
+ "super",
6520
+ "null",
6521
+ "true",
6522
+ "false"
6523
+ ]);
6524
+ var KOTLIN_TYPE_GROUP_MAP = {
6525
+ color: "Colors",
6526
+ dimension: "Spacing",
6527
+ fontFamily: "Fonts",
6528
+ fontWeight: "FontWeights",
6529
+ duration: "Durations",
6530
+ shadow: "Shadows",
6531
+ typography: "Typography",
6532
+ number: "Numbers",
6533
+ cubicBezier: "Animations",
6534
+ border: "Borders"
6485
6535
  };
6486
- var getSourceModifier = (token) => {
6487
- if (typeof token !== "object" || token === null) {
6488
- return void 0;
6536
+ function resolveColorFormat(format) {
6537
+ if (format === "argb_floats" || format === "argb_float") {
6538
+ return "argb_float";
6489
6539
  }
6490
- const maybe = token;
6491
- return typeof maybe._sourceModifier === "string" ? maybe._sourceModifier : void 0;
6492
- };
6493
- async function bundleAsCss(bundleData, resolver, options, formatTokens) {
6494
- const baseItem = bundleData.find((item) => item.isBase);
6495
- if (!baseItem) {
6496
- throw new exports.BasePermutationError("Base permutation not found in bundle data");
6540
+ return "argb_hex";
6541
+ }
6542
+ function indent(width, level) {
6543
+ return " ".repeat(width * level);
6544
+ }
6545
+ function escapeKotlinString(str) {
6546
+ return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\$/g, "\\$");
6547
+ }
6548
+ function escapeKDoc(str) {
6549
+ return str.replace(/\*\//g, "* /").replace(/\r?\n/g, " ").trim();
6550
+ }
6551
+ function formatKotlinNumber(value) {
6552
+ return Number.isInteger(value) ? `${value}.0` : String(value);
6553
+ }
6554
+ function roundComponent(value) {
6555
+ return Math.round(value * 1e3) / 1e3;
6556
+ }
6557
+ function toResourceName(family) {
6558
+ return family.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
6559
+ }
6560
+ function toPascalCase(name) {
6561
+ const pascal = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
6562
+ const result = pascal.charAt(0).toUpperCase() + pascal.slice(1);
6563
+ if (/^\d/.test(result)) {
6564
+ return `_${result}`;
6497
6565
  }
6498
- if (!formatTokens) {
6499
- throw new exports.ConfigurationError("CSS formatter was not provided");
6566
+ return KOTLIN_KEYWORDS.has(result.charAt(0).toLowerCase() + result.slice(1)) ? `\`${result}\`` : result;
6567
+ }
6568
+ function toKotlinIdentifier(name) {
6569
+ const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
6570
+ const identifier = camel.charAt(0).toLowerCase() + camel.slice(1);
6571
+ if (/^\d/.test(identifier)) {
6572
+ return `_${identifier}`;
6500
6573
  }
6501
- const orderedBundleData = orderBundleData(bundleData, resolver, baseItem);
6502
- const cssBlocks = [];
6503
- for (const item of orderedBundleData) {
6504
- if (item.isBase) {
6505
- const blocks = await formatBasePermutation(item, resolver, options, formatTokens);
6506
- cssBlocks.push(...blocks);
6507
- continue;
6574
+ return KOTLIN_KEYWORDS.has(identifier) ? `\`${identifier}\`` : identifier;
6575
+ }
6576
+ var AndroidRenderer = class {
6577
+ async format(context, options) {
6578
+ if (!options?.packageName) {
6579
+ throw new exports.ConfigurationError(
6580
+ `Output "${context.output.name}": packageName is required for Android output`
6581
+ );
6508
6582
  }
6509
- const block = await formatModifierPermutation(item, baseItem, options, formatTokens);
6510
- if (block) {
6511
- cssBlocks.push(block);
6583
+ const opts = {
6584
+ preset: options?.preset ?? "standalone",
6585
+ packageName: options.packageName,
6586
+ objectName: options?.objectName ?? "DesignTokens",
6587
+ colorFormat: resolveColorFormat(options?.colorFormat),
6588
+ colorSpace: options?.colorSpace ?? "sRGB",
6589
+ structure: options?.structure ?? "nested",
6590
+ visibility: options?.visibility,
6591
+ indent: options?.indent ?? 4
6592
+ };
6593
+ if (opts.preset === "bundle") {
6594
+ return await this.formatBundle(context, opts);
6512
6595
  }
6596
+ return await this.formatStandalone(context, opts);
6513
6597
  }
6514
- return cssBlocks.join("\n\n");
6515
- }
6516
- async function formatBasePermutation({ tokens, modifierInputs }, resolver, options, formatTokens) {
6517
- const firstModifierName = resolver.modifiers ? Object.keys(resolver.modifiers)[0] : "";
6518
- const modifier = firstModifierName ?? "";
6519
- const context = modifierInputs[modifier] ?? "";
6520
- const selector = resolveSelector(options?.selector, modifier, context, true, modifierInputs);
6521
- const mediaQuery = resolveMediaQuery(options?.mediaQuery, modifier, context, true, modifierInputs);
6522
- const referenceTokens = stripInternalMetadata(tokens);
6523
- const defaultBlocks = buildDefaultLayerBlocks(tokens, modifierInputs, resolver);
6524
- const cssBlocks = [];
6525
- for (const block of defaultBlocks) {
6526
- const cleanTokens = stripInternalMetadata(block.tokens);
6527
- const css2 = await formatTokens(cleanTokens, {
6528
- selector,
6529
- mediaQuery,
6530
- minify: options?.minify,
6531
- referenceTokens
6532
- });
6533
- const header = block.description ? `/* ${block.key} */
6534
- /* ${block.description} */` : `/* ${block.key} */`;
6535
- cssBlocks.push(`${header}
6536
- ${css2}`);
6598
+ // -----------------------------------------------------------------------
6599
+ // Token tree (nested mode)
6600
+ // -----------------------------------------------------------------------
6601
+ buildTokenTree(tokens) {
6602
+ const root = { children: /* @__PURE__ */ new Map() };
6603
+ for (const [, token] of getSortedTokenEntries(tokens)) {
6604
+ let current = root;
6605
+ const segments = token.path;
6606
+ for (let i = 0; i < segments.length - 1; i++) {
6607
+ const seg = segments[i];
6608
+ if (!current.children.has(seg)) {
6609
+ current.children.set(seg, { children: /* @__PURE__ */ new Map() });
6610
+ }
6611
+ current = current.children.get(seg);
6612
+ }
6613
+ const leafName = segments[segments.length - 1] ?? token.name;
6614
+ const leaf = current.children.get(leafName) ?? { children: /* @__PURE__ */ new Map() };
6615
+ leaf.token = token;
6616
+ current.children.set(leafName, leaf);
6617
+ }
6618
+ return root;
6537
6619
  }
6538
- return cssBlocks;
6539
- }
6540
- async function formatModifierPermutation({ tokens, modifierInputs }, baseItem, options, formatTokens) {
6541
- const differenceCount = countModifierDifferences(modifierInputs, baseItem.modifierInputs);
6542
- if (differenceCount > 1) {
6543
- return void 0;
6620
+ // -----------------------------------------------------------------------
6621
+ // Flat structure grouping
6622
+ // -----------------------------------------------------------------------
6623
+ groupTokensByType(tokens) {
6624
+ const groupMap = /* @__PURE__ */ new Map();
6625
+ for (const [, token] of getSortedTokenEntries(tokens)) {
6626
+ const groupName = KOTLIN_TYPE_GROUP_MAP[token.$type ?? ""] ?? "Other";
6627
+ const existing = groupMap.get(groupName) ?? [];
6628
+ existing.push(token);
6629
+ groupMap.set(groupName, existing);
6630
+ }
6631
+ return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
6632
+ name,
6633
+ tokens: groupTokens
6634
+ }));
6544
6635
  }
6545
- const expectedSource = getExpectedSource(modifierInputs, baseItem.modifierInputs);
6546
- let tokensToInclude = filterTokensBySource(tokens, expectedSource);
6547
- const hasSourceMetadata = Object.values(tokens).some(
6548
- (token) => token != null && getSourceModifier(token) !== void 0
6549
- );
6550
- if (Object.keys(tokensToInclude).length === 0 && !hasSourceMetadata) {
6551
- tokensToInclude = tokens;
6636
+ /**
6637
+ * Builds a flattened camelCase name from a token's path, stripping the
6638
+ * type prefix segment (which is already represented by the group object).
6639
+ */
6640
+ buildFlatKotlinName(token) {
6641
+ const path7 = token.path;
6642
+ const withoutTypePrefix = path7.length > 1 ? path7.slice(1) : path7;
6643
+ const joined = withoutTypePrefix.join("_");
6644
+ return toKotlinIdentifier(joined);
6645
+ }
6646
+ // -----------------------------------------------------------------------
6647
+ // Rendering
6648
+ // -----------------------------------------------------------------------
6649
+ formatTokens(tokens, options) {
6650
+ if (options.structure === "flat") {
6651
+ return this.formatAsFlat(tokens, options);
6652
+ }
6653
+ return this.formatAsNested(tokens, options);
6654
+ }
6655
+ formatAsNested(tokens, options) {
6656
+ const tree = this.buildTokenTree(tokens);
6657
+ const tokenTypes = /* @__PURE__ */ new Set();
6658
+ this.collectTokenTypes(tree, tokenTypes);
6659
+ return this.buildFile(tokenTypes, options, (lines, vis) => {
6660
+ lines.push(`@Suppress("unused")`);
6661
+ lines.push(`${vis}object ${options.objectName} {`);
6662
+ this.renderTreeChildren(lines, tree, 1, options);
6663
+ lines.push("}");
6664
+ });
6552
6665
  }
6553
- if (Object.keys(tokensToInclude).length === 0) {
6554
- return void 0;
6666
+ formatAsFlat(tokens, options) {
6667
+ const groups = this.groupTokensByType(tokens);
6668
+ const tokenTypes = this.collectTokenTypesFromEntries(tokens);
6669
+ return this.buildFile(tokenTypes, options, (lines, vis) => {
6670
+ lines.push(`@Suppress("unused")`);
6671
+ lines.push(`${vis}object ${options.objectName} {`);
6672
+ this.renderFlatGroups(lines, groups, 1, options);
6673
+ lines.push("}");
6674
+ });
6555
6675
  }
6556
- const [modifier, context] = parseModifierSource(expectedSource);
6557
- const cleanTokens = stripInternalMetadata(tokensToInclude);
6558
- const referenceTokens = stripInternalMetadata(tokens);
6559
- const selector = resolveSelector(options?.selector, modifier, context, false, modifierInputs);
6560
- const mediaQuery = resolveMediaQuery(
6561
- options?.mediaQuery,
6562
- modifier,
6563
- context,
6564
- false,
6565
- modifierInputs
6566
- );
6567
- const css2 = await formatTokens(cleanTokens, {
6568
- selector,
6569
- mediaQuery,
6570
- minify: options?.minify,
6571
- referenceTokens
6572
- });
6573
- return `/* Modifier: ${modifier}=${context} */
6574
- ${css2}`;
6575
- }
6576
- function collectSetTokens(tokens, setName, included) {
6577
- const result = {};
6578
- for (const [name, token] of Object.entries(tokens)) {
6579
- if (!included.has(name) && getSourceSet(token) === setName) {
6580
- result[name] = token;
6676
+ /**
6677
+ * Shared file preamble: header, package, imports, optional ShadowToken class.
6678
+ * The `renderBody` callback appends the main object(s) to `lines`.
6679
+ */
6680
+ buildFile(tokenTypes, options, renderBody) {
6681
+ const imports = this.collectImports(tokenTypes, options);
6682
+ const vis = options.visibility ? `${options.visibility} ` : "";
6683
+ const lines = [];
6684
+ lines.push(this.buildFileHeader());
6685
+ lines.push("");
6686
+ lines.push(`package ${options.packageName}`);
6687
+ lines.push("");
6688
+ for (const imp of imports) {
6689
+ lines.push(`import ${imp}`);
6581
6690
  }
6582
- }
6583
- return result;
6584
- }
6585
- function collectModifierTokens(tokens, expectedSource, included) {
6586
- const result = {};
6587
- for (const [name, token] of Object.entries(tokens)) {
6588
- if (!included.has(name) && (getSourceModifier(token) ?? "").toLowerCase() === expectedSource) {
6589
- result[name] = token;
6691
+ if (imports.length > 0) {
6692
+ lines.push("");
6693
+ }
6694
+ if (tokenTypes.has("shadow")) {
6695
+ lines.push(...this.buildShadowTokenClass(vis, options));
6696
+ lines.push("");
6590
6697
  }
6698
+ renderBody(lines, vis);
6699
+ lines.push("");
6700
+ return lines.join("\n");
6591
6701
  }
6592
- return result;
6702
+ renderFlatGroups(lines, groups, baseDepth, options) {
6703
+ const vis = options.visibility ? `${options.visibility} ` : "";
6704
+ const groupIndent = indent(options.indent, baseDepth);
6705
+ const valIndent = indent(options.indent, baseDepth + 1);
6706
+ for (const group of groups) {
6707
+ lines.push(`${groupIndent}${vis}object ${group.name} {`);
6708
+ for (const token of group.tokens) {
6709
+ const kotlinName = this.buildFlatKotlinName(token);
6710
+ const kotlinValue = this.formatKotlinValue(token, options, baseDepth + 1);
6711
+ const annotation = this.typeAnnotationSuffix(token);
6712
+ if (token.$description) {
6713
+ lines.push(`${valIndent}/** ${escapeKDoc(token.$description)} */`);
6714
+ }
6715
+ lines.push(`${valIndent}${vis}val ${kotlinName}${annotation} = ${kotlinValue}`);
6716
+ }
6717
+ lines.push(`${groupIndent}}`);
6718
+ lines.push("");
6719
+ }
6720
+ }
6721
+ renderTreeChildren(lines, node, depth, options) {
6722
+ const vis = options.visibility ? `${options.visibility} ` : "";
6723
+ const pad = indent(options.indent, depth);
6724
+ const entries = Array.from(node.children.entries());
6725
+ for (let idx = 0; idx < entries.length; idx++) {
6726
+ const [key, child] = entries[idx];
6727
+ if (child.token && child.children.size === 0) {
6728
+ this.renderLeaf(lines, key, child.token, depth, options);
6729
+ } else if (child.children.size > 0 && !child.token) {
6730
+ const objectName = toPascalCase(key);
6731
+ lines.push(`${pad}${vis}object ${objectName} {`);
6732
+ this.renderTreeChildren(lines, child, depth + 1, options);
6733
+ lines.push(`${pad}}`);
6734
+ if (idx < entries.length - 1) {
6735
+ lines.push("");
6736
+ }
6737
+ } else {
6738
+ this.renderLeaf(lines, key, child.token, depth, options);
6739
+ this.renderTreeChildren(lines, child, depth, options);
6740
+ }
6741
+ }
6742
+ }
6743
+ renderLeaf(lines, key, token, depth, options) {
6744
+ const vis = options.visibility ? `${options.visibility} ` : "";
6745
+ const pad = indent(options.indent, depth);
6746
+ const kotlinName = toKotlinIdentifier(key);
6747
+ const kotlinValue = this.formatKotlinValue(token, options, depth);
6748
+ const annotation = this.typeAnnotationSuffix(token);
6749
+ if (token.$description) {
6750
+ lines.push(`${pad}/** ${escapeKDoc(token.$description)} */`);
6751
+ }
6752
+ lines.push(`${pad}${vis}val ${kotlinName}${annotation} = ${kotlinValue}`);
6753
+ }
6754
+ buildFileHeader() {
6755
+ return [
6756
+ "// Generated by Dispersa - do not edit manually",
6757
+ "// https://github.com/timges/dispersa"
6758
+ ].join("\n");
6759
+ }
6760
+ // -----------------------------------------------------------------------
6761
+ // Shadow data class
6762
+ // -----------------------------------------------------------------------
6763
+ buildShadowTokenClass(vis, options) {
6764
+ const i1 = indent(options.indent, 1);
6765
+ return [
6766
+ "@Immutable",
6767
+ `${vis}data class ShadowToken(`,
6768
+ `${i1}val color: Color,`,
6769
+ `${i1}val elevation: Dp,`,
6770
+ `${i1}val offsetX: Dp,`,
6771
+ `${i1}val offsetY: Dp,`,
6772
+ ")"
6773
+ ];
6774
+ }
6775
+ // -----------------------------------------------------------------------
6776
+ // Imports (tree-shaken)
6777
+ // -----------------------------------------------------------------------
6778
+ collectImports(tokenTypes, options) {
6779
+ const imports = /* @__PURE__ */ new Set();
6780
+ const ns = "androidx.compose";
6781
+ const hasColors = tokenTypes.has("color") || tokenTypes.has("shadow") || tokenTypes.has("border");
6782
+ if (hasColors) {
6783
+ imports.add(`${ns}.ui.graphics.Color`);
6784
+ }
6785
+ if (tokenTypes.has("dimension") || tokenTypes.has("shadow") || tokenTypes.has("border")) {
6786
+ imports.add(`${ns}.ui.unit.Dp`);
6787
+ imports.add(`${ns}.ui.unit.dp`);
6788
+ }
6789
+ if (tokenTypes.has("typography") || tokenTypes.has("fontFamily")) {
6790
+ imports.add(`${ns}.ui.text.TextStyle`);
6791
+ imports.add(`${ns}.ui.unit.sp`);
6792
+ }
6793
+ if (tokenTypes.has("typography") || tokenTypes.has("fontWeight")) {
6794
+ imports.add(`${ns}.ui.text.font.FontWeight`);
6795
+ }
6796
+ if (tokenTypes.has("fontFamily")) {
6797
+ imports.add(`${ns}.ui.text.font.FontFamily`);
6798
+ }
6799
+ if (tokenTypes.has("duration")) {
6800
+ imports.add("kotlin.time.Duration");
6801
+ imports.add("kotlin.time.Duration.Companion.milliseconds");
6802
+ imports.add("kotlin.time.Duration.Companion.seconds");
6803
+ }
6804
+ if (tokenTypes.has("cubicBezier")) {
6805
+ imports.add(`${ns}.animation.core.CubicBezierEasing`);
6806
+ }
6807
+ if (tokenTypes.has("shadow")) {
6808
+ imports.add(`${ns}.runtime.Immutable`);
6809
+ }
6810
+ if (tokenTypes.has("border")) {
6811
+ imports.add(`${ns}.foundation.BorderStroke`);
6812
+ }
6813
+ if (options.colorSpace === "displayP3" && hasColors) {
6814
+ imports.add(`${ns}.ui.graphics.colorspace.ColorSpaces`);
6815
+ }
6816
+ return Array.from(imports).sort();
6817
+ }
6818
+ collectTokenTypes(node, types) {
6819
+ if (node.token?.$type) {
6820
+ types.add(node.token.$type);
6821
+ }
6822
+ for (const child of node.children.values()) {
6823
+ this.collectTokenTypes(child, types);
6824
+ }
6825
+ }
6826
+ collectTokenTypesFromEntries(tokens) {
6827
+ const types = /* @__PURE__ */ new Set();
6828
+ for (const [, token] of Object.entries(tokens)) {
6829
+ if (token.$type) {
6830
+ types.add(token.$type);
6831
+ }
6832
+ }
6833
+ return types;
6834
+ }
6835
+ // -----------------------------------------------------------------------
6836
+ // Type annotations
6837
+ // -----------------------------------------------------------------------
6838
+ getTypeAnnotation(token) {
6839
+ switch (token.$type) {
6840
+ case "color":
6841
+ return "Color";
6842
+ case "dimension":
6843
+ return "Dp";
6844
+ case "fontFamily":
6845
+ return "FontFamily";
6846
+ case "fontWeight":
6847
+ return "FontWeight";
6848
+ case "duration":
6849
+ return "Duration";
6850
+ case "shadow":
6851
+ return "ShadowToken";
6852
+ case "cubicBezier":
6853
+ return "CubicBezierEasing";
6854
+ case "number":
6855
+ return "Double";
6856
+ case "typography":
6857
+ return "TextStyle";
6858
+ case "border":
6859
+ return "BorderStroke";
6860
+ default: {
6861
+ const value = token.$value;
6862
+ if (typeof value === "string") {
6863
+ return "String";
6864
+ }
6865
+ if (typeof value === "boolean") {
6866
+ return "Boolean";
6867
+ }
6868
+ if (typeof value === "number") {
6869
+ return "Double";
6870
+ }
6871
+ return void 0;
6872
+ }
6873
+ }
6874
+ }
6875
+ typeAnnotationSuffix(token) {
6876
+ const type = this.getTypeAnnotation(token);
6877
+ return type ? `: ${type}` : "";
6878
+ }
6879
+ // -----------------------------------------------------------------------
6880
+ // Value formatting
6881
+ // -----------------------------------------------------------------------
6882
+ formatKotlinValue(token, options, depth) {
6883
+ const value = token.$value;
6884
+ if (token.$type === "color") {
6885
+ return this.formatColorValue(value, options);
6886
+ }
6887
+ if (token.$type === "dimension") {
6888
+ return this.formatDimensionValue(value);
6889
+ }
6890
+ if (token.$type === "fontFamily") {
6891
+ return this.formatFontFamilyValue(value);
6892
+ }
6893
+ if (token.$type === "fontWeight") {
6894
+ return this.formatFontWeightValue(value);
6895
+ }
6896
+ if (token.$type === "duration") {
6897
+ return this.formatDurationValue(value);
6898
+ }
6899
+ if (token.$type === "shadow") {
6900
+ return this.formatShadowValue(value, options, depth);
6901
+ }
6902
+ if (token.$type === "typography") {
6903
+ return this.formatTypographyValue(value, options, depth);
6904
+ }
6905
+ if (token.$type === "border") {
6906
+ return this.formatBorderValue(value, options);
6907
+ }
6908
+ if (token.$type === "number") {
6909
+ return typeof value === "number" ? formatKotlinNumber(value) : String(value);
6910
+ }
6911
+ if (token.$type === "cubicBezier" && Array.isArray(value) && value.length === 4) {
6912
+ return `CubicBezierEasing(${value[0]}f, ${value[1]}f, ${value[2]}f, ${value[3]}f)`;
6913
+ }
6914
+ if (typeof value === "string") {
6915
+ return `"${escapeKotlinString(value)}"`;
6916
+ }
6917
+ if (typeof value === "number") {
6918
+ return formatKotlinNumber(value);
6919
+ }
6920
+ if (typeof value === "boolean") {
6921
+ return value ? "true" : "false";
6922
+ }
6923
+ return `"${escapeKotlinString(String(value))}"`;
6924
+ }
6925
+ formatColorValue(value, options) {
6926
+ if (!isColorObject(value)) {
6927
+ if (typeof value === "string") {
6928
+ const hex = value.replace("#", "");
6929
+ if (/^[0-9a-fA-F]{6,8}$/.test(hex)) {
6930
+ const argb = hex.length === 8 ? hex : `FF${hex}`;
6931
+ return `Color(0x${argb.toUpperCase()})`;
6932
+ }
6933
+ }
6934
+ return "Color.Unspecified";
6935
+ }
6936
+ const colorObj = value;
6937
+ const alpha = colorObj.alpha ?? 1;
6938
+ if (options.colorFormat === "argb_float" || options.colorSpace === "displayP3") {
6939
+ return this.formatFloatColor(colorObj, alpha, options);
6940
+ }
6941
+ return this.formatHexColor(colorObj, alpha);
6942
+ }
6943
+ formatFloatColor(colorObj, alpha, options) {
6944
+ if (options.colorSpace === "displayP3") {
6945
+ const p3 = toP3(dtcgObjectToCulori(colorObj));
6946
+ const r2 = roundComponent(p3?.r ?? 0);
6947
+ const g2 = roundComponent(p3?.g ?? 0);
6948
+ const b2 = roundComponent(p3?.b ?? 0);
6949
+ return `Color(${r2}f, ${g2}f, ${b2}f, ${roundComponent(alpha)}f, ColorSpaces.DisplayP3)`;
6950
+ }
6951
+ const rgb = toSRGB(dtcgObjectToCulori(colorObj));
6952
+ const r = roundComponent(rgb?.r ?? 0);
6953
+ const g = roundComponent(rgb?.g ?? 0);
6954
+ const b = roundComponent(rgb?.b ?? 0);
6955
+ return `Color(${r}f, ${g}f, ${b}f, ${roundComponent(alpha)}f)`;
6956
+ }
6957
+ formatHexColor(colorObj, alpha) {
6958
+ const hex = colorObjectToHex(colorObj);
6959
+ const hexClean = hex.replace("#", "");
6960
+ if (hexClean.length === 8) {
6961
+ const rrggbb = hexClean.slice(0, 6);
6962
+ const aa = hexClean.slice(6, 8);
6963
+ return `Color(0x${aa.toUpperCase()}${rrggbb.toUpperCase()})`;
6964
+ }
6965
+ const alphaHex = alpha < 1 ? Math.round(alpha * 255).toString(16).padStart(2, "0").toUpperCase() : "FF";
6966
+ return `Color(0x${alphaHex}${hexClean.toUpperCase()})`;
6967
+ }
6968
+ formatDimensionValue(value) {
6969
+ if (isDimensionObject(value)) {
6970
+ const dim = value;
6971
+ const dpValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
6972
+ return `${dpValue}.dp`;
6973
+ }
6974
+ return typeof value === "number" ? `${value}.dp` : `0.dp`;
6975
+ }
6976
+ formatFontFamilyValue(value) {
6977
+ if (Array.isArray(value)) {
6978
+ const primary = value[0];
6979
+ if (typeof primary === "string") {
6980
+ return this.mapKotlinFontFamily(primary);
6981
+ }
6982
+ return "FontFamily.Default";
6983
+ }
6984
+ return typeof value === "string" ? this.mapKotlinFontFamily(value) : "FontFamily.Default";
6985
+ }
6986
+ mapKotlinFontFamily(family) {
6987
+ const normalized = family.toLowerCase().replace(/['"]/g, "").trim();
6988
+ const builtIn = {
6989
+ "sans-serif": "FontFamily.SansSerif",
6990
+ serif: "FontFamily.Serif",
6991
+ monospace: "FontFamily.Monospace",
6992
+ cursive: "FontFamily.Cursive"
6993
+ };
6994
+ return builtIn[normalized] ?? `FontFamily.Default // TODO: load "${family}" via Font(R.font.${toResourceName(family)})`;
6995
+ }
6996
+ formatFontWeightValue(value) {
6997
+ if (typeof value === "number") {
6998
+ return this.numericFontWeight(value);
6999
+ }
7000
+ if (typeof value === "string") {
7001
+ return this.namedFontWeight(value) ?? "FontWeight.Normal";
7002
+ }
7003
+ return "FontWeight.Normal";
7004
+ }
7005
+ numericFontWeight(weight) {
7006
+ if (weight <= 100) {
7007
+ return "FontWeight.Thin";
7008
+ }
7009
+ if (weight <= 200) {
7010
+ return "FontWeight.ExtraLight";
7011
+ }
7012
+ if (weight <= 300) {
7013
+ return "FontWeight.Light";
7014
+ }
7015
+ if (weight <= 400) {
7016
+ return "FontWeight.Normal";
7017
+ }
7018
+ if (weight <= 500) {
7019
+ return "FontWeight.Medium";
7020
+ }
7021
+ if (weight <= 600) {
7022
+ return "FontWeight.SemiBold";
7023
+ }
7024
+ if (weight <= 700) {
7025
+ return "FontWeight.Bold";
7026
+ }
7027
+ if (weight <= 800) {
7028
+ return "FontWeight.ExtraBold";
7029
+ }
7030
+ return "FontWeight.Black";
7031
+ }
7032
+ namedFontWeight(name) {
7033
+ const map = {
7034
+ thin: "FontWeight.Thin",
7035
+ extralight: "FontWeight.ExtraLight",
7036
+ ultralight: "FontWeight.ExtraLight",
7037
+ light: "FontWeight.Light",
7038
+ regular: "FontWeight.Normal",
7039
+ normal: "FontWeight.Normal",
7040
+ medium: "FontWeight.Medium",
7041
+ semibold: "FontWeight.SemiBold",
7042
+ demibold: "FontWeight.SemiBold",
7043
+ bold: "FontWeight.Bold",
7044
+ extrabold: "FontWeight.ExtraBold",
7045
+ heavy: "FontWeight.ExtraBold",
7046
+ black: "FontWeight.Black",
7047
+ ultrabold: "FontWeight.Black"
7048
+ };
7049
+ return map[name.toLowerCase()];
7050
+ }
7051
+ formatDurationValue(value) {
7052
+ if (typeof value === "object" && value !== null && "value" in value && "unit" in value) {
7053
+ const dur = value;
7054
+ return dur.unit === "ms" ? `${dur.value}.milliseconds` : `${dur.value}.seconds`;
7055
+ }
7056
+ return typeof value === "number" ? `${value}.milliseconds` : "0.milliseconds";
7057
+ }
7058
+ formatShadowValue(value, options, depth) {
7059
+ if (Array.isArray(value) && value.length > 0) {
7060
+ return this.formatSingleShadow(value[0], options, depth);
7061
+ }
7062
+ if (typeof value === "object" && value !== null) {
7063
+ return this.formatSingleShadow(value, options, depth);
7064
+ }
7065
+ return "ShadowToken(color = Color.Unspecified, elevation = 0.dp, offsetX = 0.dp, offsetY = 0.dp)";
7066
+ }
7067
+ formatSingleShadow(shadow, options, depth) {
7068
+ const color = isColorObject(shadow.color) ? this.formatColorValue(shadow.color, options) : "Color.Black";
7069
+ const elevation = isDimensionObject(shadow.blur) ? this.formatDimensionValue(shadow.blur) : "0.dp";
7070
+ const offsetX = isDimensionObject(shadow.offsetX) ? this.formatDimensionValue(shadow.offsetX) : "0.dp";
7071
+ const offsetY = isDimensionObject(shadow.offsetY) ? this.formatDimensionValue(shadow.offsetY) : "0.dp";
7072
+ const propIndent = indent(options.indent, depth + 1);
7073
+ const closeIndent = indent(options.indent, depth);
7074
+ return [
7075
+ "ShadowToken(",
7076
+ `${propIndent}color = ${color},`,
7077
+ `${propIndent}elevation = ${elevation},`,
7078
+ `${propIndent}offsetX = ${offsetX},`,
7079
+ `${propIndent}offsetY = ${offsetY},`,
7080
+ `${closeIndent})`
7081
+ ].join("\n");
7082
+ }
7083
+ formatBorderValue(value, options) {
7084
+ if (typeof value !== "object" || value === null) {
7085
+ return "BorderStroke(0.dp, Color.Unspecified)";
7086
+ }
7087
+ const border = value;
7088
+ const width = isDimensionObject(border.width) ? this.formatDimensionValue(border.width) : "0.dp";
7089
+ const color = isColorObject(border.color) ? this.formatColorValue(border.color, options) : "Color.Unspecified";
7090
+ return `BorderStroke(${width}, ${color})`;
7091
+ }
7092
+ formatTypographyValue(value, options, depth) {
7093
+ if (typeof value !== "object" || value === null) {
7094
+ return "TextStyle()";
7095
+ }
7096
+ const typo = value;
7097
+ const parts = [];
7098
+ if (isDimensionObject(typo.fontSize)) {
7099
+ const dim = typo.fontSize;
7100
+ const spValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
7101
+ parts.push(`fontSize = ${spValue}.sp`);
7102
+ }
7103
+ if (typo.fontWeight != null) {
7104
+ parts.push(`fontWeight = ${this.formatFontWeightValue(typo.fontWeight)}`);
7105
+ }
7106
+ if (typo.lineHeight != null && typeof typo.lineHeight === "number") {
7107
+ if (isDimensionObject(typo.fontSize)) {
7108
+ const dim = typo.fontSize;
7109
+ const spValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
7110
+ const lineHeightSp = Math.round(spValue * typo.lineHeight * 100) / 100;
7111
+ parts.push(`lineHeight = ${lineHeightSp}.sp`);
7112
+ }
7113
+ }
7114
+ if (isDimensionObject(typo.letterSpacing)) {
7115
+ const dim = typo.letterSpacing;
7116
+ const spValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
7117
+ parts.push(`letterSpacing = ${spValue}.sp`);
7118
+ }
7119
+ if (parts.length === 0) {
7120
+ return "TextStyle()";
7121
+ }
7122
+ const propIndent = indent(options.indent, depth + 1);
7123
+ const closeIndent = indent(options.indent, depth);
7124
+ return `TextStyle(
7125
+ ${parts.map((p) => `${propIndent}${p}`).join(",\n")},
7126
+ ${closeIndent})`;
7127
+ }
7128
+ // -----------------------------------------------------------------------
7129
+ // Output: standalone
7130
+ // -----------------------------------------------------------------------
7131
+ async formatStandalone(context, options) {
7132
+ const requiresFile = context.buildPath !== void 0 && context.buildPath !== "";
7133
+ if (!context.output.file && requiresFile) {
7134
+ throw new exports.ConfigurationError(
7135
+ `Output "${context.output.name}": file is required for standalone Android output`
7136
+ );
7137
+ }
7138
+ const files = {};
7139
+ for (const { tokens, modifierInputs } of context.permutations) {
7140
+ const processedTokens = stripInternalMetadata(tokens);
7141
+ const content = this.formatTokens(processedTokens, options);
7142
+ const fileName = context.output.file ? resolveFileName(context.output.file, modifierInputs) : buildInMemoryOutputKey({
7143
+ outputName: context.output.name,
7144
+ extension: "kt",
7145
+ modifierInputs,
7146
+ resolver: context.resolver,
7147
+ defaults: context.meta.defaults
7148
+ });
7149
+ files[fileName] = content;
7150
+ }
7151
+ return outputTree(files);
7152
+ }
7153
+ // -----------------------------------------------------------------------
7154
+ // Output: bundle
7155
+ // -----------------------------------------------------------------------
7156
+ async formatBundle(context, options) {
7157
+ const requiresFile = context.buildPath !== void 0 && context.buildPath !== "";
7158
+ if (!context.output.file && requiresFile) {
7159
+ throw new exports.ConfigurationError(
7160
+ `Output "${context.output.name}": file is required for bundle Android output`
7161
+ );
7162
+ }
7163
+ const content = this.formatBundleContent(context, options);
7164
+ const fileName = context.output.file ? resolveFileName(context.output.file, context.meta.basePermutation) : buildInMemoryOutputKey({
7165
+ outputName: context.output.name,
7166
+ extension: "kt",
7167
+ modifierInputs: context.meta.basePermutation,
7168
+ resolver: context.resolver,
7169
+ defaults: context.meta.defaults
7170
+ });
7171
+ return outputTree({ [fileName]: content });
7172
+ }
7173
+ formatBundleContent(context, options) {
7174
+ const allTokenTypes = this.collectAllPermutationTypes(context);
7175
+ return this.buildFile(allTokenTypes, options, (lines, vis) => {
7176
+ const i1 = indent(options.indent, 1);
7177
+ lines.push(`@Suppress("unused")`);
7178
+ lines.push(`${vis}object ${options.objectName} {`);
7179
+ for (let idx = 0; idx < context.permutations.length; idx++) {
7180
+ const { tokens, modifierInputs } = context.permutations[idx];
7181
+ const processedTokens = stripInternalMetadata(tokens);
7182
+ const permName = this.buildPermutationName(modifierInputs);
7183
+ lines.push(`${i1}${vis}object ${permName} {`);
7184
+ this.renderBundleTokens(lines, processedTokens, options, 2);
7185
+ lines.push(`${i1}}`);
7186
+ if (idx < context.permutations.length - 1) {
7187
+ lines.push("");
7188
+ }
7189
+ }
7190
+ lines.push("}");
7191
+ });
7192
+ }
7193
+ collectAllPermutationTypes(context) {
7194
+ const allTokenTypes = /* @__PURE__ */ new Set();
7195
+ for (const { tokens } of context.permutations) {
7196
+ const processed = stripInternalMetadata(tokens);
7197
+ for (const [, token] of Object.entries(processed)) {
7198
+ if (token.$type) {
7199
+ allTokenTypes.add(token.$type);
7200
+ }
7201
+ }
7202
+ }
7203
+ return allTokenTypes;
7204
+ }
7205
+ renderBundleTokens(lines, tokens, options, baseDepth) {
7206
+ if (options.structure === "flat") {
7207
+ const groups = this.groupTokensByType(tokens);
7208
+ this.renderFlatGroups(lines, groups, baseDepth, options);
7209
+ return;
7210
+ }
7211
+ const tree = this.buildTokenTree(tokens);
7212
+ this.renderTreeChildren(lines, tree, baseDepth, options);
7213
+ }
7214
+ buildPermutationName(modifierInputs) {
7215
+ const values = Object.values(modifierInputs);
7216
+ if (values.length === 0) {
7217
+ return "Default";
7218
+ }
7219
+ return values.map((v) => toPascalCase(v)).join("");
7220
+ }
7221
+ };
7222
+ function androidRenderer() {
7223
+ const rendererInstance = new AndroidRenderer();
7224
+ return {
7225
+ format: (context, options) => rendererInstance.format(
7226
+ context,
7227
+ options ?? context.output.options
7228
+ )
7229
+ };
7230
+ }
7231
+
7232
+ // src/renderers/css.ts
7233
+ init_errors();
7234
+ init_token_utils();
7235
+
7236
+ // src/renderers/bundlers/css.ts
7237
+ init_errors();
7238
+ init_utils();
7239
+ var getSourceSet = (token) => {
7240
+ if (typeof token !== "object" || token === null) {
7241
+ return void 0;
7242
+ }
7243
+ const maybe = token;
7244
+ return typeof maybe._sourceSet === "string" ? maybe._sourceSet : void 0;
7245
+ };
7246
+ var getSourceModifier = (token) => {
7247
+ if (typeof token !== "object" || token === null) {
7248
+ return void 0;
7249
+ }
7250
+ const maybe = token;
7251
+ return typeof maybe._sourceModifier === "string" ? maybe._sourceModifier : void 0;
7252
+ };
7253
+ async function bundleAsCss(bundleData, resolver, options, formatTokens) {
7254
+ const baseItem = bundleData.find((item) => item.isBase);
7255
+ if (!baseItem) {
7256
+ throw new exports.BasePermutationError("Base permutation not found in bundle data");
7257
+ }
7258
+ if (!formatTokens) {
7259
+ throw new exports.ConfigurationError("CSS formatter was not provided");
7260
+ }
7261
+ const orderedBundleData = orderBundleData(bundleData, resolver, baseItem);
7262
+ const cssBlocks = [];
7263
+ for (const item of orderedBundleData) {
7264
+ if (item.isBase) {
7265
+ const blocks = await formatBasePermutation(item, resolver, options, formatTokens);
7266
+ cssBlocks.push(...blocks);
7267
+ continue;
7268
+ }
7269
+ const block = await formatModifierPermutation(item, baseItem, options, formatTokens);
7270
+ if (block) {
7271
+ cssBlocks.push(block);
7272
+ }
7273
+ }
7274
+ return cssBlocks.join("\n\n");
7275
+ }
7276
+ async function formatBasePermutation({ tokens, modifierInputs }, resolver, options, formatTokens) {
7277
+ const firstModifierName = resolver.modifiers ? Object.keys(resolver.modifiers)[0] : "";
7278
+ const modifier = firstModifierName ?? "";
7279
+ const context = modifierInputs[modifier] ?? "";
7280
+ const selector = resolveSelector(options?.selector, modifier, context, true, modifierInputs);
7281
+ const mediaQuery = resolveMediaQuery(options?.mediaQuery, modifier, context, true, modifierInputs);
7282
+ const referenceTokens = stripInternalMetadata(tokens);
7283
+ const defaultBlocks = buildDefaultLayerBlocks(tokens, modifierInputs, resolver);
7284
+ const cssBlocks = [];
7285
+ for (const block of defaultBlocks) {
7286
+ const cleanTokens = stripInternalMetadata(block.tokens);
7287
+ const css2 = await formatTokens(cleanTokens, {
7288
+ selector,
7289
+ mediaQuery,
7290
+ minify: options?.minify,
7291
+ referenceTokens
7292
+ });
7293
+ const header = block.description ? `/* ${block.key} */
7294
+ /* ${block.description} */` : `/* ${block.key} */`;
7295
+ cssBlocks.push(`${header}
7296
+ ${css2}`);
7297
+ }
7298
+ return cssBlocks;
7299
+ }
7300
+ async function formatModifierPermutation({ tokens, modifierInputs }, baseItem, options, formatTokens) {
7301
+ const differenceCount = countModifierDifferences(modifierInputs, baseItem.modifierInputs);
7302
+ if (differenceCount > 1) {
7303
+ return void 0;
7304
+ }
7305
+ const expectedSource = getExpectedSource(modifierInputs, baseItem.modifierInputs);
7306
+ let tokensToInclude = filterTokensBySource(tokens, expectedSource);
7307
+ const hasSourceMetadata = Object.values(tokens).some(
7308
+ (token) => token != null && getSourceModifier(token) !== void 0
7309
+ );
7310
+ if (Object.keys(tokensToInclude).length === 0 && !hasSourceMetadata) {
7311
+ tokensToInclude = tokens;
7312
+ }
7313
+ if (Object.keys(tokensToInclude).length === 0) {
7314
+ return void 0;
7315
+ }
7316
+ const [modifier, context] = parseModifierSource(expectedSource);
7317
+ const cleanTokens = stripInternalMetadata(tokensToInclude);
7318
+ const referenceTokens = stripInternalMetadata(tokens);
7319
+ const selector = resolveSelector(options?.selector, modifier, context, false, modifierInputs);
7320
+ const mediaQuery = resolveMediaQuery(
7321
+ options?.mediaQuery,
7322
+ modifier,
7323
+ context,
7324
+ false,
7325
+ modifierInputs
7326
+ );
7327
+ const css2 = await formatTokens(cleanTokens, {
7328
+ selector,
7329
+ mediaQuery,
7330
+ minify: options?.minify,
7331
+ referenceTokens
7332
+ });
7333
+ return `/* Modifier: ${modifier}=${context} */
7334
+ ${css2}`;
7335
+ }
7336
+ function collectSetTokens(tokens, setName, included) {
7337
+ const result = {};
7338
+ for (const [name, token] of Object.entries(tokens)) {
7339
+ if (!included.has(name) && getSourceSet(token) === setName) {
7340
+ result[name] = token;
7341
+ }
7342
+ }
7343
+ return result;
7344
+ }
7345
+ function collectModifierTokens(tokens, expectedSource, included) {
7346
+ const result = {};
7347
+ for (const [name, token] of Object.entries(tokens)) {
7348
+ if (!included.has(name) && (getSourceModifier(token) ?? "").toLowerCase() === expectedSource) {
7349
+ result[name] = token;
7350
+ }
7351
+ }
7352
+ return result;
6593
7353
  }
6594
7354
  function collectRemainder(tokens, included) {
6595
7355
  const result = {};
@@ -6795,14 +7555,14 @@ var CssRenderer = class _CssRenderer {
6795
7555
  return opts.minify ? cssString : await this.formatWithPrettier(cssString);
6796
7556
  }
6797
7557
  buildCssBlock(lines, groupTokens, selector, tokens, referenceTokens, opts) {
6798
- const indent = opts.minify ? "" : " ";
7558
+ const indent2 = opts.minify ? "" : " ";
6799
7559
  const newline = opts.minify ? "" : "\n";
6800
7560
  const space = opts.minify ? "" : " ";
6801
7561
  const hasMediaQuery = opts.mediaQuery != null && opts.mediaQuery !== "";
6802
- const tokenIndent = hasMediaQuery ? indent + indent : indent;
7562
+ const tokenIndent = hasMediaQuery ? indent2 + indent2 : indent2;
6803
7563
  if (hasMediaQuery) {
6804
7564
  lines.push(`@media ${opts.mediaQuery}${space}{${newline}`);
6805
- lines.push(`${indent}${selector}${space}{${newline}`);
7565
+ lines.push(`${indent2}${selector}${space}{${newline}`);
6806
7566
  } else {
6807
7567
  lines.push(`${selector}${space}{${newline}`);
6808
7568
  }
@@ -6819,21 +7579,21 @@ var CssRenderer = class _CssRenderer {
6819
7579
  );
6820
7580
  }
6821
7581
  if (hasMediaQuery) {
6822
- lines.push(`${indent}}${newline}`);
7582
+ lines.push(`${indent2}}${newline}`);
6823
7583
  }
6824
7584
  lines.push(`}${newline}${newline}`);
6825
7585
  }
6826
- pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences, indent, newline, space) {
7586
+ pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences, indent2, newline, space) {
6827
7587
  const entries = this.buildCssEntries(token, tokens, referenceTokens, preserveReferences);
6828
7588
  if (token.$deprecated != null && token.$deprecated !== false) {
6829
7589
  const deprecationMsg = formatDeprecationMessage(token, "", "comment");
6830
- lines.push(`${indent}/* ${this.sanitizeCssCommentText(deprecationMsg)} */${newline}`);
7590
+ lines.push(`${indent2}/* ${this.sanitizeCssCommentText(deprecationMsg)} */${newline}`);
6831
7591
  }
6832
7592
  if (token.$description && token.$description !== "") {
6833
- lines.push(`${indent}/* ${this.sanitizeCssCommentText(token.$description)} */${newline}`);
7593
+ lines.push(`${indent2}/* ${this.sanitizeCssCommentText(token.$description)} */${newline}`);
6834
7594
  }
6835
7595
  for (const entry of entries) {
6836
- lines.push(`${indent}--${entry.name}:${space}${entry.value};${newline}`);
7596
+ lines.push(`${indent2}--${entry.name}:${space}${entry.value};${newline}`);
6837
7597
  }
6838
7598
  }
6839
7599
  async formatWithPrettier(css2) {
@@ -7408,18 +8168,641 @@ var CssRenderer = class _CssRenderer {
7408
8168
  return { modifierName: name, modifierContext: value };
7409
8169
  }
7410
8170
  }
7411
- return { modifierName: "", modifierContext: "" };
7412
- }
7413
- isBasePermutation(modifierInputs, defaults) {
7414
- const normalizedInputs = normalizeModifierInputs(modifierInputs);
7415
- const normalizedDefaults = normalizeModifierInputs(defaults);
7416
- return Object.entries(normalizedDefaults).every(
7417
- ([key, value]) => normalizedInputs[key] === value
7418
- );
8171
+ return { modifierName: "", modifierContext: "" };
8172
+ }
8173
+ isBasePermutation(modifierInputs, defaults) {
8174
+ const normalizedInputs = normalizeModifierInputs(modifierInputs);
8175
+ const normalizedDefaults = normalizeModifierInputs(defaults);
8176
+ return Object.entries(normalizedDefaults).every(
8177
+ ([key, value]) => normalizedInputs[key] === value
8178
+ );
8179
+ }
8180
+ };
8181
+ function cssRenderer() {
8182
+ const rendererInstance = new CssRenderer();
8183
+ return {
8184
+ format: (context, options) => rendererInstance.format(
8185
+ context,
8186
+ options ?? context.output.options
8187
+ )
8188
+ };
8189
+ }
8190
+
8191
+ // src/renderers/ios.ts
8192
+ init_errors();
8193
+ init_token_utils();
8194
+ init_utils();
8195
+ var toSRGB2 = culori.converter("rgb");
8196
+ var toP32 = culori.converter("p3");
8197
+ var SWIFT_TYPE_GROUP_MAP = {
8198
+ color: "Colors",
8199
+ dimension: "Spacing",
8200
+ fontFamily: "Fonts",
8201
+ fontWeight: "FontWeights",
8202
+ duration: "Durations",
8203
+ shadow: "Shadows",
8204
+ typography: "Typography",
8205
+ number: "Numbers",
8206
+ cubicBezier: "Animations",
8207
+ border: "Borders",
8208
+ gradient: "Gradients"
8209
+ };
8210
+ var SWIFT_KEYWORDS = /* @__PURE__ */ new Set([
8211
+ "associatedtype",
8212
+ "class",
8213
+ "deinit",
8214
+ "enum",
8215
+ "extension",
8216
+ "fileprivate",
8217
+ "func",
8218
+ "import",
8219
+ "init",
8220
+ "inout",
8221
+ "internal",
8222
+ "let",
8223
+ "open",
8224
+ "operator",
8225
+ "private",
8226
+ "protocol",
8227
+ "public",
8228
+ "rethrows",
8229
+ "static",
8230
+ "struct",
8231
+ "subscript",
8232
+ "typealias",
8233
+ "var",
8234
+ "break",
8235
+ "case",
8236
+ "continue",
8237
+ "default",
8238
+ "defer",
8239
+ "do",
8240
+ "else",
8241
+ "fallthrough",
8242
+ "for",
8243
+ "guard",
8244
+ "if",
8245
+ "in",
8246
+ "repeat",
8247
+ "return",
8248
+ "switch",
8249
+ "where",
8250
+ "while",
8251
+ "as",
8252
+ "catch",
8253
+ "false",
8254
+ "is",
8255
+ "nil",
8256
+ "super",
8257
+ "self",
8258
+ "Self",
8259
+ "throw",
8260
+ "throws",
8261
+ "true",
8262
+ "try",
8263
+ "Type",
8264
+ "Protocol"
8265
+ ]);
8266
+ var IosRenderer = class {
8267
+ async format(context, options) {
8268
+ const opts = {
8269
+ preset: options?.preset ?? "standalone",
8270
+ accessLevel: options?.accessLevel ?? "public",
8271
+ structure: options?.structure ?? "enum",
8272
+ enumName: options?.enumName ?? "DesignTokens",
8273
+ extensionNamespace: options?.extensionNamespace ?? "DesignTokens",
8274
+ colorSpace: options?.colorSpace ?? "sRGB",
8275
+ swiftVersion: options?.swiftVersion ?? "5.9",
8276
+ indent: options?.indent ?? 4,
8277
+ frozen: options?.frozen ?? false
8278
+ };
8279
+ return await this.formatStandalone(context, opts);
8280
+ }
8281
+ formatTokens(tokens, options) {
8282
+ if (options.structure === "grouped") {
8283
+ return this.formatAsGrouped(tokens, options);
8284
+ }
8285
+ return this.formatAsEnum(tokens, options);
8286
+ }
8287
+ formatAsEnum(tokens, options) {
8288
+ const access3 = options.accessLevel;
8289
+ const groups = this.groupTokensByType(tokens);
8290
+ const imports = this.collectImports(tokens);
8291
+ const i1 = this.indentStr(options.indent, 1);
8292
+ const i2 = this.indentStr(options.indent, 2);
8293
+ const staticPrefix = this.staticLetPrefix(options);
8294
+ const frozen = this.frozenPrefix(options);
8295
+ const lines = [];
8296
+ lines.push(this.buildFileHeader());
8297
+ lines.push("");
8298
+ for (const imp of imports) {
8299
+ lines.push(`import ${imp}`);
8300
+ }
8301
+ lines.push(...this.buildStructDefinitions(tokens, access3, options));
8302
+ lines.push("");
8303
+ lines.push(`${frozen}${access3} enum ${options.enumName} {`);
8304
+ for (const group of groups) {
8305
+ lines.push(`${i1}${frozen}${access3} enum ${group.name} {`);
8306
+ for (const token of group.tokens) {
8307
+ const swiftName = this.buildQualifiedSwiftName(token);
8308
+ const swiftValue = this.formatSwiftValue(token, options);
8309
+ const typeAnnotation = this.getTypeAnnotation(token);
8310
+ const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
8311
+ const docComment = this.buildDocComment(token, i2);
8312
+ if (docComment) {
8313
+ lines.push(docComment);
8314
+ }
8315
+ lines.push(`${i2}${access3} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
8316
+ }
8317
+ lines.push(`${i1}}`);
8318
+ lines.push("");
8319
+ }
8320
+ lines.push("}");
8321
+ lines.push(...this.buildViewExtensions(tokens, access3, options));
8322
+ lines.push("");
8323
+ return lines.join("\n");
8324
+ }
8325
+ formatAsGrouped(tokens, options) {
8326
+ const access3 = options.accessLevel;
8327
+ const namespace = options.extensionNamespace;
8328
+ const groups = this.groupTokensByType(tokens);
8329
+ const imports = this.collectImports(tokens);
8330
+ const i1 = this.indentStr(options.indent, 1);
8331
+ const i2 = this.indentStr(options.indent, 2);
8332
+ const staticPrefix = this.staticLetPrefix(options);
8333
+ const frozen = this.frozenPrefix(options);
8334
+ const lines = [];
8335
+ lines.push(this.buildFileHeader());
8336
+ lines.push("");
8337
+ for (const imp of imports) {
8338
+ lines.push(`import ${imp}`);
8339
+ }
8340
+ lines.push(...this.buildStructDefinitions(tokens, access3, options));
8341
+ lines.push("");
8342
+ lines.push(`${frozen}${access3} enum ${namespace} {}`);
8343
+ lines.push("");
8344
+ for (const group of groups) {
8345
+ lines.push(`${access3} extension ${namespace} {`);
8346
+ lines.push(`${i1}${frozen}enum ${group.name} {`);
8347
+ for (const token of group.tokens) {
8348
+ const swiftName = this.buildQualifiedSwiftName(token);
8349
+ const swiftValue = this.formatSwiftValue(token, options);
8350
+ const typeAnnotation = this.getTypeAnnotation(token);
8351
+ const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
8352
+ const docComment = this.buildDocComment(token, i2);
8353
+ if (docComment) {
8354
+ lines.push(docComment);
8355
+ }
8356
+ lines.push(`${i2}${access3} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
8357
+ }
8358
+ lines.push(`${i1}}`);
8359
+ lines.push("}");
8360
+ lines.push("");
8361
+ }
8362
+ lines.push(...this.buildViewExtensions(tokens, access3, options));
8363
+ return lines.join("\n");
8364
+ }
8365
+ buildFileHeader() {
8366
+ return [
8367
+ "// Generated by Dispersa - do not edit manually",
8368
+ "// https://github.com/timges/dispersa"
8369
+ ].join("\n");
8370
+ }
8371
+ collectImports(tokens) {
8372
+ const imports = /* @__PURE__ */ new Set();
8373
+ imports.add("SwiftUI");
8374
+ for (const [, token] of Object.entries(tokens)) {
8375
+ if (token.$type === "duration") {
8376
+ imports.add("Foundation");
8377
+ }
8378
+ }
8379
+ return Array.from(imports).sort();
8380
+ }
8381
+ /**
8382
+ * Builds a `///` doc comment from a token's `$description`, if present.
8383
+ */
8384
+ buildDocComment(token, indent2) {
8385
+ if (!token.$description) {
8386
+ return void 0;
8387
+ }
8388
+ return `${indent2}/// ${token.$description}`;
8389
+ }
8390
+ groupTokensByType(tokens) {
8391
+ const groupMap = /* @__PURE__ */ new Map();
8392
+ for (const [, token] of getSortedTokenEntries(tokens)) {
8393
+ const groupName = SWIFT_TYPE_GROUP_MAP[token.$type ?? ""] ?? "Other";
8394
+ const existing = groupMap.get(groupName) ?? [];
8395
+ existing.push(token);
8396
+ groupMap.set(groupName, existing);
8397
+ }
8398
+ return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
8399
+ name,
8400
+ tokens: groupTokens
8401
+ }));
8402
+ }
8403
+ /**
8404
+ * Builds a qualified Swift name from a token's path, preserving parent
8405
+ * hierarchy segments to avoid duplicate identifiers.
8406
+ *
8407
+ * For example, `color.blue.400` in the `Colors` group becomes `blue400`
8408
+ * instead of just `_400`.
8409
+ */
8410
+ buildQualifiedSwiftName(token) {
8411
+ const path7 = token.path;
8412
+ const withoutTypePrefix = path7.length > 1 ? path7.slice(1) : path7;
8413
+ const joined = withoutTypePrefix.join("_");
8414
+ return this.toSwiftIdentifier(joined);
8415
+ }
8416
+ formatSwiftValue(token, options) {
8417
+ const value = token.$value;
8418
+ if (token.$type === "color") {
8419
+ return this.formatColorValue(value, options);
8420
+ }
8421
+ if (token.$type === "dimension") {
8422
+ return this.formatDimensionValue(value);
8423
+ }
8424
+ if (token.$type === "fontFamily") {
8425
+ return this.formatFontFamilyValue(value);
8426
+ }
8427
+ if (token.$type === "fontWeight") {
8428
+ return this.formatFontWeightValue(value);
8429
+ }
8430
+ if (token.$type === "duration") {
8431
+ return this.formatDurationValue(value);
8432
+ }
8433
+ if (token.$type === "shadow") {
8434
+ return this.formatShadowValue(value, options);
8435
+ }
8436
+ if (token.$type === "typography") {
8437
+ return this.formatTypographyValue(value);
8438
+ }
8439
+ if (token.$type === "border") {
8440
+ return this.formatBorderValue(value, options);
8441
+ }
8442
+ if (token.$type === "gradient") {
8443
+ return this.formatGradientValue(value, options);
8444
+ }
8445
+ if (token.$type === "number") {
8446
+ return String(value);
8447
+ }
8448
+ if (token.$type === "cubicBezier" && Array.isArray(value) && value.length === 4) {
8449
+ return `UnitCurve.bezier(startControlPoint: UnitPoint(x: ${value[0]}, y: ${value[1]}), endControlPoint: UnitPoint(x: ${value[2]}, y: ${value[3]}))`;
8450
+ }
8451
+ if (typeof value === "string") {
8452
+ return `"${this.escapeSwiftString(value)}"`;
8453
+ }
8454
+ if (typeof value === "number") {
8455
+ return String(value);
8456
+ }
8457
+ if (typeof value === "boolean") {
8458
+ return value ? "true" : "false";
8459
+ }
8460
+ return `"${this.escapeSwiftString(String(value))}"`;
8461
+ }
8462
+ formatColorValue(value, options) {
8463
+ if (!isColorObject(value)) {
8464
+ return typeof value === "string" ? `Color("${this.escapeSwiftString(value)}")` : "Color.clear";
8465
+ }
8466
+ const colorObj = value;
8467
+ const alpha = colorObj.alpha ?? 1;
8468
+ if (options.colorSpace === "displayP3") {
8469
+ const p3 = toP32(dtcgObjectToCulori(colorObj));
8470
+ const r2 = this.roundComponent(p3?.r ?? 0);
8471
+ const g2 = this.roundComponent(p3?.g ?? 0);
8472
+ const b2 = this.roundComponent(p3?.b ?? 0);
8473
+ return alpha < 1 ? `Color(.displayP3, red: ${r2}, green: ${g2}, blue: ${b2}, opacity: ${this.roundComponent(alpha)})` : `Color(.displayP3, red: ${r2}, green: ${g2}, blue: ${b2})`;
8474
+ }
8475
+ const rgb = toSRGB2(dtcgObjectToCulori(colorObj));
8476
+ const r = this.roundComponent(rgb?.r ?? 0);
8477
+ const g = this.roundComponent(rgb?.g ?? 0);
8478
+ const b = this.roundComponent(rgb?.b ?? 0);
8479
+ return alpha < 1 ? `Color(red: ${r}, green: ${g}, blue: ${b}, opacity: ${this.roundComponent(alpha)})` : `Color(red: ${r}, green: ${g}, blue: ${b})`;
8480
+ }
8481
+ formatDimensionValue(value) {
8482
+ if (isDimensionObject(value)) {
8483
+ const dim = value;
8484
+ const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
8485
+ return String(ptValue);
8486
+ }
8487
+ return String(value);
8488
+ }
8489
+ formatFontFamilyValue(value) {
8490
+ if (Array.isArray(value)) {
8491
+ const primary = value[0];
8492
+ return typeof primary === "string" ? `"${this.escapeSwiftString(primary)}"` : '"system"';
8493
+ }
8494
+ return typeof value === "string" ? `"${this.escapeSwiftString(value)}"` : '"system"';
8495
+ }
8496
+ formatFontWeightValue(value) {
8497
+ if (typeof value === "number") {
8498
+ return this.numericFontWeight(value);
8499
+ }
8500
+ if (typeof value === "string") {
8501
+ return this.namedFontWeight(value) ?? "Font.Weight.regular";
8502
+ }
8503
+ return "Font.Weight.regular";
8504
+ }
8505
+ numericFontWeight(weight) {
8506
+ if (weight <= 100) {
8507
+ return "Font.Weight.ultraLight";
8508
+ }
8509
+ if (weight <= 200) {
8510
+ return "Font.Weight.thin";
8511
+ }
8512
+ if (weight <= 300) {
8513
+ return "Font.Weight.light";
8514
+ }
8515
+ if (weight <= 400) {
8516
+ return "Font.Weight.regular";
8517
+ }
8518
+ if (weight <= 500) {
8519
+ return "Font.Weight.medium";
8520
+ }
8521
+ if (weight <= 600) {
8522
+ return "Font.Weight.semibold";
8523
+ }
8524
+ if (weight <= 700) {
8525
+ return "Font.Weight.bold";
8526
+ }
8527
+ if (weight <= 800) {
8528
+ return "Font.Weight.heavy";
8529
+ }
8530
+ return "Font.Weight.black";
8531
+ }
8532
+ namedFontWeight(name) {
8533
+ const map = {
8534
+ thin: "Font.Weight.thin",
8535
+ ultralight: "Font.Weight.ultraLight",
8536
+ extralight: "Font.Weight.ultraLight",
8537
+ light: "Font.Weight.light",
8538
+ regular: "Font.Weight.regular",
8539
+ normal: "Font.Weight.regular",
8540
+ medium: "Font.Weight.medium",
8541
+ semibold: "Font.Weight.semibold",
8542
+ demibold: "Font.Weight.semibold",
8543
+ bold: "Font.Weight.bold",
8544
+ heavy: "Font.Weight.heavy",
8545
+ extrabold: "Font.Weight.heavy",
8546
+ black: "Font.Weight.black",
8547
+ ultrabold: "Font.Weight.black"
8548
+ };
8549
+ return map[name.toLowerCase()];
8550
+ }
8551
+ formatDurationValue(value) {
8552
+ if (typeof value === "object" && value !== null && "value" in value && "unit" in value) {
8553
+ const dur = value;
8554
+ const seconds = dur.unit === "ms" ? dur.value / 1e3 : dur.value;
8555
+ return String(seconds);
8556
+ }
8557
+ return typeof value === "number" ? String(value) : "0";
8558
+ }
8559
+ formatShadowValue(value, options) {
8560
+ if (Array.isArray(value) && value.length > 0) {
8561
+ return this.formatSingleShadow(value[0], options);
8562
+ }
8563
+ if (typeof value === "object" && value !== null) {
8564
+ return this.formatSingleShadow(value, options);
8565
+ }
8566
+ return "ShadowStyle(color: .clear, radius: 0, x: 0, y: 0, spread: 0)";
8567
+ }
8568
+ formatSingleShadow(shadow, options) {
8569
+ const color = isColorObject(shadow.color) ? this.formatColorValue(shadow.color, options) : "Color.black.opacity(0.25)";
8570
+ const radius = isDimensionObject(shadow.blur) ? this.dimensionToCGFloat(shadow.blur) : "8";
8571
+ const x = isDimensionObject(shadow.offsetX) ? this.dimensionToCGFloat(shadow.offsetX) : "0";
8572
+ const y = isDimensionObject(shadow.offsetY) ? this.dimensionToCGFloat(shadow.offsetY) : "0";
8573
+ const spread = isDimensionObject(shadow.spread) ? this.dimensionToCGFloat(shadow.spread) : "0";
8574
+ return `ShadowStyle(color: ${color}, radius: ${radius}, x: ${x}, y: ${y}, spread: ${spread})`;
8575
+ }
8576
+ formatTypographyValue(value) {
8577
+ if (typeof value !== "object" || value === null) {
8578
+ return "TypographyStyle(font: Font.body, tracking: 0, lineSpacing: 0)";
8579
+ }
8580
+ const typo = value;
8581
+ const size = isDimensionObject(typo.fontSize) ? this.dimensionToPoints(typo.fontSize) : "16";
8582
+ const weight = typo.fontWeight != null ? this.formatFontWeightValue(typo.fontWeight) : "Font.Weight.regular";
8583
+ const fontExpr = this.buildFontExpression(typo, size, weight);
8584
+ const tracking = this.extractTracking(typo);
8585
+ const lineSpacing = this.extractLineSpacing(typo);
8586
+ return `TypographyStyle(font: ${fontExpr}, tracking: ${tracking}, lineSpacing: ${lineSpacing})`;
8587
+ }
8588
+ buildFontExpression(typo, size, weight) {
8589
+ if (typo.fontFamily != null) {
8590
+ const family = Array.isArray(typo.fontFamily) ? typo.fontFamily[0] : typo.fontFamily;
8591
+ if (typeof family === "string") {
8592
+ return `Font.custom("${this.escapeSwiftString(family)}", size: ${size}).weight(${weight})`;
8593
+ }
8594
+ }
8595
+ return `Font.system(size: ${size}, weight: ${weight})`;
8596
+ }
8597
+ extractTracking(typo) {
8598
+ if (!isDimensionObject(typo.letterSpacing)) {
8599
+ return "0";
8600
+ }
8601
+ const dim = typo.letterSpacing;
8602
+ const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
8603
+ return String(ptValue);
8604
+ }
8605
+ extractLineSpacing(typo) {
8606
+ if (typo.lineHeight == null || typeof typo.lineHeight !== "number") {
8607
+ return "0";
8608
+ }
8609
+ if (!isDimensionObject(typo.fontSize)) {
8610
+ return "0";
8611
+ }
8612
+ const dim = typo.fontSize;
8613
+ const basePt = dim.unit === "rem" ? dim.value * 16 : dim.value;
8614
+ const lineHeightPt = Math.round(basePt * typo.lineHeight * 100) / 100;
8615
+ return String(lineHeightPt - basePt);
8616
+ }
8617
+ dimensionToPoints(dim) {
8618
+ const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
8619
+ return String(ptValue);
8620
+ }
8621
+ /** Formats a dimension as a CGFloat literal (appends `.0` for integers). */
8622
+ dimensionToCGFloat(dim) {
8623
+ const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
8624
+ return Number.isInteger(ptValue) ? `${ptValue}.0` : String(ptValue);
8625
+ }
8626
+ getTypeAnnotation(token) {
8627
+ switch (token.$type) {
8628
+ case "dimension":
8629
+ return "CGFloat";
8630
+ case "duration":
8631
+ return "TimeInterval";
8632
+ case "number":
8633
+ return "Double";
8634
+ case "fontWeight":
8635
+ return "Font.Weight";
8636
+ case "fontFamily":
8637
+ return "String";
8638
+ default:
8639
+ return void 0;
8640
+ }
8641
+ }
8642
+ toSwiftIdentifier(name) {
8643
+ const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
8644
+ const identifier = camel.charAt(0).toLowerCase() + camel.slice(1);
8645
+ const safe = /^\d/.test(identifier) ? `_${identifier}` : identifier;
8646
+ return SWIFT_KEYWORDS.has(safe) ? `\`${safe}\`` : safe;
8647
+ }
8648
+ escapeSwiftString(str) {
8649
+ return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
8650
+ }
8651
+ roundComponent(value) {
8652
+ return Math.round(value * 1e4) / 1e4;
8653
+ }
8654
+ indentStr(width, level) {
8655
+ return " ".repeat(width * level);
8656
+ }
8657
+ /**
8658
+ * Returns the prefix for `static let` declarations.
8659
+ * Swift 6 requires `nonisolated(unsafe)` on global stored properties.
8660
+ */
8661
+ staticLetPrefix(options) {
8662
+ return options.swiftVersion === "6.0" ? "nonisolated(unsafe) static let " : "static let ";
8663
+ }
8664
+ /** Returns `@frozen ` when the frozen option is enabled, empty string otherwise. */
8665
+ frozenPrefix(options) {
8666
+ return options.frozen ? "@frozen " : "";
8667
+ }
8668
+ /** Returns `: Sendable` when targeting Swift 6, empty string otherwise. */
8669
+ structConformances(options) {
8670
+ return options.swiftVersion === "6.0" ? ": Sendable" : "";
8671
+ }
8672
+ hasShadowTokens(tokens) {
8673
+ return Object.values(tokens).some((t) => t.$type === "shadow");
8674
+ }
8675
+ hasTypographyTokens(tokens) {
8676
+ return Object.values(tokens).some((t) => t.$type === "typography");
8677
+ }
8678
+ hasBorderTokens(tokens) {
8679
+ return Object.values(tokens).some((t) => t.$type === "border");
8680
+ }
8681
+ /** Emits all struct definitions needed by the token set. */
8682
+ buildStructDefinitions(tokens, access3, options) {
8683
+ const lines = [];
8684
+ if (this.hasShadowTokens(tokens)) {
8685
+ lines.push("");
8686
+ lines.push(...this.buildShadowStyleStruct(access3, options));
8687
+ }
8688
+ if (this.hasTypographyTokens(tokens)) {
8689
+ lines.push("");
8690
+ lines.push(...this.buildTypographyStyleStruct(access3, options));
8691
+ }
8692
+ if (this.hasBorderTokens(tokens)) {
8693
+ lines.push("");
8694
+ lines.push(...this.buildBorderStyleStruct(access3, options));
8695
+ }
8696
+ return lines;
8697
+ }
8698
+ buildShadowStyleStruct(access3, options) {
8699
+ const i1 = this.indentStr(options.indent, 1);
8700
+ const conformances = this.structConformances(options);
8701
+ const frozen = this.frozenPrefix(options);
8702
+ return [
8703
+ `${frozen}${access3} struct ShadowStyle${conformances} {`,
8704
+ `${i1}${access3} let color: Color`,
8705
+ `${i1}${access3} let radius: CGFloat`,
8706
+ `${i1}${access3} let x: CGFloat`,
8707
+ `${i1}${access3} let y: CGFloat`,
8708
+ `${i1}${access3} let spread: CGFloat`,
8709
+ "}"
8710
+ ];
8711
+ }
8712
+ buildTypographyStyleStruct(access3, options) {
8713
+ const i1 = this.indentStr(options.indent, 1);
8714
+ const conformances = this.structConformances(options);
8715
+ const frozen = this.frozenPrefix(options);
8716
+ return [
8717
+ `${frozen}${access3} struct TypographyStyle${conformances} {`,
8718
+ `${i1}${access3} let font: Font`,
8719
+ `${i1}${access3} let tracking: CGFloat`,
8720
+ `${i1}${access3} let lineSpacing: CGFloat`,
8721
+ "}"
8722
+ ];
8723
+ }
8724
+ buildBorderStyleStruct(access3, options) {
8725
+ const i1 = this.indentStr(options.indent, 1);
8726
+ const conformances = this.structConformances(options);
8727
+ const frozen = this.frozenPrefix(options);
8728
+ return [
8729
+ `${frozen}${access3} struct BorderStyle${conformances} {`,
8730
+ `${i1}${access3} let color: Color`,
8731
+ `${i1}${access3} let width: CGFloat`,
8732
+ "}"
8733
+ ];
8734
+ }
8735
+ /** Emits convenience View extensions for shadow and typography application. */
8736
+ buildViewExtensions(tokens, access3, options) {
8737
+ const lines = [];
8738
+ const i1 = this.indentStr(options.indent, 1);
8739
+ const i2 = this.indentStr(options.indent, 2);
8740
+ if (this.hasShadowTokens(tokens)) {
8741
+ lines.push("");
8742
+ lines.push(`${access3} extension View {`);
8743
+ lines.push(`${i1}func shadowStyle(_ style: ShadowStyle) -> some View {`);
8744
+ lines.push(
8745
+ `${i2}self.shadow(color: style.color, radius: style.radius, x: style.x, y: style.y)`
8746
+ );
8747
+ lines.push(`${i1}}`);
8748
+ lines.push("}");
8749
+ }
8750
+ if (this.hasTypographyTokens(tokens)) {
8751
+ lines.push("");
8752
+ lines.push(`${access3} extension View {`);
8753
+ lines.push(`${i1}func typographyStyle(_ style: TypographyStyle) -> some View {`);
8754
+ lines.push(
8755
+ `${i2}self.font(style.font).tracking(style.tracking).lineSpacing(style.lineSpacing)`
8756
+ );
8757
+ lines.push(`${i1}}`);
8758
+ lines.push("}");
8759
+ }
8760
+ return lines;
8761
+ }
8762
+ formatBorderValue(value, options) {
8763
+ if (typeof value !== "object" || value === null) {
8764
+ return "BorderStyle(color: .clear, width: 0)";
8765
+ }
8766
+ const border = value;
8767
+ const color = isColorObject(border.color) ? this.formatColorValue(border.color, options) : "Color.clear";
8768
+ const width = isDimensionObject(border.width) ? this.dimensionToCGFloat(border.width) : "1.0";
8769
+ return `BorderStyle(color: ${color}, width: ${width})`;
8770
+ }
8771
+ formatGradientValue(value, options) {
8772
+ if (!Array.isArray(value) || value.length === 0) {
8773
+ return "Gradient(stops: [])";
8774
+ }
8775
+ const stops = value.map((stop) => {
8776
+ const color = isColorObject(stop.color) ? this.formatColorValue(stop.color, options) : "Color.clear";
8777
+ return `.init(color: ${color}, location: ${stop.position})`;
8778
+ });
8779
+ return `Gradient(stops: [${stops.join(", ")}])`;
8780
+ }
8781
+ async formatStandalone(context, options) {
8782
+ const requiresFile = context.buildPath !== void 0 && context.buildPath !== "";
8783
+ if (!context.output.file && requiresFile) {
8784
+ throw new exports.ConfigurationError(
8785
+ `Output "${context.output.name}": file is required for standalone iOS output`
8786
+ );
8787
+ }
8788
+ const files = {};
8789
+ for (const { tokens, modifierInputs } of context.permutations) {
8790
+ const processedTokens = stripInternalMetadata(tokens);
8791
+ const content = this.formatTokens(processedTokens, options);
8792
+ const fileName = context.output.file ? resolveFileName(context.output.file, modifierInputs) : buildInMemoryOutputKey({
8793
+ outputName: context.output.name,
8794
+ extension: "swift",
8795
+ modifierInputs,
8796
+ resolver: context.resolver,
8797
+ defaults: context.meta.defaults
8798
+ });
8799
+ files[fileName] = content;
8800
+ }
8801
+ return outputTree(files);
7419
8802
  }
7420
8803
  };
7421
- function cssRenderer() {
7422
- const rendererInstance = new CssRenderer();
8804
+ function iosRenderer() {
8805
+ const rendererInstance = new IosRenderer();
7423
8806
  return {
7424
8807
  format: (context, options) => rendererInstance.format(
7425
8808
  context,
@@ -7545,8 +8928,8 @@ var JsModuleRenderer = class {
7545
8928
  /**
7546
8929
  * Add object properties to lines
7547
8930
  */
7548
- addObjectProperties(lines, obj, indent) {
7549
- const indentStr = " ".repeat(indent);
8931
+ addObjectProperties(lines, obj, indent2) {
8932
+ const indentStr = " ".repeat(indent2);
7550
8933
  const entries = Object.entries(obj).sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
7551
8934
  for (let i = 0; i < entries.length; i++) {
7552
8935
  const entry = entries[i];
@@ -7557,7 +8940,7 @@ var JsModuleRenderer = class {
7557
8940
  const isLast = i === entries.length - 1;
7558
8941
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
7559
8942
  lines.push(`${indentStr}${this.quoteKey(key)}: {`);
7560
- this.addObjectProperties(lines, value, indent + 1);
8943
+ this.addObjectProperties(lines, value, indent2 + 1);
7561
8944
  lines.push(`${indentStr}}${isLast ? "" : ","}`);
7562
8945
  } else {
7563
8946
  const valueStr = JSON.stringify(value);
@@ -7749,6 +9132,349 @@ function jsonRenderer() {
7749
9132
  };
7750
9133
  }
7751
9134
 
9135
+ // src/renderers/tailwind.ts
9136
+ init_errors();
9137
+ init_token_utils();
9138
+
9139
+ // src/renderers/bundlers/tailwind.ts
9140
+ init_errors();
9141
+ init_utils();
9142
+ async function bundleAsTailwind(bundleData, options, formatThemeTokens, formatOverrideBlock) {
9143
+ const baseItem = bundleData.find((item) => item.isBase);
9144
+ if (!baseItem) {
9145
+ throw new exports.BasePermutationError("Base permutation not found in bundle data");
9146
+ }
9147
+ const resolvedOpts = resolveOptions(options);
9148
+ const cssBlocks = [];
9149
+ const variantDeclarations = collectVariantDeclarations(bundleData, baseItem, resolvedOpts);
9150
+ const themeOpts = { ...resolvedOpts, variantDeclarations };
9151
+ const baseTokens = stripInternalMetadata(baseItem.tokens);
9152
+ const themeBlock = await formatThemeTokens(baseTokens, themeOpts);
9153
+ cssBlocks.push(themeBlock);
9154
+ for (const item of bundleData) {
9155
+ if (item.isBase) {
9156
+ continue;
9157
+ }
9158
+ const block = await formatModifierOverride(item, baseItem, resolvedOpts, formatOverrideBlock);
9159
+ if (block) {
9160
+ cssBlocks.push(block);
9161
+ }
9162
+ }
9163
+ return cssBlocks.join("\n");
9164
+ }
9165
+ async function formatModifierOverride({ tokens, modifierInputs }, baseItem, options, formatOverrideBlock) {
9166
+ const differenceCount = countModifierDifferences(modifierInputs, baseItem.modifierInputs);
9167
+ if (differenceCount > 1) {
9168
+ return void 0;
9169
+ }
9170
+ const tokensToInclude = filterTokensByValueChange(tokens, baseItem.tokens);
9171
+ if (Object.keys(tokensToInclude).length === 0) {
9172
+ return void 0;
9173
+ }
9174
+ const expectedSource = getExpectedSource(modifierInputs, baseItem.modifierInputs);
9175
+ const [modifier, context] = parseModifierSource(expectedSource);
9176
+ const cleanTokens = stripInternalMetadata(tokensToInclude);
9177
+ const selector = resolveSelector(
9178
+ options.selector,
9179
+ modifier,
9180
+ context,
9181
+ false,
9182
+ normalizeModifierInputs(modifierInputs)
9183
+ );
9184
+ const mediaQuery = resolveMediaQuery(
9185
+ options.mediaQuery,
9186
+ modifier,
9187
+ context,
9188
+ false,
9189
+ normalizeModifierInputs(modifierInputs)
9190
+ );
9191
+ const css2 = await formatOverrideBlock(cleanTokens, selector, mediaQuery, options.minify);
9192
+ return `/* Modifier: ${modifier}=${context} */
9193
+ ${css2}`;
9194
+ }
9195
+ function filterTokensByValueChange(currentTokens, baseTokens) {
9196
+ const changed = {};
9197
+ for (const [name, token] of Object.entries(currentTokens)) {
9198
+ const baseToken = baseTokens[name];
9199
+ if (!baseToken) {
9200
+ changed[name] = token;
9201
+ continue;
9202
+ }
9203
+ if (JSON.stringify(token.$value) !== JSON.stringify(baseToken.$value)) {
9204
+ changed[name] = token;
9205
+ }
9206
+ }
9207
+ return changed;
9208
+ }
9209
+ function collectVariantDeclarations(bundleData, baseItem, options) {
9210
+ const declarations = [];
9211
+ for (const item of bundleData) {
9212
+ if (item.isBase) {
9213
+ continue;
9214
+ }
9215
+ const differenceCount = countModifierDifferences(item.modifierInputs, baseItem.modifierInputs);
9216
+ if (differenceCount > 1) {
9217
+ continue;
9218
+ }
9219
+ const expectedSource = getExpectedSource(item.modifierInputs, baseItem.modifierInputs);
9220
+ const [modifier, context] = parseModifierSource(expectedSource);
9221
+ const variantName = `${modifier}-${context}`;
9222
+ const normalized = normalizeModifierInputs(item.modifierInputs);
9223
+ const mediaQuery = resolveMediaQuery(options.mediaQuery, modifier, context, false, normalized);
9224
+ if (mediaQuery !== "") {
9225
+ declarations.push(`@custom-variant ${variantName} (@media ${mediaQuery});`);
9226
+ continue;
9227
+ }
9228
+ const selector = resolveSelector(options.selector, modifier, context, false, normalized);
9229
+ declarations.push(`@custom-variant ${variantName} (&:where(${selector}, ${selector} *));`);
9230
+ }
9231
+ return declarations;
9232
+ }
9233
+ function resolveOptions(options) {
9234
+ return {
9235
+ preset: options.preset ?? "bundle",
9236
+ includeImport: options.includeImport ?? true,
9237
+ namespace: options.namespace ?? "",
9238
+ minify: options.minify ?? false,
9239
+ selector: options.selector,
9240
+ mediaQuery: options.mediaQuery,
9241
+ variantDeclarations: []
9242
+ };
9243
+ }
9244
+
9245
+ // src/renderers/tailwind.ts
9246
+ init_utils();
9247
+ var TAILWIND_NAMESPACE_MAP = {
9248
+ color: "color",
9249
+ dimension: "spacing",
9250
+ fontFamily: "font",
9251
+ fontWeight: "font-weight",
9252
+ duration: "duration",
9253
+ shadow: "shadow",
9254
+ number: "number",
9255
+ cubicBezier: "ease"
9256
+ };
9257
+ var TailwindRenderer = class {
9258
+ async format(context, options) {
9259
+ const opts = {
9260
+ preset: options?.preset ?? "bundle",
9261
+ includeImport: options?.includeImport ?? true,
9262
+ namespace: options?.namespace ?? "",
9263
+ minify: options?.minify ?? false,
9264
+ selector: options?.selector,
9265
+ mediaQuery: options?.mediaQuery,
9266
+ variantDeclarations: []
9267
+ };
9268
+ if (opts.preset === "bundle") {
9269
+ return await this.formatBundle(context, opts);
9270
+ }
9271
+ return await this.formatStandalone(context, opts);
9272
+ }
9273
+ /**
9274
+ * Format tokens as Tailwind v4 @theme CSS variables
9275
+ */
9276
+ async formatTokens(tokens, options) {
9277
+ const lines = [];
9278
+ const indent2 = options.minify ? "" : " ";
9279
+ const newline = options.minify ? "" : "\n";
9280
+ const space = options.minify ? "" : " ";
9281
+ if (options.includeImport) {
9282
+ lines.push(`@import "tailwindcss";${newline}`);
9283
+ }
9284
+ if (options.variantDeclarations.length > 0) {
9285
+ if (options.includeImport) {
9286
+ lines.push(newline);
9287
+ }
9288
+ for (const declaration of options.variantDeclarations) {
9289
+ lines.push(`${declaration}${newline}`);
9290
+ }
9291
+ }
9292
+ if (options.includeImport || options.variantDeclarations.length > 0) {
9293
+ lines.push(newline);
9294
+ }
9295
+ const themeDirective = options.namespace ? `@theme namespace(${options.namespace})` : "@theme";
9296
+ lines.push(`${themeDirective}${space}{${newline}`);
9297
+ for (const [, token] of getSortedTokenEntries(tokens)) {
9298
+ const varName = this.buildVariableName(token);
9299
+ const varValue = this.formatValue(token);
9300
+ lines.push(`${indent2}--${varName}:${space}${varValue};${newline}`);
9301
+ }
9302
+ lines.push(`}${newline}`);
9303
+ const cssString = lines.join("");
9304
+ return options.minify ? cssString : await this.formatWithPrettier(cssString);
9305
+ }
9306
+ /**
9307
+ * Format tokens as plain CSS custom property overrides inside a selector block.
9308
+ * Used for modifier overrides (e.g., dark mode) appended after the @theme block.
9309
+ */
9310
+ async formatOverrideBlock(tokens, selector, mediaQuery, minify) {
9311
+ const indent2 = minify ? "" : " ";
9312
+ const newline = minify ? "" : "\n";
9313
+ const space = minify ? "" : " ";
9314
+ const hasMediaQuery = mediaQuery !== "";
9315
+ const tokenIndent = hasMediaQuery ? indent2 + indent2 : indent2;
9316
+ const lines = [];
9317
+ if (hasMediaQuery) {
9318
+ lines.push(`@media ${mediaQuery}${space}{${newline}`);
9319
+ lines.push(`${indent2}${selector}${space}{${newline}`);
9320
+ } else {
9321
+ lines.push(`${selector}${space}{${newline}`);
9322
+ }
9323
+ for (const [, token] of getSortedTokenEntries(tokens)) {
9324
+ const varName = this.buildVariableName(token);
9325
+ const varValue = this.formatValue(token);
9326
+ lines.push(`${tokenIndent}--${varName}:${space}${varValue};${newline}`);
9327
+ }
9328
+ if (hasMediaQuery) {
9329
+ lines.push(`${indent2}}${newline}`);
9330
+ lines.push(`}${newline}`);
9331
+ } else {
9332
+ lines.push(`}${newline}`);
9333
+ }
9334
+ return lines.join("");
9335
+ }
9336
+ buildVariableName(token) {
9337
+ const prefix = TAILWIND_NAMESPACE_MAP[token.$type ?? ""];
9338
+ if (!prefix) {
9339
+ return token.name;
9340
+ }
9341
+ const nameLower = token.name.toLowerCase();
9342
+ const prefixLower = prefix.toLowerCase();
9343
+ if (nameLower.startsWith(`${prefixLower}-`) || nameLower.startsWith(`${prefixLower}.`)) {
9344
+ return token.name;
9345
+ }
9346
+ return `${prefix}-${token.name}`;
9347
+ }
9348
+ formatValue(token) {
9349
+ const value = token.$value;
9350
+ if (token.$type === "color" && isColorObject(value)) {
9351
+ return colorObjectToHex(value);
9352
+ }
9353
+ if (token.$type === "dimension" && isDimensionObject(value)) {
9354
+ return dimensionObjectToString(value);
9355
+ }
9356
+ if (token.$type === "duration" && this.isDurationObject(value)) {
9357
+ return `${value.value}${value.unit}`;
9358
+ }
9359
+ if (token.$type === "fontFamily") {
9360
+ if (Array.isArray(value)) {
9361
+ return value.map((v) => typeof v === "string" && v.includes(" ") ? `"${v}"` : v).join(", ");
9362
+ }
9363
+ return typeof value === "string" ? value : String(value);
9364
+ }
9365
+ if (token.$type === "shadow") {
9366
+ return this.formatShadowValue(value);
9367
+ }
9368
+ if (token.$type === "cubicBezier" && Array.isArray(value) && value.length === 4) {
9369
+ return `cubic-bezier(${value.join(", ")})`;
9370
+ }
9371
+ if (typeof value === "string") {
9372
+ return value;
9373
+ }
9374
+ if (typeof value === "number") {
9375
+ return String(value);
9376
+ }
9377
+ return String(value);
9378
+ }
9379
+ formatShadowValue(value) {
9380
+ if (Array.isArray(value) && value.length > 0 && typeof value[0] === "object") {
9381
+ return value.map((s) => this.formatSingleShadow(s)).join(", ");
9382
+ }
9383
+ if (typeof value === "object" && value !== null) {
9384
+ return this.formatSingleShadow(value);
9385
+ }
9386
+ return String(value);
9387
+ }
9388
+ formatSingleShadow(shadow) {
9389
+ const parts = [];
9390
+ if (shadow.inset === true) {
9391
+ parts.push("inset");
9392
+ }
9393
+ if (isDimensionObject(shadow.offsetX)) {
9394
+ parts.push(dimensionObjectToString(shadow.offsetX));
9395
+ }
9396
+ if (isDimensionObject(shadow.offsetY)) {
9397
+ parts.push(dimensionObjectToString(shadow.offsetY));
9398
+ }
9399
+ if (isDimensionObject(shadow.blur)) {
9400
+ parts.push(dimensionObjectToString(shadow.blur));
9401
+ }
9402
+ if (shadow.spread != null && isDimensionObject(shadow.spread)) {
9403
+ parts.push(dimensionObjectToString(shadow.spread));
9404
+ }
9405
+ if (isColorObject(shadow.color)) {
9406
+ parts.push(colorObjectToHex(shadow.color));
9407
+ } else if (shadow.color != null) {
9408
+ parts.push(String(shadow.color));
9409
+ }
9410
+ return parts.join(" ");
9411
+ }
9412
+ isDurationObject(value) {
9413
+ return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
9414
+ }
9415
+ async formatWithPrettier(css2) {
9416
+ try {
9417
+ return await prettier__default.default.format(css2, {
9418
+ parser: "css",
9419
+ printWidth: 80,
9420
+ tabWidth: 2,
9421
+ useTabs: false
9422
+ });
9423
+ } catch {
9424
+ return css2;
9425
+ }
9426
+ }
9427
+ async formatBundle(context, options) {
9428
+ const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
9429
+ tokens,
9430
+ modifierInputs,
9431
+ isBase: this.isBasePermutation(modifierInputs, context.meta.defaults)
9432
+ }));
9433
+ return await bundleAsTailwind(
9434
+ bundleData,
9435
+ options,
9436
+ async (tokens, opts) => await this.formatTokens(tokens, opts),
9437
+ async (tokens, selector, mediaQuery, minify) => await this.formatOverrideBlock(tokens, selector, mediaQuery, minify)
9438
+ );
9439
+ }
9440
+ async formatStandalone(context, options) {
9441
+ const requiresFile = context.buildPath !== void 0 && context.buildPath !== "";
9442
+ if (!context.output.file && requiresFile) {
9443
+ throw new exports.ConfigurationError(
9444
+ `Output "${context.output.name}": file is required for standalone Tailwind output`
9445
+ );
9446
+ }
9447
+ const files = {};
9448
+ for (const { tokens, modifierInputs } of context.permutations) {
9449
+ const processedTokens = stripInternalMetadata(tokens);
9450
+ const content = await this.formatTokens(processedTokens, options);
9451
+ const fileName = context.output.file ? resolveFileName(context.output.file, modifierInputs) : buildInMemoryOutputKey({
9452
+ outputName: context.output.name,
9453
+ extension: "css",
9454
+ modifierInputs,
9455
+ resolver: context.resolver,
9456
+ defaults: context.meta.defaults
9457
+ });
9458
+ files[fileName] = content;
9459
+ }
9460
+ return outputTree(files);
9461
+ }
9462
+ isBasePermutation(modifierInputs, defaults) {
9463
+ return Object.entries(defaults).every(
9464
+ ([key, value]) => modifierInputs[key]?.toLowerCase() === value.toLowerCase()
9465
+ );
9466
+ }
9467
+ };
9468
+ function tailwindRenderer() {
9469
+ const rendererInstance = new TailwindRenderer();
9470
+ return {
9471
+ format: (context, options) => rendererInstance.format(
9472
+ context,
9473
+ options ?? context.output.options
9474
+ )
9475
+ };
9476
+ }
9477
+
7752
9478
  // src/builders.ts
7753
9479
  function css(config) {
7754
9480
  const {
@@ -7810,6 +9536,58 @@ function js(config) {
7810
9536
  hooks
7811
9537
  };
7812
9538
  }
9539
+ function tailwind(config) {
9540
+ const { name, file, transforms, filters, hooks, preset = "bundle", ...rendererOptions } = config;
9541
+ return {
9542
+ name,
9543
+ file,
9544
+ renderer: tailwindRenderer(),
9545
+ options: { preset, ...rendererOptions },
9546
+ transforms,
9547
+ filters,
9548
+ hooks
9549
+ };
9550
+ }
9551
+ function ios(config) {
9552
+ const {
9553
+ name,
9554
+ file,
9555
+ transforms,
9556
+ filters,
9557
+ hooks,
9558
+ preset = "standalone",
9559
+ ...rendererOptions
9560
+ } = config;
9561
+ return {
9562
+ name,
9563
+ file,
9564
+ renderer: iosRenderer(),
9565
+ options: { preset, ...rendererOptions },
9566
+ transforms,
9567
+ filters,
9568
+ hooks
9569
+ };
9570
+ }
9571
+ function android(config) {
9572
+ const {
9573
+ name,
9574
+ file,
9575
+ transforms,
9576
+ filters,
9577
+ hooks,
9578
+ preset = "standalone",
9579
+ ...rendererOptions
9580
+ } = config;
9581
+ return {
9582
+ name,
9583
+ file,
9584
+ renderer: androidRenderer(),
9585
+ options: { preset, ...rendererOptions },
9586
+ transforms,
9587
+ filters,
9588
+ hooks
9589
+ };
9590
+ }
7813
9591
 
7814
9592
  // src/renderers/types.ts
7815
9593
  function defineRenderer(renderer) {
@@ -7823,10 +9601,19 @@ init_errors();
7823
9601
  * Copyright (c) 2025 Dispersa Contributors
7824
9602
  * SPDX-License-Identifier: MIT
7825
9603
  */
9604
+ /**
9605
+ * @license MIT
9606
+ * Copyright (c) 2025-present Dispersa Contributors
9607
+ *
9608
+ * This source code is licensed under the MIT license found in the
9609
+ * LICENSE file in the root directory of this source tree.
9610
+ */
7826
9611
 
7827
9612
  exports.Dispersa = Dispersa;
9613
+ exports.android = android;
7828
9614
  exports.css = css;
7829
9615
  exports.defineRenderer = defineRenderer;
9616
+ exports.ios = ios;
7830
9617
  exports.isBorderToken = isBorderToken;
7831
9618
  exports.isColorToken = isColorToken;
7832
9619
  exports.isDimensionToken = isDimensionToken;
@@ -7839,5 +9626,6 @@ exports.isTypographyToken = isTypographyToken;
7839
9626
  exports.js = js;
7840
9627
  exports.json = json;
7841
9628
  exports.outputTree = outputTree;
9629
+ exports.tailwind = tailwind;
7842
9630
  //# sourceMappingURL=index.cjs.map
7843
9631
  //# sourceMappingURL=index.cjs.map