--- /dev/null
+/* =========================================================
+ * bootstrap-colorpicker.js
+ * http://www.eyecon.ro/bootstrap-colorpicker
+ * =========================================================
+ * Copyright 2012 Stefan Petre
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+
+!function( $ ) {
+
+ // Color object
+
+ var Color = function(val) {
+ this.value = {
+ h: 1,
+ s: 1,
+ b: 1,
+ a: 1
+ };
+ this.setColor(val);
+ };
+
+ Color.prototype = {
+ constructor: Color,
+
+ //parse a string to HSB
+ setColor: function(val){
+ val = val.toLowerCase();
+ var that = this;
+ $.each( CPGlobal.stringParsers, function( i, parser ) {
+ var match = parser.re.exec( val ),
+ values = match && parser.parse( match ),
+ space = parser.space||'rgba';
+ if ( values ) {
+ if (space == 'hsla') {
+ that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values));
+ } else {
+ that.value = CPGlobal.RGBtoHSB.apply(null, values);
+ }
+ return false;
+ }
+ });
+ },
+
+ setHue: function(h) {
+ this.value.h = 1- h;
+ },
+
+ setSaturation: function(s) {
+ this.value.s = s;
+ },
+
+ setLightness: function(b) {
+ this.value.b = 1- b;
+ },
+
+ setAlpha: function(a) {
+ this.value.a = parseInt((1 - a)*100, 10)/100;
+ },
+
+ // HSBtoRGB from RaphaelJS
+ // https://github.com/DmitryBaranovskiy/raphael/
+ toRGB: function(h, s, b, a) {
+ if (!h) {
+ h = this.value.h;
+ s = this.value.s;
+ b = this.value.b;
+ }
+ h *= 360;
+ var R, G, B, X, C;
+ h = (h % 360) / 60;
+ C = b * s;
+ X = C * (1 - Math.abs(h % 2 - 1));
+ R = G = B = b - C;
+
+ h = ~~h;
+ R += [C, X, 0, 0, X, C][h];
+ G += [X, C, C, X, 0, 0][h];
+ B += [0, 0, X, C, C, X][h];
+ return {
+ r: Math.round(R*255),
+ g: Math.round(G*255),
+ b: Math.round(B*255),
+ a: a||this.value.a
+ };
+ },
+
+ toHex: function(h, s, b, a){
+ var rgb = this.toRGB(h, s, b, a);
+ return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
+ },
+
+ toHSL: function(h, s, b, a){
+ if (!h) {
+ h = this.value.h;
+ s = this.value.s;
+ b = this.value.b;
+ }
+ var H = h,
+ L = (2 - s) * b,
+ S = s * b;
+ if (L > 0 && L <= 1) {
+ S /= L;
+ } else {
+ S /= 2 - L;
+ }
+ L /= 2;
+ if (S > 1) {
+ S = 1;
+ }
+ return {
+ h: H,
+ s: S,
+ l: L,
+ a: a||this.value.a
+ };
+ }
+ };
+
+ // Picker object
+
+ var Colorpicker = function(element, options){
+ this.element = $(element);
+ var format = options.format||this.element.data('color-format')||'hex';
+ this.format = CPGlobal.translateFormats[format];
+ this.isInput = this.element.is('input');
+ this.component = this.element.is('.color') ? this.element.find('.add-on') : false;
+
+ this.picker = $(CPGlobal.template)
+ .appendTo('body')
+ .on('mousedown', $.proxy(this.mousedown, this));
+
+ if (this.isInput) {
+ this.element.on({
+ 'focus': $.proxy(this.show, this),
+ 'keyup': $.proxy(this.update, this)
+ });
+ } else if (this.component){
+ this.component.on({
+ 'click': $.proxy(this.show, this)
+ });
+ } else {
+ this.element.on({
+ 'click': $.proxy(this.show, this)
+ });
+ }
+ if (format == 'rgba' || format == 'hsla') {
+ this.picker.addClass('alpha');
+ this.alpha = this.picker.find('.colorpicker-alpha')[0].style;
+ }
+
+ if (this.component){
+ this.picker.find('.colorpicker-color').hide();
+ this.preview = this.element.find('i')[0].style;
+ } else {
+ this.preview = this.picker.find('div:last')[0].style;
+ }
+
+ this.base = this.picker.find('div:first')[0].style;
+ this.update();
+ };
+
+ Colorpicker.prototype = {
+ constructor: Colorpicker,
+
+ show: function(e) {
+ this.picker.show();
+ this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
+ this.place();
+ $(window).on('resize', $.proxy(this.place, this));
+ if (!this.isInput) {
+ if (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ }
+ $(document).on({
+ 'mousedown': $.proxy(this.hide, this)
+ });
+ this.element.trigger({
+ type: 'show',
+ color: this.color
+ });
+ },
+
+ update: function(){
+ this.color = new Color(this.isInput ? this.element.prop('value') : this.element.data('color'));
+ this.picker.find('i')
+ .eq(0).css({left: this.color.value.s*100, top: 100 - this.color.value.b*100}).end()
+ .eq(1).css('top', 100 * (1 - this.color.value.h)).end()
+ .eq(2).css('top', 100 * (1 - this.color.value.a));
+ this.previewColor();
+ },
+
+ hide: function(){
+ this.picker.hide();
+ $(window).off('resize', this.place);
+ if (!this.isInput) {
+ $(document).off({
+ 'mousedown': this.hide
+ });
+ if (this.component){
+ this.element.find('input').prop('value', this.format.call(this));
+ }
+ this.element.data('color', this.format.call(this));
+ } else {
+ this.element.prop('value', this.format.call(this));
+ }
+ this.element.trigger({
+ type: 'hide',
+ color: this.color
+ });
+ },
+
+ place: function(){
+ var offset = this.component ? this.component.offset() : this.element.offset();
+ this.picker.css({
+ top: offset.top + this.height,
+ left: offset.left
+ });
+ },
+
+ //preview color change
+ previewColor: function(){
+ this.preview.backgroundColor = this.format.call(this);
+ //set the color for brightness/saturation slider
+ this.base.backgroundColor = this.color.toHex(this.color.value.h, 1, 1, 1);
+ //set te color for alpha slider
+ if (this.alpha) {
+ this.alpha.backgroundColor = this.color.toHex();
+ }
+ },
+
+ pointer: null,
+
+ slider: null,
+
+ mousedown: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+
+ var target = $(e.target);
+
+ //detect the slider and set the limits and callbacks
+ var zone = target.closest('div');
+ if (!zone.is('.colorpicker')) {
+ if (zone.is('.colorpicker-saturation')) {
+ this.slider = $.extend({}, CPGlobal.sliders['saturation']);
+ }
+ else if (zone.is('.colorpicker-hue')) {
+ this.slider = $.extend({}, CPGlobal.sliders['hue']);
+ }
+ else if (zone.is('.colorpicker-alpha')) {
+ this.slider = $.extend({}, CPGlobal.sliders['alpha']);
+ }
+ var offset = zone.offset();
+ //reference to knob's style
+ this.slider.knob = zone.find('i')[0].style;
+ this.slider.left = e.pageX - offset.left;
+ this.slider.top = e.pageY - offset.top;
+ this.pointer = {
+ left: e.pageX,
+ top: e.pageY
+ };
+ //trigger mousemove to move the knob to the current position
+ $(document).on({
+ mousemove: $.proxy(this.mousemove, this),
+ mouseup: $.proxy(this.mouseup, this)
+ }).trigger('mousemove');
+ }
+ return false;
+ },
+
+ mousemove: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ var left = Math.max(
+ 0,
+ Math.min(
+ this.slider.maxLeft,
+ this.slider.left + ((e.pageX||this.pointer.left) - this.pointer.left)
+ )
+ );
+ var top = Math.max(
+ 0,
+ Math.min(
+ this.slider.maxTop,
+ this.slider.top + ((e.pageY||this.pointer.top) - this.pointer.top)
+ )
+ );
+ this.slider.knob.left = left + 'px';
+ this.slider.knob.top = top + 'px';
+ if (this.slider.callLeft) {
+ this.color[this.slider.callLeft].call(this.color, left/100);
+ }
+ if (this.slider.callTop) {
+ this.color[this.slider.callTop].call(this.color, top/100);
+ }
+ this.previewColor();
+ this.element.trigger({
+ type: 'changeColor',
+ color: this.color
+ });
+ return false;
+ },
+
+ mouseup: function(e){
+ e.stopPropagation();
+ e.preventDefault();
+ $(document).off({
+ mousemove: this.mousemove,
+ mouseup: this.mouseup
+ });
+ return false;
+ }
+ }
+
+ $.fn.colorpicker = function ( option ) {
+ return this.each(function () {
+ var $this = $(this),
+ data = $this.data('colorpicker'),
+ options = typeof option == 'object' && option;
+ if (!data) {
+ $this.data('colorpicker', (data = new Colorpicker(this, $.extend({}, $.fn.colorpicker.defaults, options))));
+ }
+ if (typeof option == 'string') data[option]();
+ });
+ };
+
+ $.fn.colorpicker.defaults = {
+ };
+
+ $.fn.colorpicker.Constructor = Colorpicker;
+
+ var CPGlobal = {
+
+ // translate a format from Color object to a string
+ translateFormats: {
+ 'rgb': function(){
+ var rgb = this.color.toRGB();
+ return 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
+ },
+
+ 'rgba': function(){
+ var rgb = this.color.toRGB();
+ return 'rgba('+rgb.r+','+rgb.g+','+rgb.b+','+rgb.a+')';
+ },
+
+ 'hsl': function(){
+ var hsl = this.color.toHSL();
+ return 'hsl('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%)';
+ },
+
+ 'hsla': function(){
+ var hsl = this.color.toHSL();
+ return 'hsla('+Math.round(hsl.h*360)+','+Math.round(hsl.s*100)+'%,'+Math.round(hsl.l*100)+'%,'+hsl.a+')';
+ },
+
+ 'hex': function(){
+ return this.color.toHex();
+ }
+ },
+
+ sliders: {
+ saturation: {
+ maxLeft: 100,
+ maxTop: 100,
+ callLeft: 'setSaturation',
+ callTop: 'setLightness'
+ },
+
+ hue: {
+ maxLeft: 0,
+ maxTop: 100,
+ callLeft: false,
+ callTop: 'setHue'
+ },
+
+ alpha: {
+ maxLeft: 0,
+ maxTop: 100,
+ callLeft: false,
+ callTop: 'setAlpha'
+ }
+ },
+
+ // HSBtoRGB from RaphaelJS
+ // https://github.com/DmitryBaranovskiy/raphael/
+ RGBtoHSB: function (r, g, b, a){
+ r /= 255;
+ g /= 255;
+ b /= 255;
+
+ var H, S, V, C;
+ V = Math.max(r, g, b);
+ C = V - Math.min(r, g, b);
+ H = (C == 0 ? null :
+ V == r ? (g - b) / C :
+ V == g ? (b - r) / C + 2 :
+ (r - g) / C + 4
+ );
+ H = ((H + 360) % 6) * 60 / 360;
+ S = C == 0 ? 0 : C / V;
+ return {h: H||1, s: S, b: V, a: a||1};
+ },
+
+ HueToRGB: function (p, q, h) {
+ if (h < 0)
+ h += 1;
+ else if (h > 1)
+ h -= 1;
+
+ if ((h * 6) < 1)
+ return p + (q - p) * h * 6;
+ else if ((h * 2) < 1)
+ return q;
+ else if ((h * 3) < 2)
+ return p + (q - p) * ((2 / 3) - h) * 6;
+ else
+ return p;
+ },
+
+ HSLtoRGB: function (h, s, l, a)
+ {
+
+ if (s < 0)
+ s = 0;
+
+ if (l <= 0.5)
+ var q = l * (1 + s);
+ else
+ var q = l + s - (l * s);
+
+ var p = 2 * l - q;
+
+ var tr = h + (1 / 3);
+ var tg = h;
+ var tb = h - (1 / 3);
+
+ var r = Math.round(CPGlobal.HueToRGB(p, q, tr) * 255);
+ var g = Math.round(CPGlobal.HueToRGB(p, q, tg) * 255);
+ var b = Math.round(CPGlobal.HueToRGB(p, q, tb) * 255);
+ return [r, g, b, a||1];
+ },
+
+ // a set of RE's that can match strings and generate color tuples.
+ // from John Resig color plugin
+ // https://github.com/jquery/jquery-color/
+ stringParsers: [
+ {
+ re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ parse: function( execResult ) {
+ return [
+ execResult[ 1 ],
+ execResult[ 2 ],
+ execResult[ 3 ],
+ execResult[ 4 ]
+ ];
+ }
+ }, {
+ re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ parse: function( execResult ) {
+ return [
+ 2.55 * execResult[1],
+ 2.55 * execResult[2],
+ 2.55 * execResult[3],
+ execResult[ 4 ]
+ ];
+ }
+ }, {
+ re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
+ parse: function( execResult ) {
+ return [
+ parseInt( execResult[ 1 ], 16 ),
+ parseInt( execResult[ 2 ], 16 ),
+ parseInt( execResult[ 3 ], 16 )
+ ];
+ }
+ }, {
+ re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
+ parse: function( execResult ) {
+ return [
+ parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
+ parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
+ parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
+ ];
+ }
+ }, {
+ re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
+ space: 'hsla',
+ parse: function( execResult ) {
+ return [
+ execResult[1]/360,
+ execResult[2] / 100,
+ execResult[3] / 100,
+ execResult[4]
+ ];
+ }
+ }
+ ],
+ template: '<div class="colorpicker dropdown-menu">'+
+ '<div class="colorpicker-saturation"><i><b></b></i></div>'+
+ '<div class="colorpicker-hue"><i></i></div>'+
+ '<div class="colorpicker-alpha"><i></i></div>'+
+ '<div class="colorpicker-color"><div /></div>'+
+ '</div>'
+ };
+
+}( window.jQuery )
\ No newline at end of file
--- /dev/null
+/*!
+* Datepicker for Bootstrap
+*
+* Copyright 2012 Stefan Petre
+* Licensed under the Apache License v2.0
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+*/
+.datepicker {
+top: 0;
+left: 0;
+padding: 4px;
+margin-top: 1px;
+-webkit-border-radius: 4px;
+-moz-border-radius: 4px;
+border-radius: 4px;
+/*.dow {
+border-top: 1px solid #ddd !important;
+}*/
+}
+.datepicker:before {
+content: '';
+display: inline-block;
+border-left: 7px solid transparent;
+border-right: 7px solid transparent;
+border-bottom: 7px solid #ccc;
+border-bottom-color: rgba(0, 0, 0, 0.2);
+position: absolute;
+top: -7px;
+left: 6px;
+}
+.datepicker:after {
+content: '';
+display: inline-block;
+border-left: 6px solid transparent;
+border-right: 6px solid transparent;
+border-bottom: 6px solid #ffffff;
+position: absolute;
+top: -6px;
+left: 7px;
+}
+.datepicker > div {
+display: none;
+}
+.datepicker table {
+width: 100%;
+margin: 0;
+}
+.datepicker td, .datepicker th {
+text-align: center;
+width: 20px;
+height: 20px;
+-webkit-border-radius: 4px;
+-moz-border-radius: 4px;
+border-radius: 4px;
+}
+.datepicker td.day:hover {
+background: #eeeeee;
+cursor: pointer;
+}
+.datepicker td.old, .datepicker td.new {
+color: #999999;
+}
+.datepicker td.active, .datepicker td.active:hover {
+background-color: #006dcc;
+background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
+background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
+background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
+background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
+background-image: -o-linear-gradient(top, #0088cc, #0044cc);
+background-image: linear-gradient(top, #0088cc, #0044cc);
+background-repeat: repeat-x;
+filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
+border-color: #0044cc #0044cc #002a80;
+border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+color: #fff;
+text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+.datepicker td.active:hover,
+.datepicker td.active:hover:hover,
+.datepicker td.active:active,
+.datepicker td.active:hover:active,
+.datepicker td.active.active,
+.datepicker td.active:hover.active,
+.datepicker td.active.disabled,
+.datepicker td.active:hover.disabled,
+.datepicker td.active[disabled],
+.datepicker td.active:hover[disabled] {
+background-color: #0044cc;
+}
+.datepicker td.active:active,
+.datepicker td.active:hover:active,
+.datepicker td.active.active,
+.datepicker td.active:hover.active {
+background-color: #003399 \9;
+}
+.datepicker td span {
+display: block;
+width: 47px;
+height: 54px;
+line-height: 54px;
+float: left;
+margin: 2px;
+cursor: pointer;
+-webkit-border-radius: 4px;
+-moz-border-radius: 4px;
+border-radius: 4px;
+}
+.datepicker td span:hover {
+background: #eeeeee;
+}
+.datepicker td span.active {
+background-color: #006dcc;
+background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
+background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
+background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
+background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
+background-image: -o-linear-gradient(top, #0088cc, #0044cc);
+background-image: linear-gradient(top, #0088cc, #0044cc);
+background-repeat: repeat-x;
+filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
+border-color: #0044cc #0044cc #002a80;
+border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+color: #fff;
+text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+.datepicker td span.active:hover,
+.datepicker td span.active:active,
+.datepicker td span.active.active,
+.datepicker td span.active.disabled,
+.datepicker td span.active[disabled] {
+background-color: #0044cc;
+}
+.datepicker td span.active:active, .datepicker td span.active.active {
+background-color: #003399 \9;
+}
+.datepicker td span.old {
+color: #999999;
+}
+.datepicker th.switch {
+width: 145px;
+}
+.datepicker thead tr:first-child th {
+cursor: pointer;
+}
+.datepicker thead tr:first-child th:hover {
+background: #eeeeee;
+}
+.input-append.date .add-on i, .input-prepend.date .add-on i {
+display: block;
+cursor: pointer;
+width: 16px;
+height: 16px;
+}
\ No newline at end of file