]> lifelog.hopto.org Git - LifeLog.git/commitdiff
Now the RTF panel background can be changed.
authorMetabox <redacted>
Tue, 6 Aug 2019 02:47:27 +0000 (12:47 +1000)
committerMetabox <redacted>
Tue, 6 Aug 2019 02:47:27 +0000 (12:47 +1000)
htdocs/cgi-bin/main.cgi
htdocs/cgi-bin/wsrc/jscolor.js [new file with mode: 0644]

index 48c81f480bb5deb0a50502b81cf0519de583af6e..5e7705d1970d12a71602591d3af347a6ed76fa5a 100755 (executable)
@@ -166,6 +166,7 @@ print $cgi->start_html(
         { -type => 'text/javascript', -src => 'wsrc/quill/katex.min.js' },
         { -type => 'text/javascript', -src => 'wsrc/quill/highlight.min.js' },
         { -type => 'text/javascript', -src => 'wsrc/quill/quill.min.js' },
+        { -type => 'text/javascript', -src => 'wsrc/jscolor.js' },
 
     ],
 );
@@ -842,7 +843,7 @@ return $today;
 
                 $st = $db->prepare('INSERT INTO LOG VALUES (?,?,?,?,?)');
                 $st->execute( $cat, $date, $log, $am, $rtf );
-                if($rtf){ #Update 0 ground NOTES entry to just inserted log.
+                if($rtf){ #Update 0 ground NOTES entry to the just inserted log.
                    
                    #last_insert_id() -> Not reliable commented out.
                    #my $gzero = $db->last_insert_id();#//$db->prepare('SELECT last_insert_rowid();');
@@ -868,7 +869,12 @@ return $today;
                       $st = $db->prepare("INSERT INTO NOTES(LID, DOC) VALUES (?, ?);"); 
                      # 
                       $st->execute($lid[0], $gzero[0]);
+
+                       #Flatten ground zero                   
+                       $st = $db->prepare("UPDATE NOTES SET DOC='' WHERE LID = 0;");
+                       $st->execute();   
                    }
+
                    
                 }
                 #
@@ -959,28 +965,25 @@ qq!<td><input type="button" onclick="submitNext($tbl_cur_id);return false;"
         $tbl = $tbl . '<td colspan="2"></td></tr>';
     }
 
-    sub authenticate {
+sub authenticate {
         try {
 
             if ($AUTHORITY) {
                 return;
             }
 
-            my $st = $db->prepare(
-"SELECT * FROM AUTH WHERE alias='$userid' and passw='$password';"
-            );
+            my $st = $db->prepare( "SELECT alias FROM AUTH WHERE alias='$userid' and passw='$password';");
             $st->execute();
-            if ( $st->fetchrow_array() ) { return; }
+            my @c = $st->fetchrow_array(); 
+            if (@c && $c[0] eq $userid ) { return; }
 
             #Check if passw has been wiped for reset?
             $st = $db->prepare("SELECT * FROM AUTH WHERE alias='$userid';");
             $st->execute();
-            my @w = $st->fetchrow_array();
-            if ( @w && $w[1] == "" ) {
-
+            @c = $st->fetchrow_array(); 
+            if ( @c && $c[1] == "" ) {
                 #Wiped with -> UPDATE AUTH SET passw='' WHERE alias='$userid';
-                $st = $db->prepare(
-                    "UPDATE AUTH SET passw='$password' WHERE alias='$userid';");
+                $st = $db->prepare("UPDATE AUTH SET passw='$password' WHERE alias='$userid';");
                 $st->execute();
                 return;
             }
@@ -994,7 +997,7 @@ qq!<td><input type="button" onclick="submitNext($tbl_cur_id);return false;"
             );
 
             print $cgi->center(
-                $cgi->div("<b>Access Denied!</b> alias:$userid pass:$password")
+                $cgi->div("<b>Access Denied!</b> alias:$userid pass:$password SQL->SELECT * FROM AUTH WHERE alias='$userid' and passw='$password'; ")
             );
             print $cgi->end_html;
 
@@ -1009,7 +1012,7 @@ qq!<td><input type="button" onclick="submitNext($tbl_cur_id);return false;"
             print $cgi->end_html;
             exit;
         }
-    }
+}
 
     sub fetchAutocomplete {
         try {
@@ -1100,7 +1103,6 @@ qq!<td><input type="button" onclick="submitNext($tbl_cur_id);return false;"
 
     sub cam {
         my $am = sprintf( "%.2f", shift @_ );
-
         # Add one comma each time through the do-nothing loop
         1 while $am =~ s/^(-?\d+)(\d\d\d)/$1,$2/;
         return $am;
@@ -1169,17 +1171,16 @@ return <<___STR;
       <button class="ql-video"></button>
       <button class="ql-formula"></button>
     </span>  
-    <span class="ql-formats">        
-        <button class="ql-formats" id="pbck_lighter" onClick="editorBackgroundLighter();">Lighter&nbsp;&nbsp;</button>
-        <button class="ql-formats" id="pbck_neutral" onClick="editorBackgroundReset();">&nbsp;Reset&nbsp;</button>
-        <button id="pbck_darker" onClick="editorBackgroundDarker();">&nbsp;&nbsp;Darker</button>        
-    </span>
+    <span class="ql-formats" style="float:right; border:1px;">        
+        Background <input id="fldBG" type="field" class="jscolor {onFineChange:'editorBackground(false)',closable:true,closeText:'Close',hash:true}" size="10" value="000000"/>
+        <button onClick="editorBackground(true);" style="float:right; border:1px;">&nbsp;&nbsp;Reset</button>
+    </span>    
   </div>
   <div id="editor-container" style="$height"></div>
   <div class="save_button">
   <input type="button" id="btn_save_doc" onclick="saveRTF(0, 'store'); return false;"); value="Save"/>
   </div>
-  </td></tr></table>
+  </td></tr></table>  
 ___STR
 
 }
diff --git a/htdocs/cgi-bin/wsrc/jscolor.js b/htdocs/cgi-bin/wsrc/jscolor.js
new file mode 100644 (file)
index 0000000..5c77177
--- /dev/null
@@ -0,0 +1,1855 @@
+/**\r
+ * jscolor - JavaScript Color Picker\r
+ *\r
+ * @link    http://jscolor.com\r
+ * @license For open source use: GPLv3\r
+ *          For commercial use: JSColor Commercial License\r
+ * @author  Jan Odvarko\r
+ * @version 2.0.5\r
+ *\r
+ * See usage examples at http://jscolor.com/examples/\r
+ */\r
+\r
+\r
+"use strict";\r
+\r
+\r
+if (!window.jscolor) { window.jscolor = (function () {\r
+\r
+\r
+var jsc = {\r
+\r
+\r
+       register : function () {\r
+               jsc.attachDOMReadyEvent(jsc.init);\r
+               jsc.attachEvent(document, 'mousedown', jsc.onDocumentMouseDown);\r
+               jsc.attachEvent(document, 'touchstart', jsc.onDocumentTouchStart);\r
+               jsc.attachEvent(window, 'resize', jsc.onWindowResize);\r
+       },\r
+\r
+\r
+       init : function () {\r
+               if (jsc.jscolor.lookupClass) {\r
+                       jsc.jscolor.installByClassName(jsc.jscolor.lookupClass);\r
+               }\r
+       },\r
+\r
+\r
+       tryInstallOnElements : function (elms, className) {\r
+               var matchClass = new RegExp('(^|\\s)(' + className + ')(\\s*(\\{[^}]*\\})|\\s|$)', 'i');\r
+\r
+               for (var i = 0; i < elms.length; i += 1) {\r
+                       if (elms[i].type !== undefined && elms[i].type.toLowerCase() == 'color') {\r
+                               if (jsc.isColorAttrSupported) {\r
+                                       // skip inputs of type 'color' if supported by the browser\r
+                                       continue;\r
+                               }\r
+                       }\r
+                       var m;\r
+                       if (!elms[i].jscolor && elms[i].className && (m = elms[i].className.match(matchClass))) {\r
+                               var targetElm = elms[i];\r
+                               var optsStr = null;\r
+\r
+                               var dataOptions = jsc.getDataAttr(targetElm, 'jscolor');\r
+                               if (dataOptions !== null) {\r
+                                       optsStr = dataOptions;\r
+                               } else if (m[4]) {\r
+                                       optsStr = m[4];\r
+                               }\r
+\r
+                               var opts = {};\r
+                               if (optsStr) {\r
+                                       try {\r
+                                               opts = (new Function ('return (' + optsStr + ')'))();\r
+                                       } catch(eParseError) {\r
+                                               jsc.warn('Error parsing jscolor options: ' + eParseError + ':\n' + optsStr);\r
+                                       }\r
+                               }\r
+                               targetElm.jscolor = new jsc.jscolor(targetElm, opts);\r
+                       }\r
+               }\r
+       },\r
+\r
+\r
+       isColorAttrSupported : (function () {\r
+               var elm = document.createElement('input');\r
+               if (elm.setAttribute) {\r
+                       elm.setAttribute('type', 'color');\r
+                       if (elm.type.toLowerCase() == 'color') {\r
+                               return true;\r
+                       }\r
+               }\r
+               return false;\r
+       })(),\r
+\r
+\r
+       isCanvasSupported : (function () {\r
+               var elm = document.createElement('canvas');\r
+               return !!(elm.getContext && elm.getContext('2d'));\r
+       })(),\r
+\r
+\r
+       fetchElement : function (mixed) {\r
+               return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;\r
+       },\r
+\r
+\r
+       isElementType : function (elm, type) {\r
+               return elm.nodeName.toLowerCase() === type.toLowerCase();\r
+       },\r
+\r
+\r
+       getDataAttr : function (el, name) {\r
+               var attrName = 'data-' + name;\r
+               var attrValue = el.getAttribute(attrName);\r
+               if (attrValue !== null) {\r
+                       return attrValue;\r
+               }\r
+               return null;\r
+       },\r
+\r
+\r
+       attachEvent : function (el, evnt, func) {\r
+               if (el.addEventListener) {\r
+                       el.addEventListener(evnt, func, false);\r
+               } else if (el.attachEvent) {\r
+                       el.attachEvent('on' + evnt, func);\r
+               }\r
+       },\r
+\r
+\r
+       detachEvent : function (el, evnt, func) {\r
+               if (el.removeEventListener) {\r
+                       el.removeEventListener(evnt, func, false);\r
+               } else if (el.detachEvent) {\r
+                       el.detachEvent('on' + evnt, func);\r
+               }\r
+       },\r
+\r
+\r
+       _attachedGroupEvents : {},\r
+\r
+\r
+       attachGroupEvent : function (groupName, el, evnt, func) {\r
+               if (!jsc._attachedGroupEvents.hasOwnProperty(groupName)) {\r
+                       jsc._attachedGroupEvents[groupName] = [];\r
+               }\r
+               jsc._attachedGroupEvents[groupName].push([el, evnt, func]);\r
+               jsc.attachEvent(el, evnt, func);\r
+       },\r
+\r
+\r
+       detachGroupEvents : function (groupName) {\r
+               if (jsc._attachedGroupEvents.hasOwnProperty(groupName)) {\r
+                       for (var i = 0; i < jsc._attachedGroupEvents[groupName].length; i += 1) {\r
+                               var evt = jsc._attachedGroupEvents[groupName][i];\r
+                               jsc.detachEvent(evt[0], evt[1], evt[2]);\r
+                       }\r
+                       delete jsc._attachedGroupEvents[groupName];\r
+               }\r
+       },\r
+\r
+\r
+       attachDOMReadyEvent : function (func) {\r
+               var fired = false;\r
+               var fireOnce = function () {\r
+                       if (!fired) {\r
+                               fired = true;\r
+                               func();\r
+                       }\r
+               };\r
+\r
+               if (document.readyState === 'complete') {\r
+                       setTimeout(fireOnce, 1); // async\r
+                       return;\r
+               }\r
+\r
+               if (document.addEventListener) {\r
+                       document.addEventListener('DOMContentLoaded', fireOnce, false);\r
+\r
+                       // Fallback\r
+                       window.addEventListener('load', fireOnce, false);\r
+\r
+               } else if (document.attachEvent) {\r
+                       // IE\r
+                       document.attachEvent('onreadystatechange', function () {\r
+                               if (document.readyState === 'complete') {\r
+                                       document.detachEvent('onreadystatechange', arguments.callee);\r
+                                       fireOnce();\r
+                               }\r
+                       })\r
+\r
+                       // Fallback\r
+                       window.attachEvent('onload', fireOnce);\r
+\r
+                       // IE7/8\r
+                       if (document.documentElement.doScroll && window == window.top) {\r
+                               var tryScroll = function () {\r
+                                       if (!document.body) { return; }\r
+                                       try {\r
+                                               document.documentElement.doScroll('left');\r
+                                               fireOnce();\r
+                                       } catch (e) {\r
+                                               setTimeout(tryScroll, 1);\r
+                                       }\r
+                               };\r
+                               tryScroll();\r
+                       }\r
+               }\r
+       },\r
+\r
+\r
+       warn : function (msg) {\r
+               if (window.console && window.console.warn) {\r
+                       window.console.warn(msg);\r
+               }\r
+       },\r
+\r
+\r
+       preventDefault : function (e) {\r
+               if (e.preventDefault) { e.preventDefault(); }\r
+               e.returnValue = false;\r
+       },\r
+\r
+\r
+       captureTarget : function (target) {\r
+               // IE\r
+               if (target.setCapture) {\r
+                       jsc._capturedTarget = target;\r
+                       jsc._capturedTarget.setCapture();\r
+               }\r
+       },\r
+\r
+\r
+       releaseTarget : function () {\r
+               // IE\r
+               if (jsc._capturedTarget) {\r
+                       jsc._capturedTarget.releaseCapture();\r
+                       jsc._capturedTarget = null;\r
+               }\r
+       },\r
+\r
+\r
+       fireEvent : function (el, evnt) {\r
+               if (!el) {\r
+                       return;\r
+               }\r
+               if (document.createEvent) {\r
+                       var ev = document.createEvent('HTMLEvents');\r
+                       ev.initEvent(evnt, true, true);\r
+                       el.dispatchEvent(ev);\r
+               } else if (document.createEventObject) {\r
+                       var ev = document.createEventObject();\r
+                       el.fireEvent('on' + evnt, ev);\r
+               } else if (el['on' + evnt]) { // alternatively use the traditional event model\r
+                       el['on' + evnt]();\r
+               }\r
+       },\r
+\r
+\r
+       classNameToList : function (className) {\r
+               return className.replace(/^\s+|\s+$/g, '').split(/\s+/);\r
+       },\r
+\r
+\r
+       // The className parameter (str) can only contain a single class name\r
+       hasClass : function (elm, className) {\r
+               if (!className) {\r
+                       return false;\r
+               }\r
+               return -1 != (' ' + elm.className.replace(/\s+/g, ' ') + ' ').indexOf(' ' + className + ' ');\r
+       },\r
+\r
+\r
+       // The className parameter (str) can contain multiple class names separated by whitespace\r
+       setClass : function (elm, className) {\r
+               var classList = jsc.classNameToList(className);\r
+               for (var i = 0; i < classList.length; i += 1) {\r
+                       if (!jsc.hasClass(elm, classList[i])) {\r
+                               elm.className += (elm.className ? ' ' : '') + classList[i];\r
+                       }\r
+               }\r
+       },\r
+\r
+\r
+       // The className parameter (str) can contain multiple class names separated by whitespace\r
+       unsetClass : function (elm, className) {\r
+               var classList = jsc.classNameToList(className);\r
+               for (var i = 0; i < classList.length; i += 1) {\r
+                       var repl = new RegExp(\r
+                               '^\\s*' + classList[i] + '\\s*|' +\r
+                               '\\s*' + classList[i] + '\\s*$|' +\r
+                               '\\s+' + classList[i] + '(\\s+)',\r
+                               'g'\r
+                       );\r
+                       elm.className = elm.className.replace(repl, '$1');\r
+               }\r
+       },\r
+\r
+\r
+       getStyle : function (elm) {\r
+               return window.getComputedStyle ? window.getComputedStyle(elm) : elm.currentStyle;\r
+       },\r
+\r
+\r
+       setStyle : (function () {\r
+               var helper = document.createElement('div');\r
+               var getSupportedProp = function (names) {\r
+                       for (var i = 0; i < names.length; i += 1) {\r
+                               if (names[i] in helper.style) {\r
+                                       return names[i];\r
+                               }\r
+                       }\r
+               };\r
+               var props = {\r
+                       borderRadius: getSupportedProp(['borderRadius', 'MozBorderRadius', 'webkitBorderRadius']),\r
+                       boxShadow: getSupportedProp(['boxShadow', 'MozBoxShadow', 'webkitBoxShadow'])\r
+               };\r
+               return function (elm, prop, value) {\r
+                       switch (prop.toLowerCase()) {\r
+                       case 'opacity':\r
+                               var alphaOpacity = Math.round(parseFloat(value) * 100);\r
+                               elm.style.opacity = value;\r
+                               elm.style.filter = 'alpha(opacity=' + alphaOpacity + ')';\r
+                               break;\r
+                       default:\r
+                               elm.style[props[prop]] = value;\r
+                               break;\r
+                       }\r
+               };\r
+       })(),\r
+\r
+\r
+       setBorderRadius : function (elm, value) {\r
+               jsc.setStyle(elm, 'borderRadius', value || '0');\r
+       },\r
+\r
+\r
+       setBoxShadow : function (elm, value) {\r
+               jsc.setStyle(elm, 'boxShadow', value || 'none');\r
+       },\r
+\r
+\r
+       getElementPos : function (e, relativeToViewport) {\r
+               var x=0, y=0;\r
+               var rect = e.getBoundingClientRect();\r
+               x = rect.left;\r
+               y = rect.top;\r
+               if (!relativeToViewport) {\r
+                       var viewPos = jsc.getViewPos();\r
+                       x += viewPos[0];\r
+                       y += viewPos[1];\r
+               }\r
+               return [x, y];\r
+       },\r
+\r
+\r
+       getElementSize : function (e) {\r
+               return [e.offsetWidth, e.offsetHeight];\r
+       },\r
+\r
+\r
+       // get pointer's X/Y coordinates relative to viewport\r
+       getAbsPointerPos : function (e) {\r
+               if (!e) { e = window.event; }\r
+               var x = 0, y = 0;\r
+               if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {\r
+                       // touch devices\r
+                       x = e.changedTouches[0].clientX;\r
+                       y = e.changedTouches[0].clientY;\r
+               } else if (typeof e.clientX === 'number') {\r
+                       x = e.clientX;\r
+                       y = e.clientY;\r
+               }\r
+               return { x: x, y: y };\r
+       },\r
+\r
+\r
+       // get pointer's X/Y coordinates relative to target element\r
+       getRelPointerPos : function (e) {\r
+               if (!e) { e = window.event; }\r
+               var target = e.target || e.srcElement;\r
+               var targetRect = target.getBoundingClientRect();\r
+\r
+               var x = 0, y = 0;\r
+\r
+               var clientX = 0, clientY = 0;\r
+               if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {\r
+                       // touch devices\r
+                       clientX = e.changedTouches[0].clientX;\r
+                       clientY = e.changedTouches[0].clientY;\r
+               } else if (typeof e.clientX === 'number') {\r
+                       clientX = e.clientX;\r
+                       clientY = e.clientY;\r
+               }\r
+\r
+               x = clientX - targetRect.left;\r
+               y = clientY - targetRect.top;\r
+               return { x: x, y: y };\r
+       },\r
+\r
+\r
+       getViewPos : function () {\r
+               var doc = document.documentElement;\r
+               return [\r
+                       (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0),\r
+                       (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)\r
+               ];\r
+       },\r
+\r
+\r
+       getViewSize : function () {\r
+               var doc = document.documentElement;\r
+               return [\r
+                       (window.innerWidth || doc.clientWidth),\r
+                       (window.innerHeight || doc.clientHeight),\r
+               ];\r
+       },\r
+\r
+\r
+       redrawPosition : function () {\r
+\r
+               if (jsc.picker && jsc.picker.owner) {\r
+                       var thisObj = jsc.picker.owner;\r
+\r
+                       var tp, vp;\r
+\r
+                       if (thisObj.fixed) {\r
+                               // Fixed elements are positioned relative to viewport,\r
+                               // therefore we can ignore the scroll offset\r
+                               tp = jsc.getElementPos(thisObj.targetElement, true); // target pos\r
+                               vp = [0, 0]; // view pos\r
+                       } else {\r
+                               tp = jsc.getElementPos(thisObj.targetElement); // target pos\r
+                               vp = jsc.getViewPos(); // view pos\r
+                       }\r
+\r
+                       var ts = jsc.getElementSize(thisObj.targetElement); // target size\r
+                       var vs = jsc.getViewSize(); // view size\r
+                       var ps = jsc.getPickerOuterDims(thisObj); // picker size\r
+                       var a, b, c;\r
+                       switch (thisObj.position.toLowerCase()) {\r
+                               case 'left': a=1; b=0; c=-1; break;\r
+                               case 'right':a=1; b=0; c=1; break;\r
+                               case 'top':  a=0; b=1; c=-1; break;\r
+                               default:     a=0; b=1; c=1; break;\r
+                       }\r
+                       var l = (ts[b]+ps[b])/2;\r
+\r
+                       // compute picker position\r
+                       if (!thisObj.smartPosition) {\r
+                               var pp = [\r
+                                       tp[a],\r
+                                       tp[b]+ts[b]-l+l*c\r
+                               ];\r
+                       } else {\r
+                               var pp = [\r
+                                       -vp[a]+tp[a]+ps[a] > vs[a] ?\r
+                                               (-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :\r
+                                               tp[a],\r
+                                       -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?\r
+                                               (-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :\r
+                                               (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)\r
+                               ];\r
+                       }\r
+\r
+                       var x = pp[a];\r
+                       var y = pp[b];\r
+                       var positionValue = thisObj.fixed ? 'fixed' : 'absolute';\r
+                       var contractShadow =\r
+                               (pp[0] + ps[0] > tp[0] || pp[0] < tp[0] + ts[0]) &&\r
+                               (pp[1] + ps[1] < tp[1] + ts[1]);\r
+\r
+                       jsc._drawPosition(thisObj, x, y, positionValue, contractShadow);\r
+               }\r
+       },\r
+\r
+\r
+       _drawPosition : function (thisObj, x, y, positionValue, contractShadow) {\r
+               var vShadow = contractShadow ? 0 : thisObj.shadowBlur; // px\r
+\r
+               jsc.picker.wrap.style.position = positionValue;\r
+               jsc.picker.wrap.style.left = x + 'px';\r
+               jsc.picker.wrap.style.top = y + 'px';\r
+\r
+               jsc.setBoxShadow(\r
+                       jsc.picker.boxS,\r
+                       thisObj.shadow ?\r
+                               new jsc.BoxShadow(0, vShadow, thisObj.shadowBlur, 0, thisObj.shadowColor) :\r
+                               null);\r
+       },\r
+\r
+\r
+       getPickerDims : function (thisObj) {\r
+               var displaySlider = !!jsc.getSliderComponent(thisObj);\r
+               var dims = [\r
+                       2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.width +\r
+                               (displaySlider ? 2 * thisObj.insetWidth + jsc.getPadToSliderPadding(thisObj) + thisObj.sliderSize : 0),\r
+                       2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.height +\r
+                               (thisObj.closable ? 2 * thisObj.insetWidth + thisObj.padding + thisObj.buttonHeight : 0)\r
+               ];\r
+               return dims;\r
+       },\r
+\r
+\r
+       getPickerOuterDims : function (thisObj) {\r
+               var dims = jsc.getPickerDims(thisObj);\r
+               return [\r
+                       dims[0] + 2 * thisObj.borderWidth,\r
+                       dims[1] + 2 * thisObj.borderWidth\r
+               ];\r
+       },\r
+\r
+\r
+       getPadToSliderPadding : function (thisObj) {\r
+               return Math.max(thisObj.padding, 1.5 * (2 * thisObj.pointerBorderWidth + thisObj.pointerThickness));\r
+       },\r
+\r
+\r
+       getPadYComponent : function (thisObj) {\r
+               switch (thisObj.mode.charAt(1).toLowerCase()) {\r
+                       case 'v': return 'v'; break;\r
+               }\r
+               return 's';\r
+       },\r
+\r
+\r
+       getSliderComponent : function (thisObj) {\r
+               if (thisObj.mode.length > 2) {\r
+                       switch (thisObj.mode.charAt(2).toLowerCase()) {\r
+                               case 's': return 's'; break;\r
+                               case 'v': return 'v'; break;\r
+                       }\r
+               }\r
+               return null;\r
+       },\r
+\r
+\r
+       onDocumentMouseDown : function (e) {\r
+               if (!e) { e = window.event; }\r
+               var target = e.target || e.srcElement;\r
+\r
+               if (target._jscLinkedInstance) {\r
+                       if (target._jscLinkedInstance.showOnClick) {\r
+                               target._jscLinkedInstance.show();\r
+                       }\r
+               } else if (target._jscControlName) {\r
+                       jsc.onControlPointerStart(e, target, target._jscControlName, 'mouse');\r
+               } else {\r
+                       // Mouse is outside the picker controls -> hide the color picker!\r
+                       if (jsc.picker && jsc.picker.owner) {\r
+                               jsc.picker.owner.hide();\r
+                       }\r
+               }\r
+       },\r
+\r
+\r
+       onDocumentTouchStart : function (e) {\r
+               if (!e) { e = window.event; }\r
+               var target = e.target || e.srcElement;\r
+\r
+               if (target._jscLinkedInstance) {\r
+                       if (target._jscLinkedInstance.showOnClick) {\r
+                               target._jscLinkedInstance.show();\r
+                       }\r
+               } else if (target._jscControlName) {\r
+                       jsc.onControlPointerStart(e, target, target._jscControlName, 'touch');\r
+               } else {\r
+                       if (jsc.picker && jsc.picker.owner) {\r
+                               jsc.picker.owner.hide();\r
+                       }\r
+               }\r
+       },\r
+\r
+\r
+       onWindowResize : function (e) {\r
+               jsc.redrawPosition();\r
+       },\r
+\r
+\r
+       onParentScroll : function (e) {\r
+               // hide the picker when one of the parent elements is scrolled\r
+               if (jsc.picker && jsc.picker.owner) {\r
+                       jsc.picker.owner.hide();\r
+               }\r
+       },\r
+\r
+\r
+       _pointerMoveEvent : {\r
+               mouse: 'mousemove',\r
+               touch: 'touchmove'\r
+       },\r
+       _pointerEndEvent : {\r
+               mouse: 'mouseup',\r
+               touch: 'touchend'\r
+       },\r
+\r
+\r
+       _pointerOrigin : null,\r
+       _capturedTarget : null,\r
+\r
+\r
+       onControlPointerStart : function (e, target, controlName, pointerType) {\r
+               var thisObj = target._jscInstance;\r
+\r
+               jsc.preventDefault(e);\r
+               jsc.captureTarget(target);\r
+\r
+               var registerDragEvents = function (doc, offset) {\r
+                       jsc.attachGroupEvent('drag', doc, jsc._pointerMoveEvent[pointerType],\r
+                               jsc.onDocumentPointerMove(e, target, controlName, pointerType, offset));\r
+                       jsc.attachGroupEvent('drag', doc, jsc._pointerEndEvent[pointerType],\r
+                               jsc.onDocumentPointerEnd(e, target, controlName, pointerType));\r
+               };\r
+\r
+               registerDragEvents(document, [0, 0]);\r
+\r
+               if (window.parent && window.frameElement) {\r
+                       var rect = window.frameElement.getBoundingClientRect();\r
+                       var ofs = [-rect.left, -rect.top];\r
+                       registerDragEvents(window.parent.window.document, ofs);\r
+               }\r
+\r
+               var abs = jsc.getAbsPointerPos(e);\r
+               var rel = jsc.getRelPointerPos(e);\r
+               jsc._pointerOrigin = {\r
+                       x: abs.x - rel.x,\r
+                       y: abs.y - rel.y\r
+               };\r
+\r
+               switch (controlName) {\r
+               case 'pad':\r
+                       // if the slider is at the bottom, move it up\r
+                       switch (jsc.getSliderComponent(thisObj)) {\r
+                       case 's': if (thisObj.hsv[1] === 0) { thisObj.fromHSV(null, 100, null); }; break;\r
+                       case 'v': if (thisObj.hsv[2] === 0) { thisObj.fromHSV(null, null, 100); }; break;\r
+                       }\r
+                       jsc.setPad(thisObj, e, 0, 0);\r
+                       break;\r
+\r
+               case 'sld':\r
+                       jsc.setSld(thisObj, e, 0);\r
+                       break;\r
+               }\r
+\r
+               jsc.dispatchFineChange(thisObj);\r
+       },\r
+\r
+\r
+       onDocumentPointerMove : function (e, target, controlName, pointerType, offset) {\r
+               return function (e) {\r
+                       var thisObj = target._jscInstance;\r
+                       switch (controlName) {\r
+                       case 'pad':\r
+                               if (!e) { e = window.event; }\r
+                               jsc.setPad(thisObj, e, offset[0], offset[1]);\r
+                               jsc.dispatchFineChange(thisObj);\r
+                               break;\r
+\r
+                       case 'sld':\r
+                               if (!e) { e = window.event; }\r
+                               jsc.setSld(thisObj, e, offset[1]);\r
+                               jsc.dispatchFineChange(thisObj);\r
+                               break;\r
+                       }\r
+               }\r
+       },\r
+\r
+\r
+       onDocumentPointerEnd : function (e, target, controlName, pointerType) {\r
+               return function (e) {\r
+                       var thisObj = target._jscInstance;\r
+                       jsc.detachGroupEvents('drag');\r
+                       jsc.releaseTarget();\r
+                       // Always dispatch changes after detaching outstanding mouse handlers,\r
+                       // in case some user interaction will occur in user's onchange callback\r
+                       // that would intrude with current mouse events\r
+                       jsc.dispatchChange(thisObj);\r
+               };\r
+       },\r
+\r
+\r
+       dispatchChange : function (thisObj) {\r
+               if (thisObj.valueElement) {\r
+                       if (jsc.isElementType(thisObj.valueElement, 'input')) {\r
+                               jsc.fireEvent(thisObj.valueElement, 'change');\r
+                       }\r
+               }\r
+       },\r
+\r
+\r
+       dispatchFineChange : function (thisObj) {\r
+               if (thisObj.onFineChange) {\r
+                       var callback;\r
+                       if (typeof thisObj.onFineChange === 'string') {\r
+                               callback = new Function (thisObj.onFineChange);\r
+                       } else {\r
+                               callback = thisObj.onFineChange;\r
+                       }\r
+                       callback.call(thisObj);\r
+               }\r
+       },\r
+\r
+\r
+       setPad : function (thisObj, e, ofsX, ofsY) {\r
+               var pointerAbs = jsc.getAbsPointerPos(e);\r
+               var x = ofsX + pointerAbs.x - jsc._pointerOrigin.x - thisObj.padding - thisObj.insetWidth;\r
+               var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;\r
+\r
+               var xVal = x * (360 / (thisObj.width - 1));\r
+               var yVal = 100 - (y * (100 / (thisObj.height - 1)));\r
+\r
+               switch (jsc.getPadYComponent(thisObj)) {\r
+               case 's': thisObj.fromHSV(xVal, yVal, null, jsc.leaveSld); break;\r
+               case 'v': thisObj.fromHSV(xVal, null, yVal, jsc.leaveSld); break;\r
+               }\r
+       },\r
+\r
+\r
+       setSld : function (thisObj, e, ofsY) {\r
+               var pointerAbs = jsc.getAbsPointerPos(e);\r
+               var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;\r
+\r
+               var yVal = 100 - (y * (100 / (thisObj.height - 1)));\r
+\r
+               switch (jsc.getSliderComponent(thisObj)) {\r
+               case 's': thisObj.fromHSV(null, yVal, null, jsc.leavePad); break;\r
+               case 'v': thisObj.fromHSV(null, null, yVal, jsc.leavePad); break;\r
+               }\r
+       },\r
+\r
+\r
+       _vmlNS : 'jsc_vml_',\r
+       _vmlCSS : 'jsc_vml_css_',\r
+       _vmlReady : false,\r
+\r
+\r
+       initVML : function () {\r
+               if (!jsc._vmlReady) {\r
+                       // init VML namespace\r
+                       var doc = document;\r
+                       if (!doc.namespaces[jsc._vmlNS]) {\r
+                               doc.namespaces.add(jsc._vmlNS, 'urn:schemas-microsoft-com:vml');\r
+                       }\r
+                       if (!doc.styleSheets[jsc._vmlCSS]) {\r
+                               var tags = ['shape', 'shapetype', 'group', 'background', 'path', 'formulas', 'handles', 'fill', 'stroke', 'shadow', 'textbox', 'textpath', 'imagedata', 'line', 'polyline', 'curve', 'rect', 'roundrect', 'oval', 'arc', 'image'];\r
+                               var ss = doc.createStyleSheet();\r
+                               ss.owningElement.id = jsc._vmlCSS;\r
+                               for (var i = 0; i < tags.length; i += 1) {\r
+                                       ss.addRule(jsc._vmlNS + '\\:' + tags[i], 'behavior:url(#default#VML);');\r
+                               }\r
+                       }\r
+                       jsc._vmlReady = true;\r
+               }\r
+       },\r
+\r
+\r
+       createPalette : function () {\r
+\r
+               var paletteObj = {\r
+                       elm: null,\r
+                       draw: null\r
+               };\r
+\r
+               if (jsc.isCanvasSupported) {\r
+                       // Canvas implementation for modern browsers\r
+\r
+                       var canvas = document.createElement('canvas');\r
+                       var ctx = canvas.getContext('2d');\r
+\r
+                       var drawFunc = function (width, height, type) {\r
+                               canvas.width = width;\r
+                               canvas.height = height;\r
+\r
+                               ctx.clearRect(0, 0, canvas.width, canvas.height);\r
+\r
+                               var hGrad = ctx.createLinearGradient(0, 0, canvas.width, 0);\r
+                               hGrad.addColorStop(0 / 6, '#F00');\r
+                               hGrad.addColorStop(1 / 6, '#FF0');\r
+                               hGrad.addColorStop(2 / 6, '#0F0');\r
+                               hGrad.addColorStop(3 / 6, '#0FF');\r
+                               hGrad.addColorStop(4 / 6, '#00F');\r
+                               hGrad.addColorStop(5 / 6, '#F0F');\r
+                               hGrad.addColorStop(6 / 6, '#F00');\r
+\r
+                               ctx.fillStyle = hGrad;\r
+                               ctx.fillRect(0, 0, canvas.width, canvas.height);\r
+\r
+                               var vGrad = ctx.createLinearGradient(0, 0, 0, canvas.height);\r
+                               switch (type.toLowerCase()) {\r
+                               case 's':\r
+                                       vGrad.addColorStop(0, 'rgba(255,255,255,0)');\r
+                                       vGrad.addColorStop(1, 'rgba(255,255,255,1)');\r
+                                       break;\r
+                               case 'v':\r
+                                       vGrad.addColorStop(0, 'rgba(0,0,0,0)');\r
+                                       vGrad.addColorStop(1, 'rgba(0,0,0,1)');\r
+                                       break;\r
+                               }\r
+                               ctx.fillStyle = vGrad;\r
+                               ctx.fillRect(0, 0, canvas.width, canvas.height);\r
+                       };\r
+\r
+                       paletteObj.elm = canvas;\r
+                       paletteObj.draw = drawFunc;\r
+\r
+               } else {\r
+                       // VML fallback for IE 7 and 8\r
+\r
+                       jsc.initVML();\r
+\r
+                       var vmlContainer = document.createElement('div');\r
+                       vmlContainer.style.position = 'relative';\r
+                       vmlContainer.style.overflow = 'hidden';\r
+\r
+                       var hGrad = document.createElement(jsc._vmlNS + ':fill');\r
+                       hGrad.type = 'gradient';\r
+                       hGrad.method = 'linear';\r
+                       hGrad.angle = '90';\r
+                       hGrad.colors = '16.67% #F0F, 33.33% #00F, 50% #0FF, 66.67% #0F0, 83.33% #FF0'\r
+\r
+                       var hRect = document.createElement(jsc._vmlNS + ':rect');\r
+                       hRect.style.position = 'absolute';\r
+                       hRect.style.left = -1 + 'px';\r
+                       hRect.style.top = -1 + 'px';\r
+                       hRect.stroked = false;\r
+                       hRect.appendChild(hGrad);\r
+                       vmlContainer.appendChild(hRect);\r
+\r
+                       var vGrad = document.createElement(jsc._vmlNS + ':fill');\r
+                       vGrad.type = 'gradient';\r
+                       vGrad.method = 'linear';\r
+                       vGrad.angle = '180';\r
+                       vGrad.opacity = '0';\r
+\r
+                       var vRect = document.createElement(jsc._vmlNS + ':rect');\r
+                       vRect.style.position = 'absolute';\r
+                       vRect.style.left = -1 + 'px';\r
+                       vRect.style.top = -1 + 'px';\r
+                       vRect.stroked = false;\r
+                       vRect.appendChild(vGrad);\r
+                       vmlContainer.appendChild(vRect);\r
+\r
+                       var drawFunc = function (width, height, type) {\r
+                               vmlContainer.style.width = width + 'px';\r
+                               vmlContainer.style.height = height + 'px';\r
+\r
+                               hRect.style.width =\r
+                               vRect.style.width =\r
+                                       (width + 1) + 'px';\r
+                               hRect.style.height =\r
+                               vRect.style.height =\r
+                                       (height + 1) + 'px';\r
+\r
+                               // Colors must be specified during every redraw, otherwise IE won't display\r
+                               // a full gradient during a subsequential redraw\r
+                               hGrad.color = '#F00';\r
+                               hGrad.color2 = '#F00';\r
+\r
+                               switch (type.toLowerCase()) {\r
+                               case 's':\r
+                                       vGrad.color = vGrad.color2 = '#FFF';\r
+                                       break;\r
+                               case 'v':\r
+                                       vGrad.color = vGrad.color2 = '#000';\r
+                                       break;\r
+                               }\r
+                       };\r
+                       \r
+                       paletteObj.elm = vmlContainer;\r
+                       paletteObj.draw = drawFunc;\r
+               }\r
+\r
+               return paletteObj;\r
+       },\r
+\r
+\r
+       createSliderGradient : function () {\r
+\r
+               var sliderObj = {\r
+                       elm: null,\r
+                       draw: null\r
+               };\r
+\r
+               if (jsc.isCanvasSupported) {\r
+                       // Canvas implementation for modern browsers\r
+\r
+                       var canvas = document.createElement('canvas');\r
+                       var ctx = canvas.getContext('2d');\r
+\r
+                       var drawFunc = function (width, height, color1, color2) {\r
+                               canvas.width = width;\r
+                               canvas.height = height;\r
+\r
+                               ctx.clearRect(0, 0, canvas.width, canvas.height);\r
+\r
+                               var grad = ctx.createLinearGradient(0, 0, 0, canvas.height);\r
+                               grad.addColorStop(0, color1);\r
+                               grad.addColorStop(1, color2);\r
+\r
+                               ctx.fillStyle = grad;\r
+                               ctx.fillRect(0, 0, canvas.width, canvas.height);\r
+                       };\r
+\r
+                       sliderObj.elm = canvas;\r
+                       sliderObj.draw = drawFunc;\r
+\r
+               } else {\r
+                       // VML fallback for IE 7 and 8\r
+\r
+                       jsc.initVML();\r
+\r
+                       var vmlContainer = document.createElement('div');\r
+                       vmlContainer.style.position = 'relative';\r
+                       vmlContainer.style.overflow = 'hidden';\r
+\r
+                       var grad = document.createElement(jsc._vmlNS + ':fill');\r
+                       grad.type = 'gradient';\r
+                       grad.method = 'linear';\r
+                       grad.angle = '180';\r
+\r
+                       var rect = document.createElement(jsc._vmlNS + ':rect');\r
+                       rect.style.position = 'absolute';\r
+                       rect.style.left = -1 + 'px';\r
+                       rect.style.top = -1 + 'px';\r
+                       rect.stroked = false;\r
+                       rect.appendChild(grad);\r
+                       vmlContainer.appendChild(rect);\r
+\r
+                       var drawFunc = function (width, height, color1, color2) {\r
+                               vmlContainer.style.width = width + 'px';\r
+                               vmlContainer.style.height = height + 'px';\r
+\r
+                               rect.style.width = (width + 1) + 'px';\r
+                               rect.style.height = (height + 1) + 'px';\r
+\r
+                               grad.color = color1;\r
+                               grad.color2 = color2;\r
+                       };\r
+                       \r
+                       sliderObj.elm = vmlContainer;\r
+                       sliderObj.draw = drawFunc;\r
+               }\r
+\r
+               return sliderObj;\r
+       },\r
+\r
+\r
+       leaveValue : 1<<0,\r
+       leaveStyle : 1<<1,\r
+       leavePad : 1<<2,\r
+       leaveSld : 1<<3,\r
+\r
+\r
+       BoxShadow : (function () {\r
+               var BoxShadow = function (hShadow, vShadow, blur, spread, color, inset) {\r
+                       this.hShadow = hShadow;\r
+                       this.vShadow = vShadow;\r
+                       this.blur = blur;\r
+                       this.spread = spread;\r
+                       this.color = color;\r
+                       this.inset = !!inset;\r
+               };\r
+\r
+               BoxShadow.prototype.toString = function () {\r
+                       var vals = [\r
+                               Math.round(this.hShadow) + 'px',\r
+                               Math.round(this.vShadow) + 'px',\r
+                               Math.round(this.blur) + 'px',\r
+                               Math.round(this.spread) + 'px',\r
+                               this.color\r
+                       ];\r
+                       if (this.inset) {\r
+                               vals.push('inset');\r
+                       }\r
+                       return vals.join(' ');\r
+               };\r
+\r
+               return BoxShadow;\r
+       })(),\r
+\r
+\r
+       //\r
+       // Usage:\r
+       // var myColor = new jscolor(<targetElement> [, <options>])\r
+       //\r
+\r
+       jscolor : function (targetElement, options) {\r
+\r
+               // General options\r
+               //\r
+               this.value = null; // initial HEX color. To change it later, use methods fromString(), fromHSV() and fromRGB()\r
+               this.valueElement = targetElement; // element that will be used to display and input the color code\r
+               this.styleElement = targetElement; // element that will preview the picked color using CSS backgroundColor\r
+               this.required = true; // whether the associated text <input> can be left empty\r
+               this.refine = true; // whether to refine the entered color code (e.g. uppercase it and remove whitespace)\r
+               this.hash = false; // whether to prefix the HEX color code with # symbol\r
+               this.uppercase = true; // whether to show the color code in upper case\r
+               this.onFineChange = null; // called instantly every time the color changes (value can be either a function or a string with javascript code)\r
+               this.activeClass = 'jscolor-active'; // class to be set to the target element when a picker window is open on it\r
+               this.overwriteImportant = false; // whether to overwrite colors of styleElement using !important\r
+               this.minS = 0; // min allowed saturation (0 - 100)\r
+               this.maxS = 100; // max allowed saturation (0 - 100)\r
+               this.minV = 0; // min allowed value (brightness) (0 - 100)\r
+               this.maxV = 100; // max allowed value (brightness) (0 - 100)\r
+\r
+               // Accessing the picked color\r
+               //\r
+               this.hsv = [0, 0, 100]; // read-only  [0-360, 0-100, 0-100]\r
+               this.rgb = [255, 255, 255]; // read-only  [0-255, 0-255, 0-255]\r
+\r
+               // Color Picker options\r
+               //\r
+               this.width = 181; // width of color palette (in px)\r
+               this.height = 101; // height of color palette (in px)\r
+               this.showOnClick = true; // whether to display the color picker when user clicks on its target element\r
+               this.mode = 'HSV'; // HSV | HVS | HS | HV - layout of the color picker controls\r
+               this.position = 'bottom'; // left | right | top | bottom - position relative to the target element\r
+               this.smartPosition = true; // automatically change picker position when there is not enough space for it\r
+               this.sliderSize = 16; // px\r
+               this.crossSize = 8; // px\r
+               this.closable = false; // whether to display the Close button\r
+               this.closeText = 'Close';\r
+               this.buttonColor = '#000000'; // CSS color\r
+               this.buttonHeight = 18; // px\r
+               this.padding = 12; // px\r
+               this.backgroundColor = '#FFFFFF'; // CSS color\r
+               this.borderWidth = 1; // px\r
+               this.borderColor = '#BBBBBB'; // CSS color\r
+               this.borderRadius = 8; // px\r
+               this.insetWidth = 1; // px\r
+               this.insetColor = '#BBBBBB'; // CSS color\r
+               this.shadow = true; // whether to display shadow\r
+               this.shadowBlur = 15; // px\r
+               this.shadowColor = 'rgba(0,0,0,0.2)'; // CSS color\r
+               this.pointerColor = '#4C4C4C'; // px\r
+               this.pointerBorderColor = '#FFFFFF'; // px\r
+        this.pointerBorderWidth = 1; // px\r
+        this.pointerThickness = 2; // px\r
+               this.zIndex = 1000;\r
+               this.container = null; // where to append the color picker (BODY element by default)\r
+\r
+\r
+               for (var opt in options) {\r
+                       if (options.hasOwnProperty(opt)) {\r
+                               this[opt] = options[opt];\r
+                       }\r
+               }\r
+\r
+\r
+               this.hide = function () {\r
+                       if (isPickerOwner()) {\r
+                               detachPicker();\r
+                       }\r
+               };\r
+\r
+\r
+               this.show = function () {\r
+                       drawPicker();\r
+               };\r
+\r
+\r
+               this.redraw = function () {\r
+                       if (isPickerOwner()) {\r
+                               drawPicker();\r
+                       }\r
+               };\r
+\r
+\r
+               this.importColor = function () {\r
+                       if (!this.valueElement) {\r
+                               this.exportColor();\r
+                       } else {\r
+                               if (jsc.isElementType(this.valueElement, 'input')) {\r
+                                       if (!this.refine) {\r
+                                               if (!this.fromString(this.valueElement.value, jsc.leaveValue)) {\r
+                                                       if (this.styleElement) {\r
+                                                               this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;\r
+                                                               this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;\r
+                                                               this.styleElement.style.color = this.styleElement._jscOrigStyle.color;\r
+                                                       }\r
+                                                       this.exportColor(jsc.leaveValue | jsc.leaveStyle);\r
+                                               }\r
+                                       } else if (!this.required && /^\s*$/.test(this.valueElement.value)) {\r
+                                               this.valueElement.value = '';\r
+                                               if (this.styleElement) {\r
+                                                       this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;\r
+                                                       this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;\r
+                                                       this.styleElement.style.color = this.styleElement._jscOrigStyle.color;\r
+                                               }\r
+                                               this.exportColor(jsc.leaveValue | jsc.leaveStyle);\r
+\r
+                                       } else if (this.fromString(this.valueElement.value)) {\r
+                                               // managed to import color successfully from the value -> OK, don't do anything\r
+                                       } else {\r
+                                               this.exportColor();\r
+                                       }\r
+                               } else {\r
+                                       // not an input element -> doesn't have any value\r
+                                       this.exportColor();\r
+                               }\r
+                       }\r
+               };\r
+\r
+\r
+               this.exportColor = function (flags) {\r
+                       if (!(flags & jsc.leaveValue) && this.valueElement) {\r
+                               var value = this.toString();\r
+                               if (this.uppercase) { value = value.toUpperCase(); }\r
+                               if (this.hash) { value = '#' + value; }\r
+\r
+                               if (jsc.isElementType(this.valueElement, 'input')) {\r
+                                       this.valueElement.value = value;\r
+                               } else {\r
+                                       this.valueElement.innerHTML = value;\r
+                               }\r
+                       }\r
+                       if (!(flags & jsc.leaveStyle)) {\r
+                               if (this.styleElement) {\r
+                                       var bgColor = '#' + this.toString();\r
+                                       var fgColor = this.isLight() ? '#000' : '#FFF';\r
+\r
+                                       this.styleElement.style.backgroundImage = 'none';\r
+                                       this.styleElement.style.backgroundColor = bgColor;\r
+                                       this.styleElement.style.color = fgColor;\r
+\r
+                                       if (this.overwriteImportant) {\r
+                                               this.styleElement.setAttribute('style',\r
+                                                       'background: ' + bgColor + ' !important; ' +\r
+                                                       'color: ' + fgColor + ' !important;'\r
+                                               );\r
+                                       }\r
+                               }\r
+                       }\r
+                       if (!(flags & jsc.leavePad) && isPickerOwner()) {\r
+                               redrawPad();\r
+                       }\r
+                       if (!(flags & jsc.leaveSld) && isPickerOwner()) {\r
+                               redrawSld();\r
+                       }\r
+               };\r
+\r
+\r
+               // h: 0-360\r
+               // s: 0-100\r
+               // v: 0-100\r
+               //\r
+               this.fromHSV = function (h, s, v, flags) { // null = don't change\r
+                       if (h !== null) {\r
+                               if (isNaN(h)) { return false; }\r
+                               h = Math.max(0, Math.min(360, h));\r
+                       }\r
+                       if (s !== null) {\r
+                               if (isNaN(s)) { return false; }\r
+                               s = Math.max(0, Math.min(100, this.maxS, s), this.minS);\r
+                       }\r
+                       if (v !== null) {\r
+                               if (isNaN(v)) { return false; }\r
+                               v = Math.max(0, Math.min(100, this.maxV, v), this.minV);\r
+                       }\r
+\r
+                       this.rgb = HSV_RGB(\r
+                               h===null ? this.hsv[0] : (this.hsv[0]=h),\r
+                               s===null ? this.hsv[1] : (this.hsv[1]=s),\r
+                               v===null ? this.hsv[2] : (this.hsv[2]=v)\r
+                       );\r
+\r
+                       this.exportColor(flags);\r
+               };\r
+\r
+\r
+               // r: 0-255\r
+               // g: 0-255\r
+               // b: 0-255\r
+               //\r
+               this.fromRGB = function (r, g, b, flags) { // null = don't change\r
+                       if (r !== null) {\r
+                               if (isNaN(r)) { return false; }\r
+                               r = Math.max(0, Math.min(255, r));\r
+                       }\r
+                       if (g !== null) {\r
+                               if (isNaN(g)) { return false; }\r
+                               g = Math.max(0, Math.min(255, g));\r
+                       }\r
+                       if (b !== null) {\r
+                               if (isNaN(b)) { return false; }\r
+                               b = Math.max(0, Math.min(255, b));\r
+                       }\r
+\r
+                       var hsv = RGB_HSV(\r
+                               r===null ? this.rgb[0] : r,\r
+                               g===null ? this.rgb[1] : g,\r
+                               b===null ? this.rgb[2] : b\r
+                       );\r
+                       if (hsv[0] !== null) {\r
+                               this.hsv[0] = Math.max(0, Math.min(360, hsv[0]));\r
+                       }\r
+                       if (hsv[2] !== 0) {\r
+                               this.hsv[1] = hsv[1]===null ? null : Math.max(0, this.minS, Math.min(100, this.maxS, hsv[1]));\r
+                       }\r
+                       this.hsv[2] = hsv[2]===null ? null : Math.max(0, this.minV, Math.min(100, this.maxV, hsv[2]));\r
+\r
+                       // update RGB according to final HSV, as some values might be trimmed\r
+                       var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);\r
+                       this.rgb[0] = rgb[0];\r
+                       this.rgb[1] = rgb[1];\r
+                       this.rgb[2] = rgb[2];\r
+\r
+                       this.exportColor(flags);\r
+               };\r
+\r
+\r
+               this.fromString = function (str, flags) {\r
+                       var m;\r
+                       if (m = str.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i)) {\r
+                               // HEX notation\r
+                               //\r
+\r
+                               if (m[1].length === 6) {\r
+                                       // 6-char notation\r
+                                       this.fromRGB(\r
+                                               parseInt(m[1].substr(0,2),16),\r
+                                               parseInt(m[1].substr(2,2),16),\r
+                                               parseInt(m[1].substr(4,2),16),\r
+                                               flags\r
+                                       );\r
+                               } else {\r
+                                       // 3-char notation\r
+                                       this.fromRGB(\r
+                                               parseInt(m[1].charAt(0) + m[1].charAt(0),16),\r
+                                               parseInt(m[1].charAt(1) + m[1].charAt(1),16),\r
+                                               parseInt(m[1].charAt(2) + m[1].charAt(2),16),\r
+                                               flags\r
+                                       );\r
+                               }\r
+                               return true;\r
+\r
+                       } else if (m = str.match(/^\W*rgba?\(([^)]*)\)\W*$/i)) {\r
+                               var params = m[1].split(',');\r
+                               var re = /^\s*(\d*)(\.\d+)?\s*$/;\r
+                               var mR, mG, mB;\r
+                               if (\r
+                                       params.length >= 3 &&\r
+                                       (mR = params[0].match(re)) &&\r
+                                       (mG = params[1].match(re)) &&\r
+                                       (mB = params[2].match(re))\r
+                               ) {\r
+                                       var r = parseFloat((mR[1] || '0') + (mR[2] || ''));\r
+                                       var g = parseFloat((mG[1] || '0') + (mG[2] || ''));\r
+                                       var b = parseFloat((mB[1] || '0') + (mB[2] || ''));\r
+                                       this.fromRGB(r, g, b, flags);\r
+                                       return true;\r
+                               }\r
+                       }\r
+                       return false;\r
+               };\r
+\r
+\r
+               this.toString = function () {\r
+                       return (\r
+                               (0x100 | Math.round(this.rgb[0])).toString(16).substr(1) +\r
+                               (0x100 | Math.round(this.rgb[1])).toString(16).substr(1) +\r
+                               (0x100 | Math.round(this.rgb[2])).toString(16).substr(1)\r
+                       );\r
+               };\r
+\r
+\r
+               this.toHEXString = function () {\r
+                       return '#' + this.toString().toUpperCase();\r
+               };\r
+\r
+\r
+               this.toRGBString = function () {\r
+                       return ('rgb(' +\r
+                               Math.round(this.rgb[0]) + ',' +\r
+                               Math.round(this.rgb[1]) + ',' +\r
+                               Math.round(this.rgb[2]) + ')'\r
+                       );\r
+               };\r
+\r
+\r
+               this.isLight = function () {\r
+                       return (\r
+                               0.213 * this.rgb[0] +\r
+                               0.715 * this.rgb[1] +\r
+                               0.072 * this.rgb[2] >\r
+                               255 / 2\r
+                       );\r
+               };\r
+\r
+\r
+               this._processParentElementsInDOM = function () {\r
+                       if (this._linkedElementsProcessed) { return; }\r
+                       this._linkedElementsProcessed = true;\r
+\r
+                       var elm = this.targetElement;\r
+                       do {\r
+                               // If the target element or one of its parent nodes has fixed position,\r
+                               // then use fixed positioning instead\r
+                               //\r
+                               // Note: In Firefox, getComputedStyle returns null in a hidden iframe,\r
+                               // that's why we need to check if the returned style object is non-empty\r
+                               var currStyle = jsc.getStyle(elm);\r
+                               if (currStyle && currStyle.position.toLowerCase() === 'fixed') {\r
+                                       this.fixed = true;\r
+                               }\r
+\r
+                               if (elm !== this.targetElement) {\r
+                                       // Ensure to attach onParentScroll only once to each parent element\r
+                                       // (multiple targetElements can share the same parent nodes)\r
+                                       //\r
+                                       // Note: It's not just offsetParents that can be scrollable,\r
+                                       // that's why we loop through all parent nodes\r
+                                       if (!elm._jscEventsAttached) {\r
+                                               jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);\r
+                                               elm._jscEventsAttached = true;\r
+                                       }\r
+                               }\r
+                       } while ((elm = elm.parentNode) && !jsc.isElementType(elm, 'body'));\r
+               };\r
+\r
+\r
+               // r: 0-255\r
+               // g: 0-255\r
+               // b: 0-255\r
+               //\r
+               // returns: [ 0-360, 0-100, 0-100 ]\r
+               //\r
+               function RGB_HSV (r, g, b) {\r
+                       r /= 255;\r
+                       g /= 255;\r
+                       b /= 255;\r
+                       var n = Math.min(Math.min(r,g),b);\r
+                       var v = Math.max(Math.max(r,g),b);\r
+                       var m = v - n;\r
+                       if (m === 0) { return [ null, 0, 100 * v ]; }\r
+                       var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);\r
+                       return [\r
+                               60 * (h===6?0:h),\r
+                               100 * (m/v),\r
+                               100 * v\r
+                       ];\r
+               }\r
+\r
+\r
+               // h: 0-360\r
+               // s: 0-100\r
+               // v: 0-100\r
+               //\r
+               // returns: [ 0-255, 0-255, 0-255 ]\r
+               //\r
+               function HSV_RGB (h, s, v) {\r
+                       var u = 255 * (v / 100);\r
+\r
+                       if (h === null) {\r
+                               return [ u, u, u ];\r
+                       }\r
+\r
+                       h /= 60;\r
+                       s /= 100;\r
+\r
+                       var i = Math.floor(h);\r
+                       var f = i%2 ? h-i : 1-(h-i);\r
+                       var m = u * (1 - s);\r
+                       var n = u * (1 - s * f);\r
+                       switch (i) {\r
+                               case 6:\r
+                               case 0: return [u,n,m];\r
+                               case 1: return [n,u,m];\r
+                               case 2: return [m,u,n];\r
+                               case 3: return [m,n,u];\r
+                               case 4: return [n,m,u];\r
+                               case 5: return [u,m,n];\r
+                       }\r
+               }\r
+\r
+\r
+               function detachPicker () {\r
+                       jsc.unsetClass(THIS.targetElement, THIS.activeClass);\r
+                       jsc.picker.wrap.parentNode.removeChild(jsc.picker.wrap);\r
+                       delete jsc.picker.owner;\r
+               }\r
+\r
+\r
+               function drawPicker () {\r
+\r
+                       // At this point, when drawing the picker, we know what the parent elements are\r
+                       // and we can do all related DOM operations, such as registering events on them\r
+                       // or checking their positioning\r
+                       THIS._processParentElementsInDOM();\r
+\r
+                       if (!jsc.picker) {\r
+                               jsc.picker = {\r
+                                       owner: null,\r
+                                       wrap : document.createElement('div'),\r
+                                       box : document.createElement('div'),\r
+                                       boxS : document.createElement('div'), // shadow area\r
+                                       boxB : document.createElement('div'), // border\r
+                                       pad : document.createElement('div'),\r
+                                       padB : document.createElement('div'), // border\r
+                                       padM : document.createElement('div'), // mouse/touch area\r
+                                       padPal : jsc.createPalette(),\r
+                                       cross : document.createElement('div'),\r
+                                       crossBY : document.createElement('div'), // border Y\r
+                                       crossBX : document.createElement('div'), // border X\r
+                                       crossLY : document.createElement('div'), // line Y\r
+                                       crossLX : document.createElement('div'), // line X\r
+                                       sld : document.createElement('div'),\r
+                                       sldB : document.createElement('div'), // border\r
+                                       sldM : document.createElement('div'), // mouse/touch area\r
+                                       sldGrad : jsc.createSliderGradient(),\r
+                                       sldPtrS : document.createElement('div'), // slider pointer spacer\r
+                                       sldPtrIB : document.createElement('div'), // slider pointer inner border\r
+                                       sldPtrMB : document.createElement('div'), // slider pointer middle border\r
+                                       sldPtrOB : document.createElement('div'), // slider pointer outer border\r
+                                       btn : document.createElement('div'),\r
+                                       btnT : document.createElement('span') // text\r
+                               };\r
+\r
+                               jsc.picker.pad.appendChild(jsc.picker.padPal.elm);\r
+                               jsc.picker.padB.appendChild(jsc.picker.pad);\r
+                               jsc.picker.cross.appendChild(jsc.picker.crossBY);\r
+                               jsc.picker.cross.appendChild(jsc.picker.crossBX);\r
+                               jsc.picker.cross.appendChild(jsc.picker.crossLY);\r
+                               jsc.picker.cross.appendChild(jsc.picker.crossLX);\r
+                               jsc.picker.padB.appendChild(jsc.picker.cross);\r
+                               jsc.picker.box.appendChild(jsc.picker.padB);\r
+                               jsc.picker.box.appendChild(jsc.picker.padM);\r
+\r
+                               jsc.picker.sld.appendChild(jsc.picker.sldGrad.elm);\r
+                               jsc.picker.sldB.appendChild(jsc.picker.sld);\r
+                               jsc.picker.sldB.appendChild(jsc.picker.sldPtrOB);\r
+                               jsc.picker.sldPtrOB.appendChild(jsc.picker.sldPtrMB);\r
+                               jsc.picker.sldPtrMB.appendChild(jsc.picker.sldPtrIB);\r
+                               jsc.picker.sldPtrIB.appendChild(jsc.picker.sldPtrS);\r
+                               jsc.picker.box.appendChild(jsc.picker.sldB);\r
+                               jsc.picker.box.appendChild(jsc.picker.sldM);\r
+\r
+                               jsc.picker.btn.appendChild(jsc.picker.btnT);\r
+                               jsc.picker.box.appendChild(jsc.picker.btn);\r
+\r
+                               jsc.picker.boxB.appendChild(jsc.picker.box);\r
+                               jsc.picker.wrap.appendChild(jsc.picker.boxS);\r
+                               jsc.picker.wrap.appendChild(jsc.picker.boxB);\r
+                       }\r
+\r
+                       var p = jsc.picker;\r
+\r
+                       var displaySlider = !!jsc.getSliderComponent(THIS);\r
+                       var dims = jsc.getPickerDims(THIS);\r
+                       var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);\r
+                       var padToSliderPadding = jsc.getPadToSliderPadding(THIS);\r
+                       var borderRadius = Math.min(\r
+                               THIS.borderRadius,\r
+                               Math.round(THIS.padding * Math.PI)); // px\r
+                       var padCursor = 'crosshair';\r
+\r
+                       // wrap\r
+                       p.wrap.style.clear = 'both';\r
+                       p.wrap.style.width = (dims[0] + 2 * THIS.borderWidth) + 'px';\r
+                       p.wrap.style.height = (dims[1] + 2 * THIS.borderWidth) + 'px';\r
+                       p.wrap.style.zIndex = THIS.zIndex;\r
+\r
+                       // picker\r
+                       p.box.style.width = dims[0] + 'px';\r
+                       p.box.style.height = dims[1] + 'px';\r
+\r
+                       p.boxS.style.position = 'absolute';\r
+                       p.boxS.style.left = '0';\r
+                       p.boxS.style.top = '0';\r
+                       p.boxS.style.width = '100%';\r
+                       p.boxS.style.height = '100%';\r
+                       jsc.setBorderRadius(p.boxS, borderRadius + 'px');\r
+\r
+                       // picker border\r
+                       p.boxB.style.position = 'relative';\r
+                       p.boxB.style.border = THIS.borderWidth + 'px solid';\r
+                       p.boxB.style.borderColor = THIS.borderColor;\r
+                       p.boxB.style.background = THIS.backgroundColor;\r
+                       jsc.setBorderRadius(p.boxB, borderRadius + 'px');\r
+\r
+                       // IE hack:\r
+                       // If the element is transparent, IE will trigger the event on the elements under it,\r
+                       // e.g. on Canvas or on elements with border\r
+                       p.padM.style.background =\r
+                       p.sldM.style.background =\r
+                               '#FFF';\r
+                       jsc.setStyle(p.padM, 'opacity', '0');\r
+                       jsc.setStyle(p.sldM, 'opacity', '0');\r
+\r
+                       // pad\r
+                       p.pad.style.position = 'relative';\r
+                       p.pad.style.width = THIS.width + 'px';\r
+                       p.pad.style.height = THIS.height + 'px';\r
+\r
+                       // pad palettes (HSV and HVS)\r
+                       p.padPal.draw(THIS.width, THIS.height, jsc.getPadYComponent(THIS));\r
+\r
+                       // pad border\r
+                       p.padB.style.position = 'absolute';\r
+                       p.padB.style.left = THIS.padding + 'px';\r
+                       p.padB.style.top = THIS.padding + 'px';\r
+                       p.padB.style.border = THIS.insetWidth + 'px solid';\r
+                       p.padB.style.borderColor = THIS.insetColor;\r
+\r
+                       // pad mouse area\r
+                       p.padM._jscInstance = THIS;\r
+                       p.padM._jscControlName = 'pad';\r
+                       p.padM.style.position = 'absolute';\r
+                       p.padM.style.left = '0';\r
+                       p.padM.style.top = '0';\r
+                       p.padM.style.width = (THIS.padding + 2 * THIS.insetWidth + THIS.width + padToSliderPadding / 2) + 'px';\r
+                       p.padM.style.height = dims[1] + 'px';\r
+                       p.padM.style.cursor = padCursor;\r
+\r
+                       // pad cross\r
+                       p.cross.style.position = 'absolute';\r
+                       p.cross.style.left =\r
+                       p.cross.style.top =\r
+                               '0';\r
+                       p.cross.style.width =\r
+                       p.cross.style.height =\r
+                               crossOuterSize + 'px';\r
+\r
+                       // pad cross border Y and X\r
+                       p.crossBY.style.position =\r
+                       p.crossBX.style.position =\r
+                               'absolute';\r
+                       p.crossBY.style.background =\r
+                       p.crossBX.style.background =\r
+                               THIS.pointerBorderColor;\r
+                       p.crossBY.style.width =\r
+                       p.crossBX.style.height =\r
+                               (2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';\r
+                       p.crossBY.style.height =\r
+                       p.crossBX.style.width =\r
+                               crossOuterSize + 'px';\r
+                       p.crossBY.style.left =\r
+                       p.crossBX.style.top =\r
+                               (Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2) - THIS.pointerBorderWidth) + 'px';\r
+                       p.crossBY.style.top =\r
+                       p.crossBX.style.left =\r
+                               '0';\r
+\r
+                       // pad cross line Y and X\r
+                       p.crossLY.style.position =\r
+                       p.crossLX.style.position =\r
+                               'absolute';\r
+                       p.crossLY.style.background =\r
+                       p.crossLX.style.background =\r
+                               THIS.pointerColor;\r
+                       p.crossLY.style.height =\r
+                       p.crossLX.style.width =\r
+                               (crossOuterSize - 2 * THIS.pointerBorderWidth) + 'px';\r
+                       p.crossLY.style.width =\r
+                       p.crossLX.style.height =\r
+                               THIS.pointerThickness + 'px';\r
+                       p.crossLY.style.left =\r
+                       p.crossLX.style.top =\r
+                               (Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2)) + 'px';\r
+                       p.crossLY.style.top =\r
+                       p.crossLX.style.left =\r
+                               THIS.pointerBorderWidth + 'px';\r
+\r
+                       // slider\r
+                       p.sld.style.overflow = 'hidden';\r
+                       p.sld.style.width = THIS.sliderSize + 'px';\r
+                       p.sld.style.height = THIS.height + 'px';\r
+\r
+                       // slider gradient\r
+                       p.sldGrad.draw(THIS.sliderSize, THIS.height, '#000', '#000');\r
+\r
+                       // slider border\r
+                       p.sldB.style.display = displaySlider ? 'block' : 'none';\r
+                       p.sldB.style.position = 'absolute';\r
+                       p.sldB.style.right = THIS.padding + 'px';\r
+                       p.sldB.style.top = THIS.padding + 'px';\r
+                       p.sldB.style.border = THIS.insetWidth + 'px solid';\r
+                       p.sldB.style.borderColor = THIS.insetColor;\r
+\r
+                       // slider mouse area\r
+                       p.sldM._jscInstance = THIS;\r
+                       p.sldM._jscControlName = 'sld';\r
+                       p.sldM.style.display = displaySlider ? 'block' : 'none';\r
+                       p.sldM.style.position = 'absolute';\r
+                       p.sldM.style.right = '0';\r
+                       p.sldM.style.top = '0';\r
+                       p.sldM.style.width = (THIS.sliderSize + padToSliderPadding / 2 + THIS.padding + 2 * THIS.insetWidth) + 'px';\r
+                       p.sldM.style.height = dims[1] + 'px';\r
+                       p.sldM.style.cursor = 'default';\r
+\r
+                       // slider pointer inner and outer border\r
+                       p.sldPtrIB.style.border =\r
+                       p.sldPtrOB.style.border =\r
+                               THIS.pointerBorderWidth + 'px solid ' + THIS.pointerBorderColor;\r
+\r
+                       // slider pointer outer border\r
+                       p.sldPtrOB.style.position = 'absolute';\r
+                       p.sldPtrOB.style.left = -(2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';\r
+                       p.sldPtrOB.style.top = '0';\r
+\r
+                       // slider pointer middle border\r
+                       p.sldPtrMB.style.border = THIS.pointerThickness + 'px solid ' + THIS.pointerColor;\r
+\r
+                       // slider pointer spacer\r
+                       p.sldPtrS.style.width = THIS.sliderSize + 'px';\r
+                       p.sldPtrS.style.height = sliderPtrSpace + 'px';\r
+\r
+                       // the Close button\r
+                       function setBtnBorder () {\r
+                               var insetColors = THIS.insetColor.split(/\s+/);\r
+                               var outsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];\r
+                               p.btn.style.borderColor = outsetColor;\r
+                       }\r
+                       p.btn.style.display = THIS.closable ? 'block' : 'none';\r
+                       p.btn.style.position = 'absolute';\r
+                       p.btn.style.left = THIS.padding + 'px';\r
+                       p.btn.style.bottom = THIS.padding + 'px';\r
+                       p.btn.style.padding = '0 15px';\r
+                       p.btn.style.height = THIS.buttonHeight + 'px';\r
+                       p.btn.style.border = THIS.insetWidth + 'px solid';\r
+                       setBtnBorder();\r
+                       p.btn.style.color = THIS.buttonColor;\r
+                       p.btn.style.font = '12px sans-serif';\r
+                       p.btn.style.textAlign = 'center';\r
+                       try {\r
+                               p.btn.style.cursor = 'pointer';\r
+                       } catch(eOldIE) {\r
+                               p.btn.style.cursor = 'hand';\r
+                       }\r
+                       p.btn.onmousedown = function () {\r
+                               THIS.hide();\r
+                       };\r
+                       p.btnT.style.lineHeight = THIS.buttonHeight + 'px';\r
+                       p.btnT.innerHTML = '';\r
+                       p.btnT.appendChild(document.createTextNode(THIS.closeText));\r
+\r
+                       // place pointers\r
+                       redrawPad();\r
+                       redrawSld();\r
+\r
+                       // If we are changing the owner without first closing the picker,\r
+                       // make sure to first deal with the old owner\r
+                       if (jsc.picker.owner && jsc.picker.owner !== THIS) {\r
+                               jsc.unsetClass(jsc.picker.owner.targetElement, THIS.activeClass);\r
+                       }\r
+\r
+                       // Set the new picker owner\r
+                       jsc.picker.owner = THIS;\r
+\r
+                       // The redrawPosition() method needs picker.owner to be set, that's why we call it here,\r
+                       // after setting the owner\r
+                       if (jsc.isElementType(container, 'body')) {\r
+                               jsc.redrawPosition();\r
+                       } else {\r
+                               jsc._drawPosition(THIS, 0, 0, 'relative', false);\r
+                       }\r
+\r
+                       if (p.wrap.parentNode != container) {\r
+                               container.appendChild(p.wrap);\r
+                       }\r
+\r
+                       jsc.setClass(THIS.targetElement, THIS.activeClass);\r
+               }\r
+\r
+\r
+               function redrawPad () {\r
+                       // redraw the pad pointer\r
+                       switch (jsc.getPadYComponent(THIS)) {\r
+                       case 's': var yComponent = 1; break;\r
+                       case 'v': var yComponent = 2; break;\r
+                       }\r
+                       var x = Math.round((THIS.hsv[0] / 360) * (THIS.width - 1));\r
+                       var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));\r
+                       var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);\r
+                       var ofs = -Math.floor(crossOuterSize / 2);\r
+                       jsc.picker.cross.style.left = (x + ofs) + 'px';\r
+                       jsc.picker.cross.style.top = (y + ofs) + 'px';\r
+\r
+                       // redraw the slider\r
+                       switch (jsc.getSliderComponent(THIS)) {\r
+                       case 's':\r
+                               var rgb1 = HSV_RGB(THIS.hsv[0], 100, THIS.hsv[2]);\r
+                               var rgb2 = HSV_RGB(THIS.hsv[0], 0, THIS.hsv[2]);\r
+                               var color1 = 'rgb(' +\r
+                                       Math.round(rgb1[0]) + ',' +\r
+                                       Math.round(rgb1[1]) + ',' +\r
+                                       Math.round(rgb1[2]) + ')';\r
+                               var color2 = 'rgb(' +\r
+                                       Math.round(rgb2[0]) + ',' +\r
+                                       Math.round(rgb2[1]) + ',' +\r
+                                       Math.round(rgb2[2]) + ')';\r
+                               jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);\r
+                               break;\r
+                       case 'v':\r
+                               var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 100);\r
+                               var color1 = 'rgb(' +\r
+                                       Math.round(rgb[0]) + ',' +\r
+                                       Math.round(rgb[1]) + ',' +\r
+                                       Math.round(rgb[2]) + ')';\r
+                               var color2 = '#000';\r
+                               jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);\r
+                               break;\r
+                       }\r
+               }\r
+\r
+\r
+               function redrawSld () {\r
+                       var sldComponent = jsc.getSliderComponent(THIS);\r
+                       if (sldComponent) {\r
+                               // redraw the slider pointer\r
+                               switch (sldComponent) {\r
+                               case 's': var yComponent = 1; break;\r
+                               case 'v': var yComponent = 2; break;\r
+                               }\r
+                               var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));\r
+                               jsc.picker.sldPtrOB.style.top = (y - (2 * THIS.pointerBorderWidth + THIS.pointerThickness) - Math.floor(sliderPtrSpace / 2)) + 'px';\r
+                       }\r
+               }\r
+\r
+\r
+               function isPickerOwner () {\r
+                       return jsc.picker && jsc.picker.owner === THIS;\r
+               }\r
+\r
+\r
+               function blurValue () {\r
+                       THIS.importColor();\r
+               }\r
+\r
+\r
+               // Find the target element\r
+               if (typeof targetElement === 'string') {\r
+                       var id = targetElement;\r
+                       var elm = document.getElementById(id);\r
+                       if (elm) {\r
+                               this.targetElement = elm;\r
+                       } else {\r
+                               jsc.warn('Could not find target element with ID \'' + id + '\'');\r
+                       }\r
+               } else if (targetElement) {\r
+                       this.targetElement = targetElement;\r
+               } else {\r
+                       jsc.warn('Invalid target element: \'' + targetElement + '\'');\r
+               }\r
+\r
+               if (this.targetElement._jscLinkedInstance) {\r
+                       jsc.warn('Cannot link jscolor twice to the same element. Skipping.');\r
+                       return;\r
+               }\r
+               this.targetElement._jscLinkedInstance = this;\r
+\r
+               // Find the value element\r
+               this.valueElement = jsc.fetchElement(this.valueElement);\r
+               // Find the style element\r
+               this.styleElement = jsc.fetchElement(this.styleElement);\r
+\r
+               var THIS = this;\r
+               var container =\r
+                       this.container ?\r
+                       jsc.fetchElement(this.container) :\r
+                       document.getElementsByTagName('body')[0];\r
+               var sliderPtrSpace = 3; // px\r
+\r
+               // For BUTTON elements it's important to stop them from sending the form when clicked\r
+               // (e.g. in Safari)\r
+               if (jsc.isElementType(this.targetElement, 'button')) {\r
+                       if (this.targetElement.onclick) {\r
+                               var origCallback = this.targetElement.onclick;\r
+                               this.targetElement.onclick = function (evt) {\r
+                                       origCallback.call(this, evt);\r
+                                       return false;\r
+                               };\r
+                       } else {\r
+                               this.targetElement.onclick = function () { return false; };\r
+                       }\r
+               }\r
+\r
+               /*\r
+               var elm = this.targetElement;\r
+               do {\r
+                       // If the target element or one of its offsetParents has fixed position,\r
+                       // then use fixed positioning instead\r
+                       //\r
+                       // Note: In Firefox, getComputedStyle returns null in a hidden iframe,\r
+                       // that's why we need to check if the returned style object is non-empty\r
+                       var currStyle = jsc.getStyle(elm);\r
+                       if (currStyle && currStyle.position.toLowerCase() === 'fixed') {\r
+                               this.fixed = true;\r
+                       }\r
+\r
+                       if (elm !== this.targetElement) {\r
+                               // attach onParentScroll so that we can recompute the picker position\r
+                               // when one of the offsetParents is scrolled\r
+                               if (!elm._jscEventsAttached) {\r
+                                       jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);\r
+                                       elm._jscEventsAttached = true;\r
+                               }\r
+                       }\r
+               } while ((elm = elm.offsetParent) && !jsc.isElementType(elm, 'body'));\r
+               */\r
+\r
+               // valueElement\r
+               if (this.valueElement) {\r
+                       if (jsc.isElementType(this.valueElement, 'input')) {\r
+                               var updateField = function () {\r
+                                       THIS.fromString(THIS.valueElement.value, jsc.leaveValue);\r
+                                       jsc.dispatchFineChange(THIS);\r
+                               };\r
+                               jsc.attachEvent(this.valueElement, 'keyup', updateField);\r
+                               jsc.attachEvent(this.valueElement, 'input', updateField);\r
+                               jsc.attachEvent(this.valueElement, 'blur', blurValue);\r
+                               this.valueElement.setAttribute('autocomplete', 'off');\r
+                       }\r
+               }\r
+\r
+               // styleElement\r
+               if (this.styleElement) {\r
+                       this.styleElement._jscOrigStyle = {\r
+                               backgroundImage : this.styleElement.style.backgroundImage,\r
+                               backgroundColor : this.styleElement.style.backgroundColor,\r
+                               color : this.styleElement.style.color\r
+                       };\r
+               }\r
+\r
+               if (this.value) {\r
+                       // Try to set the color from the .value option and if unsuccessful,\r
+                       // export the current color\r
+                       this.fromString(this.value) || this.exportColor();\r
+               } else {\r
+                       this.importColor();\r
+               }\r
+       }\r
+\r
+};\r
+\r
+\r
+//================================\r
+// Public properties and methods\r
+//================================\r
+\r
+\r
+// By default, search for all elements with class="jscolor" and install a color picker on them.\r
+//\r
+// You can change what class name will be looked for by setting the property jscolor.lookupClass\r
+// anywhere in your HTML document. To completely disable the automatic lookup, set it to null.\r
+//\r
+jsc.jscolor.lookupClass = 'jscolor';\r
+\r
+\r
+jsc.jscolor.installByClassName = function (className) {\r
+       var inputElms = document.getElementsByTagName('input');\r
+       var buttonElms = document.getElementsByTagName('button');\r
+\r
+       jsc.tryInstallOnElements(inputElms, className);\r
+       jsc.tryInstallOnElements(buttonElms, className);\r
+};\r
+\r
+\r
+jsc.register();\r
+\r
+\r
+return jsc.jscolor;\r
+\r
+\r
+})(); }\r