@al8b/palette 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @al8b/palette
2
+
3
+ Palette and color conversion utilities for L8B. This package centralizes indexed palette management and the types shared by rendering layers.
4
+
5
+ ## Public API
6
+
7
+ - `Palette`
8
+ - Type: `PaletteOptions`
9
+ - Types: `ColorHex`, `ColorRGB`, `PaletteData`
10
+
11
+ ## Notes
12
+
13
+ - Used by runtime and script-facing rendering APIs.
14
+ - Keep palette-level color logic here instead of duplicating conversions in screen or image code.
15
+
16
+ ## Scripts
17
+
18
+ ```bash
19
+ bun run build
20
+ bun run test
21
+ bun run clean
22
+ ```
@@ -0,0 +1,95 @@
1
+ import { ColorHex, PaletteData, ColorRGB } from '../types/index.mjs';
2
+
3
+ /**
4
+ * Palette - Color palette management
5
+ */
6
+
7
+ interface PaletteOptions {
8
+ colors?: ColorHex[];
9
+ name?: string;
10
+ }
11
+ declare class Palette {
12
+ private colors;
13
+ private name;
14
+ private rgbCache;
15
+ private runtime?;
16
+ constructor(options?: PaletteOptions | PaletteData, runtime?: any);
17
+ /**
18
+ * Validate palette format
19
+ */
20
+ private validatePaletteFormat;
21
+ /**
22
+ * Get color by index
23
+ */
24
+ get(index: number): ColorHex;
25
+ /**
26
+ * Get color as RGB object
27
+ */
28
+ getRGB(index: number): ColorRGB;
29
+ /**
30
+ * Get all colors
31
+ */
32
+ getAll(): ColorHex[];
33
+ /**
34
+ * Get palette size
35
+ */
36
+ get size(): number;
37
+ /**
38
+ * Get palette name
39
+ */
40
+ get paletteName(): string;
41
+ /**
42
+ * Set color at index (expands palette if needed)
43
+ */
44
+ set(index: number, color: ColorHex): void;
45
+ /**
46
+ * Add color to palette
47
+ */
48
+ add(color: ColorHex): number;
49
+ /**
50
+ * Remove color at index
51
+ */
52
+ remove(index: number): void;
53
+ /**
54
+ * Replace entire palette
55
+ */
56
+ setPalette(colors: ColorHex[]): void;
57
+ /**
58
+ * Reset to original colors
59
+ */
60
+ reset(paletteData?: PaletteData): void;
61
+ /**
62
+ * Convert hex to RGB
63
+ */
64
+ private hexToRGB;
65
+ /**
66
+ * Convert RGB to hex
67
+ */
68
+ static rgbToHex(r: number, g: number, b: number): ColorHex;
69
+ /**
70
+ * Find closest color in palette
71
+ */
72
+ findClosest(targetHex: ColorHex): number;
73
+ /**
74
+ * Create a gradient between two palette colors
75
+ */
76
+ gradient(startIndex: number, endIndex: number, steps: number): ColorHex[];
77
+ /**
78
+ * Lighten a color
79
+ */
80
+ lighten(index: number, amount?: number): ColorHex;
81
+ /**
82
+ * Darken a color
83
+ */
84
+ darken(index: number, amount?: number): ColorHex;
85
+ /**
86
+ * Mix two colors
87
+ */
88
+ mix(index1: number, index2: number, ratio?: number): ColorHex;
89
+ /**
90
+ * Export palette data
91
+ */
92
+ toData(): PaletteData;
93
+ }
94
+
95
+ export { Palette, type PaletteOptions };
@@ -0,0 +1,95 @@
1
+ import { ColorHex, PaletteData, ColorRGB } from '../types/index.js';
2
+
3
+ /**
4
+ * Palette - Color palette management
5
+ */
6
+
7
+ interface PaletteOptions {
8
+ colors?: ColorHex[];
9
+ name?: string;
10
+ }
11
+ declare class Palette {
12
+ private colors;
13
+ private name;
14
+ private rgbCache;
15
+ private runtime?;
16
+ constructor(options?: PaletteOptions | PaletteData, runtime?: any);
17
+ /**
18
+ * Validate palette format
19
+ */
20
+ private validatePaletteFormat;
21
+ /**
22
+ * Get color by index
23
+ */
24
+ get(index: number): ColorHex;
25
+ /**
26
+ * Get color as RGB object
27
+ */
28
+ getRGB(index: number): ColorRGB;
29
+ /**
30
+ * Get all colors
31
+ */
32
+ getAll(): ColorHex[];
33
+ /**
34
+ * Get palette size
35
+ */
36
+ get size(): number;
37
+ /**
38
+ * Get palette name
39
+ */
40
+ get paletteName(): string;
41
+ /**
42
+ * Set color at index (expands palette if needed)
43
+ */
44
+ set(index: number, color: ColorHex): void;
45
+ /**
46
+ * Add color to palette
47
+ */
48
+ add(color: ColorHex): number;
49
+ /**
50
+ * Remove color at index
51
+ */
52
+ remove(index: number): void;
53
+ /**
54
+ * Replace entire palette
55
+ */
56
+ setPalette(colors: ColorHex[]): void;
57
+ /**
58
+ * Reset to original colors
59
+ */
60
+ reset(paletteData?: PaletteData): void;
61
+ /**
62
+ * Convert hex to RGB
63
+ */
64
+ private hexToRGB;
65
+ /**
66
+ * Convert RGB to hex
67
+ */
68
+ static rgbToHex(r: number, g: number, b: number): ColorHex;
69
+ /**
70
+ * Find closest color in palette
71
+ */
72
+ findClosest(targetHex: ColorHex): number;
73
+ /**
74
+ * Create a gradient between two palette colors
75
+ */
76
+ gradient(startIndex: number, endIndex: number, steps: number): ColorHex[];
77
+ /**
78
+ * Lighten a color
79
+ */
80
+ lighten(index: number, amount?: number): ColorHex;
81
+ /**
82
+ * Darken a color
83
+ */
84
+ darken(index: number, amount?: number): ColorHex;
85
+ /**
86
+ * Mix two colors
87
+ */
88
+ mix(index1: number, index2: number, ratio?: number): ColorHex;
89
+ /**
90
+ * Export palette data
91
+ */
92
+ toData(): PaletteData;
93
+ }
94
+
95
+ export { Palette, type PaletteOptions };
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/core/palette.ts
22
+ var palette_exports = {};
23
+ __export(palette_exports, {
24
+ Palette: () => Palette
25
+ });
26
+ module.exports = __toCommonJS(palette_exports);
27
+ var import_diagnostics = require("@al8b/diagnostics");
28
+ var HEX_COLOR_REGEX = /^#[0-9A-Fa-f]{6}$/;
29
+ var Palette = class _Palette {
30
+ static {
31
+ __name(this, "Palette");
32
+ }
33
+ colors;
34
+ name;
35
+ rgbCache;
36
+ runtime;
37
+ constructor(options = {}, runtime) {
38
+ this.runtime = runtime;
39
+ if ("colors" in options && Array.isArray(options.colors)) {
40
+ if (!this.validatePaletteFormat(options.colors)) {
41
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7072, {
42
+ format: "invalid color array"
43
+ });
44
+ this.colors = [];
45
+ this.name = "Invalid";
46
+ } else {
47
+ this.colors = [
48
+ ...options.colors
49
+ ];
50
+ this.name = options.name || "Custom";
51
+ }
52
+ } else {
53
+ this.colors = [];
54
+ this.name = "Empty";
55
+ }
56
+ this.rgbCache = /* @__PURE__ */ new Map();
57
+ }
58
+ /**
59
+ * Validate palette format
60
+ */
61
+ validatePaletteFormat(colors) {
62
+ if (!Array.isArray(colors)) return false;
63
+ return colors.every((color) => typeof color === "string" && HEX_COLOR_REGEX.test(color));
64
+ }
65
+ /**
66
+ * Get color by index
67
+ */
68
+ get(index) {
69
+ if (!isFinite(index) || index < 0) {
70
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7073, {
71
+ index,
72
+ maxIndex: this.colors.length - 1
73
+ });
74
+ return "#000000";
75
+ }
76
+ if (this.colors.length === 0) {
77
+ return "#000000";
78
+ }
79
+ return this.colors[index % this.colors.length] || "#000000";
80
+ }
81
+ /**
82
+ * Get color as RGB object
83
+ */
84
+ getRGB(index) {
85
+ if (this.rgbCache.has(index)) {
86
+ return this.rgbCache.get(index);
87
+ }
88
+ const hex = this.get(index);
89
+ const rgb = this.hexToRGB(hex);
90
+ this.rgbCache.set(index, rgb);
91
+ return rgb;
92
+ }
93
+ /**
94
+ * Get all colors
95
+ */
96
+ getAll() {
97
+ return [
98
+ ...this.colors
99
+ ];
100
+ }
101
+ /**
102
+ * Get palette size
103
+ */
104
+ get size() {
105
+ return this.colors.length;
106
+ }
107
+ /**
108
+ * Get palette name
109
+ */
110
+ get paletteName() {
111
+ return this.name;
112
+ }
113
+ /**
114
+ * Set color at index (expands palette if needed)
115
+ */
116
+ set(index, color) {
117
+ if (!isFinite(index) || index < 0) {
118
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7073, {
119
+ index,
120
+ maxIndex: this.colors.length - 1
121
+ });
122
+ return;
123
+ }
124
+ if (!HEX_COLOR_REGEX.test(color)) {
125
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7072, {
126
+ format: color
127
+ });
128
+ return;
129
+ }
130
+ while (this.colors.length <= index) {
131
+ this.colors.push("#000000");
132
+ }
133
+ this.colors[index] = color;
134
+ this.rgbCache.delete(index);
135
+ }
136
+ /**
137
+ * Add color to palette
138
+ */
139
+ add(color) {
140
+ this.colors.push(color);
141
+ return this.colors.length - 1;
142
+ }
143
+ /**
144
+ * Remove color at index
145
+ */
146
+ remove(index) {
147
+ if (index >= 0 && index < this.colors.length) {
148
+ this.colors.splice(index, 1);
149
+ this.rgbCache.clear();
150
+ }
151
+ }
152
+ /**
153
+ * Replace entire palette
154
+ */
155
+ setPalette(colors) {
156
+ if (!this.validatePaletteFormat(colors)) {
157
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7072, {
158
+ format: "invalid color array"
159
+ });
160
+ return;
161
+ }
162
+ this.colors = [
163
+ ...colors
164
+ ];
165
+ this.rgbCache.clear();
166
+ }
167
+ /**
168
+ * Reset to original colors
169
+ */
170
+ reset(paletteData) {
171
+ if (paletteData) {
172
+ this.colors = [
173
+ ...paletteData.colors
174
+ ];
175
+ this.name = paletteData.name;
176
+ }
177
+ this.rgbCache.clear();
178
+ }
179
+ /**
180
+ * Convert hex to RGB
181
+ */
182
+ hexToRGB(hex) {
183
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
184
+ return result ? {
185
+ r: Number.parseInt(result[1], 16),
186
+ g: Number.parseInt(result[2], 16),
187
+ b: Number.parseInt(result[3], 16)
188
+ } : {
189
+ r: 0,
190
+ g: 0,
191
+ b: 0
192
+ };
193
+ }
194
+ /**
195
+ * Convert RGB to hex
196
+ */
197
+ static rgbToHex(r, g, b) {
198
+ return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
199
+ }
200
+ /**
201
+ * Find closest color in palette
202
+ */
203
+ findClosest(targetHex) {
204
+ const target = this.hexToRGB(targetHex);
205
+ let closestIndex = 0;
206
+ let closestDistance = Number.POSITIVE_INFINITY;
207
+ for (let i = 0; i < this.colors.length; i++) {
208
+ const color = this.getRGB(i);
209
+ const distance = (target.r - color.r) ** 2 + (target.g - color.g) ** 2 + (target.b - color.b) ** 2;
210
+ if (distance < closestDistance) {
211
+ closestDistance = distance;
212
+ closestIndex = i;
213
+ }
214
+ }
215
+ return closestIndex;
216
+ }
217
+ /**
218
+ * Create a gradient between two palette colors
219
+ */
220
+ gradient(startIndex, endIndex, steps) {
221
+ const start = this.getRGB(startIndex);
222
+ const end = this.getRGB(endIndex);
223
+ const gradient = [];
224
+ for (let i = 0; i < steps; i++) {
225
+ const t = i / (steps - 1);
226
+ const r = Math.round(start.r + (end.r - start.r) * t);
227
+ const g = Math.round(start.g + (end.g - start.g) * t);
228
+ const b = Math.round(start.b + (end.b - start.b) * t);
229
+ gradient.push(_Palette.rgbToHex(r, g, b));
230
+ }
231
+ return gradient;
232
+ }
233
+ /**
234
+ * Lighten a color
235
+ */
236
+ lighten(index, amount = 0.2) {
237
+ const color = this.getRGB(index);
238
+ const r = Math.min(255, Math.round(color.r + (255 - color.r) * amount));
239
+ const g = Math.min(255, Math.round(color.g + (255 - color.g) * amount));
240
+ const b = Math.min(255, Math.round(color.b + (255 - color.b) * amount));
241
+ return _Palette.rgbToHex(r, g, b);
242
+ }
243
+ /**
244
+ * Darken a color
245
+ */
246
+ darken(index, amount = 0.2) {
247
+ const color = this.getRGB(index);
248
+ const r = Math.max(0, Math.round(color.r * (1 - amount)));
249
+ const g = Math.max(0, Math.round(color.g * (1 - amount)));
250
+ const b = Math.max(0, Math.round(color.b * (1 - amount)));
251
+ return _Palette.rgbToHex(r, g, b);
252
+ }
253
+ /**
254
+ * Mix two colors
255
+ */
256
+ mix(index1, index2, ratio = 0.5) {
257
+ const color1 = this.getRGB(index1);
258
+ const color2 = this.getRGB(index2);
259
+ const r = Math.round(color1.r + (color2.r - color1.r) * ratio);
260
+ const g = Math.round(color1.g + (color2.g - color1.g) * ratio);
261
+ const b = Math.round(color1.b + (color2.b - color1.b) * ratio);
262
+ return _Palette.rgbToHex(r, g, b);
263
+ }
264
+ /**
265
+ * Export palette data
266
+ */
267
+ toData() {
268
+ return {
269
+ name: this.name,
270
+ colors: this.getAll()
271
+ };
272
+ }
273
+ };
274
+ // Annotate the CommonJS export names for ESM import in node:
275
+ 0 && (module.exports = {
276
+ Palette
277
+ });
278
+ //# sourceMappingURL=palette.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/palette.ts"],"sourcesContent":["/**\n * Palette - Color palette management\n */\n\nimport { APIErrorCode, reportRuntimeError } from \"@al8b/diagnostics\";\nimport type { ColorHex, ColorRGB, PaletteData } from \"../types\";\n\n/** Matches a valid 6-digit hex color string, e.g. \"#1A2B3C\" */\nconst HEX_COLOR_REGEX = /^#[0-9A-Fa-f]{6}$/;\n\nexport interface PaletteOptions {\n\tcolors?: ColorHex[];\n\tname?: string;\n}\n\nexport class Palette {\n\tprivate colors: ColorHex[];\n\tprivate name: string;\n\tprivate rgbCache: Map<number, ColorRGB>;\n\tprivate runtime?: any;\n\n\tconstructor(options: PaletteOptions | PaletteData = {}, runtime?: any) {\n\t\tthis.runtime = runtime;\n\n\t\tif (\"colors\" in options && Array.isArray(options.colors)) {\n\t\t\t// Validate palette format to ensure all colors are valid hex strings\n\t\t\tif (!this.validatePaletteFormat(options.colors)) {\n\t\t\t\treportRuntimeError(this.runtime?.listener, APIErrorCode.E7072, { format: \"invalid color array\" });\n\t\t\t\tthis.colors = [];\n\t\t\t\tthis.name = \"Invalid\";\n\t\t\t} else {\n\t\t\t\tthis.colors = [...options.colors];\n\t\t\t\tthis.name = options.name || \"Custom\";\n\t\t\t}\n\t\t} else {\n\t\t\t// Initialize with empty palette when no valid colors provided\n\t\t\tthis.colors = [];\n\t\t\tthis.name = \"Empty\";\n\t\t}\n\n\t\tthis.rgbCache = new Map();\n\t}\n\n\t/**\n\t * Validate palette format\n\t */\n\tprivate validatePaletteFormat(colors: any[]): boolean {\n\t\tif (!Array.isArray(colors)) return false;\n\t\treturn colors.every((color) => typeof color === \"string\" && HEX_COLOR_REGEX.test(color));\n\t}\n\n\t/**\n\t * Get color by index\n\t */\n\tget(index: number): ColorHex {\n\t\t// Validate color index is a finite, non-negative number\n\t\tif (!isFinite(index) || index < 0) {\n\t\t\treportRuntimeError(this.runtime?.listener, APIErrorCode.E7073, { index, maxIndex: this.colors.length - 1 });\n\t\t\treturn \"#000000\";\n\t\t}\n\n\t\tif (this.colors.length === 0) {\n\t\t\treturn \"#000000\";\n\t\t}\n\n\t\treturn this.colors[index % this.colors.length] || \"#000000\";\n\t}\n\n\t/**\n\t * Get color as RGB object\n\t */\n\tgetRGB(index: number): ColorRGB {\n\t\tif (this.rgbCache.has(index)) {\n\t\t\treturn this.rgbCache.get(index)!;\n\t\t}\n\n\t\tconst hex = this.get(index);\n\t\tconst rgb = this.hexToRGB(hex);\n\t\tthis.rgbCache.set(index, rgb);\n\t\treturn rgb;\n\t}\n\n\t/**\n\t * Get all colors\n\t */\n\tgetAll(): ColorHex[] {\n\t\treturn [...this.colors];\n\t}\n\n\t/**\n\t * Get palette size\n\t */\n\tget size(): number {\n\t\treturn this.colors.length;\n\t}\n\n\t/**\n\t * Get palette name\n\t */\n\tget paletteName(): string {\n\t\treturn this.name;\n\t}\n\n\t/**\n\t * Set color at index (expands palette if needed)\n\t */\n\tset(index: number, color: ColorHex): void {\n\t\t// Validate color index is a finite, non-negative number\n\t\tif (!isFinite(index) || index < 0) {\n\t\t\treportRuntimeError(this.runtime?.listener, APIErrorCode.E7073, { index, maxIndex: this.colors.length - 1 });\n\t\t\treturn;\n\t\t}\n\n\t\t// Validate color format matches hex pattern (#RRGGBB)\n\t\tif (!HEX_COLOR_REGEX.test(color)) {\n\t\t\treportRuntimeError(this.runtime?.listener, APIErrorCode.E7072, { format: color });\n\t\t\treturn;\n\t\t}\n\n\t\t// Expand palette with black (#000000) if index exceeds current size\n\t\twhile (this.colors.length <= index) {\n\t\t\tthis.colors.push(\"#000000\");\n\t\t}\n\t\tthis.colors[index] = color;\n\t\tthis.rgbCache.delete(index);\n\t}\n\n\t/**\n\t * Add color to palette\n\t */\n\tadd(color: ColorHex): number {\n\t\tthis.colors.push(color);\n\t\treturn this.colors.length - 1;\n\t}\n\n\t/**\n\t * Remove color at index\n\t */\n\tremove(index: number): void {\n\t\tif (index >= 0 && index < this.colors.length) {\n\t\t\tthis.colors.splice(index, 1);\n\t\t\tthis.rgbCache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Replace entire palette\n\t */\n\tsetPalette(colors: ColorHex[]): void {\n\t\t// Validate palette format to ensure all colors are valid hex strings\n\t\tif (!this.validatePaletteFormat(colors)) {\n\t\t\treportRuntimeError(this.runtime?.listener, APIErrorCode.E7072, { format: \"invalid color array\" });\n\t\t\treturn;\n\t\t}\n\n\t\tthis.colors = [...colors];\n\t\tthis.rgbCache.clear();\n\t}\n\n\t/**\n\t * Reset to original colors\n\t */\n\treset(paletteData?: PaletteData): void {\n\t\tif (paletteData) {\n\t\t\tthis.colors = [...paletteData.colors];\n\t\t\tthis.name = paletteData.name;\n\t\t}\n\t\tthis.rgbCache.clear();\n\t}\n\n\t/**\n\t * Convert hex to RGB\n\t */\n\tprivate hexToRGB(hex: ColorHex): ColorRGB {\n\t\tconst result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n\t\treturn result\n\t\t\t? {\n\t\t\t\t\tr: Number.parseInt(result[1], 16),\n\t\t\t\t\tg: Number.parseInt(result[2], 16),\n\t\t\t\t\tb: Number.parseInt(result[3], 16),\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tr: 0,\n\t\t\t\t\tg: 0,\n\t\t\t\t\tb: 0,\n\t\t\t\t};\n\t}\n\n\t/**\n\t * Convert RGB to hex\n\t */\n\tstatic rgbToHex(r: number, g: number, b: number): ColorHex {\n\t\treturn \"#\" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();\n\t}\n\n\t/**\n\t * Find closest color in palette\n\t */\n\tfindClosest(targetHex: ColorHex): number {\n\t\tconst target = this.hexToRGB(targetHex);\n\t\tlet closestIndex = 0;\n\t\tlet closestDistance = Number.POSITIVE_INFINITY;\n\n\t\tfor (let i = 0; i < this.colors.length; i++) {\n\t\t\tconst color = this.getRGB(i);\n\t\t\tconst distance = (target.r - color.r) ** 2 + (target.g - color.g) ** 2 + (target.b - color.b) ** 2;\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance;\n\t\t\t\tclosestIndex = i;\n\t\t\t}\n\t\t}\n\n\t\treturn closestIndex;\n\t}\n\n\t/**\n\t * Create a gradient between two palette colors\n\t */\n\tgradient(startIndex: number, endIndex: number, steps: number): ColorHex[] {\n\t\tconst start = this.getRGB(startIndex);\n\t\tconst end = this.getRGB(endIndex);\n\t\tconst gradient: ColorHex[] = [];\n\n\t\tfor (let i = 0; i < steps; i++) {\n\t\t\tconst t = i / (steps - 1);\n\t\t\tconst r = Math.round(start.r + (end.r - start.r) * t);\n\t\t\tconst g = Math.round(start.g + (end.g - start.g) * t);\n\t\t\tconst b = Math.round(start.b + (end.b - start.b) * t);\n\t\t\tgradient.push(Palette.rgbToHex(r, g, b));\n\t\t}\n\n\t\treturn gradient;\n\t}\n\n\t/**\n\t * Lighten a color\n\t */\n\tlighten(index: number, amount: number = 0.2): ColorHex {\n\t\tconst color = this.getRGB(index);\n\t\tconst r = Math.min(255, Math.round(color.r + (255 - color.r) * amount));\n\t\tconst g = Math.min(255, Math.round(color.g + (255 - color.g) * amount));\n\t\tconst b = Math.min(255, Math.round(color.b + (255 - color.b) * amount));\n\t\treturn Palette.rgbToHex(r, g, b);\n\t}\n\n\t/**\n\t * Darken a color\n\t */\n\tdarken(index: number, amount: number = 0.2): ColorHex {\n\t\tconst color = this.getRGB(index);\n\t\tconst r = Math.max(0, Math.round(color.r * (1 - amount)));\n\t\tconst g = Math.max(0, Math.round(color.g * (1 - amount)));\n\t\tconst b = Math.max(0, Math.round(color.b * (1 - amount)));\n\t\treturn Palette.rgbToHex(r, g, b);\n\t}\n\n\t/**\n\t * Mix two colors\n\t */\n\tmix(index1: number, index2: number, ratio: number = 0.5): ColorHex {\n\t\tconst color1 = this.getRGB(index1);\n\t\tconst color2 = this.getRGB(index2);\n\t\tconst r = Math.round(color1.r + (color2.r - color1.r) * ratio);\n\t\tconst g = Math.round(color1.g + (color2.g - color1.g) * ratio);\n\t\tconst b = Math.round(color1.b + (color2.b - color1.b) * ratio);\n\t\treturn Palette.rgbToHex(r, g, b);\n\t}\n\n\t/**\n\t * Export palette data\n\t */\n\ttoData(): PaletteData {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tcolors: this.getAll(),\n\t\t};\n\t}\n}\n"],"mappings":"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","names":["HEX_COLOR_REGEX","Palette","colors","name","rgbCache","runtime","options","Array","isArray","validatePaletteFormat","reportRuntimeError","listener","APIErrorCode","E7072","format","Map","every","color","test","get","index","isFinite","E7073","maxIndex","length","getRGB","has","hex","rgb","hexToRGB","set","getAll","size","paletteName","push","delete","add","remove","splice","clear","setPalette","reset","paletteData","result","exec","r","Number","parseInt","g","b","rgbToHex","toString","slice","toUpperCase","findClosest","targetHex","target","closestIndex","closestDistance","POSITIVE_INFINITY","i","distance","gradient","startIndex","endIndex","steps","start","end","t","Math","round","lighten","amount","min","darken","max","mix","index1","index2","ratio","color1","color2","toData"]}