$(document).ready(function() {
    // setup date range date-pickers
    setupDatePickers('#start_date', '#end_date');

    // form highlight
    $('form').highlight('p')

    //disable submit buttons after click
    $('p.submit_btn input.btn').bind('click',
    function() {
        $(this).parents('form').submit();
        $(this).attr("disabled", "disabled");
        return true;
    });
    
    //png fix
    $(document).pngFix();
    
    //turn off auto-complete for credit-card fields
    $('input#cardnumber').attr("autocomplete","off");
    
});

function setupDatePickers(beginDate, endDate) {
    // create date-picker and make it appear on focus
    $('.date-pick').datePicker(
    {
        showYearNavigation: true,
		startDate:'01/01/1900'
    }
    );

    // restrict EndDates from being before StartDates
    $(beginDate).bind(
    'dpClosed',
    function(e, selectedDates)
    {
        var d = selectedDates[0];
        if (d) {
            d = new Date(d);
            // change 0 to 1 to disable EndDate being the same as StartDate
            $(endDate).dpSetStartDate(d.addDays(0).asString());
        }
    }
    );
    $(endDate).bind(
    'dpClosed',
    function(e, selectedDates)
    {
        var d = selectedDates[0];
        if (d) {
            d = new Date(d);
            // change 0 to -1 to disable EndDate being the same as StartDate
            $(beginDate).dpSetEndDate(d.addDays(0).asString());
        }
    }
    );
}

/////////////////////////////////////////////////////////////////////////////////
// jQuery Plug-Ins //////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

// mini-fied jquery.datepicker plug-in *** Copyright 2007 Kelvin Luck (http://www.kelvinluck.com/) * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)  * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
(function($){    $.fn.extend({renderCalendar  :   function(s){    var dc = function(a)    {return document.createElement(a);    };s = $.extend({    month    : null,    year    : null,    renderCallback    : null,    showHeader: $.dpConst.SHOW_HEADER_SHORT,    dpController    : null,    hoverClass: 'dp-hover'}, s    );if (s.showHeader != $.dpConst.SHOW_HEADER_NONE) {var headRow = $(dc('tr'));for (var i=Date.firstDayOfWeek; i<Date.firstDayOfWeek+7; i++) {    var weekday = i%7;    var day = Date.dayNames[weekday];    headRow.append(jQuery(dc('th')).attr({'scope':'col', 'abbr':day, 'title':day, 'class':(weekday == 0 || weekday == 6 ? 'weekend' : 'weekday')}).html(s.showHeader == $.dpConst.SHOW_HEADER_SHORT ? day.substr(0, 1) : day)    );}    };var calendarTable = $(dc('table'))    .attr({    'cellspacing':2,    'className':'jCalendar'}    )    .append((s.showHeader != $.dpConst.SHOW_HEADER_NONE ? $(dc('thead')).append(headRow)    :    dc('thead'))    );    var tbody = $(dc('tbody'));var today = (new Date()).zeroTime();var month = s.month == undefined ? today.getMonth() : s.month;    var year = s.year || today.getFullYear();var currentDate = new Date(year, month, 1);    var firstDayOffset = Date.firstDayOfWeek - currentDate.getDay() + 1;    if (firstDayOffset > 1) firstDayOffset -= 7;    var weeksToDraw = Math.ceil(( (-1*firstDayOffset+1) + currentDate.getDaysInMonth() ) /7);    currentDate.addDays(firstDayOffset-1);var doHover = function()    {if (s.hoverClass) {    $(this).addClass(s.hoverClass);}    };    var unHover = function()    {if (s.hoverClass) {    $(this).removeClass(s.hoverClass);}    };var w = 0;    while (w++<weeksToDraw) {var r = jQuery(dc('tr'));for (var i=0; i<7; i++) {    var thisMonth = currentDate.getMonth() == month;    var d = $(dc('td')).text(currentDate.getDate() + '').attr('className', (thisMonth ? 'current-month ' : 'other-month ') +    (currentDate.isWeekend() ? 'weekend ' : 'weekday ') +    (thisMonth && currentDate.getTime() == today.getTime() ? 'today ' : '')).hover(doHover, unHover)    ;    if (s.renderCallback) {s.renderCallback(d, currentDate, month, year);    }    r.append(d);    currentDate.addDays(1);}tbody.append(r);    }    calendarTable.append(tbody);return this.each(function(){    $(this).empty().append(calendarTable);}    );},datePicker : function(s){if (!$.event._dpCache) $.event._dpCache = [];s = $.extend({    month: undefined,    year: undefined,    startDate    : undefined,    endDate: undefined,    inline: false,    renderCallback: [],    createButton: true,    showYearNavigation    : true,    closeOnSelect: true,    displayClose: false,    selectMultiple: false,    clickInput    : false,    verticalPosition    : $.dpConst.POS_TOP,    horizontalPosition    : $.dpConst.POS_LEFT,    verticalOffset: 0,    horizontalOffset    : 0,    hoverClass    : 'dp-hover'}, s    );return this.each(function(){    var $this = $(this);    var alreadyExists = true;if (!this._dpId) {this._dpId = $.event.guid++;$.event._dpCache[this._dpId] = new DatePicker(this);alreadyExists = false;    }if (s.inline) {s.createButton = false;s.displayClose = false;s.closeOnSelect = false;$this.empty();    }var controller = $.event._dpCache[this._dpId];controller.init(s);if (!alreadyExists && s.createButton) {controller.button = $('<a href="#" class="dp-choose-date" title="' + $.dpText.TEXT_CHOOSE_DATE + '">' + $.dpText.TEXT_CHOOSE_DATE + '</a>').bind(    'click',    function()    {$this.dpDisplay(this);this.blur();return false;    });$this.after(controller.button);    }if (!alreadyExists && $this.is(':text')) {$this    .bind('dateSelected',function(e, selectedDate, $td){    this.value = selectedDate.asString();}    ).bind('change',function(){    var d = Date.fromString(this.value);    if (d) {controller.setSelected(d, true, true);    }}    );if (s.clickInput) {    $this.bind('click',function(){    $this.dpDisplay();}    );}var d = Date.fromString(this.value);if (this.value != '' && d) {    controller.setSelected(d, true, true);}    }$this.addClass('dp-applied');    }    )},dpSetDisabled : function(s){    return _w.call(this, 'setDisabled', s);},dpSetStartDate : function(d){    return _w.call(this, 'setStartDate', d);},dpSetEndDate : function(d){    return _w.call(this, 'setEndDate', d);},dpGetSelected : function(){    var c = _getController(this[0]);    if (c) {return c.getSelected();    }    return null;},dpSetSelected : function(d, v, m){    if (v == undefined) v=true;    if (m == undefined) m=true;    return _w.call(this, 'setSelected', Date.fromString(d), v, m);},dpSetDisplayedMonth : function(m, y){    return _w.call(this, 'setDisplayedMonth', Number(m), Number(y));},dpDisplay : function(e){    return _w.call(this, 'display', e);},dpSetRenderCallback : function(a){    return _w.call(this, 'setRenderCallback', a);},dpSetPosition : function(v, h){    return _w.call(this, 'setPosition', v, h);},dpSetOffset : function(v, h){    return _w.call(this, 'setOffset', v, h);},dpClose : function(){    return _w.call(this, '_closeCalendar', false, this[0]);},_dpDestroy : function(){}    });var _w = function(f, a1, a2, a3)    {return this.each(    function()    {var c = _getController(this);if (c) {    c[f](a1, a2, a3);}    });    };function DatePicker(ele)    {this.ele = ele;this.displayedMonth=    null;this.displayedYear=    null;this.startDate    =    null;this.endDate    =    null;this.showYearNavigation    =    null;this.closeOnSelect=    null;this.displayClose=    null;this.selectMultiple=    null;this.verticalPosition    =    null;this.horizontalPosition    =    null;this.verticalOffset=    null;this.horizontalOffset    =    null;this.button=    null;this.renderCallback=    [];this.selectedDates=    {};this.inline=    null;this.context    =    '#dp-popup';    };    $.extend(DatePicker.prototype,{init : function(s)    {this.setStartDate(s.startDate);this.setEndDate(s.endDate);this.setDisplayedMonth(Number(s.month), Number(s.year));this.setRenderCallback(s.renderCallback);this.showYearNavigation = s.showYearNavigation;this.closeOnSelect = s.closeOnSelect;this.displayClose = s.displayClose;this.selectMultiple = s.selectMultiple;this.verticalPosition = s.verticalPosition;this.horizontalPosition = s.horizontalPosition;this.hoverClass = s.hoverClass;this.setOffset(s.verticalOffset, s.horizontalOffset);this.inline = s.inline;if (this.inline) {    this.context = this.ele;    this.display();}    },    setStartDate : function(d)    {if (d) {    this.startDate = Date.fromString(d);}if (!this.startDate) {    this.startDate = (new Date()).zeroTime();}this.setDisplayedMonth(this.displayedMonth, this.displayedYear);    },    setEndDate : function(d)    {if (d) {    this.endDate = Date.fromString(d);}if (!this.endDate) {    this.endDate = (new Date('12/31/2999')); }if (this.endDate.getTime() < this.startDate.getTime()) {    this.endDate = this.startDate;}this.setDisplayedMonth(this.displayedMonth, this.displayedYear);    },    setPosition : function(v, h)    {this.verticalPosition = v;this.horizontalPosition = h;    },    setOffset : function(v, h)    {this.verticalOffset = parseInt(v) || 0;this.horizontalOffset = parseInt(h) || 0;    },    setDisabled : function(s)    {$e = $(this.ele);$e[s ? 'addClass' : 'removeClass']('dp-disabled');if (this.button) {    $but = $(this.button);    $but[s ? 'addClass' : 'removeClass']('dp-disabled');    $but.attr('title', s ? '' : $.dpText.TEXT_CHOOSE_DATE);}if ($e.is(':text')) {    $e.attr('disabled', s ? 'disabled' : '');}    },    setDisplayedMonth : function(m, y)    {if (this.startDate == undefined || this.endDate == undefined) {    return;}var s = new Date(this.startDate.getTime());s.setDate(1);var e = new Date(this.endDate.getTime());e.setDate(1);var t;if ((!m && !y) || (isNaN(m) && isNaN(y))) {    t = new Date().zeroTime();    t.setDate(1);} else if (isNaN(m)) {    t = new Date(y, this.displayedMonth, 1);} else if (isNaN(y)) {    t = new Date(this.displayedYear, m, 1);} else {    t = new Date(y, m, 1)}if (t.getTime() < s.getTime()) {    t = s;} else if (t.getTime() > e.getTime()) {    t = e;}this.displayedMonth = t.getMonth();this.displayedYear = t.getFullYear();    },    setSelected : function(d, v, moveToMonth)    {if (this.selectMultiple == false) {    this.selectedDates = {};    $('td.selected', this.context).removeClass('selected');}if (moveToMonth) {    this.setDisplayedMonth(d.getMonth(), d.getFullYear());}this.selectedDates[d.toString()] = v;    },    isSelected : function(d)    {return this.selectedDates[d.toString()];    },    getSelected : function()    {var r = [];for(s in this.selectedDates) {    if (this.selectedDates[s] == true) {r.push(Date.parse(s));    }}return r;    },    display : function(eleAlignTo)    {if ($(this.ele).is('.dp-disabled')) return;eleAlignTo = eleAlignTo || this.ele;var c = this;var $ele = $(eleAlignTo);var eleOffset = $ele.offset();var $createIn;var attrs;var attrsCalendarHolder;var cssRules;if (c.inline) {    $createIn = $(this.ele);    attrs = {'id':    'calendar-' + this.ele._dpId,'className'    :    'dp-popup dp-popup-inline'    };    cssRules = {    };} else {    $createIn = $('body');    attrs = {'id':    'dp-popup','className'    :    'dp-popup'    };    cssRules = {'top'    :    eleOffset.top + c.verticalOffset,'left'    :    eleOffset.left + c.horizontalOffset    };var _checkMouse = function(e)    {var el = e.target;var cal = $('#dp-popup')[0];while (true){    if (el == cal) {return true;    } else if (el == document) {c._closeCalendar();return false;    } else {el = $(el).parent()[0];    }}    };    this._checkMouse = _checkMouse;    this._closeCalendar(true);}$createIn    .append($('<div></div>')    .attr(attrs)    .css(cssRules)    .append($('<h2></h2>'),$('<div class="dp-nav-prev"></div>')    .append($('<a class="dp-nav-prev-year" href="#" title="' + $.dpText.TEXT_PREV_YEAR + '">&lt;&lt;</a>')    .bind('click',function(){    return c._displayNewMonth.call(c, this, 0, -1);}    ),$('<a class="dp-nav-prev-month" href="#" title="' + $.dpText.TEXT_PREV_MONTH + '">&lt;</a>')    .bind('click',function(){    return c._displayNewMonth.call(c, this, -1, 0);}    )    ),$('<div class="dp-nav-next"></div>')    .append($('<a class="dp-nav-next-year" href="#" title="' + $.dpText.TEXT_NEXT_YEAR + '">&gt;&gt;</a>')    .bind('click',function(){    return c._displayNewMonth.call(c, this, 0, 1);}    ),$('<a class="dp-nav-next-month" href="#" title="' + $.dpText.TEXT_NEXT_MONTH + '">&gt;</a>')    .bind('click',function(){    return c._displayNewMonth.call(c, this, 1, 0);}    )    ),$('<div></div>')    .attr('className', 'dp-calendar')    )    .bgIframe());    var $pop = this.inline ? $('.dp-popup', this.context) : $('#dp-popup');if (this.showYearNavigation == false) {    $('.dp-nav-prev-year, .dp-nav-next-year', c.context).css('display', 'none');}if (this.displayClose) {    $pop.append($('<a href="#" id="dp-close">' + $.dpText.TEXT_CLOSE + '</a>')    .bind('click',function(){    c._closeCalendar();    return false;}    )    );}c._renderCalendar();$(this.ele).trigger('dpDisplayed', $pop);if (!c.inline) {    if (this.verticalPosition == $.dpConst.POS_BOTTOM) {$pop.css('top', eleOffset.top + $ele.height() - $pop.height() + c.verticalOffset);    }    if (this.horizontalPosition == $.dpConst.POS_RIGHT) {$pop.css('left', eleOffset.left + $ele.width() - $pop.width() + c.horizontalOffset);    }    $(document).bind('mousedown', this._checkMouse);}    },    setRenderCallback : function(a)    {if (a && typeof(a) == 'function') {    a = [a];}this.renderCallback = this.renderCallback.concat(a);    },    cellRender : function ($td, thisDate, month, year) {var c = this.dpController;var d = new Date(thisDate.getTime());$td.bind(    'click',    function()    {var $this = $(this);if (!$this.is('.disabled')) {    c.setSelected(d, !$this.is('.selected') || !c.selectMultiple);    var s = c.isSelected(d);    $(c.ele).trigger('dateSelected', [d, $td, s]);    $(c.ele).trigger('change');    if (c.closeOnSelect) {c._closeCalendar();    } else {$this[s ? 'addClass' : 'removeClass']('selected');    }}    });if (c.isSelected(d)) {    $td.addClass('selected');}for (var i=0; i<c.renderCallback.length; i++) {    c.renderCallback[i].apply(this, arguments);}    },    _displayNewMonth : function(ele, m, y) {if (!$(ele).is('.disabled')) {    this.setDisplayedMonth(this.displayedMonth + m, this.displayedYear + y);    this._clearCalendar();    this._renderCalendar();    $(this.ele).trigger('dpMonthChanged', [this.displayedMonth, this.displayedYear]);}ele.blur();return false;    },    _renderCalendar : function()    {$('h2', this.context).html(Date.monthNames[this.displayedMonth] + ' ' + this.displayedYear);$('.dp-calendar', this.context).renderCalendar(    {month    : this.displayedMonth,year    : this.displayedYear,renderCallback    : this.cellRender,dpController    : this,hoverClass: this.hoverClass    });if (this.displayedYear == this.startDate.getFullYear() && this.displayedMonth == this.startDate.getMonth()) {    $('.dp-nav-prev-year', this.context).addClass('disabled');    $('.dp-nav-prev-month', this.context).addClass('disabled');    $('.dp-calendar td.other-month', this.context).each(function(){    var $this = $(this);    if (Number($this.text()) > 20) {$this.addClass('disabled');    }}    );    var d = this.startDate.getDate();    $('.dp-calendar td.current-month', this.context).each(function(){    var $this = $(this);    if (Number($this.text()) < d) {$this.addClass('disabled');    }}    );} else {    $('.dp-nav-prev-year', this.context).removeClass('disabled');    $('.dp-nav-prev-month', this.context).removeClass('disabled');    var d = this.startDate.getDate();    if (d > 20) {var sd = new Date(this.startDate.getTime());sd.addMonths(1);if (this.displayedYear == sd.getFullYear() && this.displayedMonth == sd.getMonth()) {    $('dp-calendar td.other-month', this.context).each(function(){    var $this = $(this);    if (Number($this.text()) < d) {$this.addClass('disabled');    }}    );}    }}if (this.displayedYear == this.endDate.getFullYear() && this.displayedMonth == this.endDate.getMonth()) {    $('.dp-nav-next-year', this.context).addClass('disabled');    $('.dp-nav-next-month', this.context).addClass('disabled');    $('.dp-calendar td.other-month', this.context).each(function(){    var $this = $(this);    if (Number($this.text()) < 14) {$this.addClass('disabled');    }}    );    var d = this.endDate.getDate();    $('.dp-calendar td.current-month', this.context).each(function(){    var $this = $(this);    if (Number($this.text()) > d) {$this.addClass('disabled');    }}    );} else {    $('.dp-nav-next-year', this.context).removeClass('disabled');    $('.dp-nav-next-month', this.context).removeClass('disabled');    var d = this.endDate.getDate();    if (d < 13) {var ed = new Date(this.endDate.getTime());ed.addMonths(-1);if (this.displayedYear == ed.getFullYear() && this.displayedMonth == ed.getMonth()) {    $('.dp-calendar td.other-month', this.context).each(function(){    var $this = $(this);    if (Number($this.text()) > d) {$this.addClass('disabled');    }}    );}    }}    },    _closeCalendar : function(programatic, ele)    {if (!ele || ele == this.ele){    $(document).unbind('mousedown', this._checkMouse);    this._clearCalendar();    $('#dp-popup a').unbind();    $('#dp-popup').empty().remove();    if (!programatic) {$(this.ele).trigger('dpClosed', [this.getSelected()]);    }}    },    _clearCalendar : function()    {$('.dp-calendar td', this.context).unbind();$('.dp-calendar', this.context).empty();    }}    );$.dpConst = {SHOW_HEADER_NONE    :    0,SHOW_HEADER_SHORT    :    1,SHOW_HEADER_LONG    :    2,POS_TOP:    0,POS_BOTTOM    :    1,POS_LEFT    :    0,POS_RIGHT    :    1    };    $.dpText = {TEXT_PREV_YEAR:    'Previous year',TEXT_PREV_MONTH:    'Previous month',TEXT_NEXT_YEAR:    'Next year',TEXT_NEXT_MONTH:    'Next month',TEXT_CLOSE    :    'Close',TEXT_CHOOSE_DATE    :    'Choose date'    };    $.dpVersion = '$Id: jquery.datePicker.js 3739 2007-10-25 13:55:30Z kelvin.luck $';    function _getController(ele)    {if (ele._dpId) return $.event._dpCache[ele._dpId];return false;    };if ($.fn.bgIframe == undefined) {$.fn.bgIframe = function() {return this; };    };    $(window).bind('unload', function() {    var els = $.event._dpCache || [];    for (var i in els) {$(els[i].ele)._dpDestroy();    }});    })(jQuery);

/*
 * Date prototype extensions. Doesn't depend on any
 * other code. Doens't overwrite existing methods.
 *
 * Adds dayNames, abbrDayNames, monthNames and abbrMonthNames static properties and isLeapYear,
 * isWeekend, isWeekDay, getDaysInMonth, getDayName, getMonthName, getDayOfYear, getWeekOfYear,
 * setDayOfYear, addYears, addMonths, addDays, addHours, addMinutes, addSeconds methods
 *
 * Copyright (c) 2006 J�rn Zaefferer and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 *
 * Additional methods and properties added by Kelvin Luck: firstDayOfWeek, dateFormat, zeroTime, asString, fromString -
 * I've added my name to these methods so you know who to blame if they are broken!
 * 
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */
Date.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
Date.abbrDayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
Date.monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
Date.abbrMonthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
Date.firstDayOfWeek = 7;
//Date.format = 'dd/mm/yyyy';
Date.format = 'mm/dd/yyyy';
//Date.format = 'yyyy-mm-dd';
//Date.format = 'dd mmm yy';
Date.fullYearStart = '20';
 (function() {
    function add(name, method) {
        if (!Date.prototype[name]) {
            Date.prototype[name] = method;
        }
    };
    add("isLeapYear",
    function() {
        var y = this.getFullYear();
        return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
    });
    add("isWeekend",
    function() {
        return this.getDay() == 0 || this.getDay() == 6;
    });
    add("isWeekDay",
    function() {
        return ! this.isWeekend();
    });
    add("getDaysInMonth",
    function() {
        return [31, (this.isLeapYear() ? 29: 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][this.getMonth()];
    });
    add("getDayName",
    function(abbreviated) {
        return abbreviated ? Date.abbrDayNames[this.getDay()] : Date.dayNames[this.getDay()];
    });
    add("getMonthName",
    function(abbreviated) {
        return abbreviated ? Date.abbrMonthNames[this.getMonth()] : Date.monthNames[this.getMonth()];
    });
    add("getDayOfYear",
    function() {
        var tmpdtm = new Date("1/1/" + this.getFullYear());
        return Math.floor((this.getTime() - tmpdtm.getTime()) / 86400000);
    });
    add("getWeekOfYear",
    function() {
        return Math.ceil(this.getDayOfYear() / 7);
    });
    add("setDayOfYear",
    function(day) {
        this.setMonth(0);
        this.setDate(day);
        return this;
    });
    add("addYears",
    function(num) {
        this.setFullYear(this.getFullYear() + num);
        return this;
    });
    add("addMonths",
    function(num) {
        var tmpdtm = this.getDate();
        this.setMonth(this.getMonth() + num);
        if (tmpdtm > this.getDate())
        this.addDays( - this.getDate());
        return this;
    });
    add("addDays",
    function(num) {
        this.setDate(this.getDate() + num);
        return this;
    });
    add("addHours",
    function(num) {
        this.setHours(this.getHours() + num);
        return this;
    });
    add("addMinutes",
    function(num) {
        this.setMinutes(this.getMinutes() + num);
        return this;
    });
    add("addSeconds",
    function(num) {
        this.setSeconds(this.getSeconds() + num);
        return this;
    });
    add("zeroTime",
    function() {
        this.setMilliseconds(0);
        this.setSeconds(0);
        this.setMinutes(0);
        this.setHours(0);
        return this;
    });
    add("asString",
    function() {
        var r = Date.format;
        return r
        .split('yyyy').join(this.getFullYear())
        .split('yy').join((this.getFullYear() + '').substring(2))
        .split('mmm').join(this.getMonthName(true))
        .split('mm').join(_zeroPad(this.getMonth() + 1))
        .split('dd').join(_zeroPad(this.getDate()));
    });
    Date.fromString = function(s)
    {
        var f = Date.format;
        var d = new Date('01/01/1977');
        var iY = f.indexOf('yyyy');
        if (iY > -1) {
            d.setFullYear(Number(s.substr(iY, 4)));
        } else {
            // TODO - this doesn't work very well - are there any rules for what is meant by a two digit year?
            d.setFullYear(Number(Date.fullYearStart + s.substr(f.indexOf('yy'), 2)));
        }
        var iM = f.indexOf('mmm');
        if (iM > -1) {
            var mStr = s.substr(iM, 3);
            for (var i = 0; i < Date.abbrMonthNames.length; i++) {
                if (Date.abbrMonthNames[i] == mStr) break;
            }
            d.setMonth(i);
        } else {
            d.setMonth(Number(s.substr(f.indexOf('mm'), 2)) - 1);
        }
        d.setDate(Number(s.substr(f.indexOf('dd'), 2)));
        if (isNaN(d.getTime())) {
            return false;
        }
        return d;
    };
    // utility method
    var _zeroPad = function(num) {
        var s = '0' + num;
        return s.substring(s.length - 2)
        //return ('0'+num).substring(-2); // doesn't work on IE :(
    };
})();

/** Form Highlights **/
jQuery.fn.highlight = function(selector, className, eventStart, eventEnd) {
    // variables
    var className = className || 'highlight';
    if (eventStart == undefined && eventEnd == undefined) {
        var eventStart = 'mouseover';
        var eventEnd = 'mouseout';
    }
    else if (eventStart == eventEnd || eventStart != undefined && eventEnd == undefined) {
        var toggle = true;
    }
    // code
    this.each
    (
    function() {
        var tagName = this.tagName.toLowerCase();
        if (tagName == 'form') {
            selector = selector || 'li';
            var elements = jQuery("textarea, select, multi-select, :text, :image, :password, :radio, :checkbox, :file", this);
            elements.bind
            (
            'focus',
            function() {
                var parents = jQuery(this).parents(selector)
                var parent = jQuery(parents.get(0))
                parent.addClass(className);
            }
            );
            elements.bind
            (
            'blur',
            function() {
                var parents = jQuery(this).parents(selector)
                var parent = jQuery(parents.get(0))
                parent.removeClass(className);
            }
            );
        }
        else {
            if (tagName.match(/^(table|tbody)$/) != null) {
                selector = selector || 'tr';
            }
            else if (tagName.match(/^(ul|ol)$/) != null) {
                selector = selector || 'li';
            }
            else {
                selector = '*';
            }
            var elements = jQuery(selector, this);
            if (toggle) {
                elements.bind
                (
                eventStart,
                function() {
                    if (jQuery(this).hasClass(className)) {
                        jQuery(this).removeClass(className);
                    }
                    else {
                        jQuery(this).addClass(className);
                    }
                }
                );
            }
            else {
                elements.bind
                (
                eventStart,
                function() {
                    jQuery(this).addClass(className);
                }
                );
                elements.bind
                (
                eventEnd,
                function() {
                    jQuery(this).removeClass(className);
                }
                );
            }
        }
    }
    );
}