chromonym 1.1.0 → 1.3.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/NOTICE.md +39 -0
- package/README.md +93 -8
- package/dist/colorspaces/registry.d.ts +26 -0
- package/dist/colorspaces/registry.d.ts.map +1 -0
- package/dist/colorspaces/registry.js +36 -0
- package/dist/colorspaces/registry.js.map +1 -0
- package/dist/conversions/hex.d.ts.map +1 -1
- package/dist/conversions/hex.js +6 -5
- package/dist/conversions/hex.js.map +1 -1
- package/dist/conversions/hsl.d.ts.map +1 -1
- package/dist/conversions/hsl.js +34 -52
- package/dist/conversions/hsl.js.map +1 -1
- package/dist/conversions/hsv.d.ts.map +1 -1
- package/dist/conversions/hsv.js +30 -48
- package/dist/conversions/hsv.js.map +1 -1
- package/dist/conversions/pantone.d.ts +5 -2
- package/dist/conversions/pantone.d.ts.map +1 -1
- package/dist/conversions/pantone.js +8 -44
- package/dist/conversions/pantone.js.map +1 -1
- package/dist/conversions/rgb.d.ts +4 -2
- package/dist/conversions/rgb.d.ts.map +1 -1
- package/dist/conversions/rgb.js +28 -17
- package/dist/conversions/rgb.js.map +1 -1
- package/dist/convert.d.ts +12 -1
- package/dist/convert.d.ts.map +1 -1
- package/dist/convert.js +24 -6
- package/dist/convert.js.map +1 -1
- package/dist/detectFormat.d.ts +8 -0
- package/dist/detectFormat.d.ts.map +1 -1
- package/dist/detectFormat.js +17 -5
- package/dist/detectFormat.js.map +1 -1
- package/dist/identify.d.ts +13 -5
- package/dist/identify.d.ts.map +1 -1
- package/dist/identify.js +20 -35
- package/dist/identify.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/indexing.d.ts +44 -0
- package/dist/indexing.d.ts.map +1 -0
- package/dist/indexing.js +140 -0
- package/dist/indexing.js.map +1 -0
- package/dist/math/clamp.d.ts +11 -0
- package/dist/math/clamp.d.ts.map +1 -0
- package/dist/math/clamp.js +18 -0
- package/dist/math/clamp.js.map +1 -0
- package/dist/math/colorSpace.d.ts +55 -0
- package/dist/math/colorSpace.d.ts.map +1 -0
- package/dist/math/colorSpace.js +111 -0
- package/dist/math/colorSpace.js.map +1 -0
- package/dist/math/deltaE.d.ts +52 -0
- package/dist/math/deltaE.d.ts.map +1 -0
- package/dist/math/deltaE.js +190 -0
- package/dist/math/deltaE.js.map +1 -0
- package/dist/math/euclideanDistance.d.ts +7 -0
- package/dist/math/euclideanDistance.d.ts.map +1 -1
- package/dist/math/euclideanDistance.js +13 -4
- package/dist/math/euclideanDistance.js.map +1 -1
- package/dist/math/hueSector.d.ts +15 -0
- package/dist/math/hueSector.d.ts.map +1 -0
- package/dist/math/hueSector.js +27 -0
- package/dist/math/hueSector.js.map +1 -0
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +11 -34
- package/dist/resolve.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +72 -8
- package/dist/math/index.d.ts +0 -2
- package/dist/math/index.d.ts.map +0 -1
- package/dist/math/index.js +0 -4
- package/dist/math/index.js.map +0 -1
package/NOTICE.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Notices and Trademarks
|
|
2
|
+
|
|
3
|
+
## Pantone®
|
|
4
|
+
|
|
5
|
+
**Pantone®** is a registered trademark of **Pantone LLC**. Chromonym is
|
|
6
|
+
**not affiliated with, endorsed by, licensed by, or certified by Pantone
|
|
7
|
+
LLC**.
|
|
8
|
+
|
|
9
|
+
The `pantone` colorspace in this library ships **community-derived sRGB
|
|
10
|
+
approximations** of the Pantone Coated (C) color set, sourced from
|
|
11
|
+
[`color_library`](https://github.com/draganradu/color_library) (MIT © Radu
|
|
12
|
+
Dragan). These values:
|
|
13
|
+
|
|
14
|
+
- Are **not official Pantone measurements** and will not match a licensed
|
|
15
|
+
Pantone reference (physical chips, Pantone Connect, or the Pantone SDK)
|
|
16
|
+
exactly.
|
|
17
|
+
- Are intended for on-screen reference, nearest-name identification, and
|
|
18
|
+
general tooling — **not for print color specification**.
|
|
19
|
+
- Use standard color codes (e.g. `185C`) as **nominative references** to
|
|
20
|
+
publicly identified Pantone colors. No endorsement or claim of accuracy
|
|
21
|
+
is implied.
|
|
22
|
+
|
|
23
|
+
If you need Pantone-certified color values, consult Pantone directly:
|
|
24
|
+
<https://www.pantone.com/>.
|
|
25
|
+
|
|
26
|
+
## X11 / X.Org
|
|
27
|
+
|
|
28
|
+
The `x11` colorspace is derived from the X.Org `rgb.txt` file, which is in
|
|
29
|
+
the public domain.
|
|
30
|
+
|
|
31
|
+
## CSS / SVG named colors
|
|
32
|
+
|
|
33
|
+
The `web` colorspace mirrors the CSS Color Module Level 4 named-color
|
|
34
|
+
set, which is a public specification.
|
|
35
|
+
|
|
36
|
+
## Upstream dependencies
|
|
37
|
+
|
|
38
|
+
See `package.json` for runtime and development dependencies. All are MIT
|
|
39
|
+
or ISC licensed.
|
package/README.md
CHANGED
|
@@ -1,23 +1,49 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/assets/banner.png" alt="chromonym" width="800" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://simiancraft.github.io/chromonym/">
|
|
7
|
+
<img src="https://img.shields.io/badge/▶%20Live%20demo-scrub%20a%20color%2C%20see%20the%20name-4f46e5?style=for-the-badge" alt="Live demo" />
|
|
8
|
+
</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
1
11
|
# chromonym
|
|
2
12
|
|
|
13
|
+
[](https://www.npmjs.com/package/chromonym)
|
|
14
|
+
[](https://bundlephobia.com/package/chromonym)
|
|
15
|
+
[](https://www.npmjs.com/package/chromonym)
|
|
3
16
|
[](https://github.com/simiancraft/chromonym/actions/workflows/ci.yml)
|
|
4
17
|
[](https://codecov.io/gh/simiancraft/chromonym)
|
|
5
18
|
[](https://opensource.org/licenses/MIT)
|
|
6
19
|
[](https://github.com/semantic-release/semantic-release)
|
|
7
20
|
[](https://biomejs.dev)
|
|
8
21
|
|
|
9
|
-
Identify, resolve, and convert colors across CSS, X11, and Pantone colorspaces.
|
|
22
|
+
**Tree-shakeable color naming for TypeScript.** Identify, resolve, and convert colors across CSS, X11, and Pantone — with 5 perceptual distance metrics. Add your own colorspaces and metrics as you need them.
|
|
23
|
+
|
|
24
|
+
Built as a *color-strategy machine*: the identification and resolution mechanism is the same across every colorspace, so plugging in a new set (RAL, HKS, NCS, or a custom brand palette) is one file. For color *manipulation* (mixing, scales, gamut mapping), reach for [`chroma-js`](https://gka.github.io/chroma.js/) or [`color.js`](https://colorjs.io/) — chromonym is the tool for *naming*.
|
|
10
25
|
|
|
11
26
|
```ts
|
|
12
27
|
import { identify, resolve, convert } from 'chromonym';
|
|
13
28
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
// What Pantone is this brand color closest to? (perceptually, via CIEDE2000)
|
|
30
|
+
identify('#E20074', { colorspace: 'pantone' }) // '213C'
|
|
31
|
+
|
|
32
|
+
// Resolve any Pantone code back to RGB — prefix, spacing, case all fine
|
|
33
|
+
resolve('Pantone 185 C', { colorspace: 'pantone' })// '#e4002b'
|
|
34
|
+
|
|
35
|
+
// Format conversion, format-detecting input
|
|
36
|
+
convert('#ff0000', { format: 'HSL' }) // 'hsl(0, 100%, 50%)'
|
|
37
|
+
convert({ h: 120, s: 100, l: 50 }, { format: 'HEX' }) // '#00ff00'
|
|
38
|
+
|
|
39
|
+
// The classic: nearest CSS name
|
|
40
|
+
identify('#ff8080') // 'lightcoral'
|
|
19
41
|
```
|
|
20
42
|
|
|
43
|
+
> ### Pantone® trademark notice
|
|
44
|
+
>
|
|
45
|
+
> **Pantone®** is a registered trademark of **Pantone LLC**. Chromonym is **not affiliated with, endorsed by, or certified by Pantone LLC**. The `pantone` colorspace ships **community-derived sRGB approximations** of the Pantone Coated (C) set. Values will **not** match a licensed Pantone reference exactly and are unsuitable for print color specification. See [`NOTICE.md`](./NOTICE.md) for full text.
|
|
46
|
+
|
|
21
47
|
## Install
|
|
22
48
|
|
|
23
49
|
```sh
|
|
@@ -31,16 +57,17 @@ Three primary functions. All accept an optional `opts` object; defaults fire whe
|
|
|
31
57
|
|
|
32
58
|
### `identify(input, opts?)`
|
|
33
59
|
|
|
34
|
-
**Color → name.** Finds the nearest-match name in the chosen colorspace using
|
|
60
|
+
**Color → name.** Finds the nearest-match name in the chosen colorspace using the selected perceptual distance metric.
|
|
35
61
|
|
|
36
62
|
```ts
|
|
37
63
|
function identify(
|
|
38
64
|
input: ColorInput,
|
|
39
|
-
opts?: { colorspace?: ColorspaceName },
|
|
65
|
+
opts?: { colorspace?: ColorspaceName; metric?: DistanceMetric },
|
|
40
66
|
): string | null
|
|
41
67
|
```
|
|
42
68
|
|
|
43
69
|
- **Default colorspace**: `'web'`.
|
|
70
|
+
- **Default metric**: picked per colorspace — `'deltaE76'` for web and x11 (well-separated palettes), `'deltaE2000'` for pantone (dense, perceptually-packed). Override freely via `metric`.
|
|
44
71
|
- Returns the matched name, or `null` if input is unrecognized (`detectFormat` returns `'UNKNOWN'`).
|
|
45
72
|
- Ties are broken by the first entry encountered in the colorspace data.
|
|
46
73
|
|
|
@@ -50,6 +77,8 @@ identify([255, 0, 0]) // 'red'
|
|
|
50
77
|
identify({ r: 250, g: 20, b: 60 }) // 'crimson' (nearest)
|
|
51
78
|
identify('#ff0000', { colorspace: 'x11' }) // 'red' (or 'red1', X11 has numbered variants)
|
|
52
79
|
identify('#ff0000', { colorspace: 'pantone' }) // nearest Pantone C code, e.g. '185C'
|
|
80
|
+
identify('#ff0080', { metric: 'deltaE2000' }) // force perceptual-accurate match
|
|
81
|
+
identify('#ff0000', { metric: 'euclidean-srgb' }) // force fastest (non-perceptual) match
|
|
53
82
|
```
|
|
54
83
|
|
|
55
84
|
### `resolve(name, opts?)`
|
|
@@ -120,6 +149,34 @@ import { web, x11, pantone } from 'chromonym';
|
|
|
120
149
|
web.crimson // '#dc143c'
|
|
121
150
|
```
|
|
122
151
|
|
|
152
|
+
## Distance metrics
|
|
153
|
+
|
|
154
|
+
`identify` picks the nearest-named color by comparing your input to every entry in the chosen colorspace. *How* it measures "nearest" is controlled by `metric`. Five options, roughly ordered from fast-and-approximate to slow-and-correct:
|
|
155
|
+
|
|
156
|
+
| Metric | What it does | When to use |
|
|
157
|
+
|---|---|---|
|
|
158
|
+
| `'euclidean-srgb'` | Raw `sqrt(Δr² + Δg² + Δb²)` in sRGB. Fastest. Not perceptually uniform — a unit of distance doesn't mean a unit of "visual difference." | Tight perf budgets; well-separated palettes where you just need the obvious answer. |
|
|
159
|
+
| `'euclidean-linear'` | Same math, but on linearized (gamma-removed) RGB. Somewhat better in dark regions. Still not perceptual. | Physical-light mixing contexts; incremental upgrade from sRGB Euclidean. |
|
|
160
|
+
| `'deltaE76'` | Euclidean in CIELAB (CIE 1976). Simple perceptual metric. 1 ΔE ≈ "just noticeable difference" for most of the gamut. | **Default for web and x11.** Sweet spot: meaningful perceptual accuracy, low cost. |
|
|
161
|
+
| `'deltaE94'` | ΔE76 + chroma/hue weighting (CIE 1994). Fixes "saturated colors feel too far apart." | When ΔE76 is over-penalizing saturated matches in your use case. |
|
|
162
|
+
| `'deltaE2000'` | Full CIEDE2000 formula with blue/purple rotation correction. Industry standard for print, design tools, Pantone workflows. | **Default for pantone.** Use whenever accuracy matters, especially in the blue region where ΔE76/94 break down. |
|
|
163
|
+
| `'deltaEok'` | Euclidean distance in OKLAB (Björn Ottosson, 2020). OKLAB is perceptually uniform by construction — no weighting formula needed. Strictly more uniform than CIELAB; often a better nearest-match than ΔE2000 in saturated-blue regions, and cheaper to compute. | Modern default if you want perceptual accuracy without the CIEDE2000 rotation-term complexity. |
|
|
164
|
+
|
|
165
|
+
Each metric trades cost for accuracy — the full scan over 907 Pantone entries is well under 1 ms even with ΔE2000, so for interactive UIs there's no practical reason not to use the most accurate metric. Batch-processing millions of colors is where you'd drop down.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
// Defaults: deltaE76 for web/x11, deltaE2000 for pantone.
|
|
169
|
+
identify('#ff8080') // deltaE76 (web default)
|
|
170
|
+
identify('#ff8080', { colorspace: 'pantone' }) // deltaE2000 (pantone default)
|
|
171
|
+
|
|
172
|
+
// Override per-call:
|
|
173
|
+
identify('#ff8080', { metric: 'euclidean-srgb' }) // fastest
|
|
174
|
+
identify('#ff8080', { metric: 'deltaE2000' }) // most accurate
|
|
175
|
+
identify('#ff8080', { colorspace: 'pantone', metric: 'euclidean-srgb' }) // force fast for Pantone
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The low-level `rgbaToPantone` always uses `'deltaE2000'` — appropriate for Pantone matching, where this is what the industry tools use.
|
|
179
|
+
|
|
123
180
|
## Formats
|
|
124
181
|
|
|
125
182
|
Format keys are SCREAMING_CAPS — they are used as dispatch keys internally.
|
|
@@ -135,6 +192,26 @@ Format keys are SCREAMING_CAPS — they are used as dispatch keys internally.
|
|
|
135
192
|
|
|
136
193
|
The runtime set `COLOR_FORMATS` is exported for enumeration / membership checks.
|
|
137
194
|
|
|
195
|
+
## Error handling
|
|
196
|
+
|
|
197
|
+
The three dispatchers are asymmetric — chosen deliberately, but worth knowing:
|
|
198
|
+
|
|
199
|
+
| Function | Unrecognized / unknown input | Rationale |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| `identify(input)` | returns `null` | lookup-flavored; "no match" is a normal outcome |
|
|
202
|
+
| `resolve(name)` | returns `null` | lookup-flavored; name may legitimately not exist |
|
|
203
|
+
| `convert(input)` | **throws** | parser-flavored; malformed color is a caller error |
|
|
204
|
+
|
|
205
|
+
Low-level converters (`hexToRgba`, `rgbToRgba`, `hslToRgba`, `hsvToRgba`, `pantoneToRgba`) all **throw** on malformed input. The `rgbaTo*` direction never throws. The nearest-match returner `rgbaToPantone` always returns *some* Pantone code.
|
|
206
|
+
|
|
207
|
+
If you want a `null`-returning variant of `convert`, wrap it:
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
const tryConvert = (input: ColorInput, opts = {}) => {
|
|
211
|
+
try { return convert(input, opts); } catch { return null; }
|
|
212
|
+
};
|
|
213
|
+
```
|
|
214
|
+
|
|
138
215
|
## Utilities
|
|
139
216
|
|
|
140
217
|
- **`detectFormat(input): DetectedFormat`** — runtime format detection. Returns one of the format keys or `'UNKNOWN'`.
|
|
@@ -184,6 +261,14 @@ bun run scripts/generate-pantone.ts # reads color_library (MIT dependency)
|
|
|
184
261
|
|
|
185
262
|
Each ring is a directory; each leaf is a file. Green is covered, red is gaps.
|
|
186
263
|
|
|
264
|
+
## See also
|
|
265
|
+
|
|
266
|
+
chromonym deliberately limits its scope to color *naming*. For other color-related work, reach for tools that do those things well:
|
|
267
|
+
|
|
268
|
+
- **[color.js](https://colorjs.io/)** — modern, spec-first color library by the CSS Color WG authors. CSS Color 4/5, OKLAB, P3, gamut mapping, interpolation, ΔE.
|
|
269
|
+
- **[chroma.js](https://gka.github.io/chroma.js/)** — color mixing, scales, interpolation, contrast ratios, luminance.
|
|
270
|
+
- **[tinycolor2](https://github.com/bgrins/TinyColor)** — lightweight manipulation (lighten / darken / mix) with CSS-string I/O.
|
|
271
|
+
|
|
187
272
|
## License
|
|
188
273
|
|
|
189
274
|
MIT © [the-simian](https://github.com/the-simian)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type NormalizeFn } from '../indexing';
|
|
2
|
+
import type { Colorspace, ColorspaceName, DistanceMetric } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Internal registry of known colorspaces + their normalizers.
|
|
5
|
+
*
|
|
6
|
+
* Tree-shake note: this file imports all three colorspaces, so anything
|
|
7
|
+
* that imports from here pays for all three. It's used by `resolve` and
|
|
8
|
+
* `identify`, both of which need a string-keyed lookup; users who want
|
|
9
|
+
* to tree-shake a single colorspace should import `web`, `x11`, or
|
|
10
|
+
* `pantone` directly from the root barrel.
|
|
11
|
+
*/
|
|
12
|
+
export declare const COLORSPACES: Record<ColorspaceName, Colorspace>;
|
|
13
|
+
/** Guards Record indexing against prototype-chain keys like `__proto__`. */
|
|
14
|
+
export declare const COLORSPACE_NAMES: ReadonlySet<ColorspaceName>;
|
|
15
|
+
export declare const NORMALIZERS: Record<ColorspaceName, NormalizeFn>;
|
|
16
|
+
/**
|
|
17
|
+
* Default distance metric per colorspace, picked for the density of each
|
|
18
|
+
* palette. Users can override via `identify(_, { metric })`.
|
|
19
|
+
*
|
|
20
|
+
* web — 148 entries, well-separated; ΔE76 suffices and is cheap.
|
|
21
|
+
* x11 — 658 entries; ΔE76 is the sweet spot (ΔE94/2000 overkill).
|
|
22
|
+
* pantone — 907 entries densely packed in the blue/purple region; ΔE2000
|
|
23
|
+
* is the industry standard and what color-print tools use.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEFAULT_METRICS: Record<ColorspaceName, DistanceMetric>;
|
|
26
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/colorspaces/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAuC,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK3E;;;;;;;;GAQG;AAEH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,cAAc,EAAE,UAAU,CAAyB,CAAC;AAErF,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,cAAc,CAAsC,CAAC;AAEhG,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,cAAc,EAAE,WAAW,CAI3D,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,cAAc,EAAE,cAAc,CAIlE,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { pantoneNormalize, standardNormalize } from '../indexing';
|
|
2
|
+
import { pantone } from './pantone';
|
|
3
|
+
import { web } from './web';
|
|
4
|
+
import { x11 } from './x11';
|
|
5
|
+
/**
|
|
6
|
+
* Internal registry of known colorspaces + their normalizers.
|
|
7
|
+
*
|
|
8
|
+
* Tree-shake note: this file imports all three colorspaces, so anything
|
|
9
|
+
* that imports from here pays for all three. It's used by `resolve` and
|
|
10
|
+
* `identify`, both of which need a string-keyed lookup; users who want
|
|
11
|
+
* to tree-shake a single colorspace should import `web`, `x11`, or
|
|
12
|
+
* `pantone` directly from the root barrel.
|
|
13
|
+
*/
|
|
14
|
+
export const COLORSPACES = { web, x11, pantone };
|
|
15
|
+
/** Guards Record indexing against prototype-chain keys like `__proto__`. */
|
|
16
|
+
export const COLORSPACE_NAMES = new Set(['web', 'x11', 'pantone']);
|
|
17
|
+
export const NORMALIZERS = {
|
|
18
|
+
web: standardNormalize,
|
|
19
|
+
x11: standardNormalize,
|
|
20
|
+
pantone: pantoneNormalize,
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Default distance metric per colorspace, picked for the density of each
|
|
24
|
+
* palette. Users can override via `identify(_, { metric })`.
|
|
25
|
+
*
|
|
26
|
+
* web — 148 entries, well-separated; ΔE76 suffices and is cheap.
|
|
27
|
+
* x11 — 658 entries; ΔE76 is the sweet spot (ΔE94/2000 overkill).
|
|
28
|
+
* pantone — 907 entries densely packed in the blue/purple region; ΔE2000
|
|
29
|
+
* is the industry standard and what color-print tools use.
|
|
30
|
+
*/
|
|
31
|
+
export const DEFAULT_METRICS = {
|
|
32
|
+
web: 'deltaE76',
|
|
33
|
+
x11: 'deltaE76',
|
|
34
|
+
pantone: 'deltaE2000',
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/colorspaces/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEpF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5B;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAuC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AAErF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAgC,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AAEhG,MAAM,CAAC,MAAM,WAAW,GAAwC;IAC9D,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,OAAO,EAAE,gBAAgB;CAC1B,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAA2C;IACrE,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,UAAU;IACf,OAAO,EAAE,YAAY;CACtB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hex.d.ts","sourceRoot":"","sources":["../../src/conversions/hex.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hex.d.ts","sourceRoot":"","sources":["../../src/conversions/hex.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAsB7C;AAMD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAE9C"}
|
package/dist/conversions/hex.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { HEX_RE } from '../detectFormat';
|
|
2
|
+
import { clamp } from '../math/clamp';
|
|
2
3
|
/**
|
|
3
4
|
* Parse a hex color string into the canonical Rgba representation.
|
|
4
5
|
* Accepts 3-digit (`#rgb`), 6-digit (`#rrggbb`), and 8-digit (`#rrggbbaa`).
|
|
@@ -26,14 +27,14 @@ export function hexToRgba(hex) {
|
|
|
26
27
|
const a = body.length === 8 ? parseInt(body.slice(6, 8), 16) / 255 : 1;
|
|
27
28
|
return { r, g, b, a };
|
|
28
29
|
}
|
|
30
|
+
function channelToHex(n) {
|
|
31
|
+
return clamp(Math.round(n), 0, 255).toString(16).padStart(2, '0');
|
|
32
|
+
}
|
|
29
33
|
/**
|
|
30
34
|
* Emit a 6-digit lowercase hex string. Alpha is dropped; out-of-range
|
|
31
35
|
* channel values are clamped to 0..255; fractional values are rounded.
|
|
32
36
|
*/
|
|
33
37
|
export function rgbaToHex(rgba) {
|
|
34
|
-
|
|
35
|
-
.toString(16)
|
|
36
|
-
.padStart(2, '0');
|
|
37
|
-
return `#${clamp(rgba.r)}${clamp(rgba.g)}${clamp(rgba.b)}`;
|
|
38
|
+
return `#${channelToHex(rgba.r)}${channelToHex(rgba.g)}${channelToHex(rgba.b)}`;
|
|
38
39
|
}
|
|
39
40
|
//# sourceMappingURL=hex.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hex.js","sourceRoot":"","sources":["../../src/conversions/hex.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hex.js","sourceRoot":"","sources":["../../src/conversions/hex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,GAAa;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;IAExD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzB,OAAO;YACL,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACtB,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACtB,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACtB,CAAC,EAAE,CAAC;SACL,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,IAAU;IAClC,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAc,CAAC;AAC9F,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hsl.d.ts","sourceRoot":"","sources":["../../src/conversions/hsl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hsl.d.ts","sourceRoot":"","sources":["../../src/conversions/hsl.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAK1D;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAqC/C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAyB/C"}
|
package/dist/conversions/hsl.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { requireFinite } from '../math/clamp';
|
|
2
|
+
import { hueSectorToPrime } from '../math/hueSector';
|
|
1
3
|
const HSL_RE = /^hsl\s*\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)%?\s*,\s*(-?\d+(?:\.\d+)?)%?\s*\)$/i;
|
|
2
4
|
/**
|
|
3
5
|
* Parse HSL input (string or object) into canonical Rgba.
|
|
@@ -16,45 +18,25 @@ export function hslToRgba(input) {
|
|
|
16
18
|
l = Number(match[3]);
|
|
17
19
|
}
|
|
18
20
|
else {
|
|
19
|
-
h = input.h;
|
|
20
|
-
s = input.s;
|
|
21
|
-
l = input.l;
|
|
21
|
+
h = requireFinite(input.h, 'h');
|
|
22
|
+
s = requireFinite(input.s, 's');
|
|
23
|
+
l = requireFinite(input.l, 'l');
|
|
22
24
|
}
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
const
|
|
27
|
-
return { r:
|
|
28
|
-
}
|
|
29
|
-
const c = (1 - Math.abs(2 * lig - 1)) * sat;
|
|
30
|
-
const hp = (((h % 360) + 360) % 360) / 60;
|
|
31
|
-
const x = c * (1 - Math.abs((hp % 2) - 1));
|
|
32
|
-
const m = lig - c / 2;
|
|
33
|
-
let r1;
|
|
34
|
-
let g1;
|
|
35
|
-
let b1;
|
|
36
|
-
if (hp < 1) {
|
|
37
|
-
[r1, g1, b1] = [c, x, 0];
|
|
38
|
-
}
|
|
39
|
-
else if (hp < 2) {
|
|
40
|
-
[r1, g1, b1] = [x, c, 0];
|
|
41
|
-
}
|
|
42
|
-
else if (hp < 3) {
|
|
43
|
-
[r1, g1, b1] = [0, c, x];
|
|
44
|
-
}
|
|
45
|
-
else if (hp < 4) {
|
|
46
|
-
[r1, g1, b1] = [0, x, c];
|
|
47
|
-
}
|
|
48
|
-
else if (hp < 5) {
|
|
49
|
-
[r1, g1, b1] = [x, 0, c];
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
[r1, g1, b1] = [c, 0, x];
|
|
25
|
+
const saturation = s / 100;
|
|
26
|
+
const lightness = l / 100;
|
|
27
|
+
if (saturation === 0) {
|
|
28
|
+
const gray = Math.round(lightness * 255);
|
|
29
|
+
return { r: gray, g: gray, b: gray, a: 1 };
|
|
53
30
|
}
|
|
31
|
+
const chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;
|
|
32
|
+
const hueSector = (((h % 360) + 360) % 360) / 60;
|
|
33
|
+
const secondary = chroma * (1 - Math.abs((hueSector % 2) - 1));
|
|
34
|
+
const lightnessOffset = lightness - chroma / 2;
|
|
35
|
+
const [rPrime, gPrime, bPrime] = hueSectorToPrime(hueSector, chroma, secondary);
|
|
54
36
|
return {
|
|
55
|
-
r: Math.round((
|
|
56
|
-
g: Math.round((
|
|
57
|
-
b: Math.round((
|
|
37
|
+
r: Math.round((rPrime + lightnessOffset) * 255),
|
|
38
|
+
g: Math.round((gPrime + lightnessOffset) * 255),
|
|
39
|
+
b: Math.round((bPrime + lightnessOffset) * 255),
|
|
58
40
|
a: 1,
|
|
59
41
|
};
|
|
60
42
|
}
|
|
@@ -63,28 +45,28 @@ export function hslToRgba(input) {
|
|
|
63
45
|
* three components are rounded to whole numbers.
|
|
64
46
|
*/
|
|
65
47
|
export function rgbaToHsl(rgba) {
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
const max = Math.max(
|
|
70
|
-
const min = Math.min(
|
|
71
|
-
const
|
|
48
|
+
const rNorm = rgba.r / 255;
|
|
49
|
+
const gNorm = rgba.g / 255;
|
|
50
|
+
const bNorm = rgba.b / 255;
|
|
51
|
+
const max = Math.max(rNorm, gNorm, bNorm);
|
|
52
|
+
const min = Math.min(rNorm, gNorm, bNorm);
|
|
53
|
+
const lightness = (max + min) / 2;
|
|
72
54
|
if (max === min) {
|
|
73
|
-
return `hsl(0, 0%, ${Math.round(
|
|
55
|
+
return `hsl(0, 0%, ${Math.round(lightness * 100)}%)`;
|
|
74
56
|
}
|
|
75
57
|
const delta = max - min;
|
|
76
|
-
const
|
|
77
|
-
let
|
|
78
|
-
if (max ===
|
|
79
|
-
|
|
58
|
+
const saturation = lightness > 0.5 ? delta / (2 - max - min) : delta / (max + min);
|
|
59
|
+
let hue;
|
|
60
|
+
if (max === rNorm) {
|
|
61
|
+
hue = (gNorm - bNorm) / delta + (gNorm < bNorm ? 6 : 0);
|
|
80
62
|
}
|
|
81
|
-
else if (max ===
|
|
82
|
-
|
|
63
|
+
else if (max === gNorm) {
|
|
64
|
+
hue = (bNorm - rNorm) / delta + 2;
|
|
83
65
|
}
|
|
84
66
|
else {
|
|
85
|
-
|
|
67
|
+
hue = (rNorm - gNorm) / delta + 4;
|
|
86
68
|
}
|
|
87
|
-
|
|
88
|
-
return `hsl(${Math.round(
|
|
69
|
+
hue *= 60;
|
|
70
|
+
return `hsl(${Math.round(hue)}, ${Math.round(saturation * 100)}%, ${Math.round(lightness * 100)}%)`;
|
|
89
71
|
}
|
|
90
72
|
//# sourceMappingURL=hsl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hsl.js","sourceRoot":"","sources":["../../src/conversions/hsl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hsl.js","sourceRoot":"","sources":["../../src/conversions/hsl.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hsv.d.ts","sourceRoot":"","sources":["../../src/conversions/hsv.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hsv.d.ts","sourceRoot":"","sources":["../../src/conversions/hsv.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAK1D;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CA+B/C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAuB/C"}
|
package/dist/conversions/hsv.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { requireFinite } from '../math/clamp';
|
|
2
|
+
import { hueSectorToPrime } from '../math/hueSector';
|
|
1
3
|
const HSV_RE = /^hsv\s*\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)%?\s*,\s*(-?\d+(?:\.\d+)?)%?\s*\)$/i;
|
|
2
4
|
/**
|
|
3
5
|
* Parse HSV input (string or object) into canonical Rgba.
|
|
@@ -16,41 +18,21 @@ export function hsvToRgba(input) {
|
|
|
16
18
|
v = Number(match[3]);
|
|
17
19
|
}
|
|
18
20
|
else {
|
|
19
|
-
h = input.h;
|
|
20
|
-
s = input.s;
|
|
21
|
-
v = input.v;
|
|
22
|
-
}
|
|
23
|
-
const sat = s / 100;
|
|
24
|
-
const val = v / 100;
|
|
25
|
-
const c = val * sat;
|
|
26
|
-
const hp = (((h % 360) + 360) % 360) / 60;
|
|
27
|
-
const x = c * (1 - Math.abs((hp % 2) - 1));
|
|
28
|
-
const m = val - c;
|
|
29
|
-
let r1;
|
|
30
|
-
let g1;
|
|
31
|
-
let b1;
|
|
32
|
-
if (hp < 1) {
|
|
33
|
-
[r1, g1, b1] = [c, x, 0];
|
|
34
|
-
}
|
|
35
|
-
else if (hp < 2) {
|
|
36
|
-
[r1, g1, b1] = [x, c, 0];
|
|
37
|
-
}
|
|
38
|
-
else if (hp < 3) {
|
|
39
|
-
[r1, g1, b1] = [0, c, x];
|
|
40
|
-
}
|
|
41
|
-
else if (hp < 4) {
|
|
42
|
-
[r1, g1, b1] = [0, x, c];
|
|
43
|
-
}
|
|
44
|
-
else if (hp < 5) {
|
|
45
|
-
[r1, g1, b1] = [x, 0, c];
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
[r1, g1, b1] = [c, 0, x];
|
|
21
|
+
h = requireFinite(input.h, 'h');
|
|
22
|
+
s = requireFinite(input.s, 's');
|
|
23
|
+
v = requireFinite(input.v, 'v');
|
|
49
24
|
}
|
|
25
|
+
const saturation = s / 100;
|
|
26
|
+
const value = v / 100;
|
|
27
|
+
const chroma = value * saturation;
|
|
28
|
+
const hueSector = (((h % 360) + 360) % 360) / 60;
|
|
29
|
+
const secondary = chroma * (1 - Math.abs((hueSector % 2) - 1));
|
|
30
|
+
const valueOffset = value - chroma;
|
|
31
|
+
const [rPrime, gPrime, bPrime] = hueSectorToPrime(hueSector, chroma, secondary);
|
|
50
32
|
return {
|
|
51
|
-
r: Math.round((
|
|
52
|
-
g: Math.round((
|
|
53
|
-
b: Math.round((
|
|
33
|
+
r: Math.round((rPrime + valueOffset) * 255),
|
|
34
|
+
g: Math.round((gPrime + valueOffset) * 255),
|
|
35
|
+
b: Math.round((bPrime + valueOffset) * 255),
|
|
54
36
|
a: 1,
|
|
55
37
|
};
|
|
56
38
|
}
|
|
@@ -59,27 +41,27 @@ export function hsvToRgba(input) {
|
|
|
59
41
|
* three components are rounded to whole numbers.
|
|
60
42
|
*/
|
|
61
43
|
export function rgbaToHsv(rgba) {
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
const max = Math.max(
|
|
66
|
-
const min = Math.min(
|
|
44
|
+
const rNorm = rgba.r / 255;
|
|
45
|
+
const gNorm = rgba.g / 255;
|
|
46
|
+
const bNorm = rgba.b / 255;
|
|
47
|
+
const max = Math.max(rNorm, gNorm, bNorm);
|
|
48
|
+
const min = Math.min(rNorm, gNorm, bNorm);
|
|
67
49
|
const delta = max - min;
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
let
|
|
50
|
+
const value = max;
|
|
51
|
+
const saturation = max === 0 ? 0 : delta / max;
|
|
52
|
+
let hue = 0;
|
|
71
53
|
if (delta !== 0) {
|
|
72
|
-
if (max ===
|
|
73
|
-
|
|
54
|
+
if (max === rNorm) {
|
|
55
|
+
hue = (gNorm - bNorm) / delta + (gNorm < bNorm ? 6 : 0);
|
|
74
56
|
}
|
|
75
|
-
else if (max ===
|
|
76
|
-
|
|
57
|
+
else if (max === gNorm) {
|
|
58
|
+
hue = (bNorm - rNorm) / delta + 2;
|
|
77
59
|
}
|
|
78
60
|
else {
|
|
79
|
-
|
|
61
|
+
hue = (rNorm - gNorm) / delta + 4;
|
|
80
62
|
}
|
|
81
|
-
|
|
63
|
+
hue *= 60;
|
|
82
64
|
}
|
|
83
|
-
return `hsv(${Math.round(
|
|
65
|
+
return `hsv(${Math.round(hue)}, ${Math.round(saturation * 100)}%, ${Math.round(value * 100)}%)`;
|
|
84
66
|
}
|
|
85
67
|
//# sourceMappingURL=hsv.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hsv.js","sourceRoot":"","sources":["../../src/conversions/hsv.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hsv.js","sourceRoot":"","sources":["../../src/conversions/hsv.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,11 @@ import type { PantoneCode, Rgba } from '../types';
|
|
|
7
7
|
*/
|
|
8
8
|
export declare function pantoneToRgba(code: PantoneCode): Rgba;
|
|
9
9
|
/**
|
|
10
|
-
* Find the nearest Pantone code
|
|
11
|
-
*
|
|
10
|
+
* Find the nearest Pantone Coated code to the given Rgba. Uses ΔE*00
|
|
11
|
+
* (CIEDE2000) — the industry-standard perceptual metric — by default, since
|
|
12
|
+
* Pantone values cluster densely in the saturated blue/purple region where
|
|
13
|
+
* sRGB Euclidean distance gives visually wrong answers.
|
|
14
|
+
* Alpha is ignored. Always returns a code.
|
|
12
15
|
*/
|
|
13
16
|
export declare function rgbaToPantone(rgba: Rgba): PantoneCode;
|
|
14
17
|
//# sourceMappingURL=pantone.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pantone.d.ts","sourceRoot":"","sources":["../../src/conversions/pantone.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAY,WAAW,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"pantone.d.ts","sourceRoot":"","sources":["../../src/conversions/pantone.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAY,WAAW,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAG5D;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAKrD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAErD"}
|