adaptive-extender 0.2.13 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/CHANGELOG.md +16 -2
  2. package/README.md +9 -0
  3. package/{core → dist/core}/array.d.ts +2 -2
  4. package/{core → dist/core}/array.js +2 -0
  5. package/dist/core/array.js.map +1 -0
  6. package/{core → dist/core}/boolean.js +2 -0
  7. package/dist/core/boolean.js.map +1 -0
  8. package/{core → dist/core}/color.d.ts +2 -20
  9. package/dist/core/color.js +524 -0
  10. package/dist/core/color.js.map +1 -0
  11. package/{core → dist/core}/date.js +2 -0
  12. package/dist/core/date.js.map +1 -0
  13. package/dist/core/engine.d.ts +30 -0
  14. package/dist/core/engine.js +4 -0
  15. package/dist/core/engine.js.map +1 -0
  16. package/dist/core/error.d.ts +38 -0
  17. package/{core → dist/core}/error.js +14 -0
  18. package/dist/core/error.js.map +1 -0
  19. package/{core → dist/core}/global.js +1 -0
  20. package/dist/core/global.js.map +1 -0
  21. package/dist/core/index.d.ts +19 -0
  22. package/dist/core/index.js +21 -0
  23. package/dist/core/index.js.map +1 -0
  24. package/{core → dist/core}/math.d.ts +27 -14
  25. package/{core → dist/core}/math.js +20 -12
  26. package/dist/core/math.js.map +1 -0
  27. package/{core → dist/core}/number.js +2 -2
  28. package/dist/core/number.js.map +1 -0
  29. package/{core → dist/core}/object.d.ts +0 -10
  30. package/{core → dist/core}/object.js +1 -7
  31. package/dist/core/object.js.map +1 -0
  32. package/{core → dist/core}/primitives.d.ts +1 -1
  33. package/dist/core/primitives.js +4 -0
  34. package/dist/core/primitives.js.map +1 -0
  35. package/{core → dist/core}/promise.d.ts +5 -2
  36. package/{core → dist/core}/promise.js +1 -0
  37. package/dist/core/promise.js.map +1 -0
  38. package/{core → dist/core}/random.d.ts +0 -1
  39. package/{core → dist/core}/random.js +18 -27
  40. package/dist/core/random.js.map +1 -0
  41. package/{core → dist/core}/string.d.ts +14 -21
  42. package/{core → dist/core}/string.js +2 -7
  43. package/dist/core/string.js.map +1 -0
  44. package/dist/core/timespan.d.ts +140 -0
  45. package/dist/core/timespan.js +269 -0
  46. package/dist/core/timespan.js.map +1 -0
  47. package/dist/core/vector-1.d.ts +17 -0
  48. package/dist/core/vector-1.js +57 -0
  49. package/dist/core/vector-1.js.map +1 -0
  50. package/dist/core/vector-2.d.ts +19 -0
  51. package/dist/core/vector-2.js +63 -0
  52. package/dist/core/vector-2.js.map +1 -0
  53. package/dist/core/vector-3.d.ts +20 -0
  54. package/dist/core/vector-3.js +68 -0
  55. package/dist/core/vector-3.js.map +1 -0
  56. package/dist/core/vector.d.ts +42 -0
  57. package/dist/core/vector.js +176 -0
  58. package/dist/core/vector.js.map +1 -0
  59. package/dist/node/index.d.ts +1 -0
  60. package/dist/node/index.js +3 -0
  61. package/dist/node/index.js.map +1 -0
  62. package/dist/web/index.d.ts +1 -0
  63. package/dist/web/index.js +3 -0
  64. package/dist/web/index.js.map +1 -0
  65. package/package.json +65 -50
  66. package/core/array.js.map +0 -1
  67. package/core/boolean.js.map +0 -1
  68. package/core/color.js +0 -537
  69. package/core/color.js.map +0 -1
  70. package/core/date.js.map +0 -1
  71. package/core/error.d.ts +0 -20
  72. package/core/error.js.map +0 -1
  73. package/core/global.js.map +0 -1
  74. package/core/index.d.ts +0 -17
  75. package/core/index.js +0 -16
  76. package/core/index.js.map +0 -1
  77. package/core/math.js.map +0 -1
  78. package/core/number.js.map +0 -1
  79. package/core/object.js.map +0 -1
  80. package/core/primitives.js +0 -3
  81. package/core/primitives.js.map +0 -1
  82. package/core/promise.js.map +0 -1
  83. package/core/random.js.map +0 -1
  84. package/core/string.js.map +0 -1
  85. package/core.d.ts +0 -1
  86. package/core.js +0 -2
  87. package/core.js.map +0 -1
  88. package/node/index.d.ts +0 -8
  89. package/node/index.js +0 -7
  90. package/node/index.js.map +0 -1
  91. package/node.d.ts +0 -1
  92. package/node.js +0 -2
  93. package/node.js.map +0 -1
  94. package/web/index.d.ts +0 -8
  95. package/web/index.js +0 -7
  96. package/web/index.js.map +0 -1
  97. package/web.d.ts +0 -1
  98. package/web.js +0 -2
  99. package/web.js.map +0 -1
  100. /package/{core → dist/core}/boolean.d.ts +0 -0
  101. /package/{core → dist/core}/date.d.ts +0 -0
  102. /package/{core → dist/core}/global.d.ts +0 -0
  103. /package/{core → dist/core}/number.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
- ## 0.2.13 (20.08.2025)
2
- - Added import support for `commonjs` modules.
1
+ ## 0.5.0 (19.09.2025)
2
+ - Added [timespan]() module.
3
+ - Improved module separation.
4
+ - Optimized `Color.newBlack`.
5
+ - Added tests.
6
+ - Fixed multiple bugs.
7
+ - Improved documentation and function descriptions.
8
+ - Split many functions into overloads for optimal usage.
9
+
10
+ ## 0.4.0 (26.08.2025)
11
+ - Improved package structure.
12
+ - Configured package for the latest stable ES version.
13
+ - Added modules [vector](), [vector-1](), [vector-2](), [vector-3]().
14
+
15
+ ## 0.2.14 (20.08.2025)
16
+ - Added import support for `CommonJS` modules.
3
17
 
4
18
  ## 0.2.8 (16.08.2025)
5
19
  - Fixed root import error.
package/README.md CHANGED
@@ -3,3 +3,12 @@
3
3
  Adaptive library for JS/TS development environments
4
4
 
5
5
  [Change log](./CHANGELOG.md)
6
+
7
+ ```powershell
8
+ npm install
9
+ npm link
10
+ cd test
11
+ npm link adaptive-extender
12
+ cd ../
13
+ npm start
14
+ ```
@@ -18,11 +18,11 @@ declare global {
18
18
  /**
19
19
  * Combines elements from multiple iterables into tuples.
20
20
  * Iteration stops when the shortest iterable is exhausted.
21
- * @returns A generator yielding tuples.
21
+ * @returns An iterator yielding tuples.
22
22
  */
23
23
  zip<T extends unknown[]>(...iterables: {
24
24
  [K in keyof T]: Iterable<T[K]>;
25
- }): Generator<T, void>;
25
+ }): IteratorObject<T, void>;
26
26
  }
27
27
  interface Array<T> {
28
28
  /**
@@ -37,4 +37,6 @@ Array.prototype.resize = function (length, _default) {
37
37
  this.length = length;
38
38
  return this;
39
39
  };
40
+ //#endregion
41
+ export {};
40
42
  //# sourceMappingURL=array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/core/array.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,aAAa,CAAC;AAErB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;AA2CvB,KAAK,CAAC,MAAM,GAAG,UAAU,MAAW,EAAE,OAAe,UAAU;IAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,+BAA+B,IAAI,YAAY,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxH,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF,KAAK,CAAC,KAAK,GAAG,UAAU,GAAW,EAAE,GAAW;IAC/C,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACjB,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,EAAsB,GAAG,SAA6C;IAC1F,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzE,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,MAAM;QAC/C,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAM,CAAC;IAChD,CAAC;AACF,CAAC,CAAC;AAEF,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,UAAU,MAAc,EAAE,MAAc;IAC9D,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;AAC1B,CAAC,CAAC;AAEF,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,UAAwB,MAAc,EAAE,QAAW;IAC3E,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACrB,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AACF,YAAY;AAEZ,OAAO,EAAG,CAAC"}
@@ -5,4 +5,6 @@ Boolean.import = function (source, name = "[source]") {
5
5
  throw new TypeError(`Unable to import boolean from ${name} due its ${typename(source)} type`);
6
6
  return source.valueOf();
7
7
  };
8
+ //#endregion
9
+ export {};
8
10
  //# sourceMappingURL=boolean.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boolean.js","sourceRoot":"","sources":["../../src/core/boolean.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,aAAa,CAAC;AAgBrB,OAAO,CAAC,MAAM,GAAG,UAAU,MAAW,EAAE,OAAe,UAAU;IAChE,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,SAAS;QAAE,MAAM,IAAI,SAAS,CAAC,iCAAiC,IAAI,YAAY,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjI,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC;AACzB,CAAC,CAAC;AACF,YAAY;AAEZ,OAAO,EAAG,CAAC"}
@@ -160,92 +160,74 @@ declare class Color {
160
160
  toString(options: Partial<ColorProperties>): string;
161
161
  /**
162
162
  * Transparent color preset.
163
- * @readonly
164
163
  */
165
164
  static get newTransparent(): Color;
166
165
  /**
167
166
  * Maroon color preset.
168
- * @readonly
169
167
  */
170
168
  static get newMaroon(): Color;
171
169
  /**
172
170
  * Red color preset.
173
- * @readonly
174
171
  */
175
172
  static get newRed(): Color;
176
173
  /**
177
174
  * Orange color preset.
178
- * @readonly
179
175
  */
180
176
  static get newOrange(): Color;
181
177
  /**
182
178
  * Yellow color preset.
183
- * @readonly
184
179
  */
185
180
  static get newYellow(): Color;
186
181
  /**
187
182
  * Olive color preset.
188
- * @readonly
189
183
  */
190
184
  static get newOlive(): Color;
191
185
  /**
192
186
  * Green color preset.
193
- * @readonly
194
187
  */
195
188
  static get newGreen(): Color;
196
189
  /**
197
190
  * Purple color preset.
198
- * @readonly
199
191
  */
200
192
  static get newPurple(): Color;
201
193
  /**
202
194
  * Fuchsia color preset.
203
- * @readonly
204
195
  */
205
196
  static get newFuchsia(): Color;
206
197
  /**
207
198
  * Lime color preset.
208
- * @readonly
209
199
  */
210
200
  static get newLime(): Color;
211
201
  /**
212
202
  * Teal color preset.
213
- * @readonly
214
203
  */
215
204
  static get newTeal(): Color;
216
205
  /**
217
206
  * Aqua color preset.
218
- * @readonly
219
207
  */
220
208
  static get newAqua(): Color;
221
209
  /**
222
210
  * Blue color preset.
223
- * @readonly
224
211
  */
225
212
  static get newBlue(): Color;
226
213
  /**
227
214
  * Navy color preset.
228
- * @readonly
229
215
  */
230
216
  static get newNavy(): Color;
231
217
  /**
232
218
  * Black color preset.
233
- * @readonly
234
219
  */
235
220
  static get newBlack(): Color;
236
221
  /**
237
222
  * Gray color preset.
238
- * @readonly
239
223
  */
240
224
  static get newGray(): Color;
241
225
  /**
242
226
  * Silver color preset.
243
- * @readonly
244
227
  */
245
228
  static get newSilver(): Color;
246
229
  /**
247
230
  * White color preset.
248
- * @readonly
249
231
  */
250
232
  static get newWhite(): Color;
251
233
  /**
@@ -365,5 +347,5 @@ declare class Color {
365
347
  */
366
348
  pass(scale: number): Color;
367
349
  }
368
- export { ColorProperties };
369
- export { ColorFormats, Color };
350
+ export { ColorFormats };
351
+ export { type ColorProperties, Color };
@@ -0,0 +1,524 @@
1
+ "use strict";
2
+ import "./number.js";
3
+ import "./string.js";
4
+ const { min, max, trunc, abs } = Math;
5
+ //#region Color formats
6
+ /**
7
+ * Represents available color formats.
8
+ */
9
+ var ColorFormats;
10
+ (function (ColorFormats) {
11
+ ColorFormats["rgb"] = "RGB";
12
+ ColorFormats["hsl"] = "HSL";
13
+ ColorFormats["hex"] = "HEX";
14
+ })(ColorFormats || (ColorFormats = {}));
15
+ /**
16
+ * Represents a color in RGB, HSL, or HEX format with support for alpha channel,
17
+ * conversion between formats, creation from components, and parsing from strings.
18
+ */
19
+ class Color {
20
+ //#region Properties
21
+ #rgb = new Uint8ClampedArray([0, 0, 0]);
22
+ /**
23
+ * Gets the red color component.
24
+ */
25
+ get red() {
26
+ return this.#rgb[0];
27
+ }
28
+ /**
29
+ * Sets the red color component.
30
+ */
31
+ set red(value) {
32
+ if (!Number.isFinite(value))
33
+ return;
34
+ this.#rgb[0] = value;
35
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
36
+ }
37
+ /**
38
+ * Gets the green color component.
39
+ */
40
+ get green() {
41
+ return this.#rgb[1];
42
+ }
43
+ /**
44
+ * Sets the green color component.
45
+ */
46
+ set green(value) {
47
+ if (!Number.isFinite(value))
48
+ return;
49
+ this.#rgb[1] = value;
50
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
51
+ }
52
+ /**
53
+ * Gets the blue color component.
54
+ */
55
+ get blue() {
56
+ return this.#rgb[2];
57
+ }
58
+ /**
59
+ * Sets the blue color component.
60
+ */
61
+ set blue(value) {
62
+ if (!Number.isFinite(value))
63
+ return;
64
+ this.#rgb[2] = value;
65
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
66
+ }
67
+ #hsl = new Uint16Array([0, 0, 0]);
68
+ /**
69
+ * Gets the hue color component.
70
+ */
71
+ get hue() {
72
+ return this.#hsl[0];
73
+ }
74
+ /**
75
+ * Sets the hue color component.
76
+ */
77
+ set hue(value) {
78
+ if (!Number.isFinite(value))
79
+ return;
80
+ this.#hsl[0] = value.mod(360);
81
+ Color.#HSLtoRGB(this.#hsl, this.#rgb);
82
+ }
83
+ /**
84
+ * Gets the saturation color component.
85
+ */
86
+ get saturation() {
87
+ return this.#hsl[1];
88
+ }
89
+ /**
90
+ * Sets the saturation color component.
91
+ */
92
+ set saturation(value) {
93
+ if (!Number.isFinite(value))
94
+ return;
95
+ this.#hsl[1] = value.clamp(0, 100);
96
+ Color.#HSLtoRGB(this.#hsl, this.#rgb);
97
+ }
98
+ /**
99
+ * Gets the lightness color component.
100
+ */
101
+ get lightness() {
102
+ return this.#hsl[2];
103
+ }
104
+ /**
105
+ * Sets the lightness color component.
106
+ */
107
+ set lightness(value) {
108
+ if (!Number.isFinite(value))
109
+ return;
110
+ this.#hsl[2] = value.clamp(0, 100);
111
+ Color.#HSLtoRGB(this.#hsl, this.#rgb);
112
+ }
113
+ #alpha = 1;
114
+ /**
115
+ * Gets the alpha color component.
116
+ */
117
+ get alpha() {
118
+ return this.#alpha;
119
+ }
120
+ /**
121
+ * Sets the alpha color component.
122
+ */
123
+ set alpha(value) {
124
+ if (!Number.isFinite(value))
125
+ return;
126
+ this.#alpha = value.clamp(0, 1);
127
+ }
128
+ //#endregion
129
+ //#region Builders
130
+ static #patternRGB = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;
131
+ static #patternRGBA = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\S+)\s*\)$/i;
132
+ static #patternHSL = /^hsl\(\s*(\d+)(?:deg)?\s*,\s*(\d+)(?:%)?\s*,\s*(\d+)(?:%)?\s*\)$/i;
133
+ static #patternHSLA = /^hsla\(\s*(\d+)(?:deg)?\s*,\s*(\d+)(?:%)?\s*,\s*(\d+)(?:%)?\s*,\s*(\S+)\s*\)$/i;
134
+ static #patternHEX = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;
135
+ static #patternHEXA = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;
136
+ static #variations = Object.values(ColorFormats).flatMap(format => [{ format, deep: false }, { format, deep: true }]);
137
+ constructor(source) {
138
+ if (!(source instanceof Color))
139
+ return;
140
+ this.#rgb = Uint8ClampedArray.from(source.#rgb);
141
+ this.#hsl = Uint16Array.from(source.#hsl);
142
+ this.#alpha = source.#alpha;
143
+ }
144
+ static fromRGB(red, green, blue, alpha = 1) {
145
+ if (!Number.isFinite(red))
146
+ throw new Error(`The red ${red} must be a finite number`);
147
+ if (!Number.isFinite(green))
148
+ throw new Error(`The green ${green} must be a finite number`);
149
+ if (!Number.isFinite(blue))
150
+ throw new Error(`The blue ${blue} must be a finite number`);
151
+ if (!Number.isFinite(alpha))
152
+ throw new Error(`The alpha ${alpha} must be a finite number`);
153
+ const color = new Color();
154
+ color.#rgb[0] = red;
155
+ color.#rgb[1] = green;
156
+ color.#rgb[2] = blue;
157
+ color.#alpha = alpha.clamp(0, 1);
158
+ Color.#RGBtoHSL(color.#rgb, color.#hsl);
159
+ return color;
160
+ }
161
+ static fromHSL(hue, saturation, lightness, alpha = 1) {
162
+ if (!Number.isFinite(hue))
163
+ throw new Error(`The hue ${hue} must be a finite number`);
164
+ if (!Number.isFinite(saturation))
165
+ throw new Error(`The saturation ${saturation} must be a finite number`);
166
+ if (!Number.isFinite(lightness))
167
+ throw new Error(`The lightness ${lightness} must be a finite number`);
168
+ if (!Number.isFinite(alpha))
169
+ throw new Error(`The alpha ${alpha} must be a finite number`);
170
+ const color = new Color();
171
+ hue %= 360;
172
+ if (hue < 0)
173
+ hue += 360;
174
+ color.#hsl[0] = hue;
175
+ color.#hsl[1] = saturation.clamp(0, 100);
176
+ color.#hsl[2] = lightness.clamp(0, 100);
177
+ color.#alpha = alpha.clamp(0, 1);
178
+ Color.#HSLtoRGB(color.#hsl, color.#rgb);
179
+ return color;
180
+ }
181
+ static #parse(string, deep, format) {
182
+ switch (format) {
183
+ case ColorFormats.rgb:
184
+ {
185
+ const regex = (deep ? Color.#patternRGBA : Color.#patternRGB);
186
+ const match = regex.exec(string.trim());
187
+ if (match === null)
188
+ throw new SyntaxError(`Invalid ${format} color '${string}' syntax`);
189
+ const [, red, green, blue, alpha] = match.map(part => Number(part));
190
+ return Color.fromRGB(red, green, blue, deep ? alpha : 1);
191
+ }
192
+ ;
193
+ case ColorFormats.hsl:
194
+ {
195
+ const regex = (deep ? Color.#patternHSLA : Color.#patternHSL);
196
+ const match = regex.exec(string.trim());
197
+ if (match === null)
198
+ throw new SyntaxError(`Invalid ${format} color '${string}' syntax`);
199
+ const [, hue, saturation, lightness, alpha] = match.map(part => Number(part));
200
+ return Color.fromHSL(hue, saturation, lightness, deep ? alpha : 1);
201
+ }
202
+ ;
203
+ case ColorFormats.hex:
204
+ {
205
+ const regex = (deep ? Color.#patternHEXA : Color.#patternHEX);
206
+ const match = regex.exec(string.trim());
207
+ if (match === null)
208
+ throw new SyntaxError(`Invalid ${format} color '${string}' syntax`);
209
+ const [, red, green, blue, alpha] = match.map(part => Number.parseInt(part, 16));
210
+ return Color.fromRGB(red, green, blue, deep ? (alpha / 255) : 1);
211
+ }
212
+ ;
213
+ default: throw new Error(`Invalid '${format}' format for color`);
214
+ }
215
+ }
216
+ static tryParse(string, options = {}) {
217
+ let variations = Color.#variations;
218
+ for (const key in options) {
219
+ const value = Reflect.get(options, key);
220
+ if (value === undefined)
221
+ continue;
222
+ variations = variations.filter(properties => Reflect.get(properties, key) === value);
223
+ }
224
+ for (const { format, deep } of variations) {
225
+ try {
226
+ return Color.#parse(string, deep, format);
227
+ }
228
+ catch {
229
+ continue;
230
+ }
231
+ }
232
+ return null;
233
+ }
234
+ static parse(string, options = {}) {
235
+ const color = Color.tryParse(string, options);
236
+ if (color === null)
237
+ throw new SyntaxError(`Unable to parse '${string}' of any selected variation`);
238
+ return color;
239
+ }
240
+ //#endregion
241
+ //#region Converters
242
+ static #toChannel(offset, hue, saturation, lightness) {
243
+ const sector = (offset + hue) % 12;
244
+ return lightness - (saturation * min(lightness, 1 - lightness)) * min(sector - 3, 9 - sector).clamp(-1, 1);
245
+ }
246
+ /**
247
+ * @param hsl [0 - 360], [0 - 100], [0 - 100]
248
+ * @param rgb [0 - 255], [0 - 255], [0 - 255]
249
+ */
250
+ static #HSLtoRGB(hsl, rgb) {
251
+ const hue = hsl[0] / 30;
252
+ const saturation = hsl[1] / 100;
253
+ const lightness = hsl[2] / 100;
254
+ rgb[0] = Color.#toChannel(0, hue, saturation, lightness) * 255;
255
+ rgb[1] = Color.#toChannel(8, hue, saturation, lightness) * 255;
256
+ rgb[2] = Color.#toChannel(4, hue, saturation, lightness) * 255;
257
+ }
258
+ static #toHue(maximum, red, green, blue, difference) {
259
+ switch (maximum) {
260
+ case red: return (green - blue) / difference + 0;
261
+ case green: return (blue - red) / difference + 2;
262
+ case blue: return (red - green) / difference + 4;
263
+ default: throw new Error(`Invalid '${maximum}' maximum for colors`);
264
+ }
265
+ }
266
+ /**
267
+ * @param rgb [0 - 255], [0 - 255], [0 - 255]
268
+ * @param hsl [0 - 360], [0 - 100], [0 - 100]
269
+ */
270
+ static #RGBtoHSL(rgb, hsl) {
271
+ const red = rgb[0] / 255;
272
+ const green = rgb[1] / 255;
273
+ const blue = rgb[2] / 255;
274
+ const minimum = min(red, green, blue);
275
+ const maximum = max(red, green, blue);
276
+ const difference = maximum - minimum;
277
+ let hue = Color.#toHue(maximum, red, green, blue, difference);
278
+ hue = difference && hue;
279
+ if (hue < 0)
280
+ hue += 6;
281
+ hsl[0] = hue * 60;
282
+ const median = 1 - abs(maximum + minimum - 1);
283
+ hsl[1] = (median && (difference / median)) * 100;
284
+ hsl[2] = (maximum + minimum) / 2 * 100;
285
+ }
286
+ static #toHEXString(byte) {
287
+ return byte.toString(16).padStart(2, "0");
288
+ }
289
+ toString(options = {}) {
290
+ let { format, deep } = options;
291
+ format ??= ColorFormats.rgb;
292
+ deep ??= true;
293
+ switch (format) {
294
+ case ColorFormats.rgb: return `rgb${deep ? "a" : String.empty}(${this.red}, ${this.green}, ${this.blue}${deep ? `, ${this.alpha}` : String.empty})`;
295
+ case ColorFormats.hsl: return `hsl${deep ? "a" : String.empty}(${this.hue}deg, ${this.saturation}%, ${this.lightness}%${deep ? `, ${this.alpha}` : String.empty})`;
296
+ case ColorFormats.hex: return `#${Color.#toHEXString(this.red)}${Color.#toHEXString(this.green)}${Color.#toHEXString(this.blue)}${deep ? Color.#toHEXString(trunc(this.alpha * 255)) : String.empty}`;
297
+ default: throw new Error(`Invalid '${format}' format for color`);
298
+ }
299
+ }
300
+ //#endregion
301
+ //#region Presets
302
+ /**
303
+ * Transparent color preset.
304
+ */
305
+ static get newTransparent() { return Color.fromRGB(0, 0, 0, 0); }
306
+ ;
307
+ /**
308
+ * Maroon color preset.
309
+ */
310
+ static get newMaroon() { return Color.fromRGB(128, 0, 0); }
311
+ ;
312
+ /**
313
+ * Red color preset.
314
+ */
315
+ static get newRed() { return Color.fromRGB(255, 0, 0); }
316
+ ;
317
+ /**
318
+ * Orange color preset.
319
+ */
320
+ static get newOrange() { return Color.fromRGB(255, 165, 0); }
321
+ ;
322
+ /**
323
+ * Yellow color preset.
324
+ */
325
+ static get newYellow() { return Color.fromRGB(255, 255, 0); }
326
+ ;
327
+ /**
328
+ * Olive color preset.
329
+ */
330
+ static get newOlive() { return Color.fromRGB(128, 128, 0); }
331
+ ;
332
+ /**
333
+ * Green color preset.
334
+ */
335
+ static get newGreen() { return Color.fromRGB(0, 128, 0); }
336
+ ;
337
+ /**
338
+ * Purple color preset.
339
+ */
340
+ static get newPurple() { return Color.fromRGB(128, 0, 128); }
341
+ ;
342
+ /**
343
+ * Fuchsia color preset.
344
+ */
345
+ static get newFuchsia() { return Color.fromRGB(255, 0, 255); }
346
+ ;
347
+ /**
348
+ * Lime color preset.
349
+ */
350
+ static get newLime() { return Color.fromRGB(0, 255, 0); }
351
+ ;
352
+ /**
353
+ * Teal color preset.
354
+ */
355
+ static get newTeal() { return Color.fromRGB(0, 128, 128); }
356
+ ;
357
+ /**
358
+ * Aqua color preset.
359
+ */
360
+ static get newAqua() { return Color.fromRGB(0, 255, 255); }
361
+ ;
362
+ /**
363
+ * Blue color preset.
364
+ */
365
+ static get newBlue() { return Color.fromRGB(0, 0, 255); }
366
+ ;
367
+ /**
368
+ * Navy color preset.
369
+ */
370
+ static get newNavy() { return Color.fromRGB(0, 0, 128); }
371
+ ;
372
+ /**
373
+ * Black color preset.
374
+ */
375
+ static get newBlack() { return new Color(); }
376
+ ;
377
+ /**
378
+ * Gray color preset.
379
+ */
380
+ static get newGray() { return Color.fromRGB(128, 128, 128); }
381
+ ;
382
+ /**
383
+ * Silver color preset.
384
+ */
385
+ static get newSilver() { return Color.fromRGB(192, 192, 192); }
386
+ ;
387
+ /**
388
+ * White color preset.
389
+ */
390
+ static get newWhite() { return Color.fromRGB(255, 255, 255); }
391
+ ;
392
+ static mix(first, second, ratio = 0.5) {
393
+ if (!Number.isFinite(ratio))
394
+ throw new Error(`The ratio ${ratio} must be a finite number`);
395
+ ratio = ratio.clamp(0, 1);
396
+ const red = first.red + (second.red - first.red) * ratio;
397
+ const green = first.green + (second.green - first.green) * ratio;
398
+ const blue = first.blue + (second.blue - first.blue) * ratio;
399
+ const alpha = first.alpha + (second.alpha - first.alpha) * ratio;
400
+ return Color.fromRGB(red, green, blue, alpha);
401
+ }
402
+ grayscale(scale = 1) {
403
+ if (!Number.isFinite(scale))
404
+ throw new Error(`The scale ${scale} must be a finite number`);
405
+ scale = scale.clamp(0, 1);
406
+ const { red, green, blue } = this;
407
+ const achromatic = (red + green + blue) / 3;
408
+ this.#rgb[0] = red + (achromatic - red) * scale;
409
+ this.#rgb[1] = green + (achromatic - green) * scale;
410
+ this.#rgb[2] = blue + (achromatic - blue) * scale;
411
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
412
+ return this;
413
+ }
414
+ redEmphasis(scale = 1) {
415
+ if (!Number.isFinite(scale))
416
+ throw new Error(`The scale ${scale} must be a finite number`);
417
+ scale = scale.clamp(0, 1);
418
+ const { green, blue } = this;
419
+ const average = (green + blue) / 2;
420
+ this.#rgb[1] = green + (average - green) * scale;
421
+ this.#rgb[2] = blue + (average - blue) * scale;
422
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
423
+ return this;
424
+ }
425
+ greenEmphasis(scale = 1) {
426
+ if (!Number.isFinite(scale))
427
+ throw new Error(`The scale ${scale} must be a finite number`);
428
+ scale = scale.clamp(0, 1);
429
+ const { red, blue } = this;
430
+ const average = (red + blue) / 2;
431
+ this.#rgb[0] = red + (average - red) * scale;
432
+ this.#rgb[2] = blue + (average - blue) * scale;
433
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
434
+ return this;
435
+ }
436
+ blueEmphasis(scale = 1) {
437
+ if (!Number.isFinite(scale))
438
+ throw new Error(`The scale ${scale} must be a finite number`);
439
+ scale = scale.clamp(0, 1);
440
+ const { red, green } = this;
441
+ const average = (red + green) / 2;
442
+ this.#rgb[0] = red + (average - red) * scale;
443
+ this.#rgb[1] = green + (average - green) * scale;
444
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
445
+ return this;
446
+ }
447
+ invert(scale = 1) {
448
+ if (!Number.isFinite(scale))
449
+ throw new Error(`The scale ${scale} must be a finite number`);
450
+ scale = scale.clamp(0, 1);
451
+ const { red, green, blue } = this;
452
+ this.#rgb[0] = red + ((255 - red) - red) * scale;
453
+ this.#rgb[1] = green + ((255 - green) - green) * scale;
454
+ this.#rgb[2] = blue + ((255 - blue) - blue) * scale;
455
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
456
+ return this;
457
+ }
458
+ sepia(scale = 1) {
459
+ if (!Number.isFinite(scale))
460
+ throw new Error(`The scale ${scale} must be a finite number`);
461
+ scale = scale.clamp(0, 1);
462
+ const { red, green, blue } = this;
463
+ const redness = (red * 0.393) + (green * 0.769) + (blue * 0.189);
464
+ const greenness = (red * 0.349) + (green * 0.686) + (blue * 0.168);
465
+ const blueness = (red * 0.272) + (green * 0.534) + (blue * 0.131);
466
+ this.#rgb[0] = red + (redness - red) * scale;
467
+ this.#rgb[1] = green + (greenness - green) * scale;
468
+ this.#rgb[2] = blue + (blueness - blue) * scale;
469
+ Color.#RGBtoHSL(this.#rgb, this.#hsl);
470
+ return this;
471
+ }
472
+ /**
473
+ * Rotates the hue of the current color by the given angle in degrees.
474
+ * @param angle Rotation angle in degrees.
475
+ * @returns The modified current color.
476
+ * @throws {Error} If `angle` is not a finite number.
477
+ */
478
+ rotate(angle) {
479
+ if (!Number.isFinite(angle))
480
+ throw new Error(`The angle ${angle} must be a finite number`);
481
+ this.hue += angle;
482
+ return this;
483
+ }
484
+ /**
485
+ * Sets the saturation of the current color by scale.
486
+ * @param scale Saturation scale [0 - 1].
487
+ * @returns The modified current color.
488
+ * @throws {Error} If `scale` is not a finite number.
489
+ */
490
+ saturate(scale) {
491
+ if (!Number.isFinite(scale))
492
+ throw new Error(`The scale ${scale} must be a finite number`);
493
+ this.saturation = 100 * scale;
494
+ return this;
495
+ }
496
+ /**
497
+ * Sets the lightness of the current color by scale.
498
+ * @param scale Lightness scale [0 - 1].
499
+ * @returns The modified current color.
500
+ * @throws {Error} If `scale` is not a finite number.
501
+ */
502
+ illuminate(scale) {
503
+ if (!Number.isFinite(scale))
504
+ throw new Error(`The scale ${scale} must be a finite number`);
505
+ this.lightness = 100 * scale;
506
+ return this;
507
+ }
508
+ /**
509
+ * Sets the alpha of the current color.
510
+ * @param scale Alpha value [0 - 1].
511
+ * @returns The modified current color.
512
+ * @throws {Error} If `scale` is not a finite number.
513
+ */
514
+ pass(scale) {
515
+ if (!Number.isFinite(scale))
516
+ throw new Error(`The scale ${scale} must be a finite number`);
517
+ this.alpha = scale;
518
+ return this;
519
+ }
520
+ }
521
+ //#endregion
522
+ export { ColorFormats };
523
+ export { Color };
524
+ //# sourceMappingURL=color.js.map