color-2-name 1.3.1 → 1.3.3

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 (90) hide show
  1. package/CODE_OF_CONDUCT.md +45 -0
  2. package/CONTRIBUTING.md +92 -0
  3. package/biome.json +12 -0
  4. package/lib/@types/color-utils.d.ts +4 -1
  5. package/lib/@types/common.d.ts +3 -3
  6. package/lib/@types/hex-utils.d.ts +1 -1
  7. package/lib/@types/hsl-utils.d.ts +1 -1
  8. package/lib/@types/index.d.ts +13 -12
  9. package/lib/@types/rgb-utils.d.ts +1 -1
  10. package/lib/@types/types.d.ts +5 -0
  11. package/lib/browser/color-2-name.js +792 -500
  12. package/lib/browser/color-2-name.min.js +1 -2
  13. package/lib/cjs/index.js +1 -0
  14. package/lib/esm/color-utils.js +1 -0
  15. package/lib/esm/common.js +1 -0
  16. package/lib/esm/data/colorSet.js +1 -0
  17. package/lib/esm/hex-utils.js +1 -0
  18. package/lib/esm/hsl-utils.js +1 -0
  19. package/lib/esm/index.js +1 -0
  20. package/lib/esm/rgb-utils.js +1 -0
  21. package/package.json +66 -91
  22. package/readme.md +274 -274
  23. package/tests/colors_hex.test.ts +73 -64
  24. package/tests/colors_hsl.test.ts +66 -47
  25. package/tests/colors_rgb.test.ts +58 -35
  26. package/tests/core.test.ts +148 -131
  27. package/tsconfig.json +15 -31
  28. package/.eslintrc.json +0 -12
  29. package/babel.config.json +0 -6
  30. package/jest.config.json +0 -21
  31. package/lib/browser/color-2-name.js.map +0 -7
  32. package/lib/browser/color-2-name.min.js.map +0 -7
  33. package/lib/cjs/_virtual/_tslib.cjs +0 -35
  34. package/lib/cjs/_virtual/_tslib.cjs.map +0 -1
  35. package/lib/cjs/color-utils.cjs +0 -38
  36. package/lib/cjs/color-utils.cjs.map +0 -1
  37. package/lib/cjs/color-utils.d.ts +0 -18
  38. package/lib/cjs/common.cjs +0 -200
  39. package/lib/cjs/common.cjs.map +0 -1
  40. package/lib/cjs/common.d.ts +0 -93
  41. package/lib/cjs/data/colorSet.cjs +0 -148
  42. package/lib/cjs/data/colorSet.cjs.map +0 -1
  43. package/lib/cjs/data/colorSet.d.ts +0 -2
  44. package/lib/cjs/hex-utils.cjs +0 -105
  45. package/lib/cjs/hex-utils.cjs.map +0 -1
  46. package/lib/cjs/hex-utils.d.ts +0 -47
  47. package/lib/cjs/hsl-utils.cjs +0 -140
  48. package/lib/cjs/hsl-utils.cjs.map +0 -1
  49. package/lib/cjs/hsl-utils.d.ts +0 -47
  50. package/lib/cjs/index.cjs +0 -165
  51. package/lib/cjs/index.cjs.map +0 -1
  52. package/lib/cjs/index.d.ts +0 -87
  53. package/lib/cjs/rgb-utils.cjs +0 -58
  54. package/lib/cjs/rgb-utils.cjs.map +0 -1
  55. package/lib/cjs/rgb-utils.d.ts +0 -26
  56. package/lib/cjs/types.d.ts +0 -37
  57. package/lib/esm/_virtual/_tslib.mjs +0 -35
  58. package/lib/esm/_virtual/_tslib.mjs.map +0 -1
  59. package/lib/esm/color-utils.d.ts +0 -18
  60. package/lib/esm/color-utils.mjs +0 -35
  61. package/lib/esm/color-utils.mjs.map +0 -1
  62. package/lib/esm/common.d.ts +0 -93
  63. package/lib/esm/common.mjs +0 -184
  64. package/lib/esm/common.mjs.map +0 -1
  65. package/lib/esm/data/colorSet.d.ts +0 -2
  66. package/lib/esm/data/colorSet.mjs +0 -146
  67. package/lib/esm/data/colorSet.mjs.map +0 -1
  68. package/lib/esm/hex-utils.d.ts +0 -47
  69. package/lib/esm/hex-utils.mjs +0 -98
  70. package/lib/esm/hex-utils.mjs.map +0 -1
  71. package/lib/esm/hsl-utils.d.ts +0 -47
  72. package/lib/esm/hsl-utils.mjs +0 -133
  73. package/lib/esm/hsl-utils.mjs.map +0 -1
  74. package/lib/esm/index.d.ts +0 -87
  75. package/lib/esm/index.mjs +0 -156
  76. package/lib/esm/index.mjs.map +0 -1
  77. package/lib/esm/rgb-utils.d.ts +0 -26
  78. package/lib/esm/rgb-utils.mjs +0 -53
  79. package/lib/esm/rgb-utils.mjs.map +0 -1
  80. package/lib/esm/types.d.ts +0 -37
  81. package/lib/umd/color-2-name.js +0 -820
  82. package/lib/umd/color-2-name.min.js +0 -1
  83. package/lib/umd/color-utils.d.ts +0 -18
  84. package/lib/umd/common.d.ts +0 -93
  85. package/lib/umd/data/colorSet.d.ts +0 -2
  86. package/lib/umd/hex-utils.d.ts +0 -47
  87. package/lib/umd/hsl-utils.d.ts +0 -47
  88. package/lib/umd/index.d.ts +0 -87
  89. package/lib/umd/rgb-utils.d.ts +0 -26
  90. package/lib/umd/types.d.ts +0 -37
@@ -1,510 +1,802 @@
1
- "use strict";
2
- var color2name = (() => {
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
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);
1
+ var color2name = (function (exports) {
2
+ 'use strict';
20
3
 
21
- // src/color-2-name.ts
22
- var color_2_name_exports = {};
23
- __export(color_2_name_exports, {
24
- color2name: () => src_exports
25
- });
26
-
27
- // src/index.ts
28
- var src_exports = {};
29
- __export(src_exports, {
30
- closest: () => closest,
31
- closestRGB: () => closestRGB,
32
- distance: () => distance,
33
- getColor: () => getColor,
34
- getColors: () => getColors,
35
- isDark: () => isDark,
36
- isLight: () => isLight,
37
- parseColor: () => parseColor,
38
- rgbToHex: () => rgbToHex
39
- });
40
-
41
- // src/data/colorSet.ts
42
- var colorSet = [
43
- [255, 255, 255, "white"],
44
- [0, 0, 0, "black"],
45
- [255, 0, 0, "red"],
46
- [0, 128, 0, "green"],
47
- [0, 0, 255, "blue"],
48
- [255, 165, 0, "orange"],
49
- [128, 128, 128, "grey"],
50
- [255, 255, 0, "yellow"],
51
- [255, 0, 255, "magenta"],
52
- [154, 205, 50, "yellowgreen"],
53
- [192, 192, 192, "silver"],
54
- [0, 255, 0, "lime"],
55
- [128, 0, 128, "purple"],
56
- [255, 99, 71, "tomato"],
57
- [64, 224, 208, "turquoise"],
58
- [255, 127, 80, "coral"],
59
- [0, 255, 255, "cyan"],
60
- [255, 250, 240, "floralwhite"],
61
- [255, 192, 203, "pink"],
62
- [34, 139, 34, "forestgreen"],
63
- [245, 245, 220, "beige"],
64
- [255, 0, 255, "fuchsia"],
65
- [220, 220, 220, "gainsboro"],
66
- [248, 248, 255, "ghostwhite"],
67
- [255, 215, 0, "gold"],
68
- [218, 165, 32, "goldenrod"],
69
- [173, 255, 47, "greenyellow"],
70
- [238, 130, 238, "violet"],
71
- [245, 222, 179, "wheat"],
72
- [245, 245, 245, "whitesmoke"],
73
- [139, 0, 0, "darkred"],
74
- [240, 248, 255, "aliceblue"],
75
- [205, 92, 92, "indianred"],
76
- [75, 0, 130, "indigo"],
77
- [250, 235, 215, "antiquewhite"],
78
- [0, 255, 255, "aqua"],
79
- [127, 255, 212, "aquamarine"],
80
- [240, 255, 255, "azure"],
81
- [255, 228, 196, "bisque"],
82
- [255, 235, 205, "blanchedalmond"],
83
- [138, 43, 226, "blueviolet"],
84
- [165, 42, 42, "brown"],
85
- [222, 184, 135, "burlywood"],
86
- [95, 158, 160, "cadetblue"],
87
- [127, 255, 0, "chartreuse"],
88
- [210, 105, 30, "chocolate"],
89
- [100, 149, 237, "cornflowerblue"],
90
- [255, 248, 220, "cornsilk"],
91
- [220, 20, 60, "crimson"],
92
- [0, 0, 139, "darkblue"],
93
- [0, 139, 139, "darkcyan"],
94
- [184, 134, 11, "darkgoldenrod"],
95
- [169, 169, 169, "darkgrey"],
96
- [0, 100, 0, "darkgreen"],
97
- [189, 183, 107, "darkkhaki"],
98
- [139, 0, 139, "darkmagenta"],
99
- [85, 107, 47, "darkolivegreen"],
100
- [255, 140, 0, "darkorange"],
101
- [153, 50, 204, "darkorchid"],
102
- [233, 150, 122, "darksalmon"],
103
- [143, 188, 143, "darkseagreen"],
104
- [72, 61, 139, "darkslateblue"],
105
- [47, 79, 79, "darkslategrey"],
106
- [0, 206, 209, "darkturquoise"],
107
- [148, 0, 211, "darkviolet"],
108
- [255, 20, 147, "deeppink"],
109
- [0, 191, 255, "deepskyblue"],
110
- [105, 105, 105, "dimgrey"],
111
- [30, 144, 255, "dodgerblue"],
112
- [178, 34, 34, "firebrick"],
113
- [240, 255, 240, "honeydew"],
114
- [255, 105, 180, "hotpink"],
115
- [255, 255, 240, "ivory"],
116
- [240, 230, 140, "khaki"],
117
- [230, 230, 250, "lavender"],
118
- [255, 240, 245, "lavenderblush"],
119
- [124, 252, 0, "lawngreen"],
120
- [255, 250, 205, "lemonchiffon"],
121
- [173, 216, 230, "lightblue"],
122
- [240, 128, 128, "lightcoral"],
123
- [224, 255, 255, "lightcyan"],
124
- [250, 250, 210, "lightgoldenrodyellow"],
125
- [144, 238, 144, "lightgreen"],
126
- [211, 211, 211, "lightgrey"],
127
- [255, 182, 193, "lightpink"],
128
- [255, 160, 122, "lightsalmon"],
129
- [32, 178, 170, "lightseagreen"],
130
- [135, 206, 250, "lightskyblue"],
131
- [119, 136, 153, "lightslategrey"],
132
- [176, 196, 222, "lightsteelblue"],
133
- [255, 255, 224, "lightyellow"],
134
- [50, 205, 50, "limegreen"],
135
- [250, 240, 230, "linen"],
136
- [128, 0, 0, "maroon"],
137
- [102, 205, 170, "mediumaquamarine"],
138
- [0, 0, 205, "mediumblue"],
139
- [186, 85, 211, "mediumorchid"],
140
- [147, 112, 219, "mediumpurple"],
141
- [60, 179, 113, "mediumseagreen"],
142
- [123, 104, 238, "mediumslateblue"],
143
- [0, 250, 154, "mediumspringgreen"],
144
- [72, 209, 204, "mediumturquoise"],
145
- [199, 21, 133, "mediumvioletred"],
146
- [25, 25, 112, "midnightblue"],
147
- [245, 255, 250, "mintcream"],
148
- [255, 228, 225, "mistyrose"],
149
- [255, 228, 181, "moccasin"],
150
- [255, 222, 173, "navajowhite"],
151
- [0, 0, 128, "navy"],
152
- [253, 245, 230, "oldlace"],
153
- [128, 128, 0, "olive"],
154
- [107, 142, 35, "olivedrab"],
155
- [255, 69, 0, "orangered"],
156
- [218, 112, 214, "orchid"],
157
- [238, 232, 170, "palegoldenrod"],
158
- [152, 251, 152, "palegreen"],
159
- [175, 238, 238, "paleturquoise"],
160
- [219, 112, 147, "palevioletred"],
161
- [255, 239, 213, "papayawhip"],
162
- [255, 218, 185, "peachpuff"],
163
- [205, 133, 63, "peru"],
164
- [221, 160, 221, "plum"],
165
- [176, 224, 230, "powderblue"],
166
- [102, 51, 153, "rebeccapurple"],
167
- [188, 143, 143, "rosybrown"],
168
- [65, 105, 225, "royalblue"],
169
- [139, 69, 19, "saddlebrown"],
170
- [250, 128, 114, "salmon"],
171
- [244, 164, 96, "sandybrown"],
172
- [46, 139, 87, "seagreen"],
173
- [255, 245, 238, "seashell"],
174
- [160, 82, 45, "sienna"],
175
- [135, 206, 235, "skyblue"],
176
- [106, 90, 205, "slateblue"],
177
- [112, 128, 144, "slategrey"],
178
- [255, 250, 250, "snow"],
179
- [0, 255, 127, "springgreen"],
180
- [70, 130, 180, "steelblue"],
181
- [210, 180, 140, "tan"],
182
- [0, 128, 128, "teal"],
183
- [216, 191, 216, "thistle"]
184
- ];
185
- var colorSet_default = colorSet;
4
+ const colorSet = [
5
+ [255, 255, 255, "white"],
6
+ [0, 0, 0, "black"],
7
+ [255, 0, 0, "red"],
8
+ [0, 128, 0, "green"],
9
+ [0, 0, 255, "blue"],
10
+ [255, 165, 0, "orange"],
11
+ [128, 128, 128, "grey"],
12
+ [255, 255, 0, "yellow"],
13
+ [255, 0, 255, "magenta"],
14
+ [154, 205, 50, "yellowgreen"],
15
+ [192, 192, 192, "silver"],
16
+ [0, 255, 0, "lime"],
17
+ [128, 0, 128, "purple"],
18
+ [255, 99, 71, "tomato"],
19
+ [64, 224, 208, "turquoise"],
20
+ [255, 127, 80, "coral"],
21
+ [0, 255, 255, "cyan"],
22
+ [255, 250, 240, "floralwhite"],
23
+ [255, 192, 203, "pink"],
24
+ [34, 139, 34, "forestgreen"],
25
+ [245, 245, 220, "beige"],
26
+ [255, 0, 255, "fuchsia"],
27
+ [220, 220, 220, "gainsboro"],
28
+ [248, 248, 255, "ghostwhite"],
29
+ [255, 215, 0, "gold"],
30
+ [218, 165, 32, "goldenrod"],
31
+ [173, 255, 47, "greenyellow"],
32
+ [238, 130, 238, "violet"],
33
+ [245, 222, 179, "wheat"],
34
+ [245, 245, 245, "whitesmoke"],
35
+ [139, 0, 0, "darkred"],
36
+ [240, 248, 255, "aliceblue"],
37
+ [205, 92, 92, "indianred"],
38
+ [75, 0, 130, "indigo"],
39
+ [250, 235, 215, "antiquewhite"],
40
+ [0, 255, 255, "aqua"],
41
+ [127, 255, 212, "aquamarine"],
42
+ [240, 255, 255, "azure"],
43
+ [255, 228, 196, "bisque"],
44
+ [255, 235, 205, "blanchedalmond"],
45
+ [138, 43, 226, "blueviolet"],
46
+ [165, 42, 42, "brown"],
47
+ [222, 184, 135, "burlywood"],
48
+ [95, 158, 160, "cadetblue"],
49
+ [127, 255, 0, "chartreuse"],
50
+ [210, 105, 30, "chocolate"],
51
+ [100, 149, 237, "cornflowerblue"],
52
+ [255, 248, 220, "cornsilk"],
53
+ [220, 20, 60, "crimson"],
54
+ [0, 0, 139, "darkblue"],
55
+ [0, 139, 139, "darkcyan"],
56
+ [184, 134, 11, "darkgoldenrod"],
57
+ [169, 169, 169, "darkgrey"],
58
+ [0, 100, 0, "darkgreen"],
59
+ [189, 183, 107, "darkkhaki"],
60
+ [139, 0, 139, "darkmagenta"],
61
+ [85, 107, 47, "darkolivegreen"],
62
+ [255, 140, 0, "darkorange"],
63
+ [153, 50, 204, "darkorchid"],
64
+ [233, 150, 122, "darksalmon"],
65
+ [143, 188, 143, "darkseagreen"],
66
+ [72, 61, 139, "darkslateblue"],
67
+ [47, 79, 79, "darkslategrey"],
68
+ [0, 206, 209, "darkturquoise"],
69
+ [148, 0, 211, "darkviolet"],
70
+ [255, 20, 147, "deeppink"],
71
+ [0, 191, 255, "deepskyblue"],
72
+ [105, 105, 105, "dimgrey"],
73
+ [30, 144, 255, "dodgerblue"],
74
+ [178, 34, 34, "firebrick"],
75
+ [240, 255, 240, "honeydew"],
76
+ [255, 105, 180, "hotpink"],
77
+ [255, 255, 240, "ivory"],
78
+ [240, 230, 140, "khaki"],
79
+ [230, 230, 250, "lavender"],
80
+ [255, 240, 245, "lavenderblush"],
81
+ [124, 252, 0, "lawngreen"],
82
+ [255, 250, 205, "lemonchiffon"],
83
+ [173, 216, 230, "lightblue"],
84
+ [240, 128, 128, "lightcoral"],
85
+ [224, 255, 255, "lightcyan"],
86
+ [250, 250, 210, "lightgoldenrodyellow"],
87
+ [144, 238, 144, "lightgreen"],
88
+ [211, 211, 211, "lightgrey"],
89
+ [255, 182, 193, "lightpink"],
90
+ [255, 160, 122, "lightsalmon"],
91
+ [32, 178, 170, "lightseagreen"],
92
+ [135, 206, 250, "lightskyblue"],
93
+ [119, 136, 153, "lightslategrey"],
94
+ [176, 196, 222, "lightsteelblue"],
95
+ [255, 255, 224, "lightyellow"],
96
+ [50, 205, 50, "limegreen"],
97
+ [250, 240, 230, "linen"],
98
+ [128, 0, 0, "maroon"],
99
+ [102, 205, 170, "mediumaquamarine"],
100
+ [0, 0, 205, "mediumblue"],
101
+ [186, 85, 211, "mediumorchid"],
102
+ [147, 112, 219, "mediumpurple"],
103
+ [60, 179, 113, "mediumseagreen"],
104
+ [123, 104, 238, "mediumslateblue"],
105
+ [0, 250, 154, "mediumspringgreen"],
106
+ [72, 209, 204, "mediumturquoise"],
107
+ [199, 21, 133, "mediumvioletred"],
108
+ [25, 25, 112, "midnightblue"],
109
+ [245, 255, 250, "mintcream"],
110
+ [255, 228, 225, "mistyrose"],
111
+ [255, 228, 181, "moccasin"],
112
+ [255, 222, 173, "navajowhite"],
113
+ [0, 0, 128, "navy"],
114
+ [253, 245, 230, "oldlace"],
115
+ [128, 128, 0, "olive"],
116
+ [107, 142, 35, "olivedrab"],
117
+ [255, 69, 0, "orangered"],
118
+ [218, 112, 214, "orchid"],
119
+ [238, 232, 170, "palegoldenrod"],
120
+ [152, 251, 152, "palegreen"],
121
+ [175, 238, 238, "paleturquoise"],
122
+ [219, 112, 147, "palevioletred"],
123
+ [255, 239, 213, "papayawhip"],
124
+ [255, 218, 185, "peachpuff"],
125
+ [205, 133, 63, "peru"],
126
+ [221, 160, 221, "plum"],
127
+ [176, 224, 230, "powderblue"],
128
+ [102, 51, 153, "rebeccapurple"],
129
+ [188, 143, 143, "rosybrown"],
130
+ [65, 105, 225, "royalblue"],
131
+ [139, 69, 19, "saddlebrown"],
132
+ [250, 128, 114, "salmon"],
133
+ [244, 164, 96, "sandybrown"],
134
+ [46, 139, 87, "seagreen"],
135
+ [255, 245, 238, "seashell"],
136
+ [160, 82, 45, "sienna"],
137
+ [135, 206, 235, "skyblue"],
138
+ [106, 90, 205, "slateblue"],
139
+ [112, 128, 144, "slategrey"],
140
+ [255, 250, 250, "snow"],
141
+ [0, 255, 127, "springgreen"],
142
+ [70, 130, 180, "steelblue"],
143
+ [210, 180, 140, "tan"],
144
+ [0, 128, 128, "teal"],
145
+ [216, 191, 216, "thistle"],
146
+ ];
186
147
 
187
- // src/common.ts
188
- var hexRegex = /^#([\da-f]{3,8})/i;
189
- var rgbRegex = /^rgba?\(([^)]+)\)/i;
190
- var hslRegex = /^hsla?\(([^)]+)\)/i;
191
- var isNumeric = /^-?\d*\.?\d+$/i;
192
- var stripComments = /(\/\*[^*]*\*\/)|(\/\/[^*]*)/g;
193
- var BLACKANDWHITE = [
194
- [255, 255, 255, "white"],
195
- [1, 1, 1, "black"]
196
- ];
197
- var RGBSET = [
198
- [255, 0, 0, "red"],
199
- [0, 255, 0, "green"],
200
- [0, 0, 255, "blue"]
201
- ];
202
- function splitValues(rawValues) {
203
- return rawValues.split(rawValues.includes(",") ? "," : " ").map((s) => s.trim());
204
- }
205
- function normalizeDegrees(angle) {
206
- let degAngle = parseFloat(angle) || 0;
207
- if (angle.indexOf("deg") > -1) {
208
- degAngle = parseFloat(angle.substring(0, angle.length - 3));
209
- } else if (angle.indexOf("rad") > -1) {
210
- degAngle = Math.round(parseFloat(angle.substring(0, angle.length - 3)) * (180 / Math.PI));
211
- } else if (angle.indexOf("turn") > -1) {
212
- degAngle = Math.round(parseFloat(angle.substring(0, angle.length - 4)) * 360);
213
- }
214
- while (degAngle < 0) {
215
- degAngle += 360;
216
- }
217
- if (degAngle >= 360)
218
- degAngle %= 360;
219
- return degAngle;
220
- }
221
- function limitValue(value, min = 0, max = 0) {
222
- return Math.min(Math.max(Math.round(value), min), max);
223
- }
224
- function calculateValue(valueString, multiplier) {
225
- const regex = /calc\(([^)]+)\)/;
226
- const match = valueString.match(regex);
227
- if (match) {
228
- valueString = match[1];
229
- }
230
- return convertToInt8(valueString, multiplier);
231
- }
232
- function cleanDefinition(string) {
233
- const cleanString = string.replace(stripComments, "");
234
- const firstParenthesisIndex = cleanString.indexOf("(");
235
- const lastParenthesisIndex = cleanString.lastIndexOf(")");
236
- return cleanString.slice(firstParenthesisIndex + 1, lastParenthesisIndex).trim();
237
- }
238
- function normalizePercentage(value, multiplier) {
239
- return parseFloat(value) / 100 * multiplier;
240
- }
241
- function colorValueFallbacks(value, err) {
242
- if (value === "infinity") {
243
- console.warn(err || `Positive infinity value has been set to 255: ${value}`);
244
- return 255;
245
- }
246
- if (value === "currentColor")
247
- console.warn(err || `The "currentColor" value has been set to 0: ${value}`);
248
- if (value === "transparent")
249
- console.warn(err || `The "transparent" value has been set to 0: ${value}`);
250
- if (value === "NaN")
251
- console.warn(err || `"NaN" value has been set to 0: ${value}`);
252
- if (value === "-infinity")
253
- console.warn(err || `"Negative" infinity value has been set to 0: ${value}`);
254
- if (value === "none")
255
- console.warn(err || `The none keyword is invalid in legacy color syntax: ${value}`);
256
- return 0;
257
- }
258
- function convertToInt8(value, multiplier = 255) {
259
- value = value ? value?.trim() : "0";
260
- if (isNumeric.test(value)) {
261
- return limitValue(parseFloat(value) || 0, 0, multiplier);
262
- } else if (value.endsWith("%")) {
263
- return normalizePercentage(value, multiplier) || 0;
264
- } else if (value.endsWith("deg") || value.endsWith("rad") || value.endsWith("turn")) {
265
- return normalizeDegrees(value);
266
- } else if (value.startsWith("calc")) {
267
- return limitValue(calculateValue(value, multiplier), 0, multiplier);
268
- }
269
- return colorValueFallbacks(value, `Invalid value: ${value}`);
270
- }
148
+ /** The maximum distance possible between colors */
149
+ /** A regex to match hex colors */
150
+ const hexRegex = /^#([\da-f]{3,8})/i;
151
+ /** A regex to match rgb colors */
152
+ const rgbRegex = /^rgba?\(([^)]+)\)/i;
153
+ /** A regex to match hsl colors */
154
+ const hslRegex = /^hsla?\(([^)]+)\)/i;
155
+ /** A regex to match strings that are only valid numbers with and without decimals and the number can be negative and without the 0 in the beginning */
156
+ const isNumeric = /^-?\d*\.?\d+$/i;
157
+ /** Remove comments from string */
158
+ const stripComments = /(\/\*[^*]*\*\/)|(\/\/[^*]*)/g;
159
+ /**
160
+ * This set is used to detect if the color is bright or dark
161
+ *
162
+ * @note the set has been corrected to get pure RGB values (eg. pure red, pure green) in the "bright" area
163
+ */
164
+ const BLACKANDWHITE = [
165
+ [255, 255, 255, "white"],
166
+ [1, 1, 1, "black"],
167
+ ];
168
+ /**
169
+ * This set is used to detect the nearest rgb color
170
+ */
171
+ const RGBSET = [
172
+ [255, 0, 0, "red"],
173
+ [0, 255, 0, "green"],
174
+ [0, 0, 255, "blue"],
175
+ ];
176
+ /**
177
+ * split the content of rgb and hsl colors depending on the parsed value of the css property
178
+ *
179
+ * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb#syntax
180
+ *
181
+ * @param {string} rawValues - the value inside the rgb(.*) css color definition
182
+ *
183
+ * @return {Array} the array of rgb values found inside the passed string
184
+ */
185
+ function splitValues(rawValues) {
186
+ return rawValues
187
+ .split(rawValues.includes(",") ? "," : " ")
188
+ .map((s) => s.trim());
189
+ }
190
+ /**
191
+ * If the value is an angle in degrees, convert it to the 0-360 range
192
+ *
193
+ * @param {string} angle - the degrees to convert into a number
194
+ *
195
+ * @return {number} the converted value
196
+ */
197
+ function normalizeDegrees(angle) {
198
+ // Strip label and convert to degrees (if necessary)
199
+ let degAngle = Number.parseFloat(angle) || 0;
200
+ if (angle.indexOf("deg") > -1) {
201
+ degAngle = Number.parseFloat(angle.substring(0, angle.length - 3));
202
+ }
203
+ else if (angle.indexOf("rad") > -1) {
204
+ degAngle = Math.round(Number.parseFloat(angle.substring(0, angle.length - 3)) * (180 / Math.PI));
205
+ }
206
+ else if (angle.indexOf("turn") > -1) {
207
+ degAngle = Math.round(Number.parseFloat(angle.substring(0, angle.length - 4)) * 360);
208
+ }
209
+ while (degAngle < 0) {
210
+ degAngle += 360;
211
+ }
212
+ // Make sure it's a number between 0 and 360
213
+ if (degAngle >= 360)
214
+ degAngle %= 360;
215
+ return degAngle;
216
+ }
217
+ /**
218
+ * Returns a value that is limited between a minimum and maximum value.
219
+ *
220
+ * @param {number} value - The value to be limited.
221
+ * @param {number} min - The minimum allowed value (default is 0).
222
+ * @param {number} max - The maximum allowed value (default is 0).
223
+ * @return {number} The limited value.
224
+ */
225
+ function limitValue(value, min = 0, max = 0) {
226
+ return Math.min(Math.max(Math.round(value), min), max);
227
+ }
228
+ /**
229
+ * Calculates the value based on a given string and multiplier.
230
+ *
231
+ * @param {string} valueString - The string representing the value to be calculated.
232
+ * @param {number} multiplier - The multiplier to be applied to the calculated value.
233
+ * @return {number} The calculated value.
234
+ */
235
+ function calculateValue(valueString, multiplier) {
236
+ // Regular expression to match the calc() function and extract the numerical value
237
+ const regex = /calc\(([^)]+)\)/;
238
+ // Match the calc() function in the CSS string
239
+ const match = valueString.match(regex);
240
+ return convertToInt8(match ? match[1] : valueString, multiplier);
241
+ }
242
+ /**
243
+ * Removes comments from the input string and extracts the content between the first opening parenthesis
244
+ * and the last closing parenthesis.
245
+ *
246
+ * @param {string} string - The input string.
247
+ * @return {string} The content between the first opening parenthesis and the last closing parenthesis.
248
+ */
249
+ function cleanDefinition(string) {
250
+ // Remove comments from the string
251
+ const cleanString = string.replace(stripComments, "");
252
+ // Find the positions of the first opening and the last closing parentheses
253
+ const firstParenthesisIndex = cleanString.indexOf("(");
254
+ const lastParenthesisIndex = cleanString.lastIndexOf(")");
255
+ // Extract the content between the parentheses
256
+ return cleanString
257
+ .slice(firstParenthesisIndex + 1, lastParenthesisIndex)
258
+ .trim();
259
+ }
260
+ /**
261
+ * Normalizes a percentage value by dividing it by 100 and multiplying it by a given multiplier.
262
+ *
263
+ * @param {string} value - The percentage value to be normalized.
264
+ * @param {number} multiplier - The number to multiply the normalized percentage by.
265
+ * @return {number} The normalized percentage value.
266
+ */
267
+ function normalizePercentage(value, multiplier) {
268
+ return (Number.parseFloat(value) / 100) * multiplier;
269
+ }
270
+ /**
271
+ * Calculates the color value fallbacks for a given value.
272
+ *
273
+ * @param {string} value - The color value to calculate fallbacks for.
274
+ * @param {string} [err] - An optional error message to display.
275
+ * @return {number} - The calculated color value fallbacks.
276
+ */
277
+ function colorValueFallbacks(value, err) {
278
+ if (value === "infinity") {
279
+ console.warn(err || `Positive infinity value has been set to 255: ${value}`);
280
+ return 255;
281
+ }
282
+ if (value === "currentColor")
283
+ console.warn(err || `The "currentColor" value has been set to 0: ${value}`);
284
+ if (value === "transparent")
285
+ console.warn(err || `The "transparent" value has been set to 0: ${value}`);
286
+ if (value === "NaN")
287
+ console.warn(err || `"NaN" value has been set to 0: ${value}`);
288
+ if (value === "-infinity")
289
+ console.warn(err || `"Negative" infinity value has been set to 0: ${value}`);
290
+ if (value === "none")
291
+ console.warn(err || `The none keyword is invalid in legacy color syntax: ${value}`);
292
+ return 0;
293
+ }
294
+ /**
295
+ * Takes a string with a css value that could be a number or percentage or an angle in degrees and returns the corresponding 8bit value
296
+ *
297
+ * @param value - a valid value for the css color definition (like 255, "100%", "324deg", etc.) *
298
+ * @param multiplier - the number that represent the maximum - default is 255 decimal - 100 hex
299
+ *
300
+ * @example convertToInt8('100%'); // 255
301
+ *
302
+ * @return {string} the corresponding value in 8-bit format
303
+ */
304
+ function convertToInt8(value, multiplier = 255) {
305
+ const newValue = typeof value === "string" ? value?.trim() : "0";
306
+ if (isNumeric.test(newValue)) {
307
+ // limit the min and the max newValue
308
+ return limitValue(Number.parseFloat(newValue) || 0, 0, multiplier);
309
+ }
310
+ if (newValue.endsWith("%")) {
311
+ // If the newValue is a percentage, divide it by 100 to get a newValue from 0 to 1
312
+ // and then multiply it by 255 to get a newValue from 0 to 255
313
+ return normalizePercentage(newValue, multiplier) || 0;
314
+ }
315
+ if (newValue.endsWith("deg") ||
316
+ newValue.endsWith("rad") ||
317
+ newValue.endsWith("turn")) {
318
+ return normalizeDegrees(newValue);
319
+ }
320
+ if (newValue.startsWith("calc")) {
321
+ // get the newValue from the calc function
322
+ return limitValue(calculateValue(newValue, multiplier), 0, multiplier);
323
+ }
324
+ // If the value is not a percentage or an angle in degrees, it is invalid
325
+ return colorValueFallbacks(newValue, `Invalid value: ${value}`);
326
+ }
271
327
 
272
- // src/rgb-utils.ts
273
- function fallbackRGB(rgb, err = `Invalid RGB color`) {
274
- console.warn(err);
275
- return [rgb[0] ?? 0, rgb[1] ?? 0, rgb[2]];
276
- }
277
- function parseRgb(rgbAsString) {
278
- const rgbvalue = cleanDefinition(rgbAsString);
279
- const rgb = splitValues(rgbvalue);
280
- if (rgb.length !== 3 && rgb.length !== 4) {
281
- return fallbackRGB(rgb, `Too few values to define rgb: ${rgbAsString} -> ${rgbvalue}`);
282
- } else {
283
- return [rgb[0], rgb[1], rgb[2]];
284
- }
285
- }
286
- function getRgbValues(rgb) {
287
- return {
288
- r: limitValue(Math.round(convertToInt8(rgb[0])), 0, 255) || 0,
289
- g: limitValue(Math.round(convertToInt8(rgb[1])), 0, 255) || 0,
290
- b: limitValue(Math.round(convertToInt8(rgb[2])), 0, 255) || 0
291
- };
292
- }
293
- function RGB(rgb) {
294
- return `rgb(${rgb.r},${rgb.g},${rgb.b})`;
295
- }
328
+ function fallbackRGB(rgb, err = "Invalid RGB color") {
329
+ console.warn(err);
330
+ return [rgb[0] ?? 0, rgb[1] ?? 0, rgb[2]];
331
+ }
332
+ /**
333
+ * Get the values of the rgb string
334
+ *
335
+ * @param rgbAsString - the rgb color as string split into values
336
+ *
337
+ * @return {Array} the values of the rgb string as Array of strings that represent the rgb color
338
+ */
339
+ function parseRgb(rgbAsString) {
340
+ const rgbvalue = cleanDefinition(rgbAsString);
341
+ const rgb = splitValues(rgbvalue);
342
+ if (rgb.length !== 3 && rgb.length !== 4) {
343
+ return fallbackRGB(rgb, `Too few values to define rgb: ${rgbAsString} -> ${rgbvalue}`);
344
+ }
345
+ return [rgb[0], rgb[1], rgb[2]];
346
+ }
347
+ /**
348
+ * This function takes an array of strings and returns and object with the rgb values converted into INT8 (0-255)
349
+ *
350
+ * @param {Array} rgb - rgb color as Array of strings
351
+ *
352
+ * @return {Object} an object that contains the r, g and b values as INT8
353
+ */
354
+ function getRgbValues(rgb) {
355
+ // use the channel key as the new array key
356
+ return {
357
+ r: limitValue(Math.round(convertToInt8(rgb[0])), 0, 255) || 0,
358
+ g: limitValue(Math.round(convertToInt8(rgb[1])), 0, 255) || 0,
359
+ b: limitValue(Math.round(convertToInt8(rgb[2])), 0, 255) || 0,
360
+ };
361
+ }
362
+ /**
363
+ * returns a string representation of the rgb values
364
+ *
365
+ * @param {Object} rgb the rgb color object
366
+ *
367
+ * @return {string} a string representation of the rgb values
368
+ */
369
+ function RGB(rgb) {
370
+ return `rgb(${rgb.r},${rgb.g},${rgb.b})`;
371
+ }
296
372
 
297
- // src/hex-utils.ts
298
- function shortHexToLongHex(value) {
299
- return Array.from(value).map((v) => (v + v).toUpperCase());
300
- }
301
- function isHex(num) {
302
- return Boolean(num.match(/^[0-9a-f]+$/i));
303
- }
304
- function parseHex(value) {
305
- const hexColor = value.substring(1);
306
- let hexArray = [];
307
- if (hexColor) {
308
- if (hexColor.length === 3 || hexColor.length === 4) {
309
- hexArray = shortHexToLongHex(hexColor);
310
- } else if (hexColor.length === 6 || hexColor.length === 8) {
311
- hexArray = (hexColor.match(/../g) || []).map((value2) => value2);
312
- }
313
- }
314
- if (hexArray.length) {
315
- hexArray?.forEach((value2, index) => {
316
- if (isHex(value2)) {
317
- hexArray[index] = value2.toUpperCase();
318
- } else {
319
- console.warn(`Invalid Hex value: ${value2}`);
373
+ /**
374
+ * It returns an object with the hex values of the 3 digit hex color
375
+ *
376
+ * @param {string} value 3 digit hex
377
+ * @return {string[]} 6 digit hex
378
+ */
379
+ function shortHexToLongHex(value) {
380
+ // split the string in to an array of digits then return an array that contains that digit doubled for each item
381
+ return Array.from(value).map((v) => (v + v).toUpperCase());
382
+ }
383
+ /**
384
+ * Checks if a given string represents a hexadecimal number.
385
+ *
386
+ * @param {string} num - The string to be checked.
387
+ * @return {boolean} Returns true if the string is a valid hexadecimal number, false otherwise.
388
+ */
389
+ function isHex(num) {
390
+ return Boolean(num.match(/^[0-9a-f]+$/i));
391
+ }
392
+ /**
393
+ * Get the hex value of the color and convert it to an Object of R G And B values (still in hex format)
394
+ *
395
+ * @param value the string that contains the color in hex format
396
+ *
397
+ * @return {string[]} an array of 6 digit hex values in a triplet of R G and B (HEX format)
398
+ */
399
+ function parseHex(value) {
400
+ // remove # at the beginning of the hex color
401
+ const hexColor = value.substring(1);
402
+ /**
403
+ * then if the number of digits is greater than 2 (so it's something like 123 or abc456)
404
+ * breakdown the string into an object that contains the r g and b values in hex
405
+ */
406
+ let hexArray = [];
407
+ if (hexColor) {
408
+ if (hexColor.length === 3 || hexColor.length === 4) {
409
+ hexArray = shortHexToLongHex(hexColor);
410
+ }
411
+ else if (hexColor.length === 6 || hexColor.length === 8) {
412
+ // match the hex value in groups of 2
413
+ hexArray = (hexColor.match(/../g) || []).map((value) => value);
414
+ }
415
+ }
416
+ if (hexArray.length) {
417
+ hexArray?.forEach((value, index) => {
418
+ if (isHex(value)) {
419
+ hexArray[index] = value.toUpperCase();
420
+ }
421
+ else {
422
+ console.warn(`Invalid Hex value: ${value}`);
423
+ }
424
+ });
425
+ return hexArray;
320
426
  }
321
- });
322
- return hexArray;
323
- }
324
- console.warn(`Invalid Hex: ${value}`);
325
- return fallbackRGB(hexArray);
326
- }
327
- function hexToRgb(hex) {
328
- return {
329
- r: parseInt(hex[0], 16),
330
- g: parseInt(hex[1], 16),
331
- b: parseInt(hex[2], 16)
332
- };
333
- }
334
- function toHex(int8) {
335
- return int8.toString(16).padStart(2, "0");
336
- }
337
- function valuesToHex(rgb) {
338
- return `#${toHex(rgb?.r)}${toHex(rgb?.g)}${toHex(rgb?.b)}`;
339
- }
427
+ console.warn(`Invalid Hex: ${value}`);
428
+ return fallbackRGB(hexArray);
429
+ }
430
+ /**
431
+ * Converts a Hex color to rgb
432
+ *
433
+ * @param {string} hex a tuple of hex values
434
+ *
435
+ * @return {string} the rgb color values for the given hex color
436
+ */
437
+ function hexToRgb(hex) {
438
+ // Extract the RGB values from the hex string
439
+ return {
440
+ r: Number.parseInt(hex[0], 16),
441
+ g: Number.parseInt(hex[1], 16),
442
+ b: Number.parseInt(hex[2], 16),
443
+ };
444
+ }
445
+ /**
446
+ * Convert a INT8 value to HEX
447
+ *
448
+ * @param {number} int8 - the integer value to convert
449
+ *
450
+ * @return {string} the hex string
451
+ */
452
+ function toHex(int8) {
453
+ return int8.toString(16).padStart(2, "0");
454
+ }
455
+ /**
456
+ * Convert rgb values to hex color
457
+ *
458
+ * @param {Object} rgb an object with the rgb values
459
+ *
460
+ * @return {string} the hex string
461
+ */
462
+ function valuesToHex(rgb) {
463
+ // Extract the RGB values from the hex string
464
+ return `#${toHex(rgb?.r)}${toHex(rgb?.g)}${toHex(rgb?.b)}`;
465
+ }
340
466
 
341
- // src/hsl-utils.ts
342
- function fallbackHSL(hsl, err = `Invalid HSL color`) {
343
- console.warn(err);
344
- return [hsl[0] ?? 0, hsl[1] ?? 0, hsl[2]];
345
- }
346
- function parseHsl(hslAsString) {
347
- const hslvalue = cleanDefinition(hslAsString);
348
- let hsl = splitValues(hslvalue);
349
- if (hsl.length !== 3 && hsl.length !== 4) {
350
- hsl = fallbackHSL(hsl);
351
- }
352
- return [hsl[0], hsl[1], hsl[2]];
353
- }
354
- var angleError = (value) => `Invalid angle: ${value} - The none keyword is invalid in legacy color syntax `;
355
- function getHslValues(hsl) {
356
- return {
357
- h: colorValueFallbacks(hsl[0], angleError(hsl[0])) || Math.round(normalizeDegrees(hsl[0])) || 0,
358
- s: colorValueFallbacks(hsl[1]) || convertToInt8(hsl[1], 100) || 0,
359
- l: colorValueFallbacks(hsl[2]) || convertToInt8(hsl[2], 100) || 0
360
- };
361
- }
362
- function getHue(c, x, h) {
363
- if (h < 60)
364
- return [c, x, 0];
365
- if (h < 120)
366
- return [x, c, 0];
367
- if (h < 180)
368
- return [0, c, x];
369
- if (h < 240)
370
- return [0, x, c];
371
- if (h < 300)
372
- return [x, 0, c];
373
- return [c, 0, x];
374
- }
375
- function hslToRgb(hslColor) {
376
- const hsl = getHslValues(hslColor), s = hsl.s / 100, l = hsl.l / 100;
377
- const c = (1 - Math.abs(2 * l - 1)) * s;
378
- const x = c * (1 - Math.abs(hsl.h / 60 % 2 - 1));
379
- const m = l - c / 2;
380
- let [r, g, b] = getHue(c, x, hsl.h);
381
- r = Math.round((r + m) * 255);
382
- g = Math.round((g + m) * 255);
383
- b = Math.round((b + m) * 255);
384
- return { r, g, b };
385
- }
386
- function valuesToHsl({ r, g, b }) {
387
- r /= 255;
388
- g /= 255;
389
- b /= 255;
390
- const cmin = Math.min(r, g, b);
391
- const cmax = Math.max(r, g, b);
392
- const delta = cmax - cmin;
393
- let h = 0;
394
- let s = 0;
395
- let l = 0;
396
- if (delta === 0) {
397
- h = 0;
398
- } else if (cmax === r) {
399
- h = (g - b) / delta % 6;
400
- } else if (cmax === g) {
401
- h = (b - r) / delta + 2;
402
- } else {
403
- h = (r - g) / delta + 4;
404
- }
405
- h = Math.round(h * 60);
406
- if (h < 0) {
407
- h += 360;
408
- }
409
- l = (cmax + cmin) / 2;
410
- s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
411
- s = +(s * 100).toFixed(1);
412
- l = +(l * 100).toFixed(1);
413
- return HSL({ h, s, l });
414
- }
415
- function HSL(hsl) {
416
- return `hsl(${hsl.h},${hsl.s}%,${hsl.l}%)`;
417
- }
467
+ function fallbackHSL(hsl, err = "Invalid HSL color") {
468
+ console.warn(err);
469
+ return [hsl[0] ?? 0, hsl[1] ?? 0, hsl[2]];
470
+ }
471
+ /**
472
+ * Get the values of the hsl string
473
+ *
474
+ * @param {string} hslAsString - the valid hsl color string
475
+ * @return {string[]} the values of the hsl string
476
+ */
477
+ function parseHsl(hslAsString) {
478
+ const hslvalue = cleanDefinition(hslAsString);
479
+ let hsl = splitValues(hslvalue);
480
+ if (hsl.length !== 3 && hsl.length !== 4) {
481
+ hsl = fallbackHSL(hsl);
482
+ }
483
+ return [hsl[0], hsl[1], hsl[2]];
484
+ }
485
+ /**
486
+ * The error message for invalid angle
487
+ * @param value - the invalid angle
488
+ */
489
+ const angleError = (value) => `Invalid angle: ${value} - The none keyword is invalid in legacy color syntax `;
490
+ /**
491
+ * This function takes an array of strings and returns and object with the hsl values converted into INT8 (0-255)
492
+ *
493
+ * @param {string[]} hsl - the hsl values to parse from string to int8 values
494
+ *
495
+ */
496
+ function getHslValues(hsl) {
497
+ return {
498
+ h: colorValueFallbacks(hsl[0], angleError(hsl[0])) ||
499
+ Math.round(normalizeDegrees(hsl[0])) ||
500
+ 0,
501
+ s: colorValueFallbacks(hsl[1]) || convertToInt8(hsl[1], 100) || 0,
502
+ l: colorValueFallbacks(hsl[2]) || convertToInt8(hsl[2], 100) || 0,
503
+ };
504
+ }
505
+ /**
506
+ * Takes the hsl values and returns the rgb values
507
+ * @param c chroma
508
+ * @param x X
509
+ * @param h Y
510
+ */
511
+ function getHue(c, x, h) {
512
+ if (h < 60)
513
+ return [c, x, 0];
514
+ if (h < 120)
515
+ return [x, c, 0];
516
+ if (h < 180)
517
+ return [0, c, x];
518
+ if (h < 240)
519
+ return [0, x, c];
520
+ if (h < 300)
521
+ return [x, 0, c];
522
+ return [c, 0, x];
523
+ }
524
+ /**
525
+ * Given the HSL color it convert the color into RGB
526
+ *
527
+ * @param {string[]} hslColor the HSL value to parse
528
+ * @return {Object} rgb value
529
+ */
530
+ function hslToRgb(hslColor) {
531
+ const hsl = getHslValues(hslColor);
532
+ const s = hsl.s / 100;
533
+ const l = hsl.l / 100;
534
+ const c = (1 - Math.abs(2 * l - 1)) * s;
535
+ const x = c * (1 - Math.abs(((hsl.h / 60) % 2) - 1));
536
+ const m = l - c / 2;
537
+ let [r, g, b] = getHue(c, x, hsl.h);
538
+ r = Math.round((r + m) * 255);
539
+ g = Math.round((g + m) * 255);
540
+ b = Math.round((b + m) * 255);
541
+ return { r, g, b };
542
+ }
543
+ /**
544
+ * Given the RGB color it convert the color into HSL
545
+ *
546
+ * @param {number} r - red
547
+ * @param {number} g - green
548
+ * @param {number} b - blue
549
+ *
550
+ * @return {Object} hsl value
551
+ */
552
+ function valuesToHsl({ r, g, b }) {
553
+ // Make r, g, and b fractions of 1
554
+ r /= 255;
555
+ g /= 255;
556
+ b /= 255;
557
+ // Find greatest and smallest channel values
558
+ const cmin = Math.min(r, g, b);
559
+ const cmax = Math.max(r, g, b);
560
+ const delta = cmax - cmin;
561
+ let h = 0;
562
+ let s = 0;
563
+ let l = 0;
564
+ // Calculate hue
565
+ if (delta === 0) {
566
+ // No difference
567
+ h = 0;
568
+ }
569
+ else if (cmax === r) {
570
+ // Red is max
571
+ h = ((g - b) / delta) % 6;
572
+ }
573
+ else if (cmax === g) {
574
+ // Green is max
575
+ h = (b - r) / delta + 2;
576
+ }
577
+ else {
578
+ h = (r - g) / delta + 4;
579
+ } // Blue is max
580
+ h = Math.round(h * 60);
581
+ // Make negative hues positive behind 360°
582
+ if (h < 0) {
583
+ h += 360;
584
+ }
585
+ // Calculate lightness
586
+ l = (cmax + cmin) / 2;
587
+ // Calculate saturation
588
+ s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
589
+ // Multiply l and s by 100
590
+ s = +(s * 100).toFixed(1);
591
+ l = +(l * 100).toFixed(1);
592
+ return HSL({ h, s, l });
593
+ }
594
+ /**
595
+ * Converts an HSL color object to a string representation.
596
+ *
597
+ * @param {Object} hsl - Object containing the HSL color values.
598
+ * @param {number} hsl.h - The hue value of the color.
599
+ * @param {number} hsl.s - The saturation value of the color.
600
+ * @param {number} hsl.l - The lightness value of the color.
601
+ * @return {string} The HSL color as a string.
602
+ */
603
+ function HSL(hsl) {
604
+ return `hsl(${hsl.h},${hsl.s}%,${hsl.l}%)`;
605
+ }
418
606
 
419
- // src/color-utils.ts
420
- function getColor(searchedColor, set = colorSet_default) {
421
- const found = set.find((color) => color[3] === searchedColor);
422
- if (typeof found !== "undefined") {
423
- const [r, g, b] = found;
424
- return {
425
- hex: valuesToHex({ r, g, b }),
426
- rgb: RGB({ r, g, b }),
427
- hsl: valuesToHsl({ r, g, b })
428
- };
429
- }
430
- throw new Error(`Error: invalid color ${searchedColor} or empty colorSet`);
431
- }
432
- function getColors() {
433
- const colors = colorSet_default.map((colorData) => {
434
- const currentColor = {
435
- name: colorData[3],
436
- ...getColor(colorData[3])
437
- };
438
- return currentColor;
439
- });
440
- return colors;
441
- }
607
+ /**
608
+ * This function was the opposite of the name of the repo and returns the color of the colorSet given the name
609
+ *
610
+ * @param {string} searchedColor -the name of the color to search for
611
+ * @param {Array} set - the colorSet to search in
612
+ */
613
+ function getColor(searchedColor, set = colorSet) {
614
+ const color = set.find((color) => color[3] === searchedColor);
615
+ if (typeof color !== "undefined") {
616
+ const [r, g, b] = color;
617
+ return {
618
+ hex: valuesToHex({ r, g, b }),
619
+ rgb: RGB({ r, g, b }),
620
+ hsl: valuesToHsl({ r, g, b }),
621
+ };
622
+ }
623
+ throw new Error(`Error: invalid color ${searchedColor} or empty colorSet`);
624
+ }
625
+ /**
626
+ * Get all the colors from the colorSet
627
+ */
628
+ function getColors() {
629
+ return colorSet.map((colorData) => {
630
+ return {
631
+ name: colorData[3],
632
+ ...getColor(colorData[3]),
633
+ };
634
+ });
635
+ }
442
636
 
443
- // src/index.ts
444
- function closest(color, set = colorSet_default, args) {
445
- let closestGap = Number.MAX_SAFE_INTEGER;
446
- const closestColor = { name: "error", color: "#F00" };
447
- if (set.length < 1) {
448
- return closestColor;
449
- }
450
- const rgbColorValues = Object.values(parseColor(color));
451
- for (const tested of set) {
452
- const gap = distance(rgbColorValues, tested, true);
453
- if (gap < closestGap) {
454
- closestGap = gap;
455
- closestColor.name = tested[3];
456
- closestColor.color = `rgb(${String(tested[0])},${String(tested[1])},${String(tested[2])})`;
457
- }
458
- if (gap === 0) {
459
- break;
460
- }
461
- }
462
- if (args?.info) {
463
- const colorValue = getColor(closestColor.name, set);
464
- return {
465
- ...colorValue,
466
- ...closestColor,
467
- gap: Math.sqrt(closestGap)
468
- };
469
- }
470
- return closestColor;
471
- }
472
- function isLight(color) {
473
- return closest(color, BLACKANDWHITE).name === "white";
474
- }
475
- function isDark(color) {
476
- return closest(color, BLACKANDWHITE).name === "black";
477
- }
478
- function closestRGB(color) {
479
- return closest(color, RGBSET).name;
480
- }
481
- function distance(rgb1, rgb2, fast = false) {
482
- const [rDiff, gDiff, bDiff] = [rgb2[0] - rgb1[0], rgb2[1] - rgb1[1], rgb2[2] - rgb1[2]];
483
- const dist = rDiff * rDiff + gDiff * gDiff + bDiff * bDiff;
484
- return fast ? dist : Math.sqrt(dist);
485
- }
486
- function rgbToHex(rgbString) {
487
- if (rgbRegex.test(rgbString)) {
488
- const rgb = parseRgb(rgbString);
489
- const RgbValues = getRgbValues(rgb);
490
- return valuesToHex(RgbValues);
491
- }
492
- throw new Error(`Invalid color: ${rgbString}`);
493
- }
494
- function parseColor(colorString) {
495
637
  const colorParsers = [
496
- { regex: hexRegex, parser: parseHex, converter: hexToRgb },
497
- { regex: rgbRegex, parser: parseRgb, converter: getRgbValues },
498
- { regex: hslRegex, parser: parseHsl, converter: hslToRgb }
638
+ { regex: hexRegex, parser: parseHex, converter: hexToRgb },
639
+ { regex: rgbRegex, parser: parseRgb, converter: getRgbValues },
640
+ { regex: hslRegex, parser: parseHsl, converter: hslToRgb },
499
641
  ];
500
- for (const { regex, parser, converter } of colorParsers) {
501
- if (regex.test(colorString)) {
502
- const result = parser(colorString);
503
- return converter(result);
504
- }
505
- }
506
- throw new Error(`Invalid color: ${colorString}`);
507
- }
508
- return __toCommonJS(color_2_name_exports);
509
- })();
510
- //# sourceMappingURL=color-2-name.js.map
642
+ /**
643
+ * Given a color string, it returns the closest corresponding name of the color.
644
+ * Uses the Euclidean distance formula to calculate the distance between colors in the RGB color space.
645
+ *
646
+ * @param {string} color - the color string you want to find the closest color name
647
+ * @param {Object} set - the color set that will be used to find the closest color
648
+ * @param {Object} args - Set a non nullish value to return some additional information (like the distance between the colors, or the hex color value)
649
+ * @param args.info - Set a non nullish value to return some additional information (like the distance between the colors, or the hex color value) about the closest color.
650
+ *
651
+ * @return {Object} the closest color name and rgb value
652
+ *
653
+ * @example // Returns the closest color name and rgb value given a css color string
654
+ * closest('#f00'); // { name: 'red', color: 'rgb(255,0,0)' }
655
+ *
656
+ * closest('#f00', undefined, {info:true}); // { name: 'red', color: 'rgb(255,0,0)', hex: '#ff0000', hsl: 'hsl(0, 100%, 50%)', distance: 0 ) }
657
+ */
658
+ function closest(color, set = colorSet, args) {
659
+ let closestGap = Number.MAX_SAFE_INTEGER;
660
+ const closestColor = { name: "error", color: "#F00" };
661
+ if (set.length < 1) {
662
+ return closestColor;
663
+ }
664
+ const rgbColorValues = Object.values(parseColor(color));
665
+ const colorSetLength = set.length;
666
+ // Precompute RGB values if needed
667
+ const precomputedRGBValues = set.map((item) => [item[0], item[1], item[2]]);
668
+ // Find the closest color in the color set
669
+ for (let i = 0; i < colorSetLength; i++) {
670
+ const tested = precomputedRGBValues[i];
671
+ const gap = distance(rgbColorValues, tested, true);
672
+ if (gap < closestGap) {
673
+ closestGap = gap;
674
+ closestColor.name = set[i][3];
675
+ closestColor.color = `rgb(${set[i][0]},${set[i][1]},${set[i][2]})`;
676
+ }
677
+ // Break if exact match found
678
+ if (gap === 0) {
679
+ break;
680
+ }
681
+ }
682
+ if (args?.info) {
683
+ const colorValue = getColor(closestColor.name, set);
684
+ return {
685
+ ...colorValue,
686
+ ...closestColor,
687
+ gap: Math.sqrt(closestGap),
688
+ };
689
+ }
690
+ return closestColor;
691
+ }
692
+ /**
693
+ * This function takes a string representing a color (color) and uses regular expressions to check if it matches any of the following formats: hex, hex+alpha, RGB, RGBA, HSL, or HSLA.
694
+ * If the color string matches one of these formats, the function returns an object with the type of color and the value of the color.
695
+ * If the color string does not match any of the formats, the function throws an error.
696
+ *
697
+ * @param {string} colorString - the color string to test and convert to rgb values
698
+ *
699
+ * @return {Object|Error} the object with rgb values of that color
700
+ */
701
+ function parseColor(colorString) {
702
+ for (const { regex, parser, converter } of colorParsers) {
703
+ if (regex.test(colorString)) {
704
+ const result = parser(colorString);
705
+ return converter(result);
706
+ }
707
+ }
708
+ // If the color string does not match any of the regular expressions, return an error
709
+ throw new Error(`Invalid color: ${colorString}`);
710
+ }
711
+ /**
712
+ * Given a color returns if the color is light (by light is meant more mathematically closer to white)
713
+ *
714
+ * @param {string} color - The color to check
715
+ *
716
+ * @returns {boolean} true when the color is light, false otherwise
717
+ *
718
+ * @example isLight('#ddd'); // true
719
+ */
720
+ function isLight(color) {
721
+ return closest(color, BLACKANDWHITE).name === "white";
722
+ }
723
+ /**
724
+ * Given a color returns if the color is dark (by dark is meant more mathematically closer to black)
725
+ *
726
+ * @param {string} color - The color to check
727
+ *
728
+ * @returns {boolean} true when the color is dark, false otherwise
729
+ *
730
+ * @example isDark('#333'); // true
731
+ */
732
+ function isDark(color) {
733
+ return closest(color, BLACKANDWHITE).name === "black";
734
+ }
735
+ /**
736
+ * Given a color returns if the color is closer to "red", "green" or "blue".
737
+ *
738
+ * @param {string} color - The color to check
739
+ *
740
+ * @returns {string} light when the color is close to white, dark otherwise
741
+ *
742
+ * @example closestRGB('#f00'); // 'red'
743
+ */
744
+ function closestRGB(color) {
745
+ return closest(color, RGBSET).name;
746
+ }
747
+ /**
748
+ * Compute the distance between the two RGB values
749
+ * There are two modes:
750
+ * fast = true -> the distance is calculated without using the Euclidean formula completely, it is reliable but its result is exponential
751
+ * fast = false -> the distance is calculated with the Euclidean formula, its result is linear
752
+ *
753
+ * @param rgb1 - The RGB value of the first color to compare
754
+ * @param rgb2 - The RGB value of the second color to compare
755
+ * @param fast - If you want to calculate the distance without calculating the square root, the result will be exponential otherwise is linear
756
+ *
757
+ * @return {number} the distance between the two RGB values
758
+ *
759
+ * @example distance([10, 20, 30], [120, 120, 120]); // 173.78147196982766
760
+ */
761
+ function distance(rgb1, rgb2, fast = false) {
762
+ const [rDiff, gDiff, bDiff] = [
763
+ rgb2[0] - rgb1[0],
764
+ rgb2[1] - rgb1[1],
765
+ rgb2[2] - rgb1[2],
766
+ ];
767
+ const dist = rDiff * rDiff + gDiff * gDiff + bDiff * bDiff;
768
+ return fast ? dist : Math.sqrt(dist);
769
+ }
770
+ /**
771
+ * Given a color string it returns the hex representation
772
+ *
773
+ * @param rgbString - the rgb color string to convert to hex
774
+ *
775
+ * @return {string} the corresponding color hex
776
+ *
777
+ * @example rgbToHex("rgba(100% 0 0 / .5)"); // #FF0000
778
+ */
779
+ function rgbToHex(rgbString) {
780
+ // if is a rgb string
781
+ if (rgbRegex.test(rgbString)) {
782
+ const rgb = parseRgb(rgbString);
783
+ const RgbValues = getRgbValues(rgb);
784
+ return valuesToHex(RgbValues);
785
+ }
786
+ throw new Error(`Invalid color: ${rgbString}`);
787
+ }
788
+
789
+ exports.closest = closest;
790
+ exports.closestRGB = closestRGB;
791
+ exports.colorParsers = colorParsers;
792
+ exports.distance = distance;
793
+ exports.getColor = getColor;
794
+ exports.getColors = getColors;
795
+ exports.isDark = isDark;
796
+ exports.isLight = isLight;
797
+ exports.parseColor = parseColor;
798
+ exports.rgbToHex = rgbToHex;
799
+
800
+ return exports;
801
+
802
+ })({});