@productivemark/snipcss 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.claude-plugin/marketplace.json +17 -0
  2. package/.claude-plugin/plugin.json +10 -0
  3. package/.mcp.json +8 -0
  4. package/dist/auth/config-manager.d.ts +13 -0
  5. package/dist/auth/config-manager.d.ts.map +1 -0
  6. package/dist/auth/config-manager.js +48 -0
  7. package/dist/auth/config-manager.js.map +1 -0
  8. package/dist/auth/usage-gate.d.ts +13 -0
  9. package/dist/auth/usage-gate.d.ts.map +1 -0
  10. package/dist/auth/usage-gate.js +69 -0
  11. package/dist/auth/usage-gate.js.map +1 -0
  12. package/dist/browser/browser-manager.d.ts +15 -0
  13. package/dist/browser/browser-manager.d.ts.map +1 -0
  14. package/dist/browser/browser-manager.js +61 -0
  15. package/dist/browser/browser-manager.js.map +1 -0
  16. package/dist/browser/viewport-manager.d.ts +8 -0
  17. package/dist/browser/viewport-manager.d.ts.map +1 -0
  18. package/dist/browser/viewport-manager.js +50 -0
  19. package/dist/browser/viewport-manager.js.map +1 -0
  20. package/dist/extraction/css-variable-resolver.d.ts +27 -0
  21. package/dist/extraction/css-variable-resolver.d.ts.map +1 -0
  22. package/dist/extraction/css-variable-resolver.js +105 -0
  23. package/dist/extraction/css-variable-resolver.js.map +1 -0
  24. package/dist/extraction/dom-labeler.d.ts +26 -0
  25. package/dist/extraction/dom-labeler.d.ts.map +1 -0
  26. package/dist/extraction/dom-labeler.js +124 -0
  27. package/dist/extraction/dom-labeler.js.map +1 -0
  28. package/dist/extraction/element-discovery.d.ts +59 -0
  29. package/dist/extraction/element-discovery.d.ts.map +1 -0
  30. package/dist/extraction/element-discovery.js +525 -0
  31. package/dist/extraction/element-discovery.js.map +1 -0
  32. package/dist/extraction/extraction-pipeline.d.ts +26 -0
  33. package/dist/extraction/extraction-pipeline.d.ts.map +1 -0
  34. package/dist/extraction/extraction-pipeline.js +200 -0
  35. package/dist/extraction/extraction-pipeline.js.map +1 -0
  36. package/dist/extraction/font-collector.d.ts +26 -0
  37. package/dist/extraction/font-collector.d.ts.map +1 -0
  38. package/dist/extraction/font-collector.js +160 -0
  39. package/dist/extraction/font-collector.js.map +1 -0
  40. package/dist/extraction/html-cleaner.d.ts +16 -0
  41. package/dist/extraction/html-cleaner.d.ts.map +1 -0
  42. package/dist/extraction/html-cleaner.js +149 -0
  43. package/dist/extraction/html-cleaner.js.map +1 -0
  44. package/dist/extraction/keyframe-collector.d.ts +16 -0
  45. package/dist/extraction/keyframe-collector.d.ts.map +1 -0
  46. package/dist/extraction/keyframe-collector.js +62 -0
  47. package/dist/extraction/keyframe-collector.js.map +1 -0
  48. package/dist/extraction/pseudo-state-handler.d.ts +36 -0
  49. package/dist/extraction/pseudo-state-handler.d.ts.map +1 -0
  50. package/dist/extraction/pseudo-state-handler.js +210 -0
  51. package/dist/extraction/pseudo-state-handler.js.map +1 -0
  52. package/dist/extraction/result-builder.d.ts +25 -0
  53. package/dist/extraction/result-builder.d.ts.map +1 -0
  54. package/dist/extraction/result-builder.js +136 -0
  55. package/dist/extraction/result-builder.js.map +1 -0
  56. package/dist/extraction/rule-deduplicator.d.ts +39 -0
  57. package/dist/extraction/rule-deduplicator.d.ts.map +1 -0
  58. package/dist/extraction/rule-deduplicator.js +107 -0
  59. package/dist/extraction/rule-deduplicator.js.map +1 -0
  60. package/dist/extraction/selector-fixer.d.ts +25 -0
  61. package/dist/extraction/selector-fixer.d.ts.map +1 -0
  62. package/dist/extraction/selector-fixer.js +111 -0
  63. package/dist/extraction/selector-fixer.js.map +1 -0
  64. package/dist/extraction/specificity.d.ts +17 -0
  65. package/dist/extraction/specificity.d.ts.map +1 -0
  66. package/dist/extraction/specificity.js +88 -0
  67. package/dist/extraction/specificity.js.map +1 -0
  68. package/dist/extraction/style-matcher.d.ts +33 -0
  69. package/dist/extraction/style-matcher.d.ts.map +1 -0
  70. package/dist/extraction/style-matcher.js +199 -0
  71. package/dist/extraction/style-matcher.js.map +1 -0
  72. package/dist/extraction/stylesheet-collector.d.ts +33 -0
  73. package/dist/extraction/stylesheet-collector.d.ts.map +1 -0
  74. package/dist/extraction/stylesheet-collector.js +71 -0
  75. package/dist/extraction/stylesheet-collector.js.map +1 -0
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +235 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/mcp-server.d.ts +3 -0
  81. package/dist/mcp-server.d.ts.map +1 -0
  82. package/dist/mcp-server.js +349 -0
  83. package/dist/mcp-server.js.map +1 -0
  84. package/dist/tailwind/css-to-tailwind.d.ts +17 -0
  85. package/dist/tailwind/css-to-tailwind.d.ts.map +1 -0
  86. package/dist/tailwind/css-to-tailwind.js +1583 -0
  87. package/dist/tailwind/css-to-tailwind.js.map +1 -0
  88. package/dist/tailwind/shorthand-expander.d.ts +27 -0
  89. package/dist/tailwind/shorthand-expander.d.ts.map +1 -0
  90. package/dist/tailwind/shorthand-expander.js +812 -0
  91. package/dist/tailwind/shorthand-expander.js.map +1 -0
  92. package/dist/tailwind/tailwind-converter.d.ts +35 -0
  93. package/dist/tailwind/tailwind-converter.d.ts.map +1 -0
  94. package/dist/tailwind/tailwind-converter.js +1223 -0
  95. package/dist/tailwind/tailwind-converter.js.map +1 -0
  96. package/dist/tailwind/tailwind-helpers.d.ts +95 -0
  97. package/dist/tailwind/tailwind-helpers.d.ts.map +1 -0
  98. package/dist/tailwind/tailwind-helpers.js +593 -0
  99. package/dist/tailwind/tailwind-helpers.js.map +1 -0
  100. package/dist/tailwind/tailwind-reducer.d.ts +36 -0
  101. package/dist/tailwind/tailwind-reducer.d.ts.map +1 -0
  102. package/dist/tailwind/tailwind-reducer.js +189 -0
  103. package/dist/tailwind/tailwind-reducer.js.map +1 -0
  104. package/dist/types/index.d.ts +239 -0
  105. package/dist/types/index.d.ts.map +1 -0
  106. package/dist/types/index.js +94 -0
  107. package/dist/types/index.js.map +1 -0
  108. package/dist/utils/helpers.d.ts +34 -0
  109. package/dist/utils/helpers.d.ts.map +1 -0
  110. package/dist/utils/helpers.js +120 -0
  111. package/dist/utils/helpers.js.map +1 -0
  112. package/dist/utils/parsel.d.ts +41 -0
  113. package/dist/utils/parsel.d.ts.map +1 -0
  114. package/dist/utils/parsel.js +314 -0
  115. package/dist/utils/parsel.js.map +1 -0
  116. package/package.json +41 -0
  117. package/skills/workflow/SKILL.md +95 -0
@@ -0,0 +1,812 @@
1
+ /**
2
+ * CSS shorthand property expansion.
3
+ * Port of tailwind_shortlong.js (1,504 lines)
4
+ */
5
+ /** Properties that inherit from parent elements */
6
+ export const passedDownProps = [
7
+ 'font', 'font-family', 'font-size', 'font-weight', 'font-style', 'font-variant', 'font-stretch',
8
+ 'font-size-adjust', 'font-kerning', 'font-feature-settings', 'font-variation-settings', 'font-optical-sizing', 'font-synthesis',
9
+ 'font-variant-alternates', 'font-variant-caps', 'font-variant-east-asian', 'font-variant-ligatures', 'font-variant-numeric',
10
+ 'font-variant-position', 'color', 'line-height', 'text-align', 'text-decoration', 'text-decoration-color', 'text-decoration-line', 'text-decoration-style',
11
+ 'text-decoration-thickness', 'text-underline-offset', 'text-indent', 'text-transform', 'text-shadow', 'text-overflow', 'text-size-adjust', 'text-rendering',
12
+ 'letter-spacing', 'word-spacing', 'white-space', 'direction', 'unicode-bidi', 'writing-mode', 'hyphens', 'tab-size', 'list-style', 'list-style-type',
13
+ 'list-style-position', 'list-style-image', 'cursor', 'visibility', 'opacity', 'quotes', 'orphans', 'widows', 'user-select', 'pointer-events',
14
+ ];
15
+ /** Shorthand-to-longhand mapping used for property type detection */
16
+ const shorthandToLonghand = {
17
+ 'background': ['background-color', 'background-image', 'background-repeat', 'background-attachment', 'background-position', 'background-size', 'background-origin', 'background-clip'],
18
+ 'flex-flow': ['flex-direction', 'flex-wrap'],
19
+ 'grid-column': ['grid-column-start', 'grid-column-end'],
20
+ 'grid-row': ['grid-row-start', 'grid-row-end'],
21
+ 'border': ['border-width', 'border-style', 'border-color'],
22
+ 'border-top': ['border-top-width', 'border-top-style', 'border-top-color'],
23
+ 'border-right': ['border-right-width', 'border-right-style', 'border-right-color'],
24
+ 'border-bottom': ['border-bottom-width', 'border-bottom-style', 'border-bottom-color'],
25
+ 'border-left': ['border-left-width', 'border-left-style', 'border-left-color'],
26
+ 'grid-area': ['grid-row-start', 'grid-column-start', 'grid-row-end', 'grid-column-end'],
27
+ 'grid-template': ['grid-template-rows', 'grid-template-columns', 'grid-template-areas'],
28
+ 'place-self': ['align-self', 'justify-self'],
29
+ 'place-content': ['align-content', 'justify-content'],
30
+ 'place-items': ['align-items', 'justify-items'],
31
+ 'transition': ['transition-property', 'transition-duration', 'transition-timing-function', 'transition-delay'],
32
+ 'list-style': ['list-style-type', 'list-style-position', 'list-style-image'],
33
+ };
34
+ /** Full shorthand-to-longhand mapping (for reference/expansion) */
35
+ export const fullShorthandToLonghand = {
36
+ 'border': ['border-width', 'border-style', 'border-color'],
37
+ 'border-top': ['border-top-width', 'border-top-style', 'border-top-color'],
38
+ 'border-right': ['border-right-width', 'border-right-style', 'border-right-color'],
39
+ 'border-bottom': ['border-bottom-width', 'border-bottom-style', 'border-bottom-color'],
40
+ 'border-left': ['border-left-width', 'border-left-style', 'border-left-color'],
41
+ 'background': ['background-color', 'background-image', 'background-repeat', 'background-attachment', 'background-position', 'background-size', 'background-origin', 'background-clip'],
42
+ 'font': ['font-style', 'font-variant', 'font-weight', 'font-stretch', 'font-size', 'line-height', 'font-family'],
43
+ 'list-style': ['list-style-type', 'list-style-position', 'list-style-image'],
44
+ 'transition': ['transition-property', 'transition-duration', 'transition-timing-function', 'transition-delay'],
45
+ 'animation': ['animation-name', 'animation-duration', 'animation-timing-function', 'animation-delay', 'animation-iteration-count', 'animation-direction', 'animation-fill-mode', 'animation-play-state'],
46
+ 'flex': ['flex-grow', 'flex-shrink', 'flex-basis'],
47
+ 'outline': ['outline-width', 'outline-style', 'outline-color'],
48
+ 'border-radius': ['border-top-left-radius', 'border-top-right-radius', 'border-bottom-right-radius', 'border-bottom-left-radius'],
49
+ 'text-decoration': ['text-decoration-line', 'text-decoration-color', 'text-decoration-style', 'text-decoration-thickness'],
50
+ 'columns': ['column-width', 'column-count'],
51
+ 'place-content': ['align-content', 'justify-content'],
52
+ 'place-items': ['align-items', 'justify-items'],
53
+ 'place-self': ['align-self', 'justify-self'],
54
+ 'overflow': ['overflow-x', 'overflow-y'],
55
+ 'inset': ['top', 'right', 'bottom', 'left'],
56
+ 'gap': ['row-gap', 'column-gap'],
57
+ 'border-image': ['border-image-source', 'border-image-slice', 'border-image-width', 'border-image-outset', 'border-image-repeat'],
58
+ 'scroll-margin': ['scroll-margin-top', 'scroll-margin-right', 'scroll-margin-bottom', 'scroll-margin-left'],
59
+ 'scroll-padding': ['scroll-padding-top', 'scroll-padding-right', 'scroll-padding-bottom', 'scroll-padding-left'],
60
+ 'grid': ['grid-template-rows', 'grid-template-columns', 'grid-template-areas', 'grid-auto-rows', 'grid-auto-columns', 'grid-auto-flow'],
61
+ 'grid-template': ['grid-template-rows', 'grid-template-columns', 'grid-template-areas'],
62
+ 'grid-area': ['grid-row-start', 'grid-column-start', 'grid-row-end', 'grid-column-end'],
63
+ 'grid-column': ['grid-column-start', 'grid-column-end'],
64
+ 'grid-row': ['grid-row-start', 'grid-row-end'],
65
+ 'flex-flow': ['flex-direction', 'flex-wrap'],
66
+ 'border-block': ['border-block-start', 'border-block-end'],
67
+ 'border-inline': ['border-inline-start', 'border-inline-end'],
68
+ 'offset': ['offset-anchor', 'offset-distance', 'offset-path', 'offset-position', 'offset-rotate'],
69
+ 'column-rule': ['column-rule-width', 'column-rule-style', 'column-rule-color'],
70
+ 'mask': ['mask-image', 'mask-mode', 'mask-position', 'mask-size', 'mask-repeat', 'mask-origin', 'mask-clip', 'mask-composite'],
71
+ 'font-variant': ['font-variant-ligatures', 'font-variant-alternates', 'font-variant-caps', 'font-variant-numeric', 'font-variant-east-asian'],
72
+ 'border-width': ['border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'],
73
+ 'border-style': ['border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style'],
74
+ 'border-color': ['border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color'],
75
+ 'padding-block': ['padding-block-start', 'padding-block-end'],
76
+ 'padding-inline': ['padding-inline-start', 'padding-inline-end'],
77
+ 'margin-block': ['margin-block-start', 'margin-block-end'],
78
+ 'margin-inline': ['margin-inline-start', 'margin-inline-end'],
79
+ };
80
+ /**
81
+ * Determine if a CSS property is shorthand, longhand, or unique.
82
+ */
83
+ export function getPropertyType(propertyName) {
84
+ if (propertyName in shorthandToLonghand) {
85
+ return { type: 'short', short: propertyName, long: '' };
86
+ }
87
+ for (const shorthand in shorthandToLonghand) {
88
+ if (shorthandToLonghand[shorthand].includes(propertyName)) {
89
+ return { type: 'long', short: shorthand, long: propertyName };
90
+ }
91
+ }
92
+ return { type: 'unique', short: propertyName, long: propertyName };
93
+ }
94
+ /** Tokenize a CSS value respecting parentheses */
95
+ function tokenizeValue(value) {
96
+ const tokens = [];
97
+ let currentToken = '';
98
+ let parenCount = 0;
99
+ for (let i = 0; i < value.length; i++) {
100
+ const char = value[i];
101
+ if (char === '(') {
102
+ parenCount++;
103
+ currentToken += char;
104
+ }
105
+ else if (char === ')') {
106
+ parenCount--;
107
+ currentToken += char;
108
+ if (parenCount === 0) {
109
+ tokens.push(currentToken.trim());
110
+ currentToken = '';
111
+ }
112
+ }
113
+ else if (parenCount === 0 && /\s/.test(char)) {
114
+ if (currentToken.trim())
115
+ tokens.push(currentToken.trim());
116
+ currentToken = '';
117
+ }
118
+ else {
119
+ currentToken += char;
120
+ }
121
+ }
122
+ if (currentToken.trim())
123
+ tokens.push(currentToken.trim());
124
+ return tokens;
125
+ }
126
+ /** Split value by commas respecting parentheses */
127
+ function splitByComma(value) {
128
+ const parts = [];
129
+ let current = '';
130
+ let parenCount = 0;
131
+ for (let i = 0; i < value.length; i++) {
132
+ const char = value[i];
133
+ if (char === '(') {
134
+ parenCount++;
135
+ current += char;
136
+ }
137
+ else if (char === ')') {
138
+ parenCount--;
139
+ current += char;
140
+ }
141
+ else if (char === ',' && parenCount === 0) {
142
+ parts.push(current.trim());
143
+ current = '';
144
+ }
145
+ else {
146
+ current += char;
147
+ }
148
+ }
149
+ if (current.trim())
150
+ parts.push(current.trim());
151
+ return parts;
152
+ }
153
+ /**
154
+ * Expand a CSS shorthand property into its longhand components.
155
+ * Returns null for unsupported properties.
156
+ */
157
+ export function expandShorthandProperty(property, value) {
158
+ if (property === 'background') {
159
+ return expandBackground(value);
160
+ }
161
+ else if (property === 'transition') {
162
+ return expandTransition(value);
163
+ }
164
+ else if (property === 'list-style') {
165
+ return expandListStyle(value);
166
+ }
167
+ else if (property === 'grid-column') {
168
+ return expandGridColumn(value);
169
+ }
170
+ else if (property === 'grid-row') {
171
+ return expandGridRow(value);
172
+ }
173
+ else if (property === 'grid-template') {
174
+ return expandGridTemplate(value);
175
+ }
176
+ else if (property === 'grid-area') {
177
+ return expandGridArea(value);
178
+ }
179
+ else if (property === 'place-self') {
180
+ return expandPlaceProperty(value, 'align-self', 'justify-self');
181
+ }
182
+ else if (property === 'place-content') {
183
+ return expandPlaceProperty(value, 'align-content', 'justify-content');
184
+ }
185
+ else if (property === 'place-items') {
186
+ return expandPlaceProperty(value, 'align-items', 'justify-items');
187
+ }
188
+ else if (property === 'flex-flow') {
189
+ return expandFlexFlow(value);
190
+ }
191
+ else if (property === 'border' || property === 'border-top' || property === 'border-right' ||
192
+ property === 'border-bottom' || property === 'border-left') {
193
+ return expandBorder(property, value);
194
+ }
195
+ else if (property === 'padding' || property === 'margin') {
196
+ return expandSpacing(property, value);
197
+ }
198
+ else if (property === 'animation') {
199
+ return expandAnimation(value);
200
+ }
201
+ return null;
202
+ }
203
+ function expandBackground(value) {
204
+ let expandedProperties = {};
205
+ let overwrittenProperties = {};
206
+ const layers = splitByComma(value);
207
+ let hasConflict = layers.length > 1;
208
+ const bgImages = [];
209
+ const bgColors = [];
210
+ const bgRepeats = [];
211
+ const bgAttachments = [];
212
+ const bgPositions = [];
213
+ const bgSizes = [];
214
+ const bgOrigins = [];
215
+ const bgClips = [];
216
+ const repeatValues = ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space', 'round'];
217
+ const attachmentValues = ['scroll', 'fixed', 'local'];
218
+ const positionKeywords = ['left', 'center', 'right', 'top', 'bottom'];
219
+ const sizeValues = ['auto', 'cover', 'contain'];
220
+ const boxValues = ['border-box', 'padding-box', 'content-box'];
221
+ layers.forEach(layer => {
222
+ const tokens = [];
223
+ let currentToken = '';
224
+ let parenCount = 0;
225
+ for (let i = 0; i < layer.length; i++) {
226
+ const char = layer[i];
227
+ if (char === '(') {
228
+ parenCount++;
229
+ currentToken += char;
230
+ }
231
+ else if (char === ')') {
232
+ parenCount--;
233
+ currentToken += char;
234
+ if (parenCount === 0) {
235
+ tokens.push(currentToken.trim());
236
+ currentToken = '';
237
+ }
238
+ }
239
+ else if (parenCount === 0 && /\s/.test(char)) {
240
+ if (currentToken.trim())
241
+ tokens.push(currentToken.trim());
242
+ currentToken = '';
243
+ }
244
+ else if (parenCount === 0 && char === '/') {
245
+ if (currentToken.trim())
246
+ tokens.push(currentToken.trim());
247
+ tokens.push('/');
248
+ currentToken = '';
249
+ }
250
+ else {
251
+ currentToken += char;
252
+ }
253
+ }
254
+ if (currentToken.trim())
255
+ tokens.push(currentToken.trim());
256
+ let layerImage = '', layerColor = '', layerRepeat = '', layerAttachment = '';
257
+ let layerPosition = '', layerSize = '', layerOrigin = '', layerClip = '';
258
+ let isAfterSlash = false;
259
+ let i = 0;
260
+ while (i < tokens.length) {
261
+ const token = tokens[i];
262
+ if (token === '/') {
263
+ isAfterSlash = true;
264
+ i++;
265
+ continue;
266
+ }
267
+ if (token.includes('gradient') || token.startsWith('url(') || token === 'none') {
268
+ layerImage = token;
269
+ i++;
270
+ continue;
271
+ }
272
+ if (repeatValues.includes(token)) {
273
+ layerRepeat = layerRepeat ? layerRepeat + ' ' + token : token;
274
+ i++;
275
+ continue;
276
+ }
277
+ if (attachmentValues.includes(token)) {
278
+ layerAttachment = token;
279
+ i++;
280
+ continue;
281
+ }
282
+ if (positionKeywords.includes(token) || /^[+-]?\d+(\.\d+)?(px|em|rem|%)?$/.test(token)) {
283
+ if (isAfterSlash) {
284
+ layerSize = layerSize ? layerSize + ' ' + token : token;
285
+ }
286
+ else {
287
+ layerPosition = layerPosition ? layerPosition + ' ' + token : token;
288
+ }
289
+ i++;
290
+ continue;
291
+ }
292
+ if (sizeValues.includes(token) && isAfterSlash) {
293
+ layerSize = layerSize ? layerSize + ' ' + token : token;
294
+ i++;
295
+ continue;
296
+ }
297
+ if (boxValues.includes(token)) {
298
+ if (!layerOrigin)
299
+ layerOrigin = token;
300
+ else if (!layerClip)
301
+ layerClip = token;
302
+ i++;
303
+ continue;
304
+ }
305
+ if (/^(#[0-9a-fA-F]{3,8}|rgba?\(.*?\)|hsla?\(.*?\)|[a-zA-Z]+)$/.test(token)) {
306
+ layerColor = token;
307
+ i++;
308
+ continue;
309
+ }
310
+ i++;
311
+ }
312
+ if (!layerClip && layerOrigin)
313
+ layerClip = layerOrigin;
314
+ bgImages.push(layerImage || 'none');
315
+ if (layerColor)
316
+ bgColors.push(layerColor);
317
+ bgRepeats.push(layerRepeat || 'repeat');
318
+ bgAttachments.push(layerAttachment || 'scroll');
319
+ bgPositions.push(layerPosition || '0% 0%');
320
+ bgSizes.push(layerSize || 'auto');
321
+ bgOrigins.push(layerOrigin || 'padding-box');
322
+ bgClips.push(layerClip || 'border-box');
323
+ });
324
+ const numLayers = bgImages.length;
325
+ const baseDefaults = {
326
+ 'background-image': 'none', 'background-color': 'transparent', 'background-repeat': 'repeat',
327
+ 'background-attachment': 'scroll', 'background-position': '0% 0%', 'background-size': 'auto',
328
+ 'background-origin': 'padding-box', 'background-clip': 'border-box',
329
+ };
330
+ const defaults = {};
331
+ for (const prop in baseDefaults) {
332
+ defaults[prop] = prop === 'background-color' ? baseDefaults[prop] : Array(numLayers).fill(baseDefaults[prop]).join(', ');
333
+ }
334
+ let conflicts = false;
335
+ const addProp = (key, vals) => {
336
+ const joined = vals.join(', ');
337
+ if (joined !== defaults[key]) {
338
+ expandedProperties[key] = joined;
339
+ overwrittenProperties[key] = joined;
340
+ if (vals.length > 1)
341
+ conflicts = true;
342
+ }
343
+ };
344
+ addProp('background-image', bgImages);
345
+ if (bgColors.length > 0 && bgColors[bgColors.length - 1] !== defaults['background-color']) {
346
+ expandedProperties['background-color'] = bgColors[bgColors.length - 1];
347
+ overwrittenProperties['background-color'] = bgColors[bgColors.length - 1];
348
+ }
349
+ addProp('background-repeat', bgRepeats);
350
+ addProp('background-attachment', bgAttachments);
351
+ addProp('background-position', bgPositions);
352
+ addProp('background-size', bgSizes);
353
+ addProp('background-origin', bgOrigins);
354
+ addProp('background-clip', bgClips);
355
+ if (conflicts) {
356
+ expandedProperties = { background: value };
357
+ overwrittenProperties = { background: value };
358
+ }
359
+ return { matched_properties: expandedProperties, overwritten_properties: overwrittenProperties };
360
+ }
361
+ function expandTransition(value) {
362
+ let expandedProperties = {};
363
+ let overwrittenProperties = {};
364
+ const transitions = splitByComma(value);
365
+ let conflicts = transitions.length > 1;
366
+ const propertiesList = [];
367
+ const durationsList = [];
368
+ const timingFunctionsList = [];
369
+ const delaysList = [];
370
+ const timingFunctionValues = ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'step-start', 'step-end'];
371
+ transitions.forEach(transition => {
372
+ const tokens = tokenizeValue(transition);
373
+ let propertyName = 'all', duration = '0s', timingFunction = 'ease', delay = '0s';
374
+ tokens.forEach(token => {
375
+ if (/^[\d.]+(ms|s)$/.test(token)) {
376
+ if (duration === '0s')
377
+ duration = token;
378
+ else
379
+ delay = token;
380
+ return;
381
+ }
382
+ if (timingFunctionValues.includes(token) || token.startsWith('cubic-bezier') || token.startsWith('steps')) {
383
+ timingFunction = token;
384
+ return;
385
+ }
386
+ propertyName = token;
387
+ });
388
+ propertiesList.push(propertyName);
389
+ durationsList.push(duration);
390
+ timingFunctionsList.push(timingFunction);
391
+ delaysList.push(delay);
392
+ });
393
+ if (propertiesList.join(', ') !== 'all') {
394
+ expandedProperties['transition-property'] = propertiesList.join(', ');
395
+ overwrittenProperties['transition-property'] = propertiesList.join(', ');
396
+ if (propertiesList.length > 1)
397
+ conflicts = true;
398
+ }
399
+ if (durationsList.join(', ') !== '0s') {
400
+ expandedProperties['transition-duration'] = durationsList.join(', ');
401
+ overwrittenProperties['transition-duration'] = durationsList.join(', ');
402
+ if (durationsList.length > 1)
403
+ conflicts = true;
404
+ }
405
+ if (timingFunctionsList.join(', ') !== 'ease') {
406
+ expandedProperties['transition-timing-function'] = timingFunctionsList.join(', ');
407
+ overwrittenProperties['transition-timing-function'] = timingFunctionsList.join(', ');
408
+ if (timingFunctionsList.length > 1)
409
+ conflicts = true;
410
+ }
411
+ if (delaysList.join(', ') !== '0s') {
412
+ expandedProperties['transition-delay'] = delaysList.join(', ');
413
+ overwrittenProperties['transition-delay'] = delaysList.join(', ');
414
+ if (delaysList.length > 1)
415
+ conflicts = true;
416
+ }
417
+ if (conflicts) {
418
+ expandedProperties = { transition: value };
419
+ overwrittenProperties = { transition: value };
420
+ }
421
+ return { matched_properties: expandedProperties, overwritten_properties: overwrittenProperties };
422
+ }
423
+ function expandListStyle(value) {
424
+ let expandedProperties = {};
425
+ let overwrittenProperties = {};
426
+ if (['inherit', 'initial', 'unset'].includes(value.trim())) {
427
+ const v = value.trim();
428
+ return {
429
+ matched_properties: { 'list-style-type': v, 'list-style-position': v, 'list-style-image': v },
430
+ overwritten_properties: { 'list-style-type': v, 'list-style-position': v, 'list-style-image': v },
431
+ };
432
+ }
433
+ const tokens = [];
434
+ let currentToken = '';
435
+ let inUrl = false;
436
+ for (let i = 0; i < value.length; i++) {
437
+ const char = value[i];
438
+ if (char === 'u' && value.slice(i, i + 4) === 'url(') {
439
+ inUrl = true;
440
+ currentToken += 'url(';
441
+ i += 3;
442
+ }
443
+ else if (char === ')' && inUrl) {
444
+ inUrl = false;
445
+ currentToken += ')';
446
+ }
447
+ else if (/\s/.test(char) && !inUrl) {
448
+ if (currentToken.trim()) {
449
+ tokens.push(currentToken.trim());
450
+ currentToken = '';
451
+ }
452
+ }
453
+ else {
454
+ currentToken += char;
455
+ }
456
+ }
457
+ if (currentToken.trim())
458
+ tokens.push(currentToken.trim());
459
+ const typeValues = ['disc', 'circle', 'square', 'decimal', 'decimal-leading-zero', 'lower-roman', 'upper-roman', 'lower-greek', 'lower-latin', 'upper-latin', 'armenian', 'georgian', 'lower-alpha', 'upper-alpha', 'none', 'inherit', 'initial', 'unset'];
460
+ const positionValues = ['inside', 'outside'];
461
+ let listStyleType = '', listStylePosition = '', listStyleImage = '';
462
+ tokens.forEach(token => {
463
+ if (token.startsWith('url('))
464
+ listStyleImage = token;
465
+ else if (positionValues.includes(token))
466
+ listStylePosition = token;
467
+ else if (typeValues.includes(token) || token.startsWith('"') || token.startsWith("'"))
468
+ listStyleType = token;
469
+ else
470
+ listStyleType = token;
471
+ });
472
+ if (!listStyleType)
473
+ listStyleType = 'disc';
474
+ if (!listStylePosition)
475
+ listStylePosition = 'outside';
476
+ if (!listStyleImage)
477
+ listStyleImage = 'none';
478
+ expandedProperties = { 'list-style-type': listStyleType, 'list-style-position': listStylePosition, 'list-style-image': listStyleImage };
479
+ const defaults = { 'list-style-type': 'disc', 'list-style-position': 'outside', 'list-style-image': 'none' };
480
+ let conflicts = false;
481
+ for (const prop in expandedProperties) {
482
+ if (expandedProperties[prop] !== defaults[prop]) {
483
+ overwrittenProperties[prop] = expandedProperties[prop];
484
+ }
485
+ }
486
+ if (tokens.length > 3 || Object.keys(overwrittenProperties).length !== tokens.length) {
487
+ conflicts = true;
488
+ }
489
+ if (conflicts) {
490
+ expandedProperties = {};
491
+ overwrittenProperties = {};
492
+ if (value === 'none') {
493
+ expandedProperties['list-style-type'] = value;
494
+ overwrittenProperties['list-style-type'] = value;
495
+ }
496
+ else {
497
+ expandedProperties['list-style'] = value;
498
+ overwrittenProperties['list-style'] = value;
499
+ }
500
+ }
501
+ return { matched_properties: expandedProperties, overwritten_properties: overwrittenProperties };
502
+ }
503
+ function expandGridColumn(value) {
504
+ const expanded = {};
505
+ const parts = value.trim().split('/').map(p => p.trim());
506
+ if (parts.length === 1) {
507
+ if (value === 'auto') {
508
+ expanded['grid-column-start'] = 'auto';
509
+ expanded['grid-column-end'] = 'auto';
510
+ }
511
+ else if (value.startsWith('span')) {
512
+ expanded['grid-column-start'] = 'auto';
513
+ expanded['grid-column-end'] = value;
514
+ }
515
+ else {
516
+ expanded['grid-column-start'] = value;
517
+ expanded['grid-column-end'] = 'auto';
518
+ }
519
+ }
520
+ else if (parts.length === 2) {
521
+ expanded['grid-column-start'] = parts[0];
522
+ expanded['grid-column-end'] = parts[1];
523
+ }
524
+ return { matched_properties: expanded, overwritten_properties: expanded };
525
+ }
526
+ function expandGridRow(value) {
527
+ const expanded = {};
528
+ const parts = value.trim().split('/').map(p => p.trim());
529
+ if (parts.length === 1) {
530
+ if (value === 'auto') {
531
+ expanded['grid-row-start'] = 'auto';
532
+ expanded['grid-row-end'] = 'auto';
533
+ }
534
+ else if (value.startsWith('span')) {
535
+ expanded['grid-row-start'] = 'auto';
536
+ expanded['grid-row-end'] = value;
537
+ }
538
+ else {
539
+ expanded['grid-row-start'] = value;
540
+ expanded['grid-row-end'] = 'auto';
541
+ }
542
+ }
543
+ else if (parts.length === 2) {
544
+ expanded['grid-row-start'] = parts[0];
545
+ expanded['grid-row-end'] = parts[1];
546
+ }
547
+ return { matched_properties: expanded, overwritten_properties: expanded };
548
+ }
549
+ function expandGridTemplate(value) {
550
+ const expanded = {};
551
+ if (value === 'none') {
552
+ expanded['grid-template-rows'] = 'none';
553
+ expanded['grid-template-columns'] = 'none';
554
+ expanded['grid-template-areas'] = 'none';
555
+ return { matched_properties: expanded, overwritten_properties: expanded };
556
+ }
557
+ const parts = value.split(/(['"].*?['"])/g).filter(Boolean);
558
+ const areaStrings = [];
559
+ const rowTrackList = [];
560
+ let columnTrackList = '';
561
+ parts.forEach(part => {
562
+ if (part.trim().startsWith('"') || part.trim().startsWith("'")) {
563
+ areaStrings.push(part.trim().replace(/['"]/g, ''));
564
+ }
565
+ else {
566
+ const tracks = part.trim().split('/');
567
+ if (tracks.length > 1) {
568
+ columnTrackList = tracks.pop().trim();
569
+ }
570
+ const rowTracks = tracks.join(' ').trim();
571
+ if (rowTracks)
572
+ rowTrackList.push(rowTracks);
573
+ }
574
+ });
575
+ if (areaStrings.length > 0)
576
+ expanded['grid-template-areas'] = `"${areaStrings.join('" "')}"`;
577
+ if (rowTrackList.length > 0)
578
+ expanded['grid-template-rows'] = rowTrackList.join(' ');
579
+ if (columnTrackList)
580
+ expanded['grid-template-columns'] = columnTrackList;
581
+ return { matched_properties: expanded, overwritten_properties: expanded };
582
+ }
583
+ function expandGridArea(value) {
584
+ const expanded = {};
585
+ const parts = value.trim().split('/').map(p => p.trim());
586
+ if (parts.length === 1 && !parts[0].includes('span') && isNaN(Number(parts[0]))) {
587
+ expanded['grid-row-start'] = parts[0];
588
+ expanded['grid-column-start'] = parts[0];
589
+ expanded['grid-row-end'] = parts[0];
590
+ expanded['grid-column-end'] = parts[0];
591
+ }
592
+ else {
593
+ switch (parts.length) {
594
+ case 1:
595
+ expanded['grid-row-start'] = parts[0];
596
+ expanded['grid-column-start'] = parts[0];
597
+ expanded['grid-row-end'] = 'auto';
598
+ expanded['grid-column-end'] = 'auto';
599
+ break;
600
+ case 2:
601
+ expanded['grid-row-start'] = parts[0];
602
+ expanded['grid-column-start'] = parts[1];
603
+ expanded['grid-row-end'] = 'auto';
604
+ expanded['grid-column-end'] = 'auto';
605
+ break;
606
+ case 3:
607
+ expanded['grid-row-start'] = parts[0];
608
+ expanded['grid-column-start'] = parts[1];
609
+ expanded['grid-row-end'] = parts[2];
610
+ expanded['grid-column-end'] = 'auto';
611
+ break;
612
+ case 4:
613
+ expanded['grid-row-start'] = parts[0];
614
+ expanded['grid-column-start'] = parts[1];
615
+ expanded['grid-row-end'] = parts[2];
616
+ expanded['grid-column-end'] = parts[3];
617
+ break;
618
+ }
619
+ }
620
+ return { matched_properties: expanded, overwritten_properties: expanded };
621
+ }
622
+ function expandPlaceProperty(value, alignProp, justifyProp) {
623
+ const expanded = {};
624
+ const values = value.trim().split(/\s+/);
625
+ if (values.length === 1) {
626
+ expanded[alignProp] = values[0];
627
+ expanded[justifyProp] = values[0];
628
+ }
629
+ else if (values.length === 2) {
630
+ expanded[alignProp] = values[0];
631
+ expanded[justifyProp] = values[1];
632
+ }
633
+ return { matched_properties: expanded, overwritten_properties: expanded };
634
+ }
635
+ function expandFlexFlow(value) {
636
+ const [firstValue, secondValue] = value.trim().split(/\s+/);
637
+ const expanded = {};
638
+ const directionValues = ['row', 'row-reverse', 'column', 'column-reverse'];
639
+ const wrapValues = ['nowrap', 'wrap', 'wrap-reverse'];
640
+ if (firstValue) {
641
+ if (directionValues.includes(firstValue)) {
642
+ expanded['flex-direction'] = firstValue;
643
+ if (!secondValue)
644
+ expanded['flex-wrap'] = 'nowrap';
645
+ }
646
+ else if (wrapValues.includes(firstValue)) {
647
+ expanded['flex-wrap'] = firstValue;
648
+ if (!secondValue)
649
+ expanded['flex-direction'] = 'row';
650
+ }
651
+ }
652
+ if (secondValue) {
653
+ if (directionValues.includes(secondValue))
654
+ expanded['flex-direction'] = secondValue;
655
+ else if (wrapValues.includes(secondValue))
656
+ expanded['flex-wrap'] = secondValue;
657
+ }
658
+ return { matched_properties: expanded, overwritten_properties: expanded };
659
+ }
660
+ function expandBorder(property, value) {
661
+ let expandedProperties = {};
662
+ let overwrittenProperties = {};
663
+ let widthProp = 'border-width', styleProp = 'border-style', colorProp = 'border-color';
664
+ if (property !== 'border') {
665
+ const side = property.split('-')[1];
666
+ widthProp = `border-${side}-width`;
667
+ styleProp = `border-${side}-style`;
668
+ colorProp = `border-${side}-color`;
669
+ }
670
+ if (['inherit', 'initial', 'unset', 'revert'].includes(value.trim())) {
671
+ const v = value.trim();
672
+ return {
673
+ matched_properties: { [widthProp]: v, [styleProp]: v, [colorProp]: v },
674
+ overwritten_properties: { [widthProp]: v, [styleProp]: v, [colorProp]: v },
675
+ };
676
+ }
677
+ if (value.trim() === 'none') {
678
+ return {
679
+ matched_properties: { [widthProp]: '0', [styleProp]: 'none', [colorProp]: 'currentColor' },
680
+ overwritten_properties: { [widthProp]: '0', [styleProp]: 'none', [colorProp]: 'currentColor' },
681
+ };
682
+ }
683
+ const tokens = tokenizeValue(value);
684
+ const borderStyleValues = ['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'];
685
+ const borderWidthKeywords = ['thin', 'medium', 'thick'];
686
+ let borderWidth = '', borderStyle = '', borderColor = '';
687
+ for (const token of tokens) {
688
+ if (borderStyleValues.includes(token.toLowerCase())) {
689
+ borderStyle = token;
690
+ continue;
691
+ }
692
+ if (borderWidthKeywords.includes(token.toLowerCase()) ||
693
+ /^[+-]?(\d+(\.\d+)?|\.\d+)(px|em|rem|%|vh|vw|vmin|vmax|in|cm|mm|pt|pc|ex|ch|lh|rlh|q)?$/i.test(token)) {
694
+ borderWidth = token;
695
+ continue;
696
+ }
697
+ borderColor = token;
698
+ }
699
+ if (!borderStyle)
700
+ borderStyle = 'none';
701
+ if (!borderWidth)
702
+ borderWidth = 'medium';
703
+ if (!borderColor)
704
+ borderColor = 'currentColor';
705
+ expandedProperties = { [widthProp]: borderWidth, [styleProp]: borderStyle, [colorProp]: borderColor };
706
+ const defaults = { [widthProp]: 'medium', [styleProp]: 'none', [colorProp]: 'currentColor' };
707
+ for (const prop in expandedProperties) {
708
+ if (expandedProperties[prop] !== defaults[prop]) {
709
+ overwrittenProperties[prop] = expandedProperties[prop];
710
+ }
711
+ }
712
+ return { matched_properties: expandedProperties, overwritten_properties: overwrittenProperties };
713
+ }
714
+ function expandSpacing(property, value) {
715
+ const expandedProperties = {};
716
+ const overwrittenProperties = {};
717
+ const sides = ['top', 'right', 'bottom', 'left'];
718
+ const properties = sides.map(side => `${property}-${side}`);
719
+ if (['inherit', 'initial', 'unset', 'revert'].includes(value.trim())) {
720
+ const v = value.trim();
721
+ properties.forEach(prop => { expandedProperties[prop] = v; overwrittenProperties[prop] = v; });
722
+ return { matched_properties: expandedProperties, overwritten_properties: overwrittenProperties };
723
+ }
724
+ const tokens = value.trim().split(/\s+/);
725
+ let values;
726
+ if (tokens.length === 1)
727
+ values = [tokens[0], tokens[0], tokens[0], tokens[0]];
728
+ else if (tokens.length === 2)
729
+ values = [tokens[0], tokens[1], tokens[0], tokens[1]];
730
+ else if (tokens.length === 3)
731
+ values = [tokens[0], tokens[1], tokens[2], tokens[1]];
732
+ else if (tokens.length === 4)
733
+ values = [tokens[0], tokens[1], tokens[2], tokens[3]];
734
+ else
735
+ return null;
736
+ properties.forEach((prop, index) => {
737
+ expandedProperties[prop] = values[index];
738
+ overwrittenProperties[prop] = values[index];
739
+ });
740
+ return { matched_properties: expandedProperties, overwritten_properties: overwrittenProperties };
741
+ }
742
+ function expandAnimation(value) {
743
+ let expandedProperties = {};
744
+ let overwrittenProperties = {};
745
+ const animations = splitByComma(value);
746
+ const names = [], durations = [], timingFunctions = [], delays = [];
747
+ const iterationCounts = [], directions = [], fillModes = [], playStates = [];
748
+ const timingFunctionValues = ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'step-start', 'step-end'];
749
+ const directionValues = ['normal', 'reverse', 'alternate', 'alternate-reverse'];
750
+ const fillModeValues = ['none', 'forwards', 'backwards', 'both'];
751
+ const playStateValues = ['running', 'paused'];
752
+ animations.forEach(animation => {
753
+ const tokens = tokenizeValue(animation);
754
+ let name = 'none', duration = '0s', timingFunction = 'ease', delay = '0s';
755
+ let iterationCount = '1', direction = 'normal', fillMode = 'none', playState = 'running';
756
+ tokens.forEach(token => {
757
+ if (/^[\d.]+(s|ms)$/.test(token)) {
758
+ if (!duration || duration === '0s')
759
+ duration = token;
760
+ else
761
+ delay = token;
762
+ return;
763
+ }
764
+ if (timingFunctionValues.includes(token) || token.includes('cubic-bezier') || token.includes('steps')) {
765
+ timingFunction = token;
766
+ return;
767
+ }
768
+ if (token === 'infinite' || /^\d+$/.test(token)) {
769
+ iterationCount = token;
770
+ return;
771
+ }
772
+ if (directionValues.includes(token)) {
773
+ direction = token;
774
+ return;
775
+ }
776
+ if (fillModeValues.includes(token)) {
777
+ fillMode = token;
778
+ return;
779
+ }
780
+ if (playStateValues.includes(token)) {
781
+ playState = token;
782
+ return;
783
+ }
784
+ if (token !== 'none')
785
+ name = token;
786
+ });
787
+ names.push(name);
788
+ durations.push(duration);
789
+ timingFunctions.push(timingFunction);
790
+ delays.push(delay);
791
+ iterationCounts.push(iterationCount);
792
+ directions.push(direction);
793
+ fillModes.push(fillMode);
794
+ playStates.push(playState);
795
+ });
796
+ const addIfNotDefault = (key, vals, defaultVal) => {
797
+ if (vals.join(', ') !== defaultVal) {
798
+ expandedProperties[key] = vals.join(', ');
799
+ overwrittenProperties[key] = vals.join(', ');
800
+ }
801
+ };
802
+ addIfNotDefault('animation-name', names, 'none');
803
+ addIfNotDefault('animation-duration', durations, '0s');
804
+ addIfNotDefault('animation-timing-function', timingFunctions, 'ease');
805
+ addIfNotDefault('animation-delay', delays, '0s');
806
+ addIfNotDefault('animation-iteration-count', iterationCounts, '1');
807
+ addIfNotDefault('animation-direction', directions, 'normal');
808
+ addIfNotDefault('animation-fill-mode', fillModes, 'none');
809
+ addIfNotDefault('animation-play-state', playStates, 'running');
810
+ return { matched_properties: expandedProperties, overwritten_properties: overwrittenProperties };
811
+ }
812
+ //# sourceMappingURL=shorthand-expander.js.map