.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / pretty-format / node_modules / color-convert / conversions.js
1 /* MIT license */
2 var cssKeywords = require('color-name');
3
4 // NOTE: conversions should only return primitive values (i.e. arrays, or
5 //       values that give correct `typeof` results).
6 //       do not use box values types (i.e. Number(), String(), etc.)
7
8 var reverseKeywords = {};
9 for (var key in cssKeywords) {
10         if (cssKeywords.hasOwnProperty(key)) {
11                 reverseKeywords[cssKeywords[key]] = key;
12         }
13 }
14
15 var convert = module.exports = {
16         rgb: {channels: 3, labels: 'rgb'},
17         hsl: {channels: 3, labels: 'hsl'},
18         hsv: {channels: 3, labels: 'hsv'},
19         hwb: {channels: 3, labels: 'hwb'},
20         cmyk: {channels: 4, labels: 'cmyk'},
21         xyz: {channels: 3, labels: 'xyz'},
22         lab: {channels: 3, labels: 'lab'},
23         lch: {channels: 3, labels: 'lch'},
24         hex: {channels: 1, labels: ['hex']},
25         keyword: {channels: 1, labels: ['keyword']},
26         ansi16: {channels: 1, labels: ['ansi16']},
27         ansi256: {channels: 1, labels: ['ansi256']},
28         hcg: {channels: 3, labels: ['h', 'c', 'g']},
29         apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
30         gray: {channels: 1, labels: ['gray']}
31 };
32
33 // hide .channels and .labels properties
34 for (var model in convert) {
35         if (convert.hasOwnProperty(model)) {
36                 if (!('channels' in convert[model])) {
37                         throw new Error('missing channels property: ' + model);
38                 }
39
40                 if (!('labels' in convert[model])) {
41                         throw new Error('missing channel labels property: ' + model);
42                 }
43
44                 if (convert[model].labels.length !== convert[model].channels) {
45                         throw new Error('channel and label counts mismatch: ' + model);
46                 }
47
48                 var channels = convert[model].channels;
49                 var labels = convert[model].labels;
50                 delete convert[model].channels;
51                 delete convert[model].labels;
52                 Object.defineProperty(convert[model], 'channels', {value: channels});
53                 Object.defineProperty(convert[model], 'labels', {value: labels});
54         }
55 }
56
57 convert.rgb.hsl = function (rgb) {
58         var r = rgb[0] / 255;
59         var g = rgb[1] / 255;
60         var b = rgb[2] / 255;
61         var min = Math.min(r, g, b);
62         var max = Math.max(r, g, b);
63         var delta = max - min;
64         var h;
65         var s;
66         var l;
67
68         if (max === min) {
69                 h = 0;
70         } else if (r === max) {
71                 h = (g - b) / delta;
72         } else if (g === max) {
73                 h = 2 + (b - r) / delta;
74         } else if (b === max) {
75                 h = 4 + (r - g) / delta;
76         }
77
78         h = Math.min(h * 60, 360);
79
80         if (h < 0) {
81                 h += 360;
82         }
83
84         l = (min + max) / 2;
85
86         if (max === min) {
87                 s = 0;
88         } else if (l <= 0.5) {
89                 s = delta / (max + min);
90         } else {
91                 s = delta / (2 - max - min);
92         }
93
94         return [h, s * 100, l * 100];
95 };
96
97 convert.rgb.hsv = function (rgb) {
98         var rdif;
99         var gdif;
100         var bdif;
101         var h;
102         var s;
103
104         var r = rgb[0] / 255;
105         var g = rgb[1] / 255;
106         var b = rgb[2] / 255;
107         var v = Math.max(r, g, b);
108         var diff = v - Math.min(r, g, b);
109         var diffc = function (c) {
110                 return (v - c) / 6 / diff + 1 / 2;
111         };
112
113         if (diff === 0) {
114                 h = s = 0;
115         } else {
116                 s = diff / v;
117                 rdif = diffc(r);
118                 gdif = diffc(g);
119                 bdif = diffc(b);
120
121                 if (r === v) {
122                         h = bdif - gdif;
123                 } else if (g === v) {
124                         h = (1 / 3) + rdif - bdif;
125                 } else if (b === v) {
126                         h = (2 / 3) + gdif - rdif;
127                 }
128                 if (h < 0) {
129                         h += 1;
130                 } else if (h > 1) {
131                         h -= 1;
132                 }
133         }
134
135         return [
136                 h * 360,
137                 s * 100,
138                 v * 100
139         ];
140 };
141
142 convert.rgb.hwb = function (rgb) {
143         var r = rgb[0];
144         var g = rgb[1];
145         var b = rgb[2];
146         var h = convert.rgb.hsl(rgb)[0];
147         var w = 1 / 255 * Math.min(r, Math.min(g, b));
148
149         b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
150
151         return [h, w * 100, b * 100];
152 };
153
154 convert.rgb.cmyk = function (rgb) {
155         var r = rgb[0] / 255;
156         var g = rgb[1] / 255;
157         var b = rgb[2] / 255;
158         var c;
159         var m;
160         var y;
161         var k;
162
163         k = Math.min(1 - r, 1 - g, 1 - b);
164         c = (1 - r - k) / (1 - k) || 0;
165         m = (1 - g - k) / (1 - k) || 0;
166         y = (1 - b - k) / (1 - k) || 0;
167
168         return [c * 100, m * 100, y * 100, k * 100];
169 };
170
171 /**
172  * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
173  * */
174 function comparativeDistance(x, y) {
175         return (
176                 Math.pow(x[0] - y[0], 2) +
177                 Math.pow(x[1] - y[1], 2) +
178                 Math.pow(x[2] - y[2], 2)
179         );
180 }
181
182 convert.rgb.keyword = function (rgb) {
183         var reversed = reverseKeywords[rgb];
184         if (reversed) {
185                 return reversed;
186         }
187
188         var currentClosestDistance = Infinity;
189         var currentClosestKeyword;
190
191         for (var keyword in cssKeywords) {
192                 if (cssKeywords.hasOwnProperty(keyword)) {
193                         var value = cssKeywords[keyword];
194
195                         // Compute comparative distance
196                         var distance = comparativeDistance(rgb, value);
197
198                         // Check if its less, if so set as closest
199                         if (distance < currentClosestDistance) {
200                                 currentClosestDistance = distance;
201                                 currentClosestKeyword = keyword;
202                         }
203                 }
204         }
205
206         return currentClosestKeyword;
207 };
208
209 convert.keyword.rgb = function (keyword) {
210         return cssKeywords[keyword];
211 };
212
213 convert.rgb.xyz = function (rgb) {
214         var r = rgb[0] / 255;
215         var g = rgb[1] / 255;
216         var b = rgb[2] / 255;
217
218         // assume sRGB
219         r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
220         g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
221         b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
222
223         var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
224         var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
225         var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
226
227         return [x * 100, y * 100, z * 100];
228 };
229
230 convert.rgb.lab = function (rgb) {
231         var xyz = convert.rgb.xyz(rgb);
232         var x = xyz[0];
233         var y = xyz[1];
234         var z = xyz[2];
235         var l;
236         var a;
237         var b;
238
239         x /= 95.047;
240         y /= 100;
241         z /= 108.883;
242
243         x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
244         y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
245         z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
246
247         l = (116 * y) - 16;
248         a = 500 * (x - y);
249         b = 200 * (y - z);
250
251         return [l, a, b];
252 };
253
254 convert.hsl.rgb = function (hsl) {
255         var h = hsl[0] / 360;
256         var s = hsl[1] / 100;
257         var l = hsl[2] / 100;
258         var t1;
259         var t2;
260         var t3;
261         var rgb;
262         var val;
263
264         if (s === 0) {
265                 val = l * 255;
266                 return [val, val, val];
267         }
268
269         if (l < 0.5) {
270                 t2 = l * (1 + s);
271         } else {
272                 t2 = l + s - l * s;
273         }
274
275         t1 = 2 * l - t2;
276
277         rgb = [0, 0, 0];
278         for (var i = 0; i < 3; i++) {
279                 t3 = h + 1 / 3 * -(i - 1);
280                 if (t3 < 0) {
281                         t3++;
282                 }
283                 if (t3 > 1) {
284                         t3--;
285                 }
286
287                 if (6 * t3 < 1) {
288                         val = t1 + (t2 - t1) * 6 * t3;
289                 } else if (2 * t3 < 1) {
290                         val = t2;
291                 } else if (3 * t3 < 2) {
292                         val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
293                 } else {
294                         val = t1;
295                 }
296
297                 rgb[i] = val * 255;
298         }
299
300         return rgb;
301 };
302
303 convert.hsl.hsv = function (hsl) {
304         var h = hsl[0];
305         var s = hsl[1] / 100;
306         var l = hsl[2] / 100;
307         var smin = s;
308         var lmin = Math.max(l, 0.01);
309         var sv;
310         var v;
311
312         l *= 2;
313         s *= (l <= 1) ? l : 2 - l;
314         smin *= lmin <= 1 ? lmin : 2 - lmin;
315         v = (l + s) / 2;
316         sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
317
318         return [h, sv * 100, v * 100];
319 };
320
321 convert.hsv.rgb = function (hsv) {
322         var h = hsv[0] / 60;
323         var s = hsv[1] / 100;
324         var v = hsv[2] / 100;
325         var hi = Math.floor(h) % 6;
326
327         var f = h - Math.floor(h);
328         var p = 255 * v * (1 - s);
329         var q = 255 * v * (1 - (s * f));
330         var t = 255 * v * (1 - (s * (1 - f)));
331         v *= 255;
332
333         switch (hi) {
334                 case 0:
335                         return [v, t, p];
336                 case 1:
337                         return [q, v, p];
338                 case 2:
339                         return [p, v, t];
340                 case 3:
341                         return [p, q, v];
342                 case 4:
343                         return [t, p, v];
344                 case 5:
345                         return [v, p, q];
346         }
347 };
348
349 convert.hsv.hsl = function (hsv) {
350         var h = hsv[0];
351         var s = hsv[1] / 100;
352         var v = hsv[2] / 100;
353         var vmin = Math.max(v, 0.01);
354         var lmin;
355         var sl;
356         var l;
357
358         l = (2 - s) * v;
359         lmin = (2 - s) * vmin;
360         sl = s * vmin;
361         sl /= (lmin <= 1) ? lmin : 2 - lmin;
362         sl = sl || 0;
363         l /= 2;
364
365         return [h, sl * 100, l * 100];
366 };
367
368 // http://dev.w3.org/csswg/css-color/#hwb-to-rgb
369 convert.hwb.rgb = function (hwb) {
370         var h = hwb[0] / 360;
371         var wh = hwb[1] / 100;
372         var bl = hwb[2] / 100;
373         var ratio = wh + bl;
374         var i;
375         var v;
376         var f;
377         var n;
378
379         // wh + bl cant be > 1
380         if (ratio > 1) {
381                 wh /= ratio;
382                 bl /= ratio;
383         }
384
385         i = Math.floor(6 * h);
386         v = 1 - bl;
387         f = 6 * h - i;
388
389         if ((i & 0x01) !== 0) {
390                 f = 1 - f;
391         }
392
393         n = wh + f * (v - wh); // linear interpolation
394
395         var r;
396         var g;
397         var b;
398         switch (i) {
399                 default:
400                 case 6:
401                 case 0: r = v; g = n; b = wh; break;
402                 case 1: r = n; g = v; b = wh; break;
403                 case 2: r = wh; g = v; b = n; break;
404                 case 3: r = wh; g = n; b = v; break;
405                 case 4: r = n; g = wh; b = v; break;
406                 case 5: r = v; g = wh; b = n; break;
407         }
408
409         return [r * 255, g * 255, b * 255];
410 };
411
412 convert.cmyk.rgb = function (cmyk) {
413         var c = cmyk[0] / 100;
414         var m = cmyk[1] / 100;
415         var y = cmyk[2] / 100;
416         var k = cmyk[3] / 100;
417         var r;
418         var g;
419         var b;
420
421         r = 1 - Math.min(1, c * (1 - k) + k);
422         g = 1 - Math.min(1, m * (1 - k) + k);
423         b = 1 - Math.min(1, y * (1 - k) + k);
424
425         return [r * 255, g * 255, b * 255];
426 };
427
428 convert.xyz.rgb = function (xyz) {
429         var x = xyz[0] / 100;
430         var y = xyz[1] / 100;
431         var z = xyz[2] / 100;
432         var r;
433         var g;
434         var b;
435
436         r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
437         g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
438         b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
439
440         // assume sRGB
441         r = r > 0.0031308
442                 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
443                 : r * 12.92;
444
445         g = g > 0.0031308
446                 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
447                 : g * 12.92;
448
449         b = b > 0.0031308
450                 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
451                 : b * 12.92;
452
453         r = Math.min(Math.max(0, r), 1);
454         g = Math.min(Math.max(0, g), 1);
455         b = Math.min(Math.max(0, b), 1);
456
457         return [r * 255, g * 255, b * 255];
458 };
459
460 convert.xyz.lab = function (xyz) {
461         var x = xyz[0];
462         var y = xyz[1];
463         var z = xyz[2];
464         var l;
465         var a;
466         var b;
467
468         x /= 95.047;
469         y /= 100;
470         z /= 108.883;
471
472         x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
473         y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
474         z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
475
476         l = (116 * y) - 16;
477         a = 500 * (x - y);
478         b = 200 * (y - z);
479
480         return [l, a, b];
481 };
482
483 convert.lab.xyz = function (lab) {
484         var l = lab[0];
485         var a = lab[1];
486         var b = lab[2];
487         var x;
488         var y;
489         var z;
490
491         y = (l + 16) / 116;
492         x = a / 500 + y;
493         z = y - b / 200;
494
495         var y2 = Math.pow(y, 3);
496         var x2 = Math.pow(x, 3);
497         var z2 = Math.pow(z, 3);
498         y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
499         x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
500         z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
501
502         x *= 95.047;
503         y *= 100;
504         z *= 108.883;
505
506         return [x, y, z];
507 };
508
509 convert.lab.lch = function (lab) {
510         var l = lab[0];
511         var a = lab[1];
512         var b = lab[2];
513         var hr;
514         var h;
515         var c;
516
517         hr = Math.atan2(b, a);
518         h = hr * 360 / 2 / Math.PI;
519
520         if (h < 0) {
521                 h += 360;
522         }
523
524         c = Math.sqrt(a * a + b * b);
525
526         return [l, c, h];
527 };
528
529 convert.lch.lab = function (lch) {
530         var l = lch[0];
531         var c = lch[1];
532         var h = lch[2];
533         var a;
534         var b;
535         var hr;
536
537         hr = h / 360 * 2 * Math.PI;
538         a = c * Math.cos(hr);
539         b = c * Math.sin(hr);
540
541         return [l, a, b];
542 };
543
544 convert.rgb.ansi16 = function (args) {
545         var r = args[0];
546         var g = args[1];
547         var b = args[2];
548         var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization
549
550         value = Math.round(value / 50);
551
552         if (value === 0) {
553                 return 30;
554         }
555
556         var ansi = 30
557                 + ((Math.round(b / 255) << 2)
558                 | (Math.round(g / 255) << 1)
559                 | Math.round(r / 255));
560
561         if (value === 2) {
562                 ansi += 60;
563         }
564
565         return ansi;
566 };
567
568 convert.hsv.ansi16 = function (args) {
569         // optimization here; we already know the value and don't need to get
570         // it converted for us.
571         return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
572 };
573
574 convert.rgb.ansi256 = function (args) {
575         var r = args[0];
576         var g = args[1];
577         var b = args[2];
578
579         // we use the extended greyscale palette here, with the exception of
580         // black and white. normal palette only has 4 greyscale shades.
581         if (r === g && g === b) {
582                 if (r < 8) {
583                         return 16;
584                 }
585
586                 if (r > 248) {
587                         return 231;
588                 }
589
590                 return Math.round(((r - 8) / 247) * 24) + 232;
591         }
592
593         var ansi = 16
594                 + (36 * Math.round(r / 255 * 5))
595                 + (6 * Math.round(g / 255 * 5))
596                 + Math.round(b / 255 * 5);
597
598         return ansi;
599 };
600
601 convert.ansi16.rgb = function (args) {
602         var color = args % 10;
603
604         // handle greyscale
605         if (color === 0 || color === 7) {
606                 if (args > 50) {
607                         color += 3.5;
608                 }
609
610                 color = color / 10.5 * 255;
611
612                 return [color, color, color];
613         }
614
615         var mult = (~~(args > 50) + 1) * 0.5;
616         var r = ((color & 1) * mult) * 255;
617         var g = (((color >> 1) & 1) * mult) * 255;
618         var b = (((color >> 2) & 1) * mult) * 255;
619
620         return [r, g, b];
621 };
622
623 convert.ansi256.rgb = function (args) {
624         // handle greyscale
625         if (args >= 232) {
626                 var c = (args - 232) * 10 + 8;
627                 return [c, c, c];
628         }
629
630         args -= 16;
631
632         var rem;
633         var r = Math.floor(args / 36) / 5 * 255;
634         var g = Math.floor((rem = args % 36) / 6) / 5 * 255;
635         var b = (rem % 6) / 5 * 255;
636
637         return [r, g, b];
638 };
639
640 convert.rgb.hex = function (args) {
641         var integer = ((Math.round(args[0]) & 0xFF) << 16)
642                 + ((Math.round(args[1]) & 0xFF) << 8)
643                 + (Math.round(args[2]) & 0xFF);
644
645         var string = integer.toString(16).toUpperCase();
646         return '000000'.substring(string.length) + string;
647 };
648
649 convert.hex.rgb = function (args) {
650         var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
651         if (!match) {
652                 return [0, 0, 0];
653         }
654
655         var colorString = match[0];
656
657         if (match[0].length === 3) {
658                 colorString = colorString.split('').map(function (char) {
659                         return char + char;
660                 }).join('');
661         }
662
663         var integer = parseInt(colorString, 16);
664         var r = (integer >> 16) & 0xFF;
665         var g = (integer >> 8) & 0xFF;
666         var b = integer & 0xFF;
667
668         return [r, g, b];
669 };
670
671 convert.rgb.hcg = function (rgb) {
672         var r = rgb[0] / 255;
673         var g = rgb[1] / 255;
674         var b = rgb[2] / 255;
675         var max = Math.max(Math.max(r, g), b);
676         var min = Math.min(Math.min(r, g), b);
677         var chroma = (max - min);
678         var grayscale;
679         var hue;
680
681         if (chroma < 1) {
682                 grayscale = min / (1 - chroma);
683         } else {
684                 grayscale = 0;
685         }
686
687         if (chroma <= 0) {
688                 hue = 0;
689         } else
690         if (max === r) {
691                 hue = ((g - b) / chroma) % 6;
692         } else
693         if (max === g) {
694                 hue = 2 + (b - r) / chroma;
695         } else {
696                 hue = 4 + (r - g) / chroma + 4;
697         }
698
699         hue /= 6;
700         hue %= 1;
701
702         return [hue * 360, chroma * 100, grayscale * 100];
703 };
704
705 convert.hsl.hcg = function (hsl) {
706         var s = hsl[1] / 100;
707         var l = hsl[2] / 100;
708         var c = 1;
709         var f = 0;
710
711         if (l < 0.5) {
712                 c = 2.0 * s * l;
713         } else {
714                 c = 2.0 * s * (1.0 - l);
715         }
716
717         if (c < 1.0) {
718                 f = (l - 0.5 * c) / (1.0 - c);
719         }
720
721         return [hsl[0], c * 100, f * 100];
722 };
723
724 convert.hsv.hcg = function (hsv) {
725         var s = hsv[1] / 100;
726         var v = hsv[2] / 100;
727
728         var c = s * v;
729         var f = 0;
730
731         if (c < 1.0) {
732                 f = (v - c) / (1 - c);
733         }
734
735         return [hsv[0], c * 100, f * 100];
736 };
737
738 convert.hcg.rgb = function (hcg) {
739         var h = hcg[0] / 360;
740         var c = hcg[1] / 100;
741         var g = hcg[2] / 100;
742
743         if (c === 0.0) {
744                 return [g * 255, g * 255, g * 255];
745         }
746
747         var pure = [0, 0, 0];
748         var hi = (h % 1) * 6;
749         var v = hi % 1;
750         var w = 1 - v;
751         var mg = 0;
752
753         switch (Math.floor(hi)) {
754                 case 0:
755                         pure[0] = 1; pure[1] = v; pure[2] = 0; break;
756                 case 1:
757                         pure[0] = w; pure[1] = 1; pure[2] = 0; break;
758                 case 2:
759                         pure[0] = 0; pure[1] = 1; pure[2] = v; break;
760                 case 3:
761                         pure[0] = 0; pure[1] = w; pure[2] = 1; break;
762                 case 4:
763                         pure[0] = v; pure[1] = 0; pure[2] = 1; break;
764                 default:
765                         pure[0] = 1; pure[1] = 0; pure[2] = w;
766         }
767
768         mg = (1.0 - c) * g;
769
770         return [
771                 (c * pure[0] + mg) * 255,
772                 (c * pure[1] + mg) * 255,
773                 (c * pure[2] + mg) * 255
774         ];
775 };
776
777 convert.hcg.hsv = function (hcg) {
778         var c = hcg[1] / 100;
779         var g = hcg[2] / 100;
780
781         var v = c + g * (1.0 - c);
782         var f = 0;
783
784         if (v > 0.0) {
785                 f = c / v;
786         }
787
788         return [hcg[0], f * 100, v * 100];
789 };
790
791 convert.hcg.hsl = function (hcg) {
792         var c = hcg[1] / 100;
793         var g = hcg[2] / 100;
794
795         var l = g * (1.0 - c) + 0.5 * c;
796         var s = 0;
797
798         if (l > 0.0 && l < 0.5) {
799                 s = c / (2 * l);
800         } else
801         if (l >= 0.5 && l < 1.0) {
802                 s = c / (2 * (1 - l));
803         }
804
805         return [hcg[0], s * 100, l * 100];
806 };
807
808 convert.hcg.hwb = function (hcg) {
809         var c = hcg[1] / 100;
810         var g = hcg[2] / 100;
811         var v = c + g * (1.0 - c);
812         return [hcg[0], (v - c) * 100, (1 - v) * 100];
813 };
814
815 convert.hwb.hcg = function (hwb) {
816         var w = hwb[1] / 100;
817         var b = hwb[2] / 100;
818         var v = 1 - b;
819         var c = v - w;
820         var g = 0;
821
822         if (c < 1) {
823                 g = (v - c) / (1 - c);
824         }
825
826         return [hwb[0], c * 100, g * 100];
827 };
828
829 convert.apple.rgb = function (apple) {
830         return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
831 };
832
833 convert.rgb.apple = function (rgb) {
834         return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
835 };
836
837 convert.gray.rgb = function (args) {
838         return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
839 };
840
841 convert.gray.hsl = convert.gray.hsv = function (args) {
842         return [0, 0, args[0]];
843 };
844
845 convert.gray.hwb = function (gray) {
846         return [0, 100, gray[0]];
847 };
848
849 convert.gray.cmyk = function (gray) {
850         return [0, 0, 0, gray[0]];
851 };
852
853 convert.gray.lab = function (gray) {
854         return [gray[0], 0, 0];
855 };
856
857 convert.gray.hex = function (gray) {
858         var val = Math.round(gray[0] / 100 * 255) & 0xFF;
859         var integer = (val << 16) + (val << 8) + val;
860
861         var string = integer.toString(16).toUpperCase();
862         return '000000'.substring(string.length) + string;
863 };
864
865 convert.rgb.gray = function (rgb) {
866         var val = (rgb[0] + rgb[1] + rgb[2]) / 3;
867         return [val / 255 * 100];
868 };