@gesslar/sassy 2.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,11 +33,16 @@ Write themes like a human, compile for VS Code:
33
33
  **After (Sassy):**
34
34
 
35
35
  ```yaml
36
+ palette:
37
+ blue: "#4b8ebd"
38
+ white: "#e6e6e6"
39
+ dark: "#1a1a1a"
40
+
36
41
  vars:
37
- accent: "#4b8ebd"
42
+ accent: $$blue
38
43
  std:
39
- fg: "#e6e6e6"
40
- bg: "#1a1a1a"
44
+ fg: $$white
45
+ bg: $$dark
41
46
  bg.panel: lighten($(std.bg), 15)
42
47
  bg.accent: darken($(accent), 15)
43
48
 
@@ -233,16 +238,23 @@ config:
233
238
  name: "My Awesome Theme"
234
239
  type: dark
235
240
 
241
+ palette:
242
+ # Raw colour values — self-contained, evaluated first
243
+ blue: "#4b8ebd"
244
+ green: "#4ab792"
245
+ red: "#b74a4a"
246
+ white: "#e6e6e6"
247
+ dark: "#1a1a1a"
248
+
236
249
  vars:
237
- # Your colour palette
238
- primary: "#4b8ebd"
239
- success: "#4ab792"
240
- error: "#b74a4a"
250
+ # Semantic relationships referencing palette via $$
251
+ primary: $$blue
252
+ success: $$green
253
+ error: $$red
241
254
 
242
- # Build semantic relationships
243
255
  std:
244
- fg: "#e6e6e6"
245
- bg: "#1a1a1a"
256
+ fg: $$white
257
+ bg: $$dark
246
258
  accent: $(primary)
247
259
  bg.accent: darken($(accent), 15)
248
260
 
@@ -271,17 +283,18 @@ While Sassy provides common functions like `lighten()`, `darken()`, and
271
283
  `mix()`, you have access to the entire spectrum of colour formats:
272
284
 
273
285
  ```yaml
274
- vars:
286
+ palette:
275
287
  # Use any colour space Culori understands
276
288
  lab_colour: lab(50 20 -30) # LAB colour space
277
289
  hwb_colour: hwb(180 30% 20%) # HWB (Hue-Whiteness-Blackness)
278
290
  lch_colour: lch(70 40 180) # LCH colour space
279
291
  p3_colour: color(display-p3 0.4 0.8 0.2) # Display P3 gamut
280
292
  rec2020: color(rec2020 0.42 0.85 0.31) # Rec. 2020 colour space
293
+ primary: oklch(0.6, 20, 220)
281
294
 
295
+ vars:
282
296
  # Mix and match freely
283
- primary: oklch(0.6, 20, 220)
284
- secondary: mix($(primary), lab(80 -20 40), 30)
297
+ secondary: mix($$primary, lab(80 -20 40), 30)
285
298
  accent: lighten(hwb(240 20% 10%), 15)
286
299
  ```
287
300
 
@@ -326,15 +339,16 @@ function (`rgba(255, 100, 200, 0.5)`, `darken($(bg), 20)`,
326
339
  Use CSS colour names with the `css()` function:
327
340
 
328
341
  ```yaml
329
- vars:
342
+ palette:
330
343
  # CSS named colours
331
344
  danger: css(crimson)
332
345
  ocean: css(deepskyblue)
333
346
  nature: css(forestgreen)
334
347
 
335
- # Mix named colours with functions
336
- muted_red: fade(css(tomato), 0.6)
337
- light_blue: lighten(css(navy), 40)
348
+ vars:
349
+ # Mix palette colours with functions
350
+ muted_red: fade($$danger, 0.6)
351
+ light_blue: lighten($$ocean, 40)
338
352
  ```
339
353
 
340
354
  > **Reference:** See the complete list of CSS named colours at [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/named-color) or [Wikipedia](https://en.wikipedia.org/wiki/Web_colors#HTML_color_names).
@@ -353,6 +367,24 @@ vars:
353
367
  variant3: ${accent} # Braced form
354
368
  ```
355
369
 
370
+ ### Palette Aliases
371
+
372
+ The `$$` prefix is shorthand for referencing `palette.*` values:
373
+
374
+ ```yaml
375
+ palette:
376
+ cyan: "#56b6c2"
377
+
378
+ vars:
379
+ # All equivalent — resolve to palette.cyan:
380
+ a: $$cyan
381
+ b: $($cyan)
382
+ c: ${$cyan}
383
+ ```
384
+
385
+ This expansion happens before any variable resolution, so downstream tools
386
+ (resolve, lint) see the canonical `$palette.cyan` form.
387
+
356
388
  ## Theme Development Workflow
357
389
 
358
390
  ### 1. Create Your Theme File
@@ -400,13 +432,12 @@ extension.
400
432
  Break your themes into reusable components using the import system:
401
433
 
402
434
  ```yaml
403
- # colours.yaml
404
- vars:
405
- palette:
406
- primary: "#4b8ebd"
407
- success: "#4ab792"
408
- error: "#b74a4a"
409
- warning: "#b36b47"
435
+ # palette.yaml
436
+ palette:
437
+ blue: "#4b8ebd"
438
+ green: "#4ab792"
439
+ red: "#b74a4a"
440
+ orange: "#b36b47"
410
441
 
411
442
  ---
412
443
 
@@ -415,11 +446,11 @@ config:
415
446
  name: "My Theme"
416
447
  type: dark
417
448
  import:
418
- - "./colours.yaml"
449
+ - "./palette.yaml"
419
450
 
420
451
  vars:
421
- # Use imported colours
422
- accent: $(palette.primary)
452
+ # Use imported palette via $$ alias
453
+ accent: $$blue
423
454
 
424
455
  # Build your design system
425
456
  std:
@@ -459,7 +490,7 @@ Imports are a simple array of file paths. Each file gets merged into your theme:
459
490
 
460
491
  The merge behaviour depends on the type of theme content:
461
492
 
462
- **Objects (composable):** `colors`, `semanticTokenColors`, `vars`, `config`
493
+ **Objects (composable):** `palette`, `colors`, `semanticTokenColors`, `vars`, `config`
463
494
 
464
495
  1. Imported files (merged in import order)
465
496
  2. Your theme file's own definitions (final override)
@@ -499,41 +530,40 @@ Now edit your YAML file and watch VS Code update automatically!
499
530
  ### Start with Meaning, Not Colours
500
531
 
501
532
  ```yaml
502
- # Don't start with random colours
503
- vars:
504
- red: "#ff0000"
505
- blue: "#0000ff"
533
+ # Raw colours go in palette
534
+ palette:
535
+ red: "#b74a4a"
536
+ green: "#4ab792"
537
+ dark: "#1a1a1a"
506
538
 
507
- # ✅ Start with semantic meaning
539
+ # ✅ Semantic meaning goes in vars
508
540
  vars:
509
541
  status:
510
- error: "#b74a4a"
511
- success: "#4ab792"
542
+ error: $$red
543
+ success: $$green
512
544
 
513
545
  ui:
514
- background: "#1a1a1a"
546
+ background: $$dark
515
547
  surface: lighten($(ui.background), 15)
516
548
  ```
517
549
 
518
550
  ### Use Mathematical Relationships
519
551
 
520
552
  ```yaml
521
- # Colours that harmonize automatically
522
- vars:
553
+ palette:
523
554
  base: "#4b8ebd"
555
+ gray: "#808080"
556
+ # OKLCH for perceptually uniform colours
557
+ primary: oklch(0.6, 20, 220)
558
+ accent: oklch(0.7, 25, 45)
524
559
 
560
+ vars:
561
+ # Colours that harmonize automatically
525
562
  harmonies:
526
- lighter: lighten($(base), 20)
527
- darker: darken($(base), 20)
528
- complement: mix($(base), invert($(base)), 50)
529
- muted: mix($(base), "#808080", 30)
530
-
531
- # OKLCH colours for perceptually uniform adjustments
532
- oklch_palette:
533
- primary: oklch(0.6, 20, 220) # Blue with controlled chroma
534
- accent: oklch(0.7, 25, 45) # Warm orange complement
535
- muted: oklch(0.5, 8, 220) # Desaturated blue
536
- bright: oklcha(0.8, 30, 220, 0.9) # Bright blue with transparency
563
+ lighter: lighten($$base, 20)
564
+ darker: darken($$base, 20)
565
+ complement: mix($$base, invert($$base), 50)
566
+ muted: mix($$base, $$gray, 30)
537
567
  ```
538
568
 
539
569
  ### Test with Real Code
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "gesslar",
6
6
  "url": "https://gesslar.dev"
7
7
  },
8
- "version": "2.0.1",
8
+ "version": "3.1.0",
9
9
  "license": "Unlicense",
10
10
  "homepage": "https://github.com/gesslar/sassy#readme",
11
11
  "repository": {
@@ -44,10 +44,10 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@gesslar/colours": "^0.8.0",
47
- "@gesslar/toolkit": "^3.30.0",
47
+ "@gesslar/toolkit": "^3.31.0",
48
48
  "chokidar": "^5.0.0",
49
49
  "color-support": "^1.1.3",
50
- "commander": "^14.0.2",
50
+ "commander": "^14.0.3",
51
51
  "culori": "^4.0.2",
52
52
  "globby": "^16.1.0",
53
53
  "json5": "^2.2.3",
package/src/Compiler.js CHANGED
@@ -35,6 +35,7 @@ export default class Compiler {
35
35
  try {
36
36
  const source = theme.getSource()
37
37
  const {config: sourceConfig} = source ?? {}
38
+ const {palette: sourcePalette} = source
38
39
  const {vars: sourceVars} = source
39
40
  const {theme: sourceTheme} = source
40
41
 
@@ -71,6 +72,7 @@ export default class Compiler {
71
72
  const merged = Data.mergeObject({},
72
73
  imported,
73
74
  {
75
+ palette: sourcePalette ?? {},
74
76
  vars: sourceVars ?? {},
75
77
  colors: sourceTheme?.colors ?? {},
76
78
  semanticTokenColors: sourceTheme?.semanticTokenColors ?? {},
@@ -80,6 +82,11 @@ export default class Compiler {
80
82
  // Add tokenColors after merging to avoid mergeObject processing
81
83
  merged.tokenColors = mergedTokenColors
82
84
 
85
+ // Palette first — self-contained, cannot reach outside itself
86
+ const palette = this.#decomposeObject({palette: merged.palette ?? {}})
87
+
88
+ evaluate(palette)
89
+
83
90
  // Shred them up! Kinda. And evaluate the variables in place
84
91
  const vars = this.#decomposeObject(merged.vars)
85
92
 
@@ -110,7 +117,7 @@ export default class Compiler {
110
117
  // Assemble into one object with the proper keys
111
118
  const colors = workColors.reduce(reducer, {})
112
119
  const tokenColors = this.#composeArray(workTokenColors)
113
- const semanticTokenColors = workSemanticTokenColors.reduce(reducer, {})
120
+ const semanticTokenColors = this.#composeObject(workSemanticTokenColors)
114
121
 
115
122
  // Mix and maaatch all jumbly wumbly...
116
123
  const output = Data.mergeObject(
@@ -142,6 +149,7 @@ export default class Compiler {
142
149
  */
143
150
  async #import(imports, theme) {
144
151
  const imported = {
152
+ palette: {},
145
153
  vars: {},
146
154
  colors: {},
147
155
  tokenColors: [],
@@ -191,18 +199,22 @@ export default class Compiler {
191
199
  }
192
200
 
193
201
  loaded.forEach((load, file) => {
202
+ const palette = load?.palette ?? {}
194
203
  const vars = load?.vars ?? {}
195
204
  const colors = load?.theme?.colors ?? {}
196
205
  const tokenColors = load?.theme?.tokenColors ?? []
197
206
  const semanticTokenColors = load?.theme?.semanticTokenColors ?? {}
198
207
 
199
208
  importByFile.set(file, new Map([
209
+ ["palette", palette],
200
210
  ["vars", vars],
201
211
  ["colors", colors],
202
212
  ["tokenColors", tokenColors],
203
213
  ["semanticTokenColors", semanticTokenColors]
204
214
  ]))
205
215
 
216
+ imported.palette =
217
+ Data.mergeObject(imported.palette, palette)
206
218
  imported.vars =
207
219
  Data.mergeObject(imported.vars, vars)
208
220
  imported.colors =
package/src/Evaluator.js CHANGED
@@ -92,6 +92,35 @@ export default class Evaluator {
92
92
  return this.#pool
93
93
  }
94
94
 
95
+ /**
96
+ * Regular expression for expanding palette alias syntax. The `$` prefix
97
+ * inside variable references is shorthand for `palette.`:
98
+ * - `$$name` → `$palette.name`
99
+ * - `$($name)` → `$(palette.name)`
100
+ * - `${$name}` → `${palette.name}`
101
+ *
102
+ * @type {RegExp}
103
+ */
104
+ static paletteAlias = /\$\(\$([^()]+)\)|\$\{\$([^{}]+)\}|\$\$([\w]+(?:\.[\w]+)*)/g
105
+
106
+ /**
107
+ * Expands palette alias references in a string value.
108
+ * Converts `$$name`, `$($name)`, and `${$name}` to their
109
+ * full `palette.` equivalents before variable resolution.
110
+ *
111
+ * @param {string} value - The string potentially containing palette aliases
112
+ * @returns {string} The string with palette aliases expanded
113
+ */
114
+ static expandPaletteAliases(value) {
115
+ return value.replace(Evaluator.paletteAlias, (match, parens, braces, bare) => {
116
+ if(parens) return `$(palette.${parens})`
117
+ if(braces) return `\${palette.${braces}}`
118
+ if(bare) return `$palette.${bare}`
119
+
120
+ return match
121
+ })
122
+ }
123
+
95
124
  /**
96
125
  * Resolve variables and theme token entries in two distinct passes to ensure
97
126
  * deterministic scoping and to prevent partially-resolved values from
@@ -126,6 +155,12 @@ export default class Evaluator {
126
155
  * // decomposed[2].value === '#5588dd' (lightened color)
127
156
  */
128
157
  evaluate(decomposed) {
158
+ // Expand palette aliases before resolution
159
+ decomposed.forEach(item => {
160
+ if(typeof item.value === "string")
161
+ item.value = Evaluator.expandPaletteAliases(item.value)
162
+ })
163
+
129
164
  let it = 0
130
165
 
131
166
  do {
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Command handler for building VS Code themes from source files.
3
+ * Handles compilation, watching for changes, and output generation.
4
+ */
5
+ export default class BuildCommand extends Command {
6
+ /**
7
+ * Creates a new BuildCommand instance.
8
+ *
9
+ * @param {object} base - Base configuration object
10
+ * @param {string} base.cwd - Current working directory path
11
+ * @param {object} base.packageJson - Package.json configuration data
12
+ */
13
+ constructor(base: {
14
+ cwd: string;
15
+ packageJson: object;
16
+ });
17
+ /** @type {EventEmitter} Internal event emitter for watch mode coordination */
18
+ emitter: EventEmitter;
19
+ /**
20
+ * Emits an event asynchronously using the internal emitter.
21
+ * This method wraps Util.asyncEmit for convenience.
22
+ *
23
+ * @param {string} event - The event name to emit
24
+ * @param {...any} args - Arguments to pass to the event handlers
25
+ * @returns {Promise<void>} Resolves when all event handlers have completed
26
+ */
27
+ asyncEmit(event: string, ...args: any[]): Promise<void>;
28
+ /**
29
+ * @typedef {object} BuildCommandOptions
30
+ * @property {boolean} [watch] - Enable watch mode for file changes
31
+ * @property {string} [outputDir] - Custom output directory path
32
+ * @property {boolean} [dryRun] - Print JSON to stdout without writing files
33
+ * @property {boolean} [silent] - Silent mode, only show errors or dry-run output
34
+ */
35
+ /**
36
+ * Executes the build command for the provided theme files.
37
+ * Processes each file in parallel, optionally watching for changes.
38
+ *
39
+ * @param {Array<string>} fileNames - Array of theme file paths to process
40
+ * @param {BuildCommandOptions} options - {@link BuildCommandOptions}
41
+ * @returns {Promise<void>} Resolves when all files are processed
42
+ * @throws {Error} When theme compilation fails
43
+ */
44
+ execute(fileNames: Array<string>, options: {
45
+ /**
46
+ * - Enable watch mode for file changes
47
+ */
48
+ watch?: boolean;
49
+ /**
50
+ * - Custom output directory path
51
+ */
52
+ outputDir?: string;
53
+ /**
54
+ * - Print JSON to stdout without writing files
55
+ */
56
+ dryRun?: boolean;
57
+ /**
58
+ * - Silent mode, only show errors or dry-run output
59
+ */
60
+ silent?: boolean;
61
+ }): Promise<void>;
62
+ #private;
63
+ }
64
+ import Command from "./Command.js";
65
+ //# sourceMappingURL=BuildCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildCommand.d.ts","sourceRoot":"","sources":["../src/BuildCommand.js"],"names":[],"mappings":"AAQA;;;GAGG;AACH;IAOE;;;;;;OAMG;IACH,kBAHG;QAAqB,GAAG,EAAhB,MAAM;QACO,WAAW,EAAxB,MAAM;KAChB,EAWA;IAvBD,8EAA8E;IAC9E,SADW,YAAY,CACK;IAwB5B;;;;;;;OAOG;IACH,iBAJW,MAAM,WACH,GAAG,EAAA,GACJ,OAAO,CAAC,IAAI,CAAC,CAIzB;IAED;;;;;;OAMG;IAEH;;;;;;;;OAQG;IACH,mBALW,KAAK,CAAC,MAAM,CAAC;;;;gBAVV,OAAO;;;;oBACP,MAAM;;;;iBACN,OAAO;;;;iBACP,OAAO;QASR,OAAO,CAAC,IAAI,CAAC,CAmCzB;;CAuFF;oBAtLmB,cAAc"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Colour manipulation utility class providing static methods for colour operations.
3
+ * Handles hex colour parsing, alpha manipulation, mixing, and format conversions.
4
+ */
5
+ export default class Colour {
6
+ /**
7
+ * Regular expression for matching long hex colour codes with optional alpha.
8
+ * Matches patterns like #ff0000 or #ff0000ff
9
+ *
10
+ * @type {RegExp}
11
+ */
12
+ static longHex: RegExp;
13
+ /**
14
+ * Regular expression for matching short hex colour codes with optional alpha.
15
+ * Matches patterns like #f00 or #f00f
16
+ *
17
+ * @type {RegExp}
18
+ */
19
+ static shortHex: RegExp;
20
+ /**
21
+ * Lightens or darkens a hex colour by a specified amount.
22
+ * Always uses OKLCH as the working color space for consistent perceptual results.
23
+ *
24
+ * @param {string} hex - The hex colour code (e.g., "#ff0000" or "#f00")
25
+ * @param {number} amount - The amount to lighten (+) or darken (-) as a percentage
26
+ * @returns {string} The modified hex colour with preserved alpha
27
+ */
28
+ static lightenOrDarken(hex: string, amount?: number): string;
29
+ /**
30
+ * Lightens or darkens a color using OKLCH as working space for consistent results.
31
+ * Preserves original color information from tokens when available.
32
+ *
33
+ * @param {ThemeToken|object|string} tokenOrColor - ThemeToken, Culori color object, or hex string
34
+ * @param {number} amount - The amount to lighten (+) or darken (-) as a percentage
35
+ * @returns {string} The modified hex colour
36
+ */
37
+ static lightenOrDarkenWithToken(tokenOrColor: converter | object | string, amount?: number): string;
38
+ /**
39
+ * Inverts a hex colour by flipping its lightness value.
40
+ * Preserves hue and saturation while inverting the lightness component.
41
+ *
42
+ * @param {string} hex - The hex colour code to invert
43
+ * @returns {string} The inverted hex colour with preserved alpha
44
+ */
45
+ static invert(hex: string): string;
46
+ /**
47
+ * Converts a hex alpha value to a decimal percentage.
48
+ * Takes a 2-digit hex alpha value and converts it to a percentage (0-100).
49
+ *
50
+ * @param {string} hex - The hex alpha value (e.g., "ff", "80")
51
+ * @returns {number} The alpha as a percentage rounded to 2 decimal places
52
+ */
53
+ static hexAlphaToDecimal(hex: string): number;
54
+ /**
55
+ * Converts a decimal percentage to a hex alpha value.
56
+ * Takes a percentage (0-100) and converts it to a 2-digit hex alpha value.
57
+ *
58
+ * @param {number} dec - The alpha percentage (0-100)
59
+ * @returns {string} The hex alpha value (e.g., "ff", "80")
60
+ */
61
+ static decimalAlphaToHex(dec: number): string;
62
+ static isHex(value: any): boolean;
63
+ /**
64
+ * Normalises a short hex colour code to a full 6-character format.
65
+ * Converts 3-character hex codes like "#f00" to "#ff0000".
66
+ *
67
+ * @param {string} code - The short hex colour code
68
+ * @returns {string} The normalized 6-character hex colour code
69
+ */
70
+ static normaliseHex(code: string): string;
71
+ /**
72
+ * Parses a hex colour string and extracts colour and alpha components.
73
+ * Supports both short (#f00) and long (#ff0000) formats with optional alpha.
74
+ *
75
+ * @param {string} hex - The hex colour string to parse
76
+ * @returns {object} Object containing colour and optional alpha information
77
+ * @throws {Sass} If the hex value is invalid or missing
78
+ */
79
+ static parseHexColour(hex: string): object;
80
+ /**
81
+ * Sets the alpha transparency of a hex colour to a specific value.
82
+ * Replaces any existing alpha with the new value.
83
+ *
84
+ * @param {string} hex - The hex colour code
85
+ * @param {number} amount - The alpha value (0-1, where 0 is transparent and 1 is opaque)
86
+ * @returns {string} The hex colour with the new alpha value
87
+ */
88
+ static setAlpha(hex: string, amount: number): string;
89
+ /**
90
+ * Adjusts the alpha transparency of a hex colour by a relative amount.
91
+ * Multiplies the current alpha by (1 + amount) and clamps the result.
92
+ *
93
+ * @param {string} hex - The hex colour code
94
+ * @param {number} amount - The relative amount to adjust alpha (-1 to make transparent, positive to increase)
95
+ * @returns {string} The hex colour with adjusted alpha
96
+ */
97
+ static addAlpha(hex: string, amount: number): string;
98
+ /**
99
+ * Removes alpha channel from a hex colour, returning only the solid colour.
100
+ *
101
+ * @param {string} hex - The hex colour code with or without alpha
102
+ * @returns {string} The solid hex colour without alpha
103
+ */
104
+ static solid(hex: string): string;
105
+ /**
106
+ * Mixes two hex colours together in a specified ratio.
107
+ * Blends both the colours and their alpha channels if present.
108
+ *
109
+ * @param {string} colourA - The first hex colour
110
+ * @param {string} colourB - The second hex colour
111
+ * @param {number} ratio - The mixing ratio as percentage (0-100, where 50 is equal mix)
112
+ * @returns {string} The mixed hex colour with blended alpha
113
+ */
114
+ static mix(colourA: string, colourB: string, ratio?: number): string;
115
+ static getColourParser(name: any): Promise<any>;
116
+ /**
117
+ * Converts colour values from various formats to hex.
118
+ * Supports RGB, RGBA, HSL, HSLA, OKLCH, and OKLCHA colour modes, and MORE!
119
+ *
120
+ * @param {string} input - The colour expression
121
+ * @returns {string} The resulting hex colour
122
+ * @throws {Sass} If the wrong function or value is provided
123
+ */
124
+ static toHex(input: string): string;
125
+ }
126
+ //# sourceMappingURL=Colour.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Colour.d.ts","sourceRoot":"","sources":["../src/Colour.js"],"names":[],"mappings":"AA2GA;;;GAGG;AACH;IACE;;;;;OAKG;IACH,gBAFU,MAAM,CAEmD;IAEnE;;;;;OAKG;IACH,iBAFU,MAAM,CAEoD;IAEpE;;;;;;;OAOG;IACH,4BAJW,MAAM,WACN,MAAM,GACJ,MAAM,CAiBlB;IAED;;;;;;;OAOG;IACH,8CAJW,SAAU,GAAC,MAAM,GAAC,MAAM,WACxB,MAAM,GACJ,MAAM,CA6BlB;IAED;;;;;;OAMG;IACH,mBAHW,MAAM,GACJ,MAAM,CAYlB;IAED;;;;;;OAMG;IACH,8BAHW,MAAM,GACJ,MAAM,CAWlB;IAED;;;;;;OAMG;IACH,8BAHW,MAAM,GACJ,MAAM,CAWlB;IAED,kCAGC;IAED;;;;;;OAMG;IACH,0BAHW,MAAM,GACJ,MAAM,CAgBlB;IAED;;;;;;;OAOG;IACH,2BAJW,MAAM,GACJ,MAAM,CA8BlB;IAED;;;;;;;OAOG;IACH,qBAJW,MAAM,UACN,MAAM,GACJ,MAAM,CASlB;IAED;;;;;;;OAOG;IACH,qBAJW,MAAM,UACN,MAAM,GACJ,MAAM,CASlB;IAED;;;;;OAKG;IACH,kBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;OAQG;IACH,oBALW,MAAM,WACN,MAAM,UACN,MAAM,GACJ,MAAM,CA6BlB;IAED,gDAOC;IAED;;;;;;;OAOG;IACH,oBAJW,MAAM,GACJ,MAAM,CAclB;CACF"}