obf 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,969 @@
1
+ // TinyColor v0.9.16
2
+ // https://github.com/bgrins/TinyColor
3
+ // 2013-08-10, Brian Grinstead, MIT License
4
+
5
+ var tiny = null;
6
+ (function() {
7
+
8
+ var trimLeft = /^[\s,#]+/,
9
+ trimRight = /\s+$/,
10
+ tinyCounter = 0,
11
+ math = Math,
12
+ mathRound = math.round,
13
+ mathMin = math.min,
14
+ mathMax = math.max,
15
+ mathRandom = math.random;
16
+
17
+ function tinycolor (color, opts) {
18
+
19
+ color = (color) ? color : '';
20
+ opts = opts || { };
21
+
22
+ // If input is already a tinycolor, return itself
23
+ if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
24
+ return color;
25
+ }
26
+
27
+ var rgb = inputToRGB(color);
28
+ var r = rgb.r,
29
+ g = rgb.g,
30
+ b = rgb.b,
31
+ a = rgb.a,
32
+ roundA = mathRound(100*a) / 100,
33
+ format = opts.format || rgb.format;
34
+
35
+ // Don't let the range of [0,255] come back in [0,1].
36
+ // Potentially lose a little bit of precision here, but will fix issues where
37
+ // .5 gets interpreted as half of the total, instead of half of 1
38
+ // If it was supposed to be 128, this was already taken care of by `inputToRgb`
39
+ if (r < 1) { r = mathRound(r); }
40
+ if (g < 1) { g = mathRound(g); }
41
+ if (b < 1) { b = mathRound(b); }
42
+
43
+ return {
44
+ ok: rgb.ok,
45
+ format: format,
46
+ _tc_id: tinyCounter++,
47
+ alpha: a,
48
+ getAlpha: function() {
49
+ return a;
50
+ },
51
+ setAlpha: function(value) {
52
+ a = boundAlpha(value);
53
+ roundA = mathRound(100*a) / 100;
54
+ },
55
+ toHsv: function() {
56
+ var hsv = rgbToHsv(r, g, b);
57
+ return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: a };
58
+ },
59
+ toHsvString: function() {
60
+ var hsv = rgbToHsv(r, g, b);
61
+ var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
62
+ return (a == 1) ?
63
+ "hsv(" + h + ", " + s + "%, " + v + "%)" :
64
+ "hsva(" + h + ", " + s + "%, " + v + "%, "+ roundA + ")";
65
+ },
66
+ toHsl: function() {
67
+ var hsl = rgbToHsl(r, g, b);
68
+ return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: a };
69
+ },
70
+ toHslString: function() {
71
+ var hsl = rgbToHsl(r, g, b);
72
+ var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
73
+ return (a == 1) ?
74
+ "hsl(" + h + ", " + s + "%, " + l + "%)" :
75
+ "hsla(" + h + ", " + s + "%, " + l + "%, "+ roundA + ")";
76
+ },
77
+ toHex: function(allow3Char) {
78
+ return rgbToHex(r, g, b, allow3Char);
79
+ },
80
+ toHexString: function(allow3Char) {
81
+ return '#' + this.toHex(allow3Char);
82
+ },
83
+ toHex8: function() {
84
+ return rgbaToHex(r, g, b, a);
85
+ },
86
+ toHex8String: function() {
87
+ return '#' + this.toHex8();
88
+ },
89
+ toRgb: function() {
90
+ return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a };
91
+ },
92
+ toRgbString: function() {
93
+ return (a == 1) ?
94
+ "rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" :
95
+ "rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")";
96
+ },
97
+ toPercentageRgb: function() {
98
+ return { r: mathRound(bound01(r, 255) * 100) + "%", g: mathRound(bound01(g, 255) * 100) + "%", b: mathRound(bound01(b, 255) * 100) + "%", a: a };
99
+ },
100
+ toPercentageRgbString: function() {
101
+ return (a == 1) ?
102
+ "rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" :
103
+ "rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")";
104
+ },
105
+ toName: function() {
106
+ if (a === 0) {
107
+ return "transparent";
108
+ }
109
+
110
+ return hexNames[rgbToHex(r, g, b, true)] || false;
111
+ },
112
+ toFilter: function(secondColor) {
113
+ var hex8String = '#' + rgbaToHex(r, g, b, a);
114
+ var secondHex8String = hex8String;
115
+ var gradientType = opts && opts.gradientType ? "GradientType = 1, " : "";
116
+
117
+ if (secondColor) {
118
+ var s = tinycolor(secondColor);
119
+ secondHex8String = s.toHex8String();
120
+ }
121
+
122
+ return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
123
+ },
124
+ toString: function(format) {
125
+ var formatSet = !!format;
126
+ format = format || this.format;
127
+
128
+ var formattedString = false;
129
+ var hasAlphaAndFormatNotSet = !formatSet && a < 1 && a > 0;
130
+ var formatWithAlpha = hasAlphaAndFormatNotSet && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
131
+
132
+ if (format === "rgb") {
133
+ formattedString = this.toRgbString();
134
+ }
135
+ if (format === "prgb") {
136
+ formattedString = this.toPercentageRgbString();
137
+ }
138
+ if (format === "hex" || format === "hex6") {
139
+ formattedString = this.toHexString();
140
+ }
141
+ if (format === "hex3") {
142
+ formattedString = this.toHexString(true);
143
+ }
144
+ if (format === "hex8") {
145
+ formattedString = this.toHex8String();
146
+ }
147
+ if (format === "name") {
148
+ formattedString = this.toName();
149
+ }
150
+ if (format === "hsl") {
151
+ formattedString = this.toHslString();
152
+ }
153
+ if (format === "hsv") {
154
+ formattedString = this.toHsvString();
155
+ }
156
+
157
+ if (formatWithAlpha) {
158
+ return this.toRgbString();
159
+ }
160
+
161
+ return formattedString || this.toHexString();
162
+ }
163
+ };
164
+ }
165
+
166
+ // If input is an object, force 1 into "1.0" to handle ratios properly
167
+ // String input requires "1.0" as input, so 1 will be treated as 1
168
+ tinycolor.fromRatio = function(color, opts) {
169
+ if (typeof color == "object") {
170
+ var newColor = {};
171
+ for (var i in color) {
172
+ if (color.hasOwnProperty(i)) {
173
+ if (i === "a") {
174
+ newColor[i] = color[i];
175
+ }
176
+ else {
177
+ newColor[i] = convertToPercentage(color[i]);
178
+ }
179
+ }
180
+ }
181
+ color = newColor;
182
+ }
183
+
184
+ return tinycolor(color, opts);
185
+ };
186
+
187
+ // Given a string or object, convert that input to RGB
188
+ // Possible string inputs:
189
+ //
190
+ // "red"
191
+ // "#f00" or "f00"
192
+ // "#ff0000" or "ff0000"
193
+ // "#ff000000" or "ff000000"
194
+ // "rgb 255 0 0" or "rgb (255, 0, 0)"
195
+ // "rgb 1.0 0 0" or "rgb (1, 0, 0)"
196
+ // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
197
+ // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
198
+ // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
199
+ // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
200
+ // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
201
+ //
202
+ function inputToRGB(color) {
203
+
204
+ var rgb = { r: 0, g: 0, b: 0 };
205
+ var a = 1;
206
+ var ok = false;
207
+ var format = false;
208
+
209
+ if (typeof color == "string") {
210
+ color = stringInputToObject(color);
211
+ }
212
+
213
+ if (typeof color == "object") {
214
+ if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
215
+ rgb = rgbToRgb(color.r, color.g, color.b);
216
+ ok = true;
217
+ format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
218
+ }
219
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
220
+ color.s = convertToPercentage(color.s);
221
+ color.v = convertToPercentage(color.v);
222
+ rgb = hsvToRgb(color.h, color.s, color.v);
223
+ ok = true;
224
+ format = "hsv";
225
+ }
226
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
227
+ color.s = convertToPercentage(color.s);
228
+ color.l = convertToPercentage(color.l);
229
+ rgb = hslToRgb(color.h, color.s, color.l);
230
+ ok = true;
231
+ format = "hsl";
232
+ }
233
+
234
+ if (color.hasOwnProperty("a")) {
235
+ a = color.a;
236
+ }
237
+ }
238
+
239
+ a = boundAlpha(a);
240
+
241
+ return {
242
+ ok: ok,
243
+ format: color.format || format,
244
+ r: mathMin(255, mathMax(rgb.r, 0)),
245
+ g: mathMin(255, mathMax(rgb.g, 0)),
246
+ b: mathMin(255, mathMax(rgb.b, 0)),
247
+ a: a
248
+ };
249
+ }
250
+
251
+
252
+ // Conversion Functions
253
+ // --------------------
254
+
255
+ // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
256
+ // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
257
+
258
+ // `rgbToRgb`
259
+ // Handle bounds / percentage checking to conform to CSS color spec
260
+ // <http://www.w3.org/TR/css3-color/>
261
+ // *Assumes:* r, g, b in [0, 255] or [0, 1]
262
+ // *Returns:* { r, g, b } in [0, 255]
263
+ function rgbToRgb(r, g, b){
264
+ return {
265
+ r: bound01(r, 255) * 255,
266
+ g: bound01(g, 255) * 255,
267
+ b: bound01(b, 255) * 255
268
+ };
269
+ }
270
+
271
+ // `rgbToHsl`
272
+ // Converts an RGB color value to HSL.
273
+ // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
274
+ // *Returns:* { h, s, l } in [0,1]
275
+ function rgbToHsl(r, g, b) {
276
+
277
+ r = bound01(r, 255);
278
+ g = bound01(g, 255);
279
+ b = bound01(b, 255);
280
+
281
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
282
+ var h, s, l = (max + min) / 2;
283
+
284
+ if(max == min) {
285
+ h = s = 0; // achromatic
286
+ }
287
+ else {
288
+ var d = max - min;
289
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
290
+ switch(max) {
291
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
292
+ case g: h = (b - r) / d + 2; break;
293
+ case b: h = (r - g) / d + 4; break;
294
+ }
295
+
296
+ h /= 6;
297
+ }
298
+
299
+ return { h: h, s: s, l: l };
300
+ }
301
+
302
+ // `hslToRgb`
303
+ // Converts an HSL color value to RGB.
304
+ // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
305
+ // *Returns:* { r, g, b } in the set [0, 255]
306
+ function hslToRgb(h, s, l) {
307
+ var r, g, b;
308
+
309
+ h = bound01(h, 360);
310
+ s = bound01(s, 100);
311
+ l = bound01(l, 100);
312
+
313
+ function hue2rgb(p, q, t) {
314
+ if(t < 0) t += 1;
315
+ if(t > 1) t -= 1;
316
+ if(t < 1/6) return p + (q - p) * 6 * t;
317
+ if(t < 1/2) return q;
318
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
319
+ return p;
320
+ }
321
+
322
+ if(s === 0) {
323
+ r = g = b = l; // achromatic
324
+ }
325
+ else {
326
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
327
+ var p = 2 * l - q;
328
+ r = hue2rgb(p, q, h + 1/3);
329
+ g = hue2rgb(p, q, h);
330
+ b = hue2rgb(p, q, h - 1/3);
331
+ }
332
+
333
+ return { r: r * 255, g: g * 255, b: b * 255 };
334
+ }
335
+
336
+ // `rgbToHsv`
337
+ // Converts an RGB color value to HSV
338
+ // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
339
+ // *Returns:* { h, s, v } in [0,1]
340
+ function rgbToHsv(r, g, b) {
341
+
342
+ r = bound01(r, 255);
343
+ g = bound01(g, 255);
344
+ b = bound01(b, 255);
345
+
346
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
347
+ var h, s, v = max;
348
+
349
+ var d = max - min;
350
+ s = max === 0 ? 0 : d / max;
351
+
352
+ if(max == min) {
353
+ h = 0; // achromatic
354
+ }
355
+ else {
356
+ switch(max) {
357
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
358
+ case g: h = (b - r) / d + 2; break;
359
+ case b: h = (r - g) / d + 4; break;
360
+ }
361
+ h /= 6;
362
+ }
363
+ return { h: h, s: s, v: v };
364
+ }
365
+
366
+ // `hsvToRgb`
367
+ // Converts an HSV color value to RGB.
368
+ // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
369
+ // *Returns:* { r, g, b } in the set [0, 255]
370
+ function hsvToRgb(h, s, v) {
371
+
372
+ h = bound01(h, 360) * 6;
373
+ s = bound01(s, 100);
374
+ v = bound01(v, 100);
375
+
376
+ var i = math.floor(h),
377
+ f = h - i,
378
+ p = v * (1 - s),
379
+ q = v * (1 - f * s),
380
+ t = v * (1 - (1 - f) * s),
381
+ mod = i % 6,
382
+ r = [v, q, p, p, t, v][mod],
383
+ g = [t, v, v, q, p, p][mod],
384
+ b = [p, p, t, v, v, q][mod];
385
+
386
+ return { r: r * 255, g: g * 255, b: b * 255 };
387
+ }
388
+
389
+ // `rgbToHex`
390
+ // Converts an RGB color to hex
391
+ // Assumes r, g, and b are contained in the set [0, 255]
392
+ // Returns a 3 or 6 character hex
393
+ function rgbToHex(r, g, b, allow3Char) {
394
+
395
+ var hex = [
396
+ pad2(mathRound(r).toString(16)),
397
+ pad2(mathRound(g).toString(16)),
398
+ pad2(mathRound(b).toString(16))
399
+ ];
400
+
401
+ // Return a 3 character hex if possible
402
+ if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
403
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
404
+ }
405
+
406
+ return hex.join("");
407
+ }
408
+ // `rgbaToHex`
409
+ // Converts an RGBA color plus alpha transparency to hex
410
+ // Assumes r, g, b and a are contained in the set [0, 255]
411
+ // Returns an 8 character hex
412
+ function rgbaToHex(r, g, b, a) {
413
+
414
+ var hex = [
415
+ pad2(convertDecimalToHex(a)),
416
+ pad2(mathRound(r).toString(16)),
417
+ pad2(mathRound(g).toString(16)),
418
+ pad2(mathRound(b).toString(16))
419
+ ];
420
+
421
+ return hex.join("");
422
+ }
423
+
424
+ // `equals`
425
+ // Can be called with any tinycolor input
426
+ tinycolor.equals = function (color1, color2) {
427
+ if (!color1 || !color2) { return false; }
428
+ return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
429
+ };
430
+ tinycolor.random = function() {
431
+ return tinycolor.fromRatio({
432
+ r: mathRandom(),
433
+ g: mathRandom(),
434
+ b: mathRandom()
435
+ });
436
+ };
437
+
438
+
439
+ // Modification Functions
440
+ // ----------------------
441
+ // Thanks to less.js for some of the basics here
442
+ // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
443
+
444
+ tinycolor.desaturate = function (color, amount) {
445
+ amount = (amount === 0) ? 0 : (amount || 10);
446
+ var hsl = tinycolor(color).toHsl();
447
+ hsl.s -= amount / 100;
448
+ hsl.s = clamp01(hsl.s);
449
+ return tinycolor(hsl);
450
+ };
451
+ tinycolor.saturate = function (color, amount) {
452
+ amount = (amount === 0) ? 0 : (amount || 10);
453
+ var hsl = tinycolor(color).toHsl();
454
+ hsl.s += amount / 100;
455
+ hsl.s = clamp01(hsl.s);
456
+ return tinycolor(hsl);
457
+ };
458
+ tinycolor.greyscale = function(color) {
459
+ return tinycolor.desaturate(color, 100);
460
+ };
461
+ tinycolor.lighten = function(color, amount) {
462
+ amount = (amount === 0) ? 0 : (amount || 10);
463
+ var hsl = tinycolor(color).toHsl();
464
+ hsl.l += amount / 100;
465
+ hsl.l = clamp01(hsl.l);
466
+ return tinycolor(hsl);
467
+ };
468
+ tinycolor.darken = function (color, amount) {
469
+ amount = (amount === 0) ? 0 : (amount || 10);
470
+ var hsl = tinycolor(color).toHsl();
471
+ hsl.l -= amount / 100;
472
+ hsl.l = clamp01(hsl.l);
473
+ return tinycolor(hsl);
474
+ };
475
+ tinycolor.complement = function(color) {
476
+ var hsl = tinycolor(color).toHsl();
477
+ hsl.h = (hsl.h + 180) % 360;
478
+ return tinycolor(hsl);
479
+ };
480
+
481
+
482
+ // Combination Functions
483
+ // ---------------------
484
+ // Thanks to jQuery xColor for some of the ideas behind these
485
+ // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
486
+
487
+ tinycolor.triad = function(color) {
488
+ var hsl = tinycolor(color).toHsl();
489
+ var h = hsl.h;
490
+ return [
491
+ tinycolor(color),
492
+ tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
493
+ tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
494
+ ];
495
+ };
496
+ tinycolor.tetrad = function(color) {
497
+ var hsl = tinycolor(color).toHsl();
498
+ var h = hsl.h;
499
+ return [
500
+ tinycolor(color),
501
+ tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
502
+ tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
503
+ tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
504
+ ];
505
+ };
506
+ tinycolor.splitcomplement = function(color) {
507
+ var hsl = tinycolor(color).toHsl();
508
+ var h = hsl.h;
509
+ return [
510
+ tinycolor(color),
511
+ tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
512
+ tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
513
+ ];
514
+ };
515
+ tinycolor.analogous = function(color, results, slices) {
516
+ results = results || 6;
517
+ slices = slices || 30;
518
+
519
+ var hsl = tinycolor(color).toHsl();
520
+ var part = 360 / slices;
521
+ var ret = [tinycolor(color)];
522
+
523
+ for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
524
+ hsl.h = (hsl.h + part) % 360;
525
+ ret.push(tinycolor(hsl));
526
+ }
527
+ return ret;
528
+ };
529
+ tinycolor.monochromatic = function(color, results) {
530
+ results = results || 6;
531
+ var hsv = tinycolor(color).toHsv();
532
+ var h = hsv.h, s = hsv.s, v = hsv.v;
533
+ var ret = [];
534
+ var modification = 1 / results;
535
+
536
+ while (results--) {
537
+ ret.push(tinycolor({ h: h, s: s, v: v}));
538
+ v = (v + modification) % 1;
539
+ }
540
+
541
+ return ret;
542
+ };
543
+
544
+
545
+ // Readability Functions
546
+ // ---------------------
547
+ // <http://www.w3.org/TR/AERT#color-contrast>
548
+
549
+ // `readability`
550
+ // Analyze the 2 colors and returns an object with the following properties:
551
+ // `brightness`: difference in brightness between the two colors
552
+ // `color`: difference in color/hue between the two colors
553
+ tinycolor.readability = function(color1, color2) {
554
+ var a = tinycolor(color1).toRgb();
555
+ var b = tinycolor(color2).toRgb();
556
+ var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
557
+ var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
558
+ var colorDiff = (
559
+ Math.max(a.r, b.r) - Math.min(a.r, b.r) +
560
+ Math.max(a.g, b.g) - Math.min(a.g, b.g) +
561
+ Math.max(a.b, b.b) - Math.min(a.b, b.b)
562
+ );
563
+
564
+ return {
565
+ brightness: Math.abs(brightnessA - brightnessB),
566
+ color: colorDiff
567
+ };
568
+ };
569
+
570
+ // `readable`
571
+ // http://www.w3.org/TR/AERT#color-contrast
572
+ // Ensure that foreground and background color combinations provide sufficient contrast.
573
+ // *Example*
574
+ // tinycolor.readable("#000", "#111") => false
575
+ tinycolor.readable = function(color1, color2) {
576
+ var readability = tinycolor.readability(color1, color2);
577
+ return readability.brightness > 125 && readability.color > 500;
578
+ };
579
+
580
+ // `mostReadable`
581
+ // Given a base color and a list of possible foreground or background
582
+ // colors for that base, returns the most readable color.
583
+ // *Example*
584
+ // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
585
+ tinycolor.mostReadable = function(baseColor, colorList) {
586
+ var bestColor = null;
587
+ var bestScore = 0;
588
+ var bestIsReadable = false;
589
+ for (var i=0; i < colorList.length; i++) {
590
+
591
+ // We normalize both around the "acceptable" breaking point,
592
+ // but rank brightness constrast higher than hue.
593
+
594
+ var readability = tinycolor.readability(baseColor, colorList[i]);
595
+ var readable = readability.brightness > 125 && readability.color > 500;
596
+ var score = 3 * (readability.brightness / 125) + (readability.color / 500);
597
+
598
+ if ((readable && ! bestIsReadable) ||
599
+ (readable && bestIsReadable && score > bestScore) ||
600
+ ((! readable) && (! bestIsReadable) && score > bestScore)) {
601
+ bestIsReadable = readable;
602
+ bestScore = score;
603
+ bestColor = tinycolor(colorList[i]);
604
+ }
605
+ }
606
+ return bestColor;
607
+ };
608
+
609
+
610
+ // Big List of Colors
611
+ // ------------------
612
+ // <http://www.w3.org/TR/css3-color/#svg-color>
613
+ var names = tinycolor.names = {
614
+ aliceblue: "f0f8ff",
615
+ antiquewhite: "faebd7",
616
+ aqua: "0ff",
617
+ aquamarine: "7fffd4",
618
+ azure: "f0ffff",
619
+ beige: "f5f5dc",
620
+ bisque: "ffe4c4",
621
+ black: "000",
622
+ blanchedalmond: "ffebcd",
623
+ blue: "00f",
624
+ blueviolet: "8a2be2",
625
+ brown: "a52a2a",
626
+ burlywood: "deb887",
627
+ burntsienna: "ea7e5d",
628
+ cadetblue: "5f9ea0",
629
+ chartreuse: "7fff00",
630
+ chocolate: "d2691e",
631
+ coral: "ff7f50",
632
+ cornflowerblue: "6495ed",
633
+ cornsilk: "fff8dc",
634
+ crimson: "dc143c",
635
+ cyan: "0ff",
636
+ darkblue: "00008b",
637
+ darkcyan: "008b8b",
638
+ darkgoldenrod: "b8860b",
639
+ darkgray: "a9a9a9",
640
+ darkgreen: "006400",
641
+ darkgrey: "a9a9a9",
642
+ darkkhaki: "bdb76b",
643
+ darkmagenta: "8b008b",
644
+ darkolivegreen: "556b2f",
645
+ darkorange: "ff8c00",
646
+ darkorchid: "9932cc",
647
+ darkred: "8b0000",
648
+ darksalmon: "e9967a",
649
+ darkseagreen: "8fbc8f",
650
+ darkslateblue: "483d8b",
651
+ darkslategray: "2f4f4f",
652
+ darkslategrey: "2f4f4f",
653
+ darkturquoise: "00ced1",
654
+ darkviolet: "9400d3",
655
+ deeppink: "ff1493",
656
+ deepskyblue: "00bfff",
657
+ dimgray: "696969",
658
+ dimgrey: "696969",
659
+ dodgerblue: "1e90ff",
660
+ firebrick: "b22222",
661
+ floralwhite: "fffaf0",
662
+ forestgreen: "228b22",
663
+ fuchsia: "f0f",
664
+ gainsboro: "dcdcdc",
665
+ ghostwhite: "f8f8ff",
666
+ gold: "ffd700",
667
+ goldenrod: "daa520",
668
+ gray: "808080",
669
+ green: "008000",
670
+ greenyellow: "adff2f",
671
+ grey: "808080",
672
+ honeydew: "f0fff0",
673
+ hotpink: "ff69b4",
674
+ indianred: "cd5c5c",
675
+ indigo: "4b0082",
676
+ ivory: "fffff0",
677
+ khaki: "f0e68c",
678
+ lavender: "e6e6fa",
679
+ lavenderblush: "fff0f5",
680
+ lawngreen: "7cfc00",
681
+ lemonchiffon: "fffacd",
682
+ lightblue: "add8e6",
683
+ lightcoral: "f08080",
684
+ lightcyan: "e0ffff",
685
+ lightgoldenrodyellow: "fafad2",
686
+ lightgray: "d3d3d3",
687
+ lightgreen: "90ee90",
688
+ lightgrey: "d3d3d3",
689
+ lightpink: "ffb6c1",
690
+ lightsalmon: "ffa07a",
691
+ lightseagreen: "20b2aa",
692
+ lightskyblue: "87cefa",
693
+ lightslategray: "789",
694
+ lightslategrey: "789",
695
+ lightsteelblue: "b0c4de",
696
+ lightyellow: "ffffe0",
697
+ lime: "0f0",
698
+ limegreen: "32cd32",
699
+ linen: "faf0e6",
700
+ magenta: "f0f",
701
+ maroon: "800000",
702
+ mediumaquamarine: "66cdaa",
703
+ mediumblue: "0000cd",
704
+ mediumorchid: "ba55d3",
705
+ mediumpurple: "9370db",
706
+ mediumseagreen: "3cb371",
707
+ mediumslateblue: "7b68ee",
708
+ mediumspringgreen: "00fa9a",
709
+ mediumturquoise: "48d1cc",
710
+ mediumvioletred: "c71585",
711
+ midnightblue: "191970",
712
+ mintcream: "f5fffa",
713
+ mistyrose: "ffe4e1",
714
+ moccasin: "ffe4b5",
715
+ navajowhite: "ffdead",
716
+ navy: "000080",
717
+ oldlace: "fdf5e6",
718
+ olive: "808000",
719
+ olivedrab: "6b8e23",
720
+ orange: "ffa500",
721
+ orangered: "ff4500",
722
+ orchid: "da70d6",
723
+ palegoldenrod: "eee8aa",
724
+ palegreen: "98fb98",
725
+ paleturquoise: "afeeee",
726
+ palevioletred: "db7093",
727
+ papayawhip: "ffefd5",
728
+ peachpuff: "ffdab9",
729
+ peru: "cd853f",
730
+ pink: "ffc0cb",
731
+ plum: "dda0dd",
732
+ powderblue: "b0e0e6",
733
+ purple: "800080",
734
+ red: "f00",
735
+ rosybrown: "bc8f8f",
736
+ royalblue: "4169e1",
737
+ saddlebrown: "8b4513",
738
+ salmon: "fa8072",
739
+ sandybrown: "f4a460",
740
+ seagreen: "2e8b57",
741
+ seashell: "fff5ee",
742
+ sienna: "a0522d",
743
+ silver: "c0c0c0",
744
+ skyblue: "87ceeb",
745
+ slateblue: "6a5acd",
746
+ slategray: "708090",
747
+ slategrey: "708090",
748
+ snow: "fffafa",
749
+ springgreen: "00ff7f",
750
+ steelblue: "4682b4",
751
+ tan: "d2b48c",
752
+ teal: "008080",
753
+ thistle: "d8bfd8",
754
+ tomato: "ff6347",
755
+ turquoise: "40e0d0",
756
+ violet: "ee82ee",
757
+ wheat: "f5deb3",
758
+ white: "fff",
759
+ whitesmoke: "f5f5f5",
760
+ yellow: "ff0",
761
+ yellowgreen: "9acd32"
762
+ };
763
+
764
+ // Make it easy to access colors via `hexNames[hex]`
765
+ var hexNames = tinycolor.hexNames = flip(names);
766
+
767
+
768
+ // Utilities
769
+ // ---------
770
+
771
+ // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
772
+ function flip(o) {
773
+ var flipped = { };
774
+ for (var i in o) {
775
+ if (o.hasOwnProperty(i)) {
776
+ flipped[o[i]] = i;
777
+ }
778
+ }
779
+ return flipped;
780
+ }
781
+
782
+ // Return a valid alpha value [0,1] with all invalid values being set to 1
783
+ function boundAlpha(a) {
784
+ a = parseFloat(a);
785
+
786
+ if (isNaN(a) || a < 0 || a > 1) {
787
+ a = 1;
788
+ }
789
+
790
+ return a;
791
+ }
792
+
793
+ // Take input from [0, n] and return it as [0, 1]
794
+ function bound01(n, max) {
795
+ if (isOnePointZero(n)) { n = "100%"; }
796
+
797
+ var processPercent = isPercentage(n);
798
+ n = mathMin(max, mathMax(0, parseFloat(n)));
799
+
800
+ // Automatically convert percentage into number
801
+ if (processPercent) {
802
+ n = parseInt(n * max, 10) / 100;
803
+ }
804
+
805
+ // Handle floating point rounding errors
806
+ if ((math.abs(n - max) < 0.000001)) {
807
+ return 1;
808
+ }
809
+
810
+ // Convert into [0, 1] range if it isn't already
811
+ return (n % max) / parseFloat(max);
812
+ }
813
+
814
+ // Force a number between 0 and 1
815
+ function clamp01(val) {
816
+ return mathMin(1, mathMax(0, val));
817
+ }
818
+
819
+ // Parse a base-16 hex value into a base-10 integer
820
+ function parseIntFromHex(val) {
821
+ return parseInt(val, 16);
822
+ }
823
+
824
+ // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
825
+ // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
826
+ function isOnePointZero(n) {
827
+ return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
828
+ }
829
+
830
+ // Check to see if string passed in is a percentage
831
+ function isPercentage(n) {
832
+ return typeof n === "string" && n.indexOf('%') != -1;
833
+ }
834
+
835
+ // Force a hex value to have 2 characters
836
+ function pad2(c) {
837
+ return c.length == 1 ? '0' + c : '' + c;
838
+ }
839
+
840
+ // Replace a decimal with it's percentage value
841
+ function convertToPercentage(n) {
842
+ if (n <= 1) {
843
+ n = (n * 100) + "%";
844
+ }
845
+
846
+ return n;
847
+ }
848
+
849
+ // Converts a decimal to a hex value
850
+ function convertDecimalToHex(d) {
851
+ return Math.round(parseFloat(d) * 255).toString(16);
852
+ }
853
+ // Converts a hex value to a decimal
854
+ function convertHexToDecimal(h) {
855
+ return (parseIntFromHex(h) / 255);
856
+ }
857
+
858
+ var matchers = (function() {
859
+
860
+ // <http://www.w3.org/TR/css3-values/#integers>
861
+ var CSS_INTEGER = "[-\\+]?\\d+%?";
862
+
863
+ // <http://www.w3.org/TR/css3-values/#number-value>
864
+ var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
865
+
866
+ // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
867
+ var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
868
+
869
+ // Actual matching.
870
+ // Parentheses and commas are optional, but not required.
871
+ // Whitespace can take the place of commas or opening paren
872
+ var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
873
+ var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
874
+
875
+ return {
876
+ rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
877
+ rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
878
+ hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
879
+ hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
880
+ hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
881
+ hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
882
+ hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
883
+ hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
884
+ };
885
+ })();
886
+
887
+ // `stringInputToObject`
888
+ // Permissive string parsing. Take in a number of formats, and output an object
889
+ // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
890
+ function stringInputToObject(color) {
891
+
892
+ color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
893
+ var named = false;
894
+ if (names[color]) {
895
+ color = names[color];
896
+ named = true;
897
+ }
898
+ else if (color == 'transparent') {
899
+ return { r: 0, g: 0, b: 0, a: 0, format: "name" };
900
+ }
901
+
902
+ // Try to match string input using regular expressions.
903
+ // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
904
+ // Just return an object and let the conversion functions handle that.
905
+ // This way the result will be the same whether the tinycolor is initialized with string or object.
906
+ var match;
907
+ if ((match = matchers.rgb.exec(color))) {
908
+ return { r: match[1], g: match[2], b: match[3] };
909
+ }
910
+ if ((match = matchers.rgba.exec(color))) {
911
+ return { r: match[1], g: match[2], b: match[3], a: match[4] };
912
+ }
913
+ if ((match = matchers.hsl.exec(color))) {
914
+ return { h: match[1], s: match[2], l: match[3] };
915
+ }
916
+ if ((match = matchers.hsla.exec(color))) {
917
+ return { h: match[1], s: match[2], l: match[3], a: match[4] };
918
+ }
919
+ if ((match = matchers.hsv.exec(color))) {
920
+ return { h: match[1], s: match[2], v: match[3] };
921
+ }
922
+ if ((match = matchers.hex8.exec(color))) {
923
+ return {
924
+ a: convertHexToDecimal(match[1]),
925
+ r: parseIntFromHex(match[2]),
926
+ g: parseIntFromHex(match[3]),
927
+ b: parseIntFromHex(match[4]),
928
+ format: named ? "name" : "hex8"
929
+ };
930
+ }
931
+ if ((match = matchers.hex6.exec(color))) {
932
+ return {
933
+ r: parseIntFromHex(match[1]),
934
+ g: parseIntFromHex(match[2]),
935
+ b: parseIntFromHex(match[3]),
936
+ format: named ? "name" : "hex"
937
+ };
938
+ }
939
+ if ((match = matchers.hex3.exec(color))) {
940
+ return {
941
+ r: parseIntFromHex(match[1] + '' + match[1]),
942
+ g: parseIntFromHex(match[2] + '' + match[2]),
943
+ b: parseIntFromHex(match[3] + '' + match[3]),
944
+ format: named ? "name" : "hex"
945
+ };
946
+ }
947
+
948
+ return false;
949
+ }
950
+
951
+ // Node: Export function
952
+ if (typeof module !== "undefined" && module.exports) {
953
+ module.exports = tinycolor;
954
+ tiny = tinycolor;
955
+ }
956
+ // AMD/requirejs: Define the module
957
+ else if (typeof define !== "undefined") {
958
+ define(function () {return tinycolor;});
959
+ }
960
+ // Browser: Expose to window
961
+ else {
962
+ window.tinycolor = tinycolor;
963
+ }
964
+
965
+ })();
966
+
967
+
968
+ var color = tiny(process.argv[2]);
969
+ console.log(color.toHex());