PageSourceSearch

https://www.roundhillfishkill.com/plugins/newcolorpicker/jquery.colorpicker.js

js roundhillfishkill.com collected 2026-09-26 05:00:26 UTC 116,333 bytes, 3,284 lines download raw bytes

1/*jslint devel: true, bitwise: true, regexp: true, browser: true, confusion: true, unparam: true, eqeq: true, white: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
2/*globals jQuery,Color,define */
3
4/*!
5 * ColorPicker
6 *
7 * Copyright (c) 2011-2017 Martijn W. van der Lee
8 * Licensed under the MIT.
9 */
10/* Full-featured colorpicker for jQueryUI with full theming support.
11 * Most images from jPicker by Christopher T. Tillman.
12 * Sourcecode created from scratch by Martijn W. van der Lee.
13 */
14(function( factory ) {
15  if ( typeof define === 'function' && define.amd ) {
16
17    // AMD. Register as an anonymous module.
18    define([
19      'jquery'
20    ], factory );
21  } else {
22
23    // Browser globals
24    factory( jQuery );
25  }
26} (function ($) {
27  'use strict';
28
29  var _colorpicker_index = 0,
30
31    _container_popup = '<div class="ui-colorpicker ui-colorpicker-dialog ui-dialog ui-widget ui-widget-content ui-corner-all" style="display: none;"></div>',
32    _container_inlineFrame = '<div class="ui-colorpicker ui-colorpicker-inline ui-dialog ui-widget ui-widget-content ui-corner-all"></div>',
33    _container_inline = '<div class="ui-colorpicker ui-colorpicker-inline"></div>',
34
35    _intToHex = function (dec) {
36      var result = Math.round(dec).toString(16);
37      if (result.length === 1) {
38        result = ('0' + result);
39      }
40      return result.toLowerCase();
41    },
42
43    _keycode = {
44      isPrint: function(keycode) {
45        return keycode == 32 // spacebar
46          || (keycode >= 48 && keycode <= 57) // number keys
47          || (keycode >= 65 && keycode <= 90) // letter keys
48          || (keycode >= 96 && keycode <= 111) // numpad keys
49          || (keycode >= 186 && keycode < 192) // ;=,-./` (in order)
50          || (keycode >= 219 && keycode < 222); // [\]' (in order)
51      },
52      isHex: function(keycode) {
53        return (keycode >= 48 && keycode <= 57) // number keys
54          || (keycode >= 96 && keycode <= 105) // numpad keys
55          || (keycode >= 65 && keycode <= 70); // a-f
56      }
57    },
58
59    _layoutTable = function(layout, callback) {
60      var bitmap,
61        x, y,
62        width, height,
63        columns, rows,
64        index,
65        cell,
66        html,
67        w, h,
68        colspan,
69        walked;
70
71      layout.sort(function(a, b) {
72        if (a.pos[1] === b.pos[1]) {
73          return a.pos[0] - b.pos[0];
74        }
75        return a.pos[1] - b.pos[1];
76      });
77
78      // Determine dimensions of the table
79      width = 0;
80      height = 0;
81      $.each (layout, function(index, part) {
82        width = Math.max(width, part.pos[0] + part.pos[2]);
83        height = Math.max(height, part.pos[1] + part.pos[3]);
84      });
85
86      // Initialize bitmap
87      bitmap = [];
88      for (x = 0; x < width; ++x) {
89        bitmap.push([]);
90      }
91
92      // Mark rows and columns which have layout assigned
93      rows = [];
94      columns = [];
95      $.each(layout, function(index, part) {
96        // mark columns
97        for (x = 0; x < part.pos[2]; x += 1) {
98          columns[part.pos[0] + x] = true;
99        }
100        for (y = 0; y < part.pos[3]; y += 1) {
101          rows[part.pos[1] + y] = true;
102        }
103      });
104
105      // Generate the table
106      html = '';
107      cell = layout[index = 0];
108      for (y = 0; y < height; ++y) {
109        html += '<tr>';
110        x = 0;
111        while (x < width) {
112          if (typeof cell !== 'undefined' && x === cell.pos[0] && y === cell.pos[1]) {
113            // Create a "real" cell
114            html += callback(cell, x, y);
115
116            for (h = 0; h < cell.pos[3]; h +=1) {
117              for (w = 0; w < cell.pos[2]; w +=1) {
118                bitmap[x + w][y + h] = true;
119              }
120            }
121
122            x += cell.pos[2];
123            cell = layout[++index];
124          } else {
125            // Fill in the gaps
126            colspan = 0;
127            walked = false;
128
129            while (x < width && bitmap[x][y] === undefined && (cell === undefined || y < cell.pos[1] || (y === cell.pos[1] && x < cell.pos[0]))) {
130              if (columns[x] === true) {
131                colspan += 1;
132              }
133              walked = true;
134              x += 1;
135            }
136
137            if (colspan > 0) {
138              html += '<td colspan="'+colspan+'"></td>';
139            } else if (!walked) {
140              x += 1;
141            }
142          }
143        }
144        html += '</tr>';
145      }
146
147      return '<table cellspacing="0" cellpadding="0" border="0"><tbody>' + html + '</tbody></table>';
148    };
149
150  $.colorpicker = new function() {
151    this.regional = {
152      '': {
153        ok:       'OK',
154        cancel:     'Cancel',
155        none:     'None',
156        button:     'Color',
157        title:      'Pick a color',
158        transparent:  'Transparent',
159        hsvH:     'H',
160        hsvS:     'S',
161        hsvV:     'V',
162        rgbR:     'R',
163        rgbG:     'G',
164        rgbB:     'B',
165        labL:     'L',
166        labA:     'a',
167        labB:     'b',
168        hslH:     'H',
169        hslS:     'S',
170        hslL:     'L',
171        cmykC:      'C',
172        cmykM:      'M',
173        cmykY:      'Y',
174        cmykK:      'K',
175        alphaA:     'A'
176      }
177    };
178
179    this.swatchesNames = {
180      'html':   'HTML'
181    };
182
183    this.swatches = {
184      'html': [
185        {name: 'black',         r: 0, g: 0, b: 0},
186        {name: 'dimgray',       r: 0.4117647058823529, g: 0.4117647058823529, b: 0.4117647058823529},
187        {name: 'gray',          r: 0.5019607843137255, g: 0.5019607843137255, b: 0.5019607843137255},
188        {name: 'darkgray',        r: 0.6627450980392157, g: 0.6627450980392157, b: 0.6627450980392157},
189        {name: 'silver',        r: 0.7529411764705882, g: 0.7529411764705882, b: 0.7529411764705882},
190        {name: 'lightgrey',       r: 0.8274509803921568, g: 0.8274509803921568, b: 0.8274509803921568},
191        {name: 'gainsboro',       r: 0.8627450980392157, g: 0.8627450980392157, b: 0.8627450980392157},
192        {name: 'whitesmoke',      r: 0.9607843137254902, g: 0.9607843137254902, b: 0.9607843137254902},
193        {name: 'white',         r: 1, g: 1, b: 1},
194        {name: 'rosybrown',       r: 0.7372549019607844, g: 0.5607843137254902, b: 0.5607843137254902},
195        {name: 'indianred',       r: 0.803921568627451, g: 0.3607843137254902, b: 0.3607843137254902},
196        {name: 'brown',         r: 0.6470588235294118, g: 0.16470588235294117, b: 0.16470588235294117},
197        {name: 'firebrick',       r: 0.6980392156862745, g: 0.13333333333333333, b: 0.13333333333333333},
198        {name: 'lightcoral',      r: 0.9411764705882353, g: 0.5019607843137255, b: 0.5019607843137255},
199        {name: 'maroon',        r: 0.5019607843137255, g: 0, b: 0},
200        {name: 'darkred',       r: 0.5450980392156862, g: 0, b: 0},
201        {name: 'red',         r: 1, g: 0, b: 0},
202        {name: 'snow',          r: 1, g: 0.9803921568627451, b: 0.9803921568627451},
203        {name: 'salmon',        r: 0.9803921568627451, g: 0.5019607843137255, b: 0.4470588235294118},
204        {name: 'mistyrose',       r: 1, g: 0.8941176470588236, b: 0.8823529411764706},
205        {name: 'tomato',        r: 1, g: 0.38823529411764707, b: 0.2784313725490196},
206        {name: 'darksalmon',      r: 0.9137254901960784, g: 0.5882352941176471, b: 0.47843137254901963},
207        {name: 'orangered',       r: 1, g: 0.27058823529411763, b: 0},
208        {name: 'coral',         r: 1, g: 0.4980392156862745, b: 0.3137254901960784},
209        {name: 'lightsalmon',     r: 1, g: 0.6274509803921569, b: 0.47843137254901963},
210        {name: 'sienna',        r: 0.6274509803921569, g: 0.3215686274509804, b: 0.17647058823529413},
211        {name: 'seashell',        r: 1, g: 0.9607843137254902, b: 0.9333333333333333},
212        {name: 'chocolate',       r: 0.8235294117647058, g: 0.4117647058823529, b: 0.11764705882352941},
213        {name: 'saddlebrown',     r: 0.5450980392156862, g: 0.27058823529411763, b: 0.07450980392156863},
214        {name: 'sandybrown',      r: 0.9568627450980393, g: 0.6431372549019608, b: 0.3764705882352941},
215        {name: 'peachpuff',       r: 1, g: 0.8549019607843137, b: 0.7254901960784313},
216        {name: 'peru',          r: 0.803921568627451, g: 0.5215686274509804, b: 0.24705882352941178},
217        {name: 'linen',         r: 0.9803921568627451, g: 0.9411764705882353, b: 0.9019607843137255},
218        {name: 'darkorange',      r: 1, g: 0.5490196078431373, b: 0},
219        {name: 'bisque',        r: 1, g: 0.8941176470588236, b: 0.7686274509803922},
220        {name: 'burlywood',       r: 0.8705882352941177, g: 0.7215686274509804, b: 0.5294117647058824},
221        {name: 'tan',         r: 0.8235294117647058, g: 0.7058823529411765, b: 0.5490196078431373},
222        {name: 'antiquewhite',      r: 0.9803921568627451, g: 0.9215686274509803, b: 0.8431372549019608},
223        {name: 'navajowhite',     r: 1, g: 0.8705882352941177, b: 0.6784313725490196},
224        {name: 'blanchedalmond',    r: 1, g: 0.9215686274509803, b: 0.803921568627451},
225        {name: 'papayawhip',      r: 1, g: 0.9372549019607843, b: 0.8352941176470589},
226        {name: 'orange',        r: 1, g: 0.6470588235294118, b: 0},
227        {name: 'moccasin',        r: 1, g: 0.8941176470588236, b: 0.7098039215686275},
228        {name: 'wheat',         r: 0.9607843137254902, g: 0.8705882352941177, b: 0.7019607843137254},
229        {name: 'oldlace',       r: 0.9921568627450981, g: 0.9607843137254902, b: 0.9019607843137255},
230        {name: 'floralwhite',     r: 1, g: 0.9803921568627451, b: 0.9411764705882353},
231        {name: 'goldenrod',       r: 0.8549019607843137, g: 0.6470588235294118, b: 0.12549019607843137},
232        {name: 'darkgoldenrod',     r: 0.7215686274509804, g: 0.5254901960784314, b: 0.043137254901960784},
233        {name: 'cornsilk',        r: 1, g: 0.9725490196078431, b: 0.8627450980392157},
234        {name: 'gold',          r: 1, g: 0.8431372549019608, b: 0},
235        {name: 'palegoldenrod',     r: 0.9333333333333333, g: 0.9098039215686274, b: 0.6666666666666666},
236        {name: 'khaki',         r: 0.9411764705882353, g: 0.9019607843137255, b: 0.5490196078431373},
237        {name: 'lemonchiffon',      r: 1, g: 0.9803921568627451, b: 0.803921568627451},
238        {name: 'darkkhaki',       r: 0.7411764705882353, g: 0.7176470588235294, b: 0.4196078431372549},
239        {name: 'beige',         r: 0.9607843137254902, g: 0.9607843137254902, b: 0.8627450980392157},
240        {name: 'lightgoldenrodyellow',  r: 0.9803921568627451, g: 0.9803921568627451, b: 0.8235294117647058},
241        {name: 'olive',         r: 0.5019607843137255, g: 0.5019607843137255, b: 0},
242        {name: 'yellow',        r: 1, g: 1, b: 0},
243        {name: 'lightyellow',     r: 1, g: 1, b: 0.8784313725490196},
244        {name: 'ivory',         r: 1, g: 1, b: 0.9411764705882353},
245        {name: 'olivedrab',       r: 0.4196078431372549, g: 0.5568627450980392, b: 0.13725490196078433},
246        {name: 'yellowgreen',     r: 0.6039215686274509, g: 0.803921568627451, b: 0.19607843137254902},
247        {name: 'darkolivegreen',    r: 0.3333333333333333, g: 0.4196078431372549, b: 0.1843137254901961},
248        {name: 'greenyellow',     r: 0.6784313725490196, g: 1, b: 0.1843137254901961},
249        {name: 'lawngreen',       r: 0.48627450980392156, g: 0.9882352941176471, b: 0},
250        {name: 'chartreuse',      r: 0.4980392156862745, g: 1, b: 0},
251        {name: 'darkseagreen',      r: 0.5607843137254902, g: 0.7372549019607844, b: 0.5607843137254902},
252        {name: 'forestgreen',     r: 0.13333333333333333, g: 0.5450980392156862, b: 0.13333333333333333},
253        {name: 'limegreen',       r: 0.19607843137254902, g: 0.803921568627451, b: 0.19607843137254902},
254        {name: 'lightgreen',      r: 0.5647058823529412, g: 0.9333333333333333, b: 0.5647058823529412},
255        {name: 'palegreen',       r: 0.596078431372549, g: 0.984313725490196, b: 0.596078431372549},
256        {name: 'darkgreen',       r: 0, g: 0.39215686274509803, b: 0},
257        {name: 'green',         r: 0, g: 0.5019607843137255, b: 0},
258        {name: 'lime',          r: 0, g: 1, b: 0},
259        {name: 'honeydew',        r: 0.9411764705882353, g: 1, b: 0.9411764705882353},
260        {name: 'mediumseagreen',    r: 0.23529411764705882, g: 0.7019607843137254, b: 0.44313725490196076},
261        {name: 'seagreen',        r: 0.1803921568627451, g: 0.5450980392156862, b: 0.3411764705882353},
262        {name: 'springgreen',     r: 0, g: 1, b: 0.4980392156862745},
263        {name: 'mintcream',       r: 0.9607843137254902, g: 1, b: 0.9803921568627451},
264        {name: 'mediumspringgreen',   r: 0, g: 0.9803921568627451, b: 0.6039215686274509},
265        {name: 'mediumaquamarine',    r: 0.4, g: 0.803921568627451, b: 0.6666666666666666},
266        {name: 'aquamarine',      r: 0.4980392156862745, g: 1, b: 0.8313725490196079},
267        {name: 'turquoise',       r: 0.25098039215686274, g: 0.8784313725490196, b: 0.8156862745098039},
268        {name: 'lightseagreen',     r: 0.12549019607843137, g: 0.6980392156862745, b: 0.6666666666666666},
269        {name: 'mediumturquoise',   r: 0.2823529411764706, g: 0.8196078431372549, b: 0.8},
270        {name: 'darkslategray',     r: 0.1843137254901961, g: 0.30980392156862746, b: 0.30980392156862746},
271        {name: 'paleturquoise',     r: 0.6862745098039216, g: 0.9333333333333333, b: 0.9333333333333333},
272        {name: 'teal',          r: 0, g: 0.5019607843137255, b: 0.5019607843137255},
273        {name: 'darkcyan',        r: 0, g: 0.5450980392156862, b: 0.5450980392156862},
274        {name: 'darkturquoise',     r: 0, g: 0.807843137254902, b: 0.8196078431372549},
275        {name: 'aqua',          r: 0, g: 1, b: 1},
276        {name: 'cyan',          r: 0, g: 1, b: 1},
277        {name: 'lightcyan',       r: 0.8784313725490196, g: 1, b: 1},
278        {name: 'azure',         r: 0.9411764705882353, g: 1, b: 1},
279        {name: 'cadetblue',       r: 0.37254901960784315, g: 0.6196078431372549, b: 0.6274509803921569},
280        {name: 'powderblue',      r: 0.6901960784313725, g: 0.8784313725490196, b: 0.9019607843137255},
281        {name: 'lightblue',       r: 0.6784313725490196, g: 0.8470588235294118, b: 0.9019607843137255},
282        {name: 'deepskyblue',     r: 0, g: 0.7490196078431373, b: 1},
283        {name: 'skyblue',       r: 0.5294117647058824, g: 0.807843137254902, b: 0.9215686274509803},
284        {name: 'lightskyblue',      r: 0.5294117647058824, g: 0.807843137254902, b: 0.9803921568627451},
285        {name: 'steelblue',       r: 0.27450980392156865, g: 0.5098039215686274, b: 0.7058823529411765},
286        {name: 'aliceblue',       r: 0.9411764705882353, g: 0.9725490196078431, b: 1},
287        {name: 'dodgerblue',      r: 0.11764705882352941, g: 0.5647058823529412, b: 1},
288        {name: 'slategray',       r: 0.4392156862745098, g: 0.5019607843137255, b: 0.5647058823529412},
289        {name: 'lightslategray',    r: 0.4666666666666667, g: 0.5333333333333333, b: 0.6},
290        {name: 'lightsteelblue',    r: 0.6901960784313725, g: 0.7686274509803922, b: 0.8705882352941177},
291        {name: 'cornflowerblue',    r: 0.39215686274509803, g: 0.5843137254901961, b: 0.9294117647058824},
292        {name: 'royalblue',       r: 0.2549019607843137, g: 0.4117647058823529, b: 0.8823529411764706},
293        {name: 'midnightblue',      r: 0.09803921568627451, g: 0.09803921568627451, b: 0.4392156862745098},
294        {name: 'lavender',        r: 0.9019607843137255, g: 0.9019607843137255, b: 0.9803921568627451},
295        {name: 'navy',          r: 0, g: 0, b: 0.5019607843137255},
296        {name: 'darkblue',        r: 0, g: 0, b: 0.5450980392156862},
297        {name: 'mediumblue',      r: 0, g: 0, b: 0.803921568627451},
298        {name: 'blue',          r: 0, g: 0, b: 1},
299        {name: 'ghostwhite',      r: 0.9725490196078431, g: 0.9725490196078431, b: 1},
300        {name: 'darkslateblue',     r: 0.2823529411764706, g: 0.23921568627450981, b: 0.5450980392156862},
301        {name: 'slateblue',       r: 0.41568627450980394, g: 0.35294117647058826, b: 0.803921568627451},
302        {name: 'mediumslateblue',   r: 0.4823529411764706, g: 0.40784313725490196, b: 0.9333333333333333},
303        {name: 'mediumpurple',      r: 0.5764705882352941, g: 0.4392156862745098, b: 0.8588235294117647},
304        {name: 'blueviolet',      r: 0.5411764705882353, g: 0.16862745098039217, b: 0.8862745098039215},
305        {name: 'indigo',        r: 0.29411764705882354, g: 0, b: 0.5098039215686274},
306        {name: 'darkorchid',      r: 0.6, g: 0.19607843137254902, b: 0.8},
307        {name: 'darkviolet',      r: 0.5803921568627451, g: 0, b: 0.8274509803921568},
308        {name: 'mediumorchid',      r: 0.7294117647058823, g: 0.3333333333333333, b: 0.8274509803921568},
309        {name: 'thistle',       r: 0.8470588235294118, g: 0.7490196078431373, b: 0.8470588235294118},
310        {name: 'plum',          r: 0.8666666666666667, g: 0.6274509803921569, b: 0.8666666666666667},
311        {name: 'violet',        r: 0.9333333333333333, g: 0.5098039215686274, b: 0.9333333333333333},
312        {name: 'purple',        r: 0.5019607843137255, g: 0, b: 0.5019607843137255},
313        {name: 'darkmagenta',     r: 0.5450980392156862, g: 0, b: 0.5450980392156862},
314        {name: 'magenta',       r: 1, g: 0, b: 1},
315        {name: 'fuchsia',       r: 1, g: 0, b: 1},
316        {name: 'orchid',        r: 0.8549019607843137, g: 0.4392156862745098, b: 0.8392156862745098},
317        {name: 'mediumvioletred',   r: 0.7803921568627451, g: 0.08235294117647059, b: 0.5215686274509804},
318        {name: 'deeppink',        r: 1, g: 0.0784313725490196, b: 0.5764705882352941},
319        {name: 'hotpink',       r: 1, g: 0.4117647058823529, b: 0.7058823529411765},
320        {name: 'palevioletred',     r: 0.8588235294117647, g: 0.4392156862745098, b: 0.5764705882352941},
321        {name: 'lavenderblush',     r: 1, g: 0.9411764705882353, b: 0.9607843137254902},
322        {name: 'crimson',       r: 0.8627450980392157, g: 0.0784313725490196, b: 0.23529411764705882},
323        {name: 'pink',          r: 1, g: 0.7529411764705882, b: 0.796078431372549},
324        {name: 'lightpink',       r: 1, g: 0.7137254901960784, b: 0.7568627450980392}
325      ]
326    };
327
328    this.writers = {
329      '#HEX':   function(color, that) {
330        return that._formatColor('#rxgxbx', color);
331      }
332      , '#HEX3':  function(color, that) {
333        var hex3 = $.colorpicker.writers.HEX3(color);
334        return hex3 === false? false : '#'+hex3;
335      }
336      , 'HEX':    function(color, that) {
337        return that._formatColor('rxgxbx', color);
338      }
339      , 'HEX3':   function(color, that) {
340        var rgb = color.getRGB(),
341          r = Math.round(rgb.r * 255),
342          g = Math.round(rgb.g * 255),
343          b = Math.round(rgb.b * 255);
344
345        if (((r >>> 4) === (r &= 0xf))
346               && ((g >>> 4) === (g &= 0xf))
347               && ((b >>> 4) === (b &= 0xf))) {
348          return r.toString(16)+g.toString(16)+b.toString(16);
349        }
350        return false;
351      }
352      , '#HEXA':  function(color, that) {
353        return that._formatColor('#rxgxbxax', color);
354      }
355      , '#HEXA4': function(color, that) {
356        var hexa4 = $.colorpicker.writers.HEXA4(color, that);
357        return hexa4 === false? false : '#'+hexa4;
358      }
359      , 'HEXA': function(color, that) {
360        return that._formatColor('rxgxbxax', color);
361      }
362      , 'HEXA4':    function(color, that) {
363        var a = Math.round(color.getAlpha() * 255);
364
365        if ((a >>> 4) === (a &= 0xf)) {
366          return $.colorpicker.writers.HEX3(color, that)+a.toString(16);
367        }
368        return false;
369      }
370      , 'RGB':    function(color, that) {
371        return color.getAlpha() >= 1
372          ? that._formatColor('rgb(rd,gd,bd)', color)
373          : false;
374      }
375      , 'RGBA':   function(color, that) {
376        return that._formatColor('rgba(rd,gd,bd,af)', color);
377      }
378      , 'RGB%':   function(color, that) {
379        return color.getAlpha() >= 1
380          ? that._formatColor('rgb(rp%,gp%,bp%)', color)
381          : false;
382      }
383      , 'RGBA%':  function(color, that) {
384        return that._formatColor('rgba(rp%,gp%,bp%,af)', color);
385      }
386      , 'HSL':    function(color, that) {
387        return color.getAlpha() >= 1
388          ? that._formatColor('hsl(hd,sd,vd)', color)
389          : false;
390      }
391      , 'HSLA':   function(color, that) {
392        return that._formatColor('hsla(hd,sd,vd,af)', color);
393      }
394      , 'HSL%':   function(color, that) {
395        return color.getAlpha() >= 1
396          ? that._formatColor('hsl(hp%,sp%,vp%)', color)
397          : false;
398      }
399      , 'HSLA%':  function(color, that) {
400        return that._formatColor('hsla(hp%,sp%,vp%,af)', color);
401      }
402      , 'NAME':   function(color, that) {
403        return that._closestName(color);
404      }
405      , 'EXACT':  function(color, that) {
406        return that._exactName(color);
407      }
408    };
409
410    this.parsers = {
411      '':     function(color) {
412        if (color === '') {
413          return new $.colorpicker.Color();
414        }
415      }
416      , 'NAME':   function(color, that) {
417        var c = that._getSwatch($.trim(color));
418        if (c) {
419          return new $.colorpicker.Color(c.r, c.g, c.b);
420        }
421      }
422      , 'RGBA':   function(color) {
423        var m = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/.exec(color);
424        if (m) {
425          return new $.colorpicker.Color(
426            m[1] / 255,
427            m[2] / 255,
428            m[3] / 255,
429            parseFloat(m[4])
430          );
431        }
432      }
433      , 'RGBA%':  function(color) {
434        var m = /^rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/.exec(color);
435        if (m) {
436          return new $.colorpicker.Color(
437            m[1] / 100,
438            m[2] / 100,
439            m[3] / 100,
440            m[4] / 100
441          );
442        }
443      }
444      , 'HSLA': function(color) {
445        var m = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/.exec(color);
446        if (m) {
447          return (new $.colorpicker.Color()).setHSL(
448            m[1] / 255,
449            m[2] / 255,
450            m[3] / 255).setAlpha(parseFloat(m[4]));
451        }
452      }
453      , 'HSLA%': function(color) {
454        var m = /^hsla?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/.exec(color);
455        if (m) {
456          return (new $.colorpicker.Color()).setHSL(
457            m[1] / 100,
458            m[2] / 100,
459            m[3] / 100).setAlpha(m[4] / 100);
460        }
461      }
462      , '#HEX': function(color) {
463        var m = /^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(color);
464        if (m) {
465          return new $.colorpicker.Color(
466            parseInt(m[1], 16) / 255,
467            parseInt(m[2], 16) / 255,
468            parseInt(m[3], 16) / 255
469          );
470        }
471      }
472      , '#HEX3': function(color) {
473        var m = /^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(color);
474        if (m) {
475          return new $.colorpicker.Color(
476            parseInt(String(m[1]) + m[1], 16) / 255,
477            parseInt(String(m[2]) + m[2], 16) / 255,
478            parseInt(String(m[3]) + m[3], 16) / 255
479          );
480        }
481      }
482      , 'HEX': function(color) {
483        var m = /^([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(color);
484        if (m) {
485          return new $.colorpicker.Color(
486            parseInt(m[1], 16) / 255,
487            parseInt(m[2], 16) / 255,
488            parseInt(m[3], 16) / 255
489          );
490        }
491      }
492      , 'HEX3': function(color) {
493        var m = /^([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(color);
494        if (m) {
495          return new $.colorpicker.Color(
496            parseInt(String(m[1]) + m[1], 16) / 255,
497            parseInt(String(m[2]) + m[2], 16) / 255,
498            parseInt(String(m[3]) + m[3], 16) / 255
499          );
500        }
501      }
502      , '#HEXA': function(color) {
503        var m = /^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(color);
504        if (m) {
505          return new $.colorpicker.Color(
506            parseInt(m[1], 16) / 255,
507            parseInt(m[2], 16) / 255,
508            parseInt(m[3], 16) / 255,
509            parseInt(m[4], 16) / 255
510          );
511        }
512      }
513      , '#HEXA4': function(color) {
514        var m = /^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(color);
515        if (m) {
516          return new $.colorpicker.Color(
517            parseInt(String(m[1]) + m[1], 16) / 255,
518            parseInt(String(m[2]) + m[2], 16) / 255,
519            parseInt(String(m[3]) + m[3], 16) / 255,
520            parseInt(String(m[4]) + m[4], 16) / 255
521          );
522        }
523      }
524      , 'HEXA': function(color) {
525        var m = /^([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(color);
526        if (m) {
527          return new $.colorpicker.Color(
528            parseInt(m[1], 16) / 255,
529            parseInt(m[2], 16) / 255,
530            parseInt(m[3], 16) / 255,
531            parseInt(m[4], 16) / 255
532          );
533        }
534      }
535      , 'HEXA4': function(color) {
536        var m = /^([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(color);
537        if (m) {
538          return new $.colorpicker.Color(
539            parseInt(String(m[1]) + m[1], 16) / 255,
540            parseInt(String(m[2]) + m[2], 16) / 255,
541            parseInt(String(m[3]) + m[3], 16) / 255,
542            parseInt(String(m[4]) + m[4], 16) / 255
543          );
544        }
545      }
546    };
547
548    this.partslists = {
549      'full': ['header', 'map', 'bar', 'hex', 'hsv', 'rgb', 'alpha', 'lab', 'cmyk', 'preview', 'swatches', 'footer'],
550      'popup': ['map', 'bar', 'hex', 'hsv', 'rgb', 'alpha', 'preview', 'footer'],
551      'draggable': ['header', 'map', 'bar', 'hex', 'hsv', 'rgb', 'alpha', 'preview', 'footer'],
552      'inline': ['map', 'bar', 'hex', 'hsv', 'rgb', 'alpha', 'preview']
553    };
554
555    this.limits = {
556      'websafe': function(color) {
557        color.limit(6);
558      },
559      'nibble': function(color) {
560        color.limit(16);
561      },
562      'binary': function(color) {
563        color.limit(2);
564      },
565      'name': function(color, that) {
566        var swatch = that._getSwatch(that._closestName(color));
567        color.setRGB(swatch.r, swatch.g, swatch.b);
568      }
569    };
570
571    this.parts = {
572      header: function (inst) {
573        var that = this,
574          part = null,
575          _html  = function() {
576            var title = inst.options.title || inst._getRegional('title'),
577              html = '<span class="ui-dialog-title">' + title + '</span>';
578
579            if (!inst.inline && inst.options.showCloseButton) {
580              html += '<a href="#" class="ui-dialog-titlebar-close ui-corner-all" role="button">'
581                + '<span class="ui-icon ui-icon-closethick">close</span></a>';
582            }
583
584            return '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix">' + html + '</div>';
585          },
586          _onclick = function(event) {
587            event.preventDefault();
588            inst.close(inst.options.revert);
589          };
590
591        this.init = function() {
592          part = $(_html()).prependTo(inst.dialog);
593
594          var close = $('.ui-dialog-titlebar-close', part);
595          inst._hoverable(close);
596          inst._focusable(close);
597          close.on('click', _onclick);
598
599          if (!inst.inline && inst.options.draggable) {
600            var draggableOptions = {
601              handle: part,
602            };
603            if (inst.options.containment) {
604              draggableOptions.containment = inst.options.containment;
605            }
606            inst.dialog.draggable(draggableOptions);
607          }
608        };
609
610        this.disable = function (disable) {
611          $('.ui-dialog-titlebar-close', part)[disable ? 'off' : 'on']('click', _onclick);
612        };
613      },
614
615      map: function (inst) {
616        var that = this,
617          part = null,
618          pointer, width, height, layers = {},
619          _mousedown, _mouseup, _mousemove, _keydown, _html;
620
621        _mousedown = function (event) {
622          if (!inst.opened) {
623            return;
624          }
625
626          var offset = layers.p.offset(),
627            x = event.pageX - offset.left,
628            y = event.pageY - offset.top;
629
630          if (x >= 0 && x < width && y >= 0 && y < height) {
631            event.stopImmediatePropagation();
632            event.preventDefault();
633            part.off('mousedown', _mousedown).focus();
634            $(document).on('mouseup', _mouseup);
635            $(document).on('mousemove', _mousemove);
636            _mousemove(event);
637          }
638        };
639
640        _mouseup = function (event) {
641          event.stopImmediatePropagation();
642          event.preventDefault();
643          $(document).off('mouseup', _mouseup);
644          $(document).off('mousemove', _mousemove);
645          part.on('mousedown', _mousedown);
646
647          inst._callback('stop');
648        };
649
650        _mousemove = function (event) {
651          event.stopImmediatePropagation();
652          event.preventDefault();
653
654          if (event.pageX === that.x && event.pageY === that.y) {
655            return;
656          }
657          that.x = event.pageX;
658          that.y = event.pageY;
659
660          var offset = layers.p.offset(),
661            x = event.pageX - offset.left,
662            y = event.pageY - offset.top;
663
664          x = Math.max(0, Math.min(x / width, 1));
665          y = Math.max(0, Math.min(y / height, 1));
666
667          // interpret values
668          switch (inst.mode) {
669          case 'h':
670            inst.color.setHSV(null, x, 1 - y);
671            break;
672
673          case 's':
674          case 'a':
675            inst.color.setHSV(x, null, 1 - y);
676            break;
677
678          case 'v':
679            inst.color.setHSV(x, 1 - y, null);
680            break;
681
682          case 'r':
683            inst.color.setRGB(null, 1 - y, x);
684            break;
685
686          case 'g':
687            inst.color.setRGB(1 - y, null, x);
688            break;
689
690          case 'b':
691            inst.color.setRGB(x, 1 - y, null);
692            break;
693          }
694
695          inst._change(false);
696        };
697
698        _keydown = function(event) {
699          var x_channel_map = {
700              'h': 's',
701              's': 'h',
702              'v': 'h',
703              'r': 'b',
704              'g': 'b',
705              'b': 'r',
706              'a': 'h'
707            },
708            x_change = {
709              37: -1,
710              39: 1,
711            },
712            y_channel_map = {
713              'h': 'v',
714              's': 'v',
715              'v': 's',
716              'r': 'g',
717              'g': 'r',
718              'b': 'g',
719              'a': 'v'
720            },
721            y_change = {
722              38: 1,
723              40: -1
724            },
725            set = {
726              35: 0,
727              36: 1
728            },
729            change, value;
730
731          if (typeof x_change[event.which] !== 'undefined') {
732            value = inst.color.getChannel(x_channel_map[inst.mode]) * width;
733            change = x_change[event.which];
734            if (event.shiftKey) {
735              change *= 10;
736            } else if (event.ctrlKey || event.metaKey) {
737              change *= width;
738            }
739            inst.color.setChannel(x_channel_map[inst.mode], (value + change) / width);
740            inst._change(false);
741          } else if (typeof y_change[event.which] !== 'undefined') {
742            value = inst.color.getChannel(y_channel_map[inst.mode]) * height;
743            change = y_change[event.which];
744            if (event.shiftKey) {
745              change *= 10;
746            } else if (event.ctrlKey || event.metaKey) {
747              change *= height;
748            }
749            inst.color.setChannel(y_channel_map[inst.mode], (value + change) / height);
750            inst._change(false);
751          } else if (typeof set[event.which] !== 'undefined') {
752            inst.color.setChannel(x_channel_map[inst.mode], 1 - set[event.which]);
753            inst.color.setChannel(y_channel_map[inst.mode], set[event.which]);
754            inst._change(false);
755          }
756        };
757
758        _html = function () {
759          var html = '<div class="ui-colorpicker-map ui-colorpicker-map-'+(inst.options.part.map.size || 256)+' ui-colorpicker-border" taonex="0">'
760            + '<span class="ui-colorpicker-map-layer-1">&nbsp;</span>'
761            + '<span class="ui-colorpicker-map-layer-2">&nbsp;</span>'
762            + (inst.options.alpha ? '<span class="ui-colorpicker-map-layer-alpha">&nbsp;</span>' : '')
763            + '<span class="ui-colorpicker-map-layer-pointer"><span class="ui-colorpicker-map-pointer"></span></span></div>';
764          return html;
765        };
766
767        this.init = function () {
768          part = $(_html()).appendTo($('.ui-colorpicker-map-container', inst.dialog));
769
770          part.on('mousedown', _mousedown);
771          part.on('keydown', _keydown);
772
773          // cache
774          layers[1] = $('.ui-colorpicker-map-layer-1', part);
775          layers[2] = $('.ui-colorpicker-map-layer-2', part);
776          layers.a = $('.ui-colorpicker-map-layer-alpha', part);
777          layers.p = $('.ui-colorpicker-map-layer-pointer', part);
778          width = layers.p.width();
779          height = layers.p.height();
780
781          pointer = $('.ui-colorpicker-map-pointer', part);
782        };
783
784        this.update = function () {
785          var step = ((inst.options.part.map.size || 256) * 65 / 64);
786
787          switch (inst.mode) {
788          case 'h':
789            layers[1].css({'background-position': '0 0', 'opacity': ''}).show();
790            layers[2].hide();
791            break;
792
793          case 's':
794          case 'a':
795            layers[1].css({'background-position': '0 ' + (-step) + 'px', 'opacity': ''}).show();
796            layers[2].css({'background-position': '0 ' + (-step * 2) + 'px', 'opacity': ''}).show();
797            break;
798
799          case 'v':
800            part.css('background-color', 'black');
801            layers[1].css({'background-position': '0 ' + (-step * 3) + 'px', 'opacity': ''}).show();
802            layers[2].hide();
803            break;
804
805          case 'r':
806            layers[1].css({'background-position': '0 ' + (-step * 4) + 'px', 'opacity': ''}).show();
807            layers[2].css({'background-position': '0 ' + (-step * 5) + 'px', 'opacity': ''}).show();
808            break;
809
810          case 'g':
811            layers[1].css({'background-position': '0 ' + (-step * 6) + 'px', 'opacity': ''}).show();
812            layers[2].css({'background-position': '0 ' + (-step * 7) + 'px', 'opacity': ''}).show();
813            break;
814
815          case 'b':
816            layers[1].css({'background-position': '0 ' + (-step * 8) + 'px', 'opacity': ''}).show();
817            layers[2].css({'background-position': '0 ' + (-step * 9) + 'px', 'opacity': ''}).show();
818            break;
819          }
820
821          that.repaint();
822        };
823
824        this.repaint = function () {
825          var x = 0,
826            y = 0;
827
828          switch (inst.mode) {
829          case 'h':
830            var hsv = inst.color.getHSV();
831            x = hsv.s * width;
832            y = (1 - hsv.v) * width;
833            part.css('background-color', inst.color.copy().setHSV(null, 1, 1).toCSS());
834            break;
835
836          case 's':
837          case 'a':
838            var hsv = inst.color.getHSV();
839            x = hsv.h * width;
840            y = (1 - hsv.v) * width;
841            layers[2].css('opacity', 1 - hsv.s);
842            break;
843
844          case 'v':
845            var hsv = inst.color.getHSV();
846            x = hsv.h * width;
847            y = (1 - hsv.s) * width;
848            layers[1].css('opacity', hsv.v);
849            break;
850
851          case 'r':
852            var rgb = inst.color.getRGB();
853            x = rgb.b * width;
854            y = (1 - rgb.g) * width;
855            layers[2].css('opacity', rgb.r);
856            break;
857
858          case 'g':
859            var rgb = inst.color.getRGB();
860            x = rgb.b * width;
861            y = (1 - rgb.r) * width;
862            layers[2].css('opacity', rgb.g);
863            break;
864
865          case 'b':
866            var rgb = inst.color.getRGB();
867            x = rgb.r * width;
868            y = (1 - rgb.g) * width;
869            layers[2].css('opacity', rgb.b);
870            break;
871          }
872
873          if (inst.options.alpha) {
874            layers.a.css('opacity', 1 - inst.color.getAlpha());
875          }
876
877          pointer.css({
878            'left': x - 7,
879            'top': y - 7
880          });
881        };
882
883        this.disable = function (disable) {
884          part[disable ? 'off' : 'on']('mousedown', _mousedown);
885          part[disable ? 'off' : 'on']('keydown', _keydown);
886        };
887      },
888
889      bar: function (inst) {
890        var that = this,
891          part = null,
892          pointer, width, height, layers = {},
893          _mousedown, _mouseup, _mousemove, _keydown, _html;
894
895        _mousedown = function (event) {
896          if (!inst.opened) {
897            return;
898          }
899
900          var offset = layers.p.offset(),
901            x = event.pageX - offset.left,
902            y = event.pageY - offset.top;
903
904          if (x >= 0 && x < width && y >= 0 && y < height) {
905            event.stopImmediatePropagation();
906            event.preventDefault();
907            part.off('mousedown', _mousedown).focus();
908            $(document).on('mouseup', _mouseup);
909            $(document).on('mousemove', _mousemove);
910            _mousemove(event);
911          }
912        };
913
914        _mouseup = function (event) {
915          event.stopImmediatePropagation();
916          event.preventDefault();
917          $(document).off('mouseup', _mouseup);
918          $(document).off('mousemove', _mousemove);
919          part.on('mousedown', _mousedown);
920
921          inst._callback('stop');
922        };
923
924        _mousemove = function (event) {
925          event.stopImmediatePropagation();
926          event.preventDefault();
927
928          if (event.pageY === that.y) {
929            return;
930          }
931          that.y = event.pageY;
932
933          var offset  = layers.p.offset(),
934            y = event.pageY - offset.top;
935
936          y = Math.max(0, Math.min(y / height, 1));
937
938          // interpret values
939          switch (inst.mode) {
940          case 'h':
941            inst.color.setHSV(1 - y, null, null);
942            break;
943
944          case 's':
945            inst.color.setHSV(null, 1 - y, null);
946            break;
947
948          case 'v':
949            inst.color.setHSV(null, null, 1 - y);
950            break;
951
952          case 'r':
953            inst.color.setRGB(1 - y, null, null);
954            break;
955
956          case 'g':
957            inst.color.setRGB(null, 1 - y, null);
958            break;
959
960          case 'b':
961            inst.color.setRGB(null, null, 1 - y);
962            break;
963
964          case 'a':
965            inst.color.setAlpha(1 - y);
966            break;
967          }
968
969          inst._change(false);
970        };
971
972        _keydown = function(event) {
973          var change = {
974              38: 1,
975              40: -1,
976              33: 10,
977              34: -10
978            },
979            set = {
980              35: 0,
981              36: 1
982            },
983            change, value;
984
985          if (typeof change[event.which] !== 'undefined') {
986            value = inst.color.getChannel(inst.mode) * height;
987            change = change[event.which];
988            if (event.shiftKey) {
989              change *= 10;
990            } else if (event.ctrlKey || event.metaKey) {
991              change *= height;
992            }
993            inst.color.setChannel(inst.mode, (value + change) / height);
994            inst._change(false);
995          } else if (typeof set[event.which] !== 'undefined') {
996            inst.color.setChannel(inst.mode, set[event.which]);
997            inst._change(false);
998          }
999        };
1000
1001        _html = function () {
1002          var html = '<div class="ui-colorpicker-bar ui-colorpicker-bar-'+(inst.options.part.bar.
1002size || 256)+'  ui-colorpicker-border" taonex="0">'
1003            + '<span class="ui-colorpicker-bar-layer-1">&nbsp;</span>'
1004            + '<span class="ui-colorpicker-bar-layer-2">&nbsp;</span>'
1005            + '<span class="ui-colorpicker-bar-layer-3">&nbsp;</span>'
1006            + '<span class="ui-colorpicker-bar-layer-4">&nbsp;</span>';
1007
1008          if (inst.options.alpha) {
1009            html += '<span class="ui-colorpicker-bar-layer-alpha">&nbsp;</span>'
1010              + '<span class="ui-colorpicker-bar-layer-alphabar">&nbsp;</span>';
1011          }
1012
1013          html += '<span class="ui-colorpicker-bar-layer-pointer"><span class="ui-colorpicker-bar-pointer"></span></span></div>';
1014
1015          return html;
1016        };
1017
1018        this.init = function () {
1019          part = $(_html()).appendTo($('.ui-colorpicker-bar-container', inst.dialog));
1020
1021          part.on('mousedown', _mousedown);
1022          part.on('keydown', _keydown);
1023
1024          // cache
1025          layers[1] = $('.ui-colorpicker-bar-layer-1', part);
1026          layers[2] = $('.ui-colorpicker-bar-layer-2', part);
1027          layers[3] = $('.ui-colorpicker-bar-layer-3', part);
1028          layers[4] = $('.ui-colorpicker-bar-layer-4', part);
1029          layers.a = $('.ui-colorpicker-bar-layer-alpha', part);
1030          layers.ab = $('.ui-colorpicker-bar-layer-alphabar', part);
1031          layers.p = $('.ui-colorpicker-bar-layer-pointer', part);
1032          width = layers.p.width();
1033          height = layers.p.height();
1034
1035          pointer = $('.ui-colorpicker-bar-pointer', part);
1036        };
1037
1038        this.update = function () {
1039          var step = ((inst.options.part.bar.size || 256) * 65 / 64);
1040
1041          switch (inst.mode) {
1042          case 'h':
1043          case 's':
1044          case 'v':
1045          case 'r':
1046          case 'g':
1047          case 'b':
1048            layers.a.show();
1049            layers.ab.hide();
1050            break;
1051
1052          case 'a':
1053            layers.a.hide();
1054            layers.ab.show();
1055            break;
1056          }
1057
1058          switch (inst.mode) {
1059          case 'h':
1060            layers[1].css({'background-position': '0 0', 'opacity': ''}).show();
1061            layers[2].hide();
1062            layers[3].hide();
1063            layers[4].hide();
1064            break;
1065
1066          case 's':
1067            layers[1].css({'background-position': '0 ' + (-step) + 'px', 'opacity': ''}).show();
1068            layers[2].css({'background-position': '0 ' + (-step * 2) + 'px', 'opacity': ''}).show();
1069            layers[3].hide();
1070            layers[4].hide();
1071            break;
1072
1073          case 'v':
1074            layers[1].css({'background-position': '0 ' + (-step * 2) + 'px', 'opacity': ''}).show();
1075            layers[2].hide();
1076            layers[3].hide();
1077            layers[4].hide();
1078            break;
1079
1080          case 'r':
1081            layers[1].css({'background-position': '0 ' + (-step * 6) + 'px', 'opacity': ''}).show();
1082            layers[2].css({'background-position': '0 ' + (-step * 5) + 'px', 'opacity': ''}).show();
1083            layers[3].css({'background-position': '0 ' + (-step * 3) + 'px', 'opacity': ''}).show();
1084            layers[4].css({'background-position': '0 ' + (-step * 4) + 'px', 'opacity': ''}).show();
1085            break;
1086
1087          case 'g':
1088            layers[1].css({'background-position': '0 ' + (-step * 10) + 'px', 'opacity': ''}).show();
1089            layers[2].css({'background-position': '0 ' + (-step * 9) + 'px', 'opacity': ''}).show();
1090            layers[3].css({'background-position': '0 ' + (-step * 7) + 'px', 'opacity': ''}).show();
1091            layers[4].css({'background-position': '0 ' + (-step * 8) + 'px', 'opacity': ''}).show();
1092            break;
1093
1094          case 'b':
1095            layers[1].css({'background-position': '0 ' + (-step * 14) + 'px', 'opacity': ''}).show();
1096            layers[2].css({'background-position': '0 ' + (-step * 13) + 'px', 'opacity': ''}).show();
1097            layers[3].css({'background-position': '0 ' + (-step * 11) + 'px', 'opacity': ''}).show();
1098            layers[4].css({'background-position': '0 ' + (-step * 12) + 'px', 'opacity': ''}).show();
1099            break;
1100
1101          case 'a':
1102            layers[1].hide();
1103            layers[2].hide();
1104            layers[3].hide();
1105            layers[4].hide();
1106            break;
1107          }
1108
1109          that.repaint();
1110        };
1111
1112        this.repaint = function () {
1113          var y = 0;
1114
1115          switch (inst.mode) {
1116          case 'h':
1117            y = (1 - inst.color.getHSV().h) * height;
1118            break;
1119
1120          case 's':
1121            var hsv = inst.color.getHSV();
1122            y = (1 - hsv.s) * height;
1123            layers[2].css('opacity', 1 - hsv.v);
1124            part.css('background-color', inst.color.copy().setHSV(null, 1, null).toCSS());
1125            break;
1126
1127          case 'v':
1128            y = (1 - inst.color.getHSV().v) * height;
1129            part.css('background-color', inst.color.copy().setHSV(null, null, 1).toCSS());
1130            break;
1131
1132          case 'r':
1133            var rgb = inst.color.getRGB();
1134            y = (1 - rgb.r) * height;
1135            layers[2].css('opacity', Math.max(0, (rgb.b - rgb.g)));
1136            layers[3].css('opacity', Math.max(0, (rgb.g - rgb.b)));
1137            layers[4].css('opacity', Math.min(rgb.b, rgb.g));
1138            break;
1139
1140          case 'g':
1141            var rgb = inst.color.getRGB();
1142            y = (1 - rgb.g) * height;
1143            layers[2].css('opacity', Math.max(0, (rgb.b - rgb.r)));
1144            layers[3].css('opacity', Math.max(0, (rgb.r - rgb.b)));
1145            layers[4].css('opacity', Math.min(rgb.r, rgb.b));
1146            break;
1147
1148          case 'b':
1149            var rgb = inst.color.getRGB();
1150            y = (1 - rgb.b) * height;
1151            layers[2].css('opacity', Math.max(0, (rgb.r - rgb.g)));
1152            layers[3].css('opacity', Math.max(0, (rgb.g - rgb.r)));
1153            layers[4].css('opacity', Math.min(rgb.r, rgb.g));
1154            break;
1155
1156          case 'a':
1157            y = (1 - inst.color.getAlpha()) * height;
1158            part.css('background-color', inst.color.copy().toCSS());
1159            break;
1160          }
1161
1162          if (inst.mode !== 'a') {
1163            layers.a.css('opacity', 1 - inst.color.getAlpha());
1164          }
1165
1166          pointer.css('top', y - 3);
1167        };
1168
1169        this.disable = function (disable) {
1170          part[disable ? 'off' : 'on']('mousedown', _mousedown);
1171          part[disable ? 'off' : 'on']('keydown', _keydown);
1172        };
1173      },
1174
1175      preview: function (inst) {
1176        var that = this,
1177          part = null,
1178          both,
1179          initial, initial_alpha,
1180          current, current_alpha,
1181          _html,
1182          onclick = function () {
1183            inst.color = inst.currentColor.copy();
1184            inst._change();
1185          };
1186
1187        _html = function () {
1188          return '<div class="ui-colorpicker-preview ui-colorpicker-border">'
1189            + '<div class="ui-colorpicker-preview-initial"><div class="ui-colorpicker-preview-initial-alpha"></div></div>'
1190            + '<div class="ui-colorpicker-preview-current"><div class="ui-colorpicker-preview-current-alpha"></div></div>'
1191            + '</div>';
1192        };
1193
1194        this.init = function () {
1195          part = $(_html()).appendTo($('.ui-colorpicker-preview-container', inst.dialog));
1196
1197          $('.ui-colorpicker-preview-initial', part).on('click', onclick);
1198
1199          // cache
1200          initial = $('.ui-colorpicker-preview-initial', part);
1201          initial_alpha = $('.ui-colorpicker-preview-initial-alpha', part);
1202          current  = $('.ui-colorpicker-preview-current', part);
1203          current_alpha = $('.ui-colorpicker-preview-current-alpha', part);
1204          both = $('.ui-colorpicker-preview-initial-alpha, .ui-colorpicker-preview-current-alpha', part);
1205        };
1206
1207        this.update = function () {
1208          both[inst.options.alpha ? 'show' : 'hide']();
1209
1210          this.repaint();
1211        };
1212
1213        this.repaint = function () {
1214          initial.css('background-color', inst.currentColor.set ? inst.currentColor.toCSS() : '').attr('title', inst.currentColor.set ? inst.currentColor.toCSS() : '');
1215          initial_alpha.css('opacity', 1 - inst.currentColor.getAlpha());
1216          current.css('background-color', inst.color.set ? inst.color.toCSS() : '').attr('title', inst.color.set ? inst.color.toCSS() : '');
1217          current_alpha.css('opacity', 1 - inst.color.getAlpha());
1218        };
1219
1220        this.disable = function (disable) {
1221          $('.ui-colorpicker-preview-initial', part)[disable ? 'off' : 'on']('click', onclick);
1222        };
1223      },
1224
1225      hsv: function (inst) {
1226        var that = this,
1227          part = null,
1228          inputs = {},
1229          _html;
1230
1231        _html = function () {
1232          var html = '';
1233
1234          if (inst.options.hsv) {
1235            html += '<div class="ui-colorpicker-hsv-h"><input class="ui-colorpicker-mode" type="radio" value="h"/><label>'
1236              + inst._getRegional('hsvH')
1237              + '</label><input class="ui-colorpicker-number" type="number" min="0" max="360" size="10"/><span class="ui-colorpicker-unit">&deg;</span></div>'
1238              + '<div class="ui-colorpicker-hsv-s"><input class="ui-colorpicker-mode" type="radio" value="s"/><label>'
1239              + inst._getRegional('hsvS')
1240              + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100" size="10"/><span class="ui-colorpicker-unit">%</span></div>'
1241              + '<div class="ui-colorpicker-hsv-v"><input class="ui-colorpicker-mode" type="radio" value="v"/><label>'
1242              + inst._getRegional('hsvV')
1243              + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100" size="10"/><span class="ui-colorpicker-unit">%</span></div>';
1244          }
1245
1246          return '<div class="ui-colorpicker-hsv">' + html + '</div>';
1247        };
1248
1249        this.init = function () {
1250          part = $(_html()).appendTo($('.ui-colorpicker-hsv-container', inst.dialog));
1251
1252          $('.ui-colorpicker-mode', part).click(function () {
1253            inst.mode = $(this).val();
1254            inst._updateAllParts();
1255          });
1256
1257          inputs.h = $('.ui-colorpicker-hsv-h .ui-colorpicker-number', part);
1258          inputs.s = $('.ui-colorpicker-hsv-s .ui-colorpicker-number', part);
1259          inputs.v = $('.ui-colorpicker-hsv-v .ui-colorpicker-number', part);
1260
1261          $('.ui-colorpicker-number', part).on('input change keyup', function () {
1262            inst.color.setHSV(
1263              inputs.h.val() / 360,
1264              inputs.s.val() / 100,
1265              inputs.v.val() / 100
1266            );
1267            inst._change();
1268          });
1269        };
1270
1271        this.repaint = function () {
1272          var hsv = inst.color.getHSV();
1273          inputs.h.val(Math.round(hsv.h * 360));
1274          inputs.s.val(Math.round(hsv.s * 100));
1275          inputs.v.val(Math.round(hsv.v * 100));
1276        };
1277
1278        this.update = function () {
1279          $('.ui-colorpicker-mode', part).each(function () {
1280            var $this = $(this);
1281            $this.prop('checked', $this.val() === inst.mode);
1282          });
1283          this.repaint();
1284        };
1285
1286        this.disable = function (disable) {
1287          $(':input', part).prop('disabled', disable);
1288        };
1289      },
1290
1291      rgb: function (inst) {
1292        var that = this,
1293          part = null,
1294          inputs = {},
1295          _html;
1296
1297        _html = function () {
1298          var html = '';
1299
1300          if (inst.options.rgb) {
1301            html += '<div class="ui-colorpicker-rgb-r"><input class="ui-colorpicker-mode" type="radio" value="r"/><label>' + inst._getRegional('rgbR') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="255"/></div>'
1302              + '<div class="ui-colorpicker-rgb-g"><input class="ui-colorpicker-mode" type="radio" value="g"/><label>' + inst._getRegional('rgbG') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="255"/></div>'
1303              + '<div class="ui-colorpicker-rgb-b"><input class="ui-colorpicker-mode" type="radio" value="b"/><label>' + inst._getRegional('rgbB') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="255"/></div>';
1304          }
1305
1306          return '<div class="ui-colorpicker-rgb">
1306' + html + '</div>';
1307        };
1308
1309        this.init = function () {
1310          part = $(_html()).appendTo($('.ui-colorpicker-rgb-container', inst.dialog));
1311
1312          $('.ui-colorpicker-mode', part).click(function () {
1313            inst.mode = $(this).val();
1314            inst._updateAllParts();
1315          });
1316
1317          inputs.r = $('.ui-colorpicker-rgb-r .ui-colorpicker-number', part);
1318          inputs.g = $('.ui-colorpicker-rgb-g .ui-colorpicker-number', part);
1319          inputs.b = $('.ui-colorpicker-rgb-b .ui-colorpicker-number', part);
1320
1321          $('.ui-colorpicker-number', part).on('input change keyup', function () {
1322            var r = $('.ui-colorpicker-rgb-r .ui-colorpicker-number', part).val();
1323            inst.color.setRGB(
1324              inputs.r.val() / 255,
1325              inputs.g.val() / 255,
1326              inputs.b.val() / 255
1327            );
1328
1329            inst._change();
1330          });
1331        };
1332
1333        this.repaint = function () {
1334          var rgb = inst.color.getRGB();
1335          inputs.r.val(Math.round(rgb.r * 255));
1336          inputs.g.val(Math.round(rgb.g * 255));
1337          inputs.b.val(Math.round(rgb.b * 255));
1338        };
1339
1340        this.update = function () {
1341          $('.ui-colorpicker-mode', part).each(function () {
1342            var $this = $(this);
1343            $this.prop('checked', $this.val() === inst.mode);
1344          });
1345          this.repaint();
1346        };
1347
1348        this.disable = function (disable) {
1349          $(':input', part).prop('disabled', disable);
1350        };
1351      },
1352
1353      lab: function (inst) {
1354        var that = this,
1355          part = null,
1356          inputs = {},
1357          html = function () {
1358            var html = '';
1359
1360            if (inst.options.hsv) {
1361              html += '<div class="ui-colorpicker-lab-l"><label>' + inst._getRegional('labL') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/></div>'
1362                + '<div class="ui-colorpicker-lab-a"><label>' + inst._getRegional('labA') + '</label><input class="ui-colorpicker-number" type="number" min="-128" max="127"/></div>'
1363                + '<div class="ui-colorpicker-lab-b"><label>' + inst._getRegional('labB') + '</label><input class="ui-colorpicker-number" type="number" min="-128" max="127"/></div>';
1364            }
1365
1366            return '<div class="ui-colorpicker-lab">' + html + '</div>';
1367          };
1368
1369        this.init = function () {
1370          var data = 0;
1371
1372          part = $(html()).appendTo($('.ui-colorpicker-lab-container', inst.dialog));
1373
1374          inputs.l = $('.ui-colorpicker-lab-l .ui-colorpicker-number', part);
1375          inputs.a = $('.ui-colorpicker-lab-a .ui-colorpicker-number', part);
1376          inputs.b = $('.ui-colorpicker-lab-b .ui-colorpicker-number', part);
1377
1378          $('.ui-colorpicker-number', part).on('input change keyup', function (event) {
1379            inst.color.setLAB(
1380              parseInt(inputs.l.val(), 10) / 100,
1381              (parseInt(inputs.a.val(), 10) + 128) / 255,
1382              (parseInt(inputs.b.val(), 10) + 128) / 255
1383            );
1384            inst._change();
1385          });
1386        };
1387
1388        this.repaint = function () {
1389          var lab = inst.color.getLAB();
1390          inputs.l.val(Math.round(lab.l * 100));
1391          inputs.a.val(Math.round(lab.a * 255) - 128);
1392          inputs.b.val(Math.round(lab.b * 255) - 128);
1393        };
1394
1395        this.update = this.repaint;
1396
1397        this.disable = function (disable) {
1398          $(':input', part).prop('disabled', disable);
1399        };
1400      },
1401
1402      cmyk: function (inst) {
1403        var that = this,
1404          part = null,
1405          inputs = {},
1406          html = function () {
1407            var html = '';
1408
1409            if (inst.options.hsv) {
1410              html += '<div class="ui-colorpicker-cmyk-c"><label>' + inst._getRegional('cmykC') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/><span class="ui-colorpicker-unit">%</span></div>'
1411                + '<div class="ui-colorpicker-cmyk-m"><label>' + inst._getRegional('cmykM') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/>
1411<span class="ui-colorpicker-unit">%</span></div>'
1412                + '<div class="ui-colorpicker-cmyk-y"><label>' + inst._getRegional('cmykY') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/><span class="ui-colorpicker-unit">%</span></div>'
1413                + '<div class="ui-colorpicker-cmyk-k"><label>' + inst._getRegional('cmykK') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/><span class="ui-colorpicker-unit">%</span></div>';
1414            }
1415
1416            return '<div class="ui-colorpicker-cmyk">' + html + '</div>';
1417          };
1418
1419        this.init = function () {
1420          part = $(html()).appendTo($('.ui-colorpicker-cmyk-container', inst.dialog));
1421
1422          inputs.c = $('.ui-colorpicker-cmyk-c .ui-colorpicker-number', part);
1423          inputs.m = $('.ui-colorpicker-cmyk-m .ui-colorpicker-number', part);
1424          inputs.y = $('.ui-colorpicker-cmyk-y .ui-colorpicker-number', part);
1425          inputs.k = $('.ui-colorpicker-cmyk-k .ui-colorpicker-number', part);
1426
1427          $('.ui-colorpicker-number', part).on('input change keyup', function (event) {
1428            inst.color.setCMYK(
1429              parseInt(inputs.c.val(), 10) / 100,
1430              parseInt(inputs.m.val(), 10) / 100,
1431              parseInt(inputs.y.val(), 10) / 100,
1432              parseInt(inputs.k.val(), 10) / 100
1433            );
1434            inst._change();
1435          });
1436        };
1437
1438        this.repaint = function () {
1439          var cmyk = inst.color.getCMYK();
1440          inputs.c.val(Math.round(cmyk.c * 100));
1441          inputs.m.val(Math.round(cmyk.m * 100));
1442          inputs.y.val(Math.round(cmyk.y * 100));
1443          inputs.k.val(Math.round(cmyk.k * 100));
1444        };
1445
1446        this.update = this.repaint;
1447
1448        this.disable = function (disable) {
1449          $(':input', part).prop('disabled', disable);
1450        };
1451      },
1452
1453      alpha: function (inst) {
1454        var that = this,
1455          part = null,
1456          input,
1457          html = function () {
1458            var html = '';
1459
1460            if (inst.options.alpha) {
1461              html += '<div class="ui-colorpicker-a"><input class="ui-colorpicker-mode" name="mode" type="radio" value="a"/><label>' + inst._getRegional('alphaA') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/><span class="ui-colorpicker-unit">%</span></div>';
1462            }
1463
1464            return '<div class="ui-colorpicker-alpha">' + html + '</div>';
1465          };
1466
1467        this.init = function () {
1468          part = $(html()).appendTo($('.ui-colorpicker-alpha-container', inst.dialog));
1469
1470          $('.ui-colorpicker-mode', part).click(function () {
1471            inst.mode = $(this).val();
1472            inst._updateAllParts();
1473          });
1474
1475          input = $('.ui-colorpicker-a .ui-colorpicker-number', part);
1476
1477          $('.ui-colorpicker-number', part).on('input change keyup', function () {
1478            inst.color.setAlpha(input.val() / 100);
1479            inst._change();
1480          });
1481        };
1482
1483        this.update = function () {
1484          $('.ui-colorpicker-mode', part).each(function () {
1485            $(this).prop('checked', $(this).val() === inst.mode);
1486          });
1487          this.repaint();
1488        };
1489
1490        this.repaint = function () {
1491          input.val(Math.round(inst.color.getAlpha() * 100));
1492        };
1493
1494        this.disable = function (disable) {
1495          $(':input', part).prop('disabled', disable);
1496        };
1497      },
1498
1499      hex: function (inst) {
1500        var that = this,
1501          part = null,
1502          inputs = {},
1503          parseHex = function(color) {
1504            var c,
1505              m;
1506
1507            // {#}rgb
1508            m = /^#?([a-fA-F0-9]{1,3})$/.exec(color);
1509            if (m) {
1510              c = parseInt(m[1], 16);
1511              return new $.colorpicker.Color(
1512                ((c >> 8) & 0xF) / 15,
1513                ((c >> 4) & 0xF) / 15,
1514                (c & 0xF) / 15
1515              );
1516            }
1517
1518            // {#}rrggbb
1519            m = /^#?([a-fA-F0-9]{1,6})$/.exec(color);
1520            if (m) {
1521              c = parseInt(m[1], 16);
1522              return new $.colorpicker.Color(
1523                ((c >> 16) & 0xFF) / 255,
1524                ((c >>  8) & 0xFF) / 255,
1525                (c & 0xFF) / 255
1526              );
1527            }
1528
1529            return new $.colorpicker.Color();
1530          },
1531          html = function () {
1532            var html = '';
1533
1534            if (inst.options.alpha) {
1535              html += '<input class="ui-colorpicker-hex-alpha" type="text" maxlength="2" size="2"/>';
1536            }
1537
1538            html += '<input class="ui-colorpicker-hex-input" type="text" maxlength="6" size="6"/>';
1539
1540            return '<div class="ui-colorpicker-hex"><label>#</label>' + html + '</div>';
1541          };
1542
1543        this.init = function () {
1544          part = $(html()).appendTo($('.ui-colorpicker-hex-container', inst.dialog));
1545
1546          inputs.color = $('.ui-colorpicker-hex-input', part);
1547          inputs.alpha = $('.ui-colorpicker-hex-alpha', part);
1548
1549          inputs.color.on('keydown keyup', function(e) {
1550            return e.ctrlKey || e.metaKey || _keycode.isHex(e.which) || !_keycode.isPrint(e.which);
1551          });
1552
1553          // repeat here makes the invalid input disappear faster
1554          inputs.color.on('change', function () {
1555            if (/[^a-fA-F0-9]/.test(inputs.color.val())) {
1556              inputs.color.val(inputs.color.val().replace(/[^a-fA-F0-9]/g, ''));
1557            }
1558          });
1559
1560          inputs.color.on('change keyup', function () {
1561            // repeat here makes sure that the invalid input doesn't get parsed
1562            inst.color = parseHex(inputs.color.val()).setAlpha(inst.color.getAlpha());
1563            inst._change();
1564          });
1565
1566          inputs.alpha.on('keydown keyup', function(e) {
1567            return e.ctrlKey || e.metaKey || _keycode.isHex(e.which) || !_keycode.isPrint(e.which);
1568          });
1569
1570          inputs.alpha.on('change', function () {
1571            if (/[^a-fA-F0-9]/.test(inputs.alpha)) {
1572              inputs.alpha.val(inputs.alpha.val().replace(/[^a-fA-F0-9]/g, ''));
1573            }
1574          });
1575
1576          inputs.alpha.on('change keyup', function () {
1577            inst.color.setAlpha(parseInt(inputs.alpha.val(), 16) / 25
15775);
1578            inst._change();
1579          });
1580        };
1581
1582        this.repaint = function () {
1583          if (!inputs.color.is(':focus')) {
1584            inputs.color.val(inst.color.toHex(true));
1585          }
1586
1587          if (!inputs.alpha.is(':focus')) {
1588            inputs.alpha.val(_intToHex(inst.color.getAlpha() * 255));
1589          }
1590        };
1591
1592        this.update = this.repaint;
1593
1594        this.disable = function (disable) {
1595          $(':input', part).prop('disabled', disable);
1596        };
1597      },
1598
1599      swatches: function (inst) {
1600        var that = this,
1601          part = null,
1602          html = function () {
1603            var html = '';
1604
1605            inst._eachSwatch(function (name, color) {
1606              var c = new $.colorpicker.Color(color.r, color.g, color.b),
1607                css = c.toCSS();
1608              html += '<div class="ui-colorpicker-swatch" style="background-color:' + css + '" title="' + name + '"></div>';
1609            });
1610
1611            return '<div class="ui-colorpicker-swatches ui-colorpicker-border" style="width:' + inst.options.swatchesWidth + 'px">' + html + '</div>';
1612          },
1613          onclick = function () {
1614            inst.color	= inst._parseColor($(this).css('background-color')) || new $.colorpicker.Color();
1615            inst._change();
1616          };
1617
1618        this.init = function () {
1619          part = $(html());
1620          $('.ui-colorpicker-swatches-container', inst.dialog).html(part);
1621          $('.ui-colorpicker-swatch', part).on('click', onclick);
1622        };
1623
1624        this.disable = function (disable) {
1625          $('.ui-colorpicker-swatch', part)[disable ? 'off' : 'on']('click', onclick);
1626        };
1627      },
1628
1629      footer: function (inst) {
1630        var that = this,
1631          part = null,
1632          id_transparent = 'ui-colorpicker-special-transparent-' + inst.colorpicker_index,
1633          id_none = 'ui-colorpicker-special-none-' + inst.colorpicker_index,
1634          html = function () {
1635            var html = '';
1636
1637            if (inst.options.alpha || (!inst.inline && inst.options.showNoneButton)) {
1638              html += '<div class="ui-colorpicker-buttonset">';
1639
1640              if (inst.options.alpha) {
1641                html += '<input type="radio" name="ui-colorpicker-special" id="'+id_transparent+'" class="ui-colorpicker-special-transparent"/><label for="'+id_transparent+'">' + inst._getRegional('transparent') + '</label>';
1642              }
1643              if (!inst.inline && inst.options.showNoneButton) {
1644                html += '<input type="radio" name="ui-colorpicker-special" id="'+id_none+'" class="ui-colorpicker-special-none"><label for="'+id_none+'">' + inst._getRegional('none') + '</label>';
1645              }
1646              html += '</div>';
1647            }
1648
1649            if (!inst.inline) {
1650              html += '<div class="ui-dialog-buttonset">';
1651              if (inst.options.showCancelButton) {
1652                html += '<button class="ui-colorpicker-cancel">' + inst._getRegional('cancel') + '</button>';
1653              }
1654              html += '<button class="ui-colorpicker-ok">' + inst._getRegional('ok') + '</button>';
1655              html += '</div>';
1656            }
1657
1658            return '<div class="ui-dialog-buttonpane ui-widget-content">' + html + '</div>';
1659          };
1660
1661        this.init = function () {
1662          part = $(html()).appendTo(inst.dialog);
1663
1664          $('.ui-colorpicker-ok', part).button().click(function () {
1665            inst.close();
1666          });
1667
1668          $('.ui-colorpicker-cancel', part).button().click(function () {
1669            inst.close(true);   //cancel
1670          });
1671
1672          $('.ui-colorpicker-buttonset', part)[$.fn.controlgroup ? 'controlgroup' : 'buttonset']();
1673
1674          $('.ui-colorpicker-special-color', part).click(function () {
1675            inst._change();
1676          });
1677
1678          $('#'+id_none, part).click(function () {
1679            inst.color.set = false;
1680            inst._change();
1681          });
1682
1683          $('#'+id_transparent, part).click(function () {
1684            inst.color.setAlpha(0);
1685            inst._change();
1686          });
1687        };
1688
1689        this.repaint = function () {
1690          $('.ui-colorpicker-special-none', part).prop('checked', !inst.color.set).button('refresh');
1691          $('.ui-colorpicker-special-transparent', part).prop('checked', inst.color.set && inst.color.getAlpha() === 0).button('refresh');
1692          $('.ui-colorpicker-ok', part).button(inst.changed ? 'enable' : 'disable');
1693        };
1694
1695        this.update = function () {};
1696
1697        this.disable = function (disabled) {
1698          $(':input, :button', part).button(disabled ? 'disable' : 'enable');
1699          if (!disabled) {
1700            $('.ui-colorpicker-ok', part).button(inst.changed ? 'enable' : 'disable');
1701          }
1702        };
1703      }
1704    };
1705
1706    this.Color = function () {
1707      var spaces = {	rgb:	{r: 0, g: 0, b: 0},
1708          hsv:	{h: 0, s: 0, v: 0},
1709          hsl:	{h: 0, s: 0, l: 0},
1710          lab:	{l: 0, a: 0, b: 0},
1711          cmyk:	{c: 0, m: 0, y: 0, k: 1}
1712        },
1713        a = 1,
1714        illuminant = [0.9504285, 1, 1.0889],	// CIE-L*ab D65/2' 1931
1715        args = arguments,
1716        _clip = function(v) {
1717          if (isNaN(v) || v === null) {
1718            return 0;
1719          }
1720          if (typeof v == 'string') {
1721            v = parseInt(v, 10);
1722          }
1723          return Math.max(0, Math.min(v, 1));
1724        },
1725        _hexify = function (number) {
1726          var number = Math.round(number),
1727            digits = '0123456789abcdef',
1728            lsd = number % 16,
1729            msd = (number - lsd) / 16,
1730            hexified = digits.charAt(msd) + digits.charAt(lsd);
1731          return hexified;
1732        },
1733        _rgb_to_xyz = function(rgb) {
1734          var r = (rgb.r > 0.04045) ? Math.pow((rgb.r + 0.055) / 1.055, 2.4) : rgb.r / 12.92,
1735            g = (rgb.g > 0.04045) ? Math.pow((rgb.g + 0.055) / 1.055, 2.4) : rgb.g / 12.92,
1736            b = (rgb.b > 0.04045) ? Math.pow((rgb.b + 0.055) / 1.055, 2.4) : rgb.b / 12.92;
1737
1738          return {
1739            x: r * 0.4124 + g * 0.3576 + b * 0.1805,
1740            y: r * 0.2126 + g * 0.7152 + b * 0.0722,
1741            z: r * 0.0193 + g * 0.1192 + b * 0.9505
1742          };
1743        },
1744        _xyz_to_rgb = function(xyz) {
1745          var rgb = {
1746            r: xyz.x *  3.2406 + xyz.y * -1.5372 + xyz.z * -0.4986,
1747            g: xyz.x * -0.9689 + xyz.y *  1.8758 + xyz.z *  0.0415,
1748            b: xyz.x *  0.0557 + xyz.y * -0.2040 + xyz.z *  1.0570
1749          };
1750
1751          rgb.r = (rgb.r > 0.0031308) ? 1.055 * Math.pow(rgb.r, (1 / 2.4)) - 0.055 : 12.92 * rgb.r;
1752          rgb.g = (rgb.g > 0.0031308) ? 1.055 * Math.pow(rgb.g, (1 / 2.4)) - 0.055 : 12.92 * rgb.g;
1753          rgb.b = (rgb.b > 0.0031308) ? 1.055 * Math.pow(rgb.b, (1 / 2.4)) - 0.055 : 12.92 * rgb.b;
1754
1755          return rgb;
1756        },
1757        _rgb_to_hsv = function(rgb) {
1758          var minVal = Math.min(rgb.r, rgb.g, rgb.b),
1759            maxVal = Math.max(rgb.r, rgb.g, rgb.b),
1760            delta = maxVal - minVal,
1761            del_R, del_G, del_B,
1762            hsv = {
1763              h: 0,
1764              s: 0,
1765              v: maxVal
1766            };
1767
1768          if (delta === 0) {
1769            hsv.h = 0;
1770            hsv.s = 0;
1771          } else {
1772            hsv.s = delta / maxVal;
1773
1774            del_R = (((maxVal - rgb.r) / 6) + (delta / 2)) / delta;
1775            del_G = (((maxVal - rgb.g) / 6) + (delta / 2)) / delta;
1776            del_B = (((maxVal - rgb.b) / 6) + (delta / 2)) / delta;
1777
1778            if (rgb.r === maxVal) {
1779              hsv.h = del_B - del_G;
1780            } else if (rgb.g === maxVal) {
1781              hsv.h = (1 / 3) + del_R - del_B;
1782            } else if (rgb.b === maxVal) {
1783              hsv.h = (2 / 3) + del_G - del_R;
1784            }
1785
1786            if (hsv.h < 0) {
1787              hsv.h += 1;
1788            } else if (hsv.h > 1) {
1789              hsv.h -= 1;
1790            }
1791          }
1792
1793          return hsv;
1794        },
1795        _hsv_to_rgb = function(hsv) {
1796          var rgb = {
1797              r: 0,
1798              g: 0,
1799              b: 0
1800            },
1801            var_h,
1802            var_i,
1803            var_1,
1804            var_2,
1805            var_3;
1806
1807          if (hsv.s === 0) {
1808            rgb.r = rgb.g = rgb.b = hsv.v;
1809          } else {
1810            var_h = hsv.h === 1 ? 0 : hsv.h * 6;
1811            var_i = Math.floor(var_h);
1812            var_1 = hsv.v * (1 - hsv.s);
1813            var_2 = hsv.v * (1 - hsv.s * (var_h - var_i));
1814            var_3 = hsv.v * (1 - hsv.s * (1 - (var_h - var_i)));
1815
1816            if (var_i === 0) {
1817              rgb.r = hsv.v;
1818              rgb.g = var_3;
1819              rgb.b = var_1;
1820            } else if (var_i === 1) {
1821              rgb.r = var_2;
1822              rgb.g = hsv.v;
1823              rgb.b = var_1;
1824            } else if (var_i === 2) {
1825              rgb.r = var_1;
1826              rgb.g = hsv.v;
1827              rgb.b = var_3;
1828            } else if (var_i === 3) {
1829              rgb.r = var_1;
1830              rgb.g = var_2;
1831              rgb.b = hsv.v;
1832            } else if (var_i === 4) {
1833              rgb.r = var_3;
1834              rgb.g = var_1;
1835              rgb.b = hsv.v;
1836            } else {
1837              rgb.r = hsv.v;
1838              rgb.g = var_1;
1839              rgb.b = var_2;
1840            }
1841          }
1842
1843          return rgb;
1844        },
1845        _rgb_to_hsl = function(rgb) {
1846          var minVal = Math.min(rgb.r, rgb.g, rgb.b),
1847            maxVal = Math.max(rgb.r, rgb.g, rgb.b),
1848            delta = maxVal - minVal,
1849            del_R, del_G, del_B,
1850            hsl = {
1851              h: 0,
1852              s: 0,
1853              l: (maxVal + minVal) / 2
1854            };
1855
1856          if (delta === 0) {
1857            hsl.h = 0;
1858            hsl.s = 0;
1859          } else {
1860            hsl.s = hsl.l < 0.5 ? delta / (maxVal + minVal) : delta / (2 - maxVal - minVal);
1861
1862            del_R = (((maxVal - rgb.r) / 6) + (delta / 2)) / delta;
1863            del_G = (((maxVal - rgb.g) / 6) + (delta / 2)) / delta;
1864            del_B = (((maxVal - rgb.b) / 6) + (delta / 2)) / delta;
1865
1866            if (rgb.r === maxVal) {
1867              hsl.h = del_B - del_G;
1868            } else if (rgb.g === maxVal) {
1869              hsl.h = (1 / 3) + del_R - del_B;
1870            } else if (rgb.b === maxVal) {
1871              hsl.h = (2 / 3) + del_G - del_R;
1872            }
1873
1874            if (hsl.h < 0) {
1875              hsl.h += 1;
1876            } else if (hsl.h > 1) {
1877              hsl.h -= 1;
1878            }
1879          }
1880
1881          return hsl;
1882        },
1883        _hsl_to_rgb = function(hsl) {
1884          var var_1,
1885            var_2,
1886            hue_to_rgb	= function(v1, v2, vH) {
1887              if (vH < 0) {
1888                vH += 1;
1889              }
1890              if (vH > 1) {
1891                vH -= 1;
1892              }
1893              if ((6 * vH) < 1) {
1894                return v1 + (v2 - v1) * 6 * vH;
1895              }
1896              if ((2 * vH) < 1) {
1897                return v2;
1898              }
1899              if ((3 * vH) < 2) {
1900                return v1 + (v2 - v1) * ((2 / 3) - vH) * 6;
1901              }
1902              return v1;
1903            };
1904
1905          if (hsl.s === 0) {
1906            return {
1907              r: hsl.l,
1908              g: hsl.l,
1909              b: hsl.l
1910            };
1911          }
1912
1913          var_2 = (hsl.l < 0.5) ? hsl.l * (1 + hsl.s) : (hsl.l + hsl.s) - (hsl.s * hsl.l);
1914          var_1 = 2 * hsl.l - var_2;
1915
1916          return {
1917            r: hue_to_rgb(var_1, var_2, hsl.h + (1 / 3)),
1918            g: hue_to_rgb(var_1, var_2, hsl.h),
1919            b: hue_to_rgb(var_1, var_2, hsl.h - (1 / 3))
1920          };
1921        },
1922        _xyz_to_lab = function(xyz) {
1923          var x = xyz.x / illuminant[0],
1924            y = xyz.y / illuminant[1],
1925            z = xyz.z / illuminant[2];
1926
1927          x = (x > 0.008856) ? Math.pow(x, (1/3)) : (7.787 * x) + (16/116);
1928          y = (y > 0.008856) ? Math.pow(y, (1/3)) : (7.787 * y) + (16/116);
1929          z = (z > 0.008856) ? Math.pow(z, (1/3)) : (7.787 * z) + (16/116);
1930
1931          return {
1932            l: ((116 * y) - 16) / 100,	// [0,100]
1933            a: ((500 * (x - y)) + 128) / 255,	// [-128,127]
1934            b: ((200 * (y - z))	+ 128) / 255	// [-128,127]
1935          };
1936        },
1937        _lab_to_xyz = function(lab) {
1938          var lab2 = {
1939              l: lab.l * 100,
1940              a: (lab.a * 255) - 128,
1941              b: (lab.b * 255) - 128
1942            },
1943            xyz = {
1944              x: 0,
1945              y: (lab2.l + 16) / 116,
1946              z: 0
1947            };
1948
1949          xyz.x = lab2.a / 500 + xyz.y;
1950          xyz.z = xyz.y - lab2.b / 200;
1951
1952          xyz.x = (Math.pow(xyz.x, 3) > 0.008856) ? Math.pow(xyz.x, 3) : (xyz.x - 16 / 116) / 7.787;
1953          xyz.y = (Math.pow(xyz.y, 3) > 0.008856) ? Math.pow(xyz.y, 3) : (xyz.y - 16 / 116) / 7.787;
1954          xyz.z = (Math.pow(xyz.z, 3) > 0.008856) ? Math.pow(xyz.z, 3) : (xyz.z - 16 / 116) / 7.787;
1955
1956          xyz.x *= illuminant[0];
1957          xyz.y *= illuminant[1];
1958          xyz.z *= illuminant[2];
1959
1960          return xyz;
1961        },
1962        _rgb_to_cmy = function(rgb) {
1963          return {
1964            c: 1 - (rgb.r),
1965            m: 1 - (rgb.g),
1966            y: 1 - (rgb.b)
1967          };
1968        },
1969        _cmy_to_rgb = function(cmy) {
1970          return {
1971            r: 1 - (cmy.c),
1972            g: 1 - (cmy.m),
1973            b: 1 - (cmy.y)
1974          };
1975        },
1976        _cmy_to_cmyk = function(cmy) {
1977          var K = 1;
1978
1979          if (cmy.c < K) {
1980            K = cmy.c;
1981          }
1982          if (cmy.m < K) {
1983            K = cmy.m;
1984          }
1985          if (cmy.y < K) {
1986            K = cmy.y;
1987          }
1988
1989          if (K === 1) {
1990            return {
1991              c: 0,
1992              m: 0,
1993              y: 0,
1994              k: 1
1995            };
1996          }
1997
1998          return {
1999            c: (cmy.c - K) / (1 - K),
2000            m: (cmy.m - K) / (1 - K),
2001            y: (cmy.y - K) / (1 - K),
2002            k: K
2003          };
2004        },
2005        _cmyk_to_cmy = function(cmyk) {
2006          return {
2007            c: cmyk.c * (1 - cmyk.k) + cmyk.k,
2008            m: cmyk.m * (1 - cmyk.k) + cmyk.k,
2009            y: cmyk.y * (1 - cmyk.k) + cmyk.k
2010          };
2011        };
2012
2013      this.set = false;
2014
2015      this.setAlpha = function(_a) {
2016        if (_a !== null) {
2017          a = _clip(_a);
2018        }
2019        this.set = true;
2020
2021        return this;
2022      };
2023
2024      this.getAlpha = function() {
2025        return a;
2026      };
2027
2028      this.setRGB = function(r, g, b) {
2029        spaces = { rgb: this.getRGB() };
2030        if (r !== null) {
2031          spaces.rgb.r = _clip(r);
2032        }
2033        if (g !== null) {
2034          spaces.rgb.g = _clip(g);
2035        }
2036        if (b !== null) {
2037          spaces.rgb.b = _clip(b);
2038        }
2039        this.set = true;
2040
2041        return this;
2042      };
2043
2044      this.getChannel = function(channel) {
2045        switch (channel) {
2046        case 'h':
2047        case 's':
2048        case 'v':
2049          return this.getHSV()[channel];
2050
2051        case 'r':
2052        case 'g':
2053        case 'b':
2054          return this.getRGB()[channel];
2055
2056        case 'a':
2057          return this.getAlpha();
2058        }
2059
2060        return null;
2061      };
2062
2063      this.setChannel = function(channel, value) {
2064        switch (channel) {
2065        case 'h':
2066          return this.setHSV(value, null, null);
2067
2068        case 's':
2069          return this.setHSV(null, value, null);
2070
2071        case 'v':
2072          return this.setHSV(null, null, value);
2073
2074        case 'r':
2075          return this.setRGB(value, null, null);
2076
2077        case 'g':
2078          return this.setRGB(null, value, null);
2079
2080        case 'b':
2081          return this.setRGB(null, null, value);
2082
2083        case 'a':
2084          return this.setAlpha(value);
2085        }
2086
2087        return this;
2088      };
2089
2090      this.setHSV = function(h, s, v) {
2091        spaces = {hsv: this.getHSV()};
2092        if (h !== null) {
2093          spaces.hsv.h = _clip(h);
2094        }
2095        if (s !== null)	{
2096          spaces.hsv.s = _clip(s);
2097        }
2098        if (v !== null)	{
2099          spaces.hsv.v = _clip(v);
2100        }
2101        this.set = true;
2102
2103        return this;
2104      };
2105
2106      this.setHSL = function(h, s, l) {
2107        spaces = {hsl: this.getHSL()};
2108        if (h !== null)	{
2109          spaces.hsl.h = _clip(h);
2110        }
2111        if (s !== null) {
2112          spaces.hsl.s = _clip(s);
2113        }
2114        if (l !== null) {
2115          spaces.hsl.l = _clip(l);
2116        }
2117        this.set = true;
2118
2119        return this;
2120      };
2121
2122      this.setLAB = function(l, a, b) {
2123        spaces = {lab: this.getLAB()};
2124        if (l !== null) {
2125          spaces.lab.l = _clip(l);
2126        }
2127        if (a !== null) {
2128          spaces.lab.a = _clip(a);
2129        }
2130        if (b !== null) {
2131          spaces.lab.b = _clip(b);
2132        }
2133        this.set = true;
2134
2135        return this;
2136      };
2137
2138      this.setCMYK = function(c, m, y, k) {
2139        spaces = {cmyk: this.getCMYK()};
2140        if (c !== null) {
2141          spaces.cmyk.c = _clip(c);
2142        }
2143        if (m !== null) {
2144          spaces.cmyk.m = _clip(m);
2145        }
2146        if (y !== null) {
2147          spaces.cmyk.y = _clip(y);
2148        }
2149        if (k !== null) {
2150          spaces.cmyk.k = _clip(k);
2151        }
2152        this.set = true;
2153
2154        return this;
2155      };
2156
2157      this.getRGB = function() {
2158        if (!spaces.rgb) {
2159          spaces.rgb	= spaces.lab ?	_xyz_to_rgb(_lab_to_xyz(spaces.lab))
2160            : spaces.hsv ?	_hsv_to_rgb(spaces.hsv)
2161              : spaces.hsl ?	_hsl_to_rgb(spaces.hsl)
2162                : spaces.cmyk ?	_cmy_to_rgb(_cmyk_to_cmy(spaces.cmyk))
2163                  : {r: 0, g: 0, b: 0};
2164          spaces.rgb.r = _clip(spaces.rgb.r);
2165          spaces.rgb.g = _clip(spaces.rgb.g);
2166          spaces.rgb.b = _clip(spaces.rgb.b);
2167        }
2168        return $.extend({}, spaces.rgb);
2169      };
2170
2171      this.getHSV = function() {
2172        if (!spaces.hsv) {
2173          spaces.hsv	= spaces.lab ? _rgb_to_hsv(this.getRGB())
2174            : spaces.rgb ?	_rgb_to_hsv(spaces.rgb)
2175              : spaces.hsl ?	_rgb_to_hsv(this.getRGB())
2176                : spaces.cmyk ?	_rgb_to_hsv(this.getRGB())
2177                  : {h: 0, s: 0, v: 0};
2178          spaces.hsv.h = _clip(spaces.hsv.h);
2179          spaces.hsv.s = _clip(spaces.hsv.s);
2180          spaces.hsv.v = _clip(spaces.hsv.v);
2181        }
2182        return $.extend({}, spaces.hsv);
2183      };
2184
2185      this.getHSL = function() {
2186        if (!spaces.hsl) {
2187          spaces.hsl	= spaces.rgb ?	_rgb_to_hsl(spaces.rgb)
2188            : spaces.hsv ?	_rgb_to_hsl(this.getRGB())
2189              : spaces.cmyk ?	_rgb_to_hsl(this.getRGB())
2190                : spaces.hsv ?	_rgb_to_hsl(this.getRGB())
2191                  : {h: 0, s: 0, l: 0};
2192          spaces.hsl.h = _clip(spaces.hsl.h);
2193          spaces.hsl.s = _clip(spaces.hsl.s);
2194          spaces.hsl.l = _clip(spaces.hsl.l);
2195        }
2196        return $.extend({}, spaces.hsl);
2197      };
2198
2199      this.getCMYK = function() {
2200        if (!spaces.cmyk) {
2201          spaces.cmyk	= spaces.rgb ?	_cmy_to_cmyk(_rgb_to_cmy(spaces.rgb))
2202            : spaces.hsv ?	_cmy_to_cmyk(_rgb_to_cmy(this.getRGB()))
2203              : spaces.hsl ?	_cmy_to_cmyk(_rgb_to_cmy(this.getRGB()))
2204                : spaces.lab ?	_cmy_to_cmyk(_rgb_to_cmy(this.getRGB()))
2205                  : {c: 0, m: 0, y: 0, k: 1};
2206          spaces.cmyk.c = _clip(spaces.cmyk.c);
2207          spaces.cmyk.m = _clip(spaces.cmyk.m);
2208          spaces.cmyk.y = _clip(spaces.cmyk.y);
2209          spaces.cmyk.k = _clip(spaces.cmyk.k);
2210        }
2211        return $.extend({}, spaces.cmyk);
2212      };
2213
2214      this.getLAB = function() {
2215        if (!spaces.lab) {
2216          spaces.lab  = spaces.rgb ?  _xyz_to_lab(_rgb_to_xyz(spaces.rgb))
2217            : spaces.hsv ?  _xyz_to_lab(_rgb_to_xyz(this.getRGB()))
2218              : spaces.hsl ?  _xyz_to_lab(_rgb_to_xyz(this.getRGB()))
2219                : spaces.cmyk ? _xyz_to_lab(_rgb_to_xyz(this.getRGB()))
2220                  : {l: 0, a: 0, b: 0};
2221          spaces.lab.l = _clip(spaces.lab.l);
2222          spaces.lab.a = _clip(spaces.lab.a);
2223          spaces.lab.b = _clip(spaces.lab.b);
2224        }
2225        return $.extend({}, spaces.lab);
2226      };
2227
2228      this.getChannels = function() {
2229        return {
2230          r: this.getRGB().r,
2231          g: this.getRGB().g,
2232          b: this.getRGB().b,
2233          a: this.getAlpha(),
2234          h: this.getHSV().h,
2235          s: this.getHSV().s,
2236          v: this.getHSV().v,
2237          c: this.getCMYK().c,
2238          m: this.getCMYK().m,
2239          y: this.getCMYK().y,
2240          k: this.getCMYK().k,
2241          L: this.getLAB().l,
2242          A: this.getLAB().a,
2243          B: this.getLAB().b
2244        };
2245      };
2246
2247      this.getSpaces = function() {
2248        return $.extend(true, {}, spaces);
2249      };
2250
2251      this.distance = function(color) {
2252        var space = 'lab',
2253          getter  = 'get'+space.toUpperCase(),
2254          a = this[getter](),
2255          b = color[getter](),
2256          distance = 0,
2257          channel;
2258
2259        for (channel in a) {
2260          distance += Math.pow(a[channel] - b[channel], 2);
2261        }
2262
2263        return distance;
2264      };
2265
2266      this.equals = function(color) {
2267        if (color) {
2268          var a = this.getRGB(),
2269            b = color.getRGB();
2270
2271          return this.set === color.set
2272            && this.getAlpha() === color.getAlpha()
2273            && a.r === b.r
2274            && a.g === b.g
2275            && a.b === b.b;
2276        }
2277        return false;
2278      };
2279
2280      this.limit = function(steps) {
2281        steps -= 1;
2282        var rgb = this.getRGB();
2283        this.setRGB(
2284          Math.round(rgb.r * steps) / steps,
2285          Math.round(rgb.g * steps) / steps,
2286          Math.round(rgb.b * steps) / steps
2287        );
2288      };
2289
2290      this.toHex = function() {
2291        var rgb = this.getRGB();
2292        return _hexify(rgb.r * 255) + _hexify(rgb.g * 255) + _hexify(rgb.b * 255);
2293      };
2294
2295      this.toCSS = function() {
2296        return '#' + this.toHex();
2297      };
2298
2299      this.copy = function() {
2300        var color = new $.colorpicker.Color(this.getSpaces(), this.getAlpha());
2301        color.set = this.set;
2302        return color;
2303      };
2304
2305      // Construct
2306      if (args.length === 2) {
2307        spaces = args[0];
2308        this.setAlpha(args[1] === 0 ? 0 : args[1] || 1);
2309        this.set = true;
2310      }
2311      if (args.length > 2) {
2312        this.setRGB(args[0], args[1], args[2]);
2313        this.setAlpha(args[3] === 0 ? 0 : args[3] || 1);
2314        this.set = true;
2315      }
2316    };
2317  }();
2318
2319  $.widget('vanderlee.colorpicker', {
2320    options: {
2321      alpha:        false,    // Show alpha controls and mode
2322      altAlpha:     true,   // change opacity of altField as well?
2323      altField:     '',     // selector for DOM elements which change background color on change.
2324      altOnChange:    true,   // true to update on each change, false to update only on close.
2325      altProperties:    'background-color', // comma separated list of any of 'background-color', 'color', 'border-color', 'outline-color'
2326      autoOpen:     false,    // Open dialog automatically upon creation
2327      buttonClass:    null,   // If set, the button will get this/these classname(s).
2328      buttonColorize:   false,
2329      buttonImage:    'images/ui-colorpicker.png',
2330      buttonImageOnly:  false,
2331      buttonText:     null,   // Text on the button and/or title of button image.
2332      cancelOnExit:     false, // Should we revert to original value if user clicks outside?
2333      closeOnEscape:    true,   // Close the dialog when the escape key is pressed.
2334      closeOnOutside:   true,   // Close the dialog when clicking outside the dialog (not for inline)
2335      color:        '#00FF00',  // Initial color (for inline only)
2336      colorFormat:    'HEX',    // Format string for output color format
2337      disabled:     false,    // Disable or enable the colorpicker initially
2338      draggable:      true,   // Make popup dialog draggable if header is visible.
2339      containment:    null,   // Constrains dragging to within the bounds of the specified element or region.
2340      duration:     'fast',
2341      hideOn:       'button', // 'focus', 'click', 'button', 'alt', 'all'
2342      hsv:        true,   // Show HSV controls and modes
2343      inline:       true,   // Show any divs as inline by default
2344      inlineFrame:    true,   // Show a border and background when inline.
2345      layout: {
2346        map:    [0, 0, 1, 5], // Left, Top, Width, Height (in table cells).
2347        bar:    [1, 0, 1, 5],
2348        preview:  [2, 0, 1, 1],
2349        hsv:    [2, 1, 1, 1],
2350        rgb:    [2, 2, 1, 1],
2351        alpha:    [2, 3, 1, 1],
2352        hex:    [2, 4, 1, 1],
2353        lab:    [3, 1, 1, 1],
2354        cmyk:   [3, 2, 1, 2],
2355        swatches: [4, 0, 1, 5]
2356      },
2357      limit:        '',     // Limit color "resolution": '', 'websafe', 'nibble', 'binary', 'name'
2358      modal:        false,    // Modal dialog?
2359      mode:       'h',    // Initial editing mode, h, s, v, r, g, b or a
2360      okOnEnter:      false,    // Close (with OK) when pressing the enter key
2361      parts:        '',     // leave empty for automatic selection
2362      part: {
2363        map:    { size: 256 },
2364        bar:    { size: 256 }
2365      },      // options per part
2366      position:     null,
2367      regional:     '',
2368      revert:       false,    // Revert color upon non
2369      rgb:        true,   // Show RGB controls and modes
2370      showAnim:     'fadeIn',
2371      showCancelButton: true,
2372      showNoneButton:   false,
2373      showCloseButton:  true,
2374      showOn:       'focus click alt',    // 'focus', 'click', 'button', 'alt', 'all'
2375      showOptions:    {},
2376      swatches:     null,   // null for default or kv-object or names swatches set
2377      swatchesWidth:    84,     // width (in number of pixels) of swatches box.
2378      title:        null,
2379
2380      cancel:             null,
2381      close:              null,
2382      init:       null,
2383      ok:                 null,
2384      open:               null,
2385      select:             null,
2386      stop:       null,
2387      ready:    null
2388    },
2389
2390    _create: function () {
2391      var that = this,
2392        text;
2393
2394      that.colorpicker_index = _colorpicker_index++;
2395
2396      that.widgetEventPrefix = 'colorpicker';
2397
2398      that.opened   = false;
2399      that.generated  = false;
2400      that.inline   = false;
2401      that.changed  = false;
2402
2403      that.dialog   = null;
2404      that.button   = null;
2405      that.image    = null;
2406      that.overlay  = null;
2407
2408      that.events = {
2409        window_resize:      null,
2410        document_keydown:   null,
2411        document_click_html:  null
2412      };
2413
2414      that.mode   = that.options.mode;
2415
2416      if (that.element.is('input') || that.options.inline === false) {
2417        // Initial color
2418        that._setColor(that.element.is('input') ? that.element.val() : that.options.color);
2419        that._callback('init');
2420
2421        // showOn focus
2422        if (/\bfocus|all|both\b/.test(that.options.showOn)) {
2423          that.element.on('focus', function () {
2424            that.open();
2425          });
2426        }
2427        if (/\bfocus|all|both\b/.test(that.options.hideOn)) {
2428          that.element.on('focusout', function (e) {
2429            that.close();
2430          });
2431        }
2432
2433        // showOn click
2434        if (/\bclick|all|both\b/.test(that.options.showOn)) {
2435          that.element.on('click', function (e) {
2436            if (that.opened && /\bclick|all|both\b/.test(that.options.hideOn)) {
2437              that.close();
2438            } else {
2439              that.open();
2440            }
2441          });
2442        }
2443
2444        // showOn button
2445        if (/\bbutton|all|both\b/.test(that.options.showOn)) {
2446          if (that.options.buttonImage !== '') {
2447            text = that.options.buttonText || that._getRegional('button');
2448
2449            that.image = $('<img/>').attr({
2450              'src': that.options.buttonImage,
2451              'alt': text,
2452              'title': text
2453            });
2454            if (that.options.buttonClass) {
2455              that.image.attr('class', that.options.buttonClass);
2456            }
2457
2458            that._setImageBackground();
2459          }
2460
2461          if (that.options.buttonImageOnly && that.image) {
2462            that.button = that.image;
2463          } else {
2464            that.button = $('<button type="button"></button>').html(that.image || that.options.buttonText).button();
2465            that.image = that.image ? $('img', that.button).first() : null;
2466          }
2467          that.button.insertAfter(that.element).click(function () {
2468            if (!that.options.disabled) {
2469              if (that.opened && /\bbutton|all|both\b/.test(that.options.hideOn)) {
2470                that.close();
2471              } else {
2472                that.open();
2473              }
2474            }
2475          });
2476        }
2477
2478        // showOn alt
2479        if (/\balt|all|both\b/.test(that.options.showOn)) {
2480          $(that.options.altField).on('click', function () {
2481            if (that.opened && /\balt|all|both\b/.test(that.options.hideOn)) {
2482              that.close();
2483            } else {
2484              that.open();
2485            }
2486          });
2487        }
2488
2489        if (that.options.autoOpen) {
2490          that.open();
2491        }
2492
2493      } else {
2494        that.inline = true;
2495
2496        that._generate();
2497        that.opened = true;
2498      }
2499
2500      // Disable Widget-style
2501      (that.element.is(':disabled') || that.options.disabled) && that.disable();
2502
2503      // Set callback just before creation ending
2504      that._callback('ready');
2505
2506      return this;
2507    },
2508
2509    _setOption: function(key, value) {
2510      switch (key) {
2511      case 'disabled':
2512        this[value ? 'disable' : 'enable']();
2513        break;
2514
2515      case 'swatches':
2516        this.options.swatches = value;
2517        this.parts.swatches.init();
2518        break;
2519      }
2520
2521      $.Widget.prototype._setOption.apply(this, arguments);
2522    },
2523
2524    enable: function () {
2525      //$.Widget.prototype.enable.call(this);
2526      this.element && this.element.prop('disabled', false);
2527      this.button && this.button.prop('disabled', false);
2528      this.dialog && this.dialog.removeClass('ui-colorpicker-disabled');
2529      this.options.disabled = false;
2530
2531      this.parts && $.each(this.parts, function (index, part) {
2532        part.disable && part.disable(false);
2533      });
2534    },
2535
2536    disable: function () {
2537      //$.Widget.prototype.disable.call(this);
2538      this.element && this.element.prop('disabled', true);
2539      this.button && this.button.prop('disabled', true);
2540      this.dialog && this.dialog.addClass('ui-colorpicker-disabled');
2541      this.options.disabled = true;
2542
2543      this.parts && $.each(this.parts, function (index, part) {
2544        part.disable && part.disable(true);
2545      });
2546    },
2547
2548    _setImageBackground: function() {
2549      if (this.image && this.options.buttonColorize) {
2550        this.image.css('background-color', this.color.set? this._formatColor('RGBA', this.color) : '');
2551      }
2552    },
2553
2554    /**
2555     * If an alternate field is specified, set it according to the current color.
2556     */
2557    _setAltField: function () {
2558      if (this.options.altOnChange && this.options.altField && this.options.altProperties) {
2559        var index,
2560          property,
2561          properties = this.options.altProperties.split(',');
2562
2563        for (index = 0; index <= properties.length; ++index) {
2564          property = $.trim(properties[index]);
2565          switch (property) {
2566          case 'color':
2567          case 'fill':
2568          case 'stroke':
2569          case 'background-color':
2570          case 'backgroundColor':
2571          case 'outline-color':
2572          case 'border-color':
2573            $(this.options.altField).css(property, this.color.set? this.color.toCSS() : '');
2574            break;
2575          }
2576        }
2577
2578        this.options.altAlpha &&
2579          $(this.options.altField).css('opacity', this.color.set? this.color.getAlpha() : '');
2580      }
2581    },
2582
2583    _setColor: function(text) {
2584      this.color = this._parseColor(text) || new $.colorpicker.Color();
2585      this.currentColor = this.color.copy();
2586
2587      this._setImageBackground();
2588      this._setAltField();
2589    },
2590
2591    setColor: function(text) {
2592      this._setColor(text);
2593      this._change();
2594    },
2595
2596    getColor: function(format) {
2597      return this._formatColor(format || this.options.colorFormat, this.color);
2598    },
2599
2600    _generateInline: function() {
2601      var that = this;
2602
2603      $(that.element).html(that.options.inlineFrame ? _container_inlineFrame : _container_inline);
2604
2605      that.dialog = $('.ui-colorpicker', that.element);
2606    },
2607
2608    _generatePopup: function() {
2609      var that = this;
2610
2611      that.dialog = $(_container_popup).appendTo('body');
2612
2613      // Close on clicking outside window and controls
2614      if (that.events.document_click_html === null) {
2615        $(document).on('touchstart click', 'html', that.events.document_click_html = function (event) {
2616          if (!that.opened || event.target === that.element[0] || that.overlay) {
2617            return;
2618          }
2619
2620          // Check if clicked on any part of dialog
2621          if (that.dialog.is(event.target) || that.dialog.has(event.target).length > 0) {
2622            that.element.blur();	// inside window!
2623            return;
2624          }
2625
2626          // Check if clicked on known external elements
2627          var p,
2628            parents = $(event.target).parents();
2629          // add the event.target in case of buttonImageOnly and closeOnOutside both are set to true
2630          parents.push(event.target);
2631          for (p = 0; p <= parents.length; ++p) {
2632            // button
2633            if (that.button !== null && parents[p] === that.button[0]) {
2634              return;
2635            }
2636            // showOn alt
2637            if (/\balt|all|both\b/.test(that.options.showOn) && $(that.options.altField).is(parents[p])) {
2638              return;
2639            }
2640          }
2641
2642          // no closeOnOutside
2643          if (!that.options.closeOnOutside) {
2644            return;
2645          }
2646
2647          // bring back the previous color if cancelOnExit is set to true
2648          if (that.options.cancelOnExit) {
2649            that.color = that.currentColor.copy();
2650            that._change();
2651          }
2652
2653          that.close(that.options.revert);
2654        });
2655      }
2656
2657      if (that.events.document_keydown === null) {
2658        $(document).on('keydown', that.events.document_keydown = function (event) {
2659          // close on ESC key
2660          if (that.opened && event.keyCode === 27 && that.options.closeOnEscape) {
2661            that.close(that.options.revert);
2662          }
2663
2664          // OK on Enter key
2665          if (that.opened && event.keyCode === 13 && that.options.okOnEnter) {
2666            that.close();
2667          }
2668        });
2669      }
2670
2671      // Close (with OK) on tab key in element
2672      that.element.keydown(function (event) {
2673        if (event.keyCode === 9) {
2674          that.close();
2675        }
2676      }).keyup(function (event) {
2677        var color = that._parseColor(that.element.val());
2678        if (color && !that.color.equals(color)) {
2679          that.color = color;
2680          that._change();
2681        }
2682      });
2683    },
2684
2685    _generate: function () {
2686      var that = this,
2687        index,
2688        part,
2689        parts_list,
2690        layout_parts,
2691        table,
2692        classes;
2693
2694      that._setColor(that.inline || !that.element.is('input') ? that.options.color : that.element.val());
2695
2696      that[that.inline ? '_generateInline' : '_generatePopup']();
2697
2698      // Determine the parts to include in this colorpicker
2699      if (typeof that.options.parts === 'string') {
2700        if ($.colorpicker.partslists[that.options.parts]) {
2701          parts_list = $.colorpicker.partslists[that.options.parts];
2702        } else {
2703          // automatic
2704          parts_list = $.colorpicker.partslists[that.inline ? 'inline' : 'popup'];
2705        }
2706      } else {
2707        parts_list = that.options.parts;
2708      }
2709
2710      // Add any parts to the internal parts list
2711      that.parts = {};
2712      $.each(parts_list, function(index, part) {
2713        if ($.colorpicker.parts[part]) {
2714          that.parts[part] = new $.colorpicker.parts[part](that);
2715        }
2716      });
2717
2718      if (!that.generated) {
2719        layout_parts = [];
2720
2721        $.each(that.options.layout, function(part, pos) {
2722          if (that.parts[part]) {
2723            layout_parts.push({
2724              'part': part,
2725              'pos':  pos
2726            });
2727          }
2728        });
2729
2730        table = $(_layoutTable(layout_parts, function(cell, x, y) {
2731          classes = ['ui-colorpicker-' + cell.part + '-container'];
2732
2733          if (x > 0) {
2734            classes.push('ui-colorpicker-padding-left');
2735          }
2736
2737          if (y > 0) {
2738            classes.push('ui-colorpicker-padding-top');
2739          }
2740
2741          return '<td  class="' + classes.join(' ') + '"'
2742            + (cell.pos[2] > 1 ? ' colspan="' + cell.pos[2] + '"' : '')
2743            + (cell.pos[3] > 1 ? ' rowspan="' + cell.pos[3] + '"' : '')
2744            + ' valign="top"></td>';
2745        })).appendTo(that.dialog);
2746        if (that.options.inlineFrame) {
2747          table.addClass('ui-dialog-content ui-widget-content');
2748        }
2749
2750        that._initAllParts();
2751        that._updateAllParts();
2752        that.generated = true;
2753      }
2754    },
2755
2756    _effectGeneric: function (element, show, slide, fade, callback) {
2757      var that = this;
2758
2759      if ($.effects && $.effects[that.options.showAnim]) {
2760        element[show](that.options.showAnim, that.options.showOptions, that.options.duration, callback);
2761      } else {
2762        element[(that.options.showAnim === 'slideDown' ?
2763          slide
2764          :	(that.options.showAnim === 'fadeIn' ?
2765            fade
2766            :	show))]((that.options.showAnim ? that.options.duration : null), callback);
2767        if ($.isFunction(callback) && (!that.options.showAnim || !that.options.duration)) {
2768          callback();
2769        }
2770      }
2771    },
2772
2773    _effectShow: function(element, callback) {
2774      this._effectGeneric(element, 'show', 'slideDown', 'fadeIn', callback);
2775    },
2776
2777    _effectHide: function(element, callback) {
2778      this._effectGeneric(element, 'hide', 'slideUp', 'fadeOut', callback);
2779    },
2780
2781    open: function() {
2782      var that = this,
2783        offset,
2784        bottom, right,
2785        height, width,
2786        x, y,
2787        zIndex,
2788        element,
2789        position;
2790
2791      if (!that.opened) {
2792        that._generate();
2793
2794        if (that.element.is(':hidden')) {
2795          element = $('<div/>').insertBefore(that.element);
2796        } else {
2797          element = that.element;
2798        }
2799
2800        if (that.element.is(':hidden')) {
2801          element.remove();
2802        }
2803
2804        // Automatically find highest z-index.
2805        zIndex = 0;
2806        $(that.element[0]).parents().each(function() {
2807          var z = $(this).css('z-index');
2808          if ((typeof(z) === 'number' || typeof(z) === 'string') && z !== '' && !isNaN(z)) {
2809            if (z > zIndex) {
2810              zIndex = parseInt(z, 10);
2811              return false;
2812            }
2813          }
2814          else {
2815            $(this).siblings().each(function() {
2816              var z = $(this).css('z-index');
2817              if ((typeof(z) === 'number' || typeof(z) === 'string') && z !== '' && !isNaN(z)) {
2818                if (z > zIndex) {
2819                  zIndex = parseInt(z, 10);
2820                }
2821              }
2822            });
2823          }
2824        });
2825
2826        zIndex += 2;
2827        that.dialog.css('z-index', zIndex);
2828
2829        if (that.options.modal) {
2830          that.overlay = $('<div class="ui-widget-overlay"></div>').appendTo('body').css('z-index', zIndex - 1);
2831
2832          if (that.events.window_resize !== null) {
2833            $(window).off('resize', that.events.window_resize);
2834          }
2835
2836          that.events.window_resize = function() {
2837            if (that.overlay) {
2838              that.overlay.width($(document).width());
2839              that.overlay.height($(document).height());
2840            }
2841          },
2842
2843          $(window).on('resize', that.events.window_resize);
2844          that.events.window_resize();
2845        }
2846
2847        that._effectShow(this.dialog);
2848
2849        if (that.options.position) {
2850          position = $.extend({}, that.options.position);
2851          if (position.of === 'element') {
2852            position.of = element;
2853          }
2854        } else {
2855          position = {
2856            my: 'left top',
2857            at: 'left bottom',
2858            of: element,
2859            collision:  'flip'
2860          };
2861        }
2862        that.dialog.position(position);
2863
2864        that.opened = true;
2865        that._callback('open');
2866
2867        // Without waiting for domready the width of the map is 0 and we
2868        // wind up with the cursor stuck in the upper left corner
2869        $(function() {
2870          that._repaintAllParts();
2871        });
2872      }
2873    },
2874
2875    close: function (cancel) {
2876      var that = this;
2877
2878      if (!that.opened) {
2879        return;
2880      }
2881
2882      if (cancel) {
2883        that.color = that.currentColor.copy();
2884        that._change();
2885        that._callback('cancel');
2886      } else {
2887        that.currentColor	= that.color.copy();
2888        that._callback('ok');
2889      }
2890      that.changed		= false;
2891
2892      if (that.overlay) {
2893        $(window).off('resize', that.events.window_resize);
2894        that.overlay.remove();
2895      }
2896
2897      // tear down the interface
2898      that._effectHide(that.dialog, function () {
2899        that.dialog.remove();
2900        that.dialog		= null;
2901        that.generated	= false;
2902
2903        that.opened		= false;
2904        that._callback('close');
2905      });
2906    },
2907
2908    destroy: function() {
2909      var that = this;
2910      if (that.events.document_click_html !== null) {
2911        $(document).off('touchstart click', 'html', that.events.document_click_html);
2912      }
2913
2914      if (that.events.document_keydown !== null) {
2915        $(document).off('keydown', that.events.document_keydown);
2916      }
2917
2918      if (that.events.window_resize !== null) {
2919        $(window).off('resize', that.events.window_resize);
2920      }
2921
2922      this.element.off();
2923
2924      if (this.overlay) {
2925        this.overlay.remove();
2926      }
2927
2928      if (this.dialog !== null) {
2929        this.dialog.remove();
2930      }
2931
2932      if (this.image !== null) {
2933        this.image.remove();
2934      }
2935
2936      if (this.button !== null) {
2937        this.button.remove();
2938      }
2939    },
2940
2941    _callback: function (callback) {
2942      var that = this,
2943        data,
2944        lab;
2945
2946      if (that.color.set) {
2947        data = {
2948          formatted: that._formatColor(that.options.colorFormat, that.color),
2949          colorPicker: that
2950        };
2951
2952        data.hex  = that.color.toHex();
2953        data.css  = that.color.toCSS();
2954        data.a    = that.color.getAlpha();
2955        data.rgb  = that.color.getRGB();
2956        data.hsv  = that.color.getHSV();
2957        data.cmyk = that.color.getCMYK();
2958        data.hsl  = that.color.getHSL();
2959
2960        lab = that.color.getLAB();
2961        lab.a = (lab.a * 2) - 1;
2962        lab.b = (lab.b * 2) - 1;
2963        data.lab  = lab;
2964
2965        return that._trigger(callback, null, data);
2966      } else {
2967        return that._trigger(callback, null, {
2968          formatted: '',
2969          colorPicker: that
2970        });
2971      }
2972    },
2973
2974    _initAllParts: function () {
2975      $.each(this.parts, function (index, part) {
2976        if (part.init) {
2977          part.init();
2978        }
2979      });
2980    },
2981
2982    _updateAllParts: function () {
2983      $.each(this.parts, function (index, part) {
2984        if (part.update) {
2985          part.update();
2986        }
2987      });
2988    },
2989
2990    _repaintAllParts: function () {
2991      $.each(this.parts, function (index, part) {
2992        if (part.repaint) {
2993          part.repaint();
2994        }
2995      });
2996    },
2997
2998    _change: function (stoppedChanging /* = true */) {
2999      // Limit color palette
3000      if (this.color.set && this.options.limit && $.colorpicker.limits[this.options.limit]) {
3001        $.colorpicker.limits[this.options.limit](this.color, this);
3002      }
3003
3004      // Set changed if different from starting color
3005      this.changed = !this.color.equals(this.currentColor);
3006
3007      // update input element content
3008      if (!this.inline) {
3009        if (!this.color.set) {
3010          if (this.element.val() !== '') {
3011            this.element.val('').change();
3012          }
3013        } else if (!this.color.equals(this._parseColor(this.element.val()))) {
3014          this.element.val(this._formatColor(this.options.colorFormat, this.color)).change();
3015        }
3016
3017        this._setImageBackground();
3018      }
3019
3020      // Set the alt field
3021      this._setAltField();
3022
3023      // update color option
3024      this.options.color = this.color.set ? this.color.toCSS() : '';
3025
3026      if (this.opened) {
3027        this._repaintAllParts();
3028      }
3029
3030      // callbacks
3031      this._callback('select');
3032
3033      if (typeof stoppedChanging === 'undefined' ? true : !!stoppedChanging) {
3034        this._callback('stop');
3035      }
3036    },
3037
3038    // This will be deprecated by jQueryUI 1.9 widget
3039    _hoverable: function (e) {
3040      e.hover(function () {
3041        e.addClass('ui-state-hover');
3042      }, function () {
3043        e.removeClass('ui-state-hover');
3044      });
3045    },
3046
3047    // This will be deprecated by jQueryUI 1.9 widget
3048    _focusable: function (e) {
3049      e.focus(function () {
3050        e.addClass('ui-state-focus');
3051      }).blur(function () {
3052        e.removeClass('ui-state-focus');
3053      });
3054    },
3055
3056    _getRegional: function(name) {
3057      return $.colorpicker.regional[this.options.regional][name] !== undefined ?
3058        $.colorpicker.regional[this.options.regional][name] : $.colorpicker.regional[''][name];
3059    },
3060
3061    _getSwatches: function() {
3062      if (typeof(this.options.swatches) === 'string') {
3063        return $.colorpicker.swatches[this.options.swatches];
3064      }
3065
3066      if ($.isPlainObject(this.options.swatches)) {
3067        return this.options.swatches;
3068      }
3069
3070      return $.colorpicker.swatches.html;
3071    },
3072
3073    _eachSwatch: function (callback) {
3074      var currentSwatches = this._getSwatches(),
3075        name;
3076      $.each(currentSwatches, function (nameOrIndex, swatch) {
3077        name = $.isArray(currentSwatches) ? swatch.name : nameOrIndex;
3078        return callback(name, swatch);
3079      });
3080    },
3081
3082    _getSwatch: function(name) {
3083      var swatch = false;
3084
3085      this._eachSwatch(function(swatchName, current) {
3086        if (swatchName.toLowerCase() == name.toLowerCase()) {
3087          swatch = current;
3088          return false;
3089        }
3090      });
3091
3092      return swatch;
3093    },
3094
3095    _parseFormat: function(format, text) {
3096      var that = this,
3097        typeRegexps = {
3098          x:  function() {return '([0-9a-fA-F]{2})';}
3099          , d:  function() {return '([12]?[0-9]{1,2})';}
3100          , f:  function() {return '([0-9]*\\.?[0-9]*)';}
3101          , p:  function() {return '([0-9]*\\.?[0-9]*)';}
3102        },
3103        typeConverters = {
3104          x:  function(v) {return parseInt(v, 16) / 255.;}
3105          , d:  function(v) {return v / 255.;}
3106          , f:  function(v) {return v;}
3107          , p:  function(v) {return v * 0.01;}
3108        },
3109        setters = {
3110          r:  'setRGB'
3111          , g:  'setRGB'
3112          , b:  'setRGB'
3113          , h:  'setHSV'
3114          , s:  'setHSV'
3115          , v:  'setHSV'
3116          , c:  'setCMYK'
3117          , m:  'setCMYK'
3118          , y:  'setCMYK'
3119          , k:  'setCMYK'
3120          , L:  'setLAB'
3121          , A:  'setLAB'
3122          , B:  'setLAB'
3123        },
3124        setterChannels = {
3125          setRGB:   [ 'r', 'g', 'b']
3126          , setHSV:   [ 'h', 's', 'v' ]
3127          , setCMYK:  [ 'c', 'm', 'y', 'k' ]
3128          , setLAB:   [ 'L', 'A', 'B' ]
3129        },
3130        channels = [],
3131        converters = [],
3132        setter = null,
3133        color,
3134        pattern;
3135
3136      // Construct pattern
3137      pattern = format.replace(/[()\\^$.|?*+[\]]/g, function(m) {
3138        return '\\'+m;
3139      });
3140
3141
3142      pattern = pattern.replace(/\\?[argbhsvcmykLAB][xdfp]/g, function(variable) {
3143        if (variable.match(/^\\/)) {
3144          return variable.slice(1);
3145        }
3146
3147        var channel = variable.charAt(0),
3148          type = variable.charAt(1);
3149
3150        channels.push(channel);
3151        converters.push(typeConverters[type]);
3152        if (setters[channel]) {
3153          setter = setters[channel];
3154        }
3155
3156        return typeRegexps[type]();
3157      });
3158
3159      if (setter) {
3160        var values = text.match(new RegExp(pattern));
3161        if (values) {
3162          var args = [],
3163            channelIndex;
3164
3165          values.shift();
3166
3167          $.each(setterChannels[setter], function(index, channel) {
3168            channelIndex = $.inArray(channel, channels);
3169            args[index] = converters[channelIndex](values[channelIndex]);
3170          });
3171
3172          color = new $.colorpicker.Color();
3173          color[setter].apply(color, args);
3174        }
3175      }
3176
3177      return color;
3178    },
3179
3180    _parseColor: function(text) {
3181      var that = this,
3182        color;
3183
3184      var formats = $.isArray(that.options.colorFormat)
3185        ? that.options.colorFormat
3186        : [ that.options.colorFormat ];
3187
3188      $.each(formats, function(index, format) {
3189        if ($.colorpicker.parsers[format]) {
3190          color = $.colorpicker.parsers[format](text, that);
3191        } else {
3192          color = that._parseFormat(format, text);
3193        }
3194
3195        if (color) {
3196          return false;
3197        }
3198      });
3199
3200      if (!color) {
3201        // fallback; check all registered parsers
3202        $.each($.colorpicker.parsers, function(name, parser) {
3203          color = parser(text, that);
3204          if (color) {
3205            return false;
3206          }
3207        });
3208      }
3209
3210      if (color) {
3211        return color;
3212      }
3213
3214      return false;
3215    },
3216
3217    _exactName: function(color) {
3218      var name = false;
3219
3220      this._eachSwatch(function(n, swatch) {
3221        if (color.equals(new $.colorpicker.Color(swatch.r, swatch.g, swatch.b))) {
3222          name = n;
3223          return false;
3224        }
3225      });
3226
3227      return name;
3228    },
3229
3230    _closestName: function(color) {
3231      var rgb     = color.getRGB(),
3232        distance  = null,
3233        name    = false,
3234        d;
3235
3236      this._eachSwatch(function(n, swatch) {
3237        d = color.distance(new $.colorpicker.Color(swatch.r, swatch.g, swatch.b));
3238        if (d < distance || distance === null) {
3239          name = n;
3240          if (d <= 1e-20) { // effectively 0 by maximum rounding error
3241            return false; // can't get much closer than 0
3242          }
3243          distance = d; // safety net
3244        }
3245      });
3246
3247      return name;
3248    },
3249
3250    _formatColor: function (formats, color) {
3251      var that = this,
3252        text = null,
3253        types = { 'x':  function(v) {return _intToHex(v * 255);}
3254          ,'d':function(v) {return Math.round(v * 255);}
3255          ,'f':function(v) {return v;}
3256          ,'p':function(v) {return v * 100.;}
3257        },
3258        channels  = color.getChannels();
3259
3260      if (!$.isArray(formats)) {
3261        formats = [formats];
3262      }
3263
3264      $.each(formats, function(index, format) {
3265        if ($.colorpicker.writers[format]) {
3266          text = $.colorpicker.writers[format](color, that);
3267          return (text === false);
3268        } else {
3269          text = format.replace(/\\?[argbhsvcmykLAB][xdfp]/g, function(m) {
3270            if (m.match(/^\\/)) {
3271              return m.slice(1);
3272            }
3273            return types[m.charAt(1)](channels[m.charAt(0)]);
3274          });
3275          return false;
3276        }
3277      });
3278
3279      return text;
3280    }
3281  });
3282
3283  return $.vanderlee.colorpicker;
3284}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.