0xV3NOMx
Linux ip-172-26-7-228 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64



Your IP : 3.147.77.119


Current Path : /proc/thread-self/root/var/www/oasis/js/
Upload File :
Current File : //proc/thread-self/root/var/www/oasis/js/month_cal.js

/*
 * jQuery UI Datepicker 1.7.2
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Datepicker
 *
 * Depends:
 *	ui.core.js
 */

(function ($) {
  // hide the namespace

  $.extend($.ui, { datepicker: { version: "1.7.2" } });

  var PROP_NAME = "Monthpicker";

  /* Date picker manager.
   Use the singleton instance of this class, $.Monthpicker, to interact with the date picker.
   Settings for (groups of) date pickers are maintained in an instance object,
   allowing multiple different settings on the same page. */

  function Monthpicker() {
    this.debug = false; // Change this to true to start debugging
    this._curInst = null; // The current instance in use
    this._keyEvent = false; // If the last event was a key event
    this._disabledInputs = []; // List of date picker inputs that have been disabled
    this._datepickerShowing = false; // True if the popup picker is showing , false if not
    this._inDialog = false; // True if showing within a "dialog", false if not
    this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
    this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
    this._appendClass = "ui-datepicker-append"; // The name of the append marker class
    this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
    this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
    this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
    this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
    this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
    this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
    this.regional = []; // Available regional settings, indexed by language code
    this.regional[""] = {
      // Default regional settings
      closeText: "Done", // Display text for close link
      prevText: "Prev", // Display text for previous month link
      nextText: "Next", // Display text for next month link
      currentText: "Today", // Display text for current month link
      monthNames: [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December",
      ], // Names of months for drop-down and formatting
      monthNamesShort: [
        "Jan",
        "Feb",
        "Mar",
        "Apr",
        "May",
        "Jun",
        "Jul",
        "Aug",
        "Sep",
        "Oct",
        "Nov",
        "Dec",
      ], // For formatting
      dayNames: [
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
      ], // For formatting
      dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
      dayNamesMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], // Column headings for days starting at Sunday
      dateFormat: "mm/dd/yy", // See format options on parseDate
      firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
      isRTL: false, // True if right-to-left language, false if left-to-right
    };
    this._defaults = {
      // Global defaults for all the date picker instances
      showOn: "focus", // 'focus' for popup on focus,
      // 'button' for trigger button, or 'both' for either
      showAnim: "show", // Name of jQuery animation for popup
      showOptions: {}, // Options for enhanced animations
      defaultDate: null, // Used when field is blank: actual date,
      // +/-number for offset from today, null for today
      appendText: "", // Display text following the input box, e.g. showing the format
      buttonText: "...", // Text for trigger button
      buttonImage: "", // URL for trigger button image
      buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
      hideIfNoPrevNext: false, // True to hide next/previous month links
      // if not applicable, false to just disable them
      navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
      gotoCurrent: false, // True if today link goes back to current selection instead
      changeMonth: false, // True if month can be selected directly, false if only prev/next
      changeYear: false, // True if year can be selected directly, false if only prev/next
      showMonthAfterYear: false, // True if the year select precedes month, false for month then year
      yearRange: "-10:+10", // Range of years to display in drop-down,
      // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
      showOtherMonths: false, // True to show dates in other months, false to leave blank
      calculateWeek: this.iso8601Week, // How to calculate the week of the year,
      // takes a Date and returns the number of the week for it
      shortYearCutoff: "+10", // Short year values < this are in the current century,
      // > this are in the previous century,
      // string value starting with '+' for current year + value
      minDate: null, // The earliest selectable date, or null for no limit
      maxDate: null, // The latest selectable date, or null for no limit
      duration: "normal", // Duration of display/closure
      beforeShowDay: null, // Function that takes a date and returns an array with
      // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
      // [2] = cell title (optional), e.g. $.Monthpicker.noWeekends
      beforeShow: null, // Function that takes an input field and
      // returns a set of custom settings for the date picker
      onSelect: null, // Define a callback function when a date is selected
      onChangeMonthYear: null, // Define a callback function when the month or year is changed
      onClose: null, // Define a callback function when the datepicker is closed
      numberOfMonths: 1, // Number of months to show at a time
      showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
      stepMonths: 1, // Number of months to step back/forward
      stepBigMonths: 12, // Number of months to step back/forward for the big links
      altField: "", // Selector for an alternate field to store selected dates into
      altFormat: "", // The date format to use for the alternate field
      constrainInput: true, // The input is constrained by the current date format
      showButtonPanel: false, // True to show button panel, false to not show it
    };
    $.extend(this._defaults, this.regional[""]);
    this.dpDiv = $(
      '<div id="' +
        this._mainDivId +
        '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>'
    );
  }

  $.extend(Monthpicker.prototype, {
    /* Class name added to elements to indicate already configured with a date picker. */
    markerClassName: "hasDatepicker",

    /* Debug logging (if enabled). */
    log: function () {
      if (this.debug) console.log.apply("", arguments);
    },

    /* Override the default settings for all instances of the date picker.
	   @param  settings  object - the new settings to use as defaults (anonymous object)
	   @return the manager object */
    setDefaults: function (settings) {
      extendRemove(this._defaults, settings || {});
      return this;
    },

    /* Attach the date picker to a jQuery selection.
	   @param  target    element - the target input field or division or span
	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
    _attachDatepicker: function (target, settings) {
      // check for settings on the control itself - in namespace 'date:'
      var inlineSettings = null;
      for (var attrName in this._defaults) {
        var attrValue = target.getAttribute("date:" + attrName);
        if (attrValue) {
          inlineSettings = inlineSettings || {};
          try {
            inlineSettings[attrName] = eval(attrValue);
          } catch (err) {
            inlineSettings[attrName] = attrValue;
          }
        }
      }
      var nodeName = target.nodeName.toLowerCase();
      var inline = nodeName == "div" || nodeName == "span";
      if (!target.id) target.id = "dp" + ++this.uuid;
      var inst = this._newInst($(target), inline);
      inst.settings = $.extend({}, settings || {}, inlineSettings || {});
      if (nodeName == "input") {
        this._connectDatepicker(target, inst);
      } else if (inline) {
        this._inlineDatepicker(target, inst);
      }
    },

    /* Create a new instance object. */
    _newInst: function (target, inline) {
      var id = target[0].id.replace(/([:\[\]\.])/g, "\\\\$1"); // escape jQuery meta chars
      return {
        id: id,
        input: target, // associated target
        selectedDay: 0,
        selectedMonth: 0,
        selectedYear: 0, // current selection
        drawMonth: 0,
        drawYear: 0, // month being drawn
        inline: inline, // is datepicker inline or not
        dpDiv: !inline
          ? this.dpDiv // presentation div
          : $(
              '<div class="' +
                this._inlineClass +
                ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'
            ),
      };
    },

    /* Attach the date picker to an input field. */
    _connectDatepicker: function (target, inst) {
      var input = $(target);
      inst.append = $([]);
      inst.trigger = $([]);
      if (input.hasClass(this.markerClassName)) return;
      var appendText = this._get(inst, "appendText");
      var isRTL = this._get(inst, "isRTL");
      if (appendText) {
        inst.append = $(
          '<span class="' + this._appendClass + '">' + appendText + "</span>"
        );
        input[isRTL ? "before" : "after"](inst.append);
      }
      var showOn = this._get(inst, "showOn");
      if (showOn == "focus" || showOn == "both")
        // pop-up date picker when in the marked field
        input.focus(this._showDatepicker);
      if (showOn == "button" || showOn == "both") {
        // pop-up date picker when button clicked
        var buttonText = this._get(inst, "buttonText");
        var buttonImage = this._get(inst, "buttonImage");
        inst.trigger = $(
          this._get(inst, "buttonImageOnly")
            ? $("<img/>")
                .addClass(this._triggerClass)
                .attr({ src: buttonImage, alt: buttonText, title: buttonText })
            : $('<button type="button"></button>')
                .addClass(this._triggerClass)
                .html(
                  buttonImage == ""
                    ? buttonText
                    : $("<img/>").attr({
                        src: buttonImage,
                        alt: buttonText,
                        title: buttonText,
                      })
                )
        );
        input[isRTL ? "before" : "after"](inst.trigger);
        inst.trigger.click(function () {
          if (
            $.Monthpicker._datepickerShowing &&
            $.Monthpicker._lastInput == target
          )
            $.Monthpicker._hideDatepicker();
          else $.Monthpicker._showDatepicker(target);
          return false;
        });
      }
      input
        .addClass(this.markerClassName)
        .keydown(this._doKeyDown)
        .keypress(this._doKeyPress)
        .bind("setData.datepicker", function (event, key, value) {
          inst.settings[key] = value;
        })
        .bind("getData.datepicker", function (event, key) {
          return this._get(inst, key);
        });
      $.data(target, PROP_NAME, inst);
    },

    /* Attach an inline date picker to a div. */
    _inlineDatepicker: function (target, inst) {
      var divSpan = $(target);
      if (divSpan.hasClass(this.markerClassName)) return;
      divSpan
        .addClass(this.markerClassName)
        .append(inst.dpDiv)
        .bind("setData.datepicker", function (event, key, value) {
          inst.settings[key] = value;
        })
        .bind("getData.datepicker", function (event, key) {
          return this._get(inst, key);
        });
      $.data(target, PROP_NAME, inst);
      this._setDate(inst, this._getDefaultDate(inst));
      this._updateDatepicker(inst);
      this._updateAlternate(inst);
    },

    /* Pop-up the date picker in a "dialog" box.
	   @param  input     element - ignored
	   @param  dateText  string - the initial date to display (in the current format)
	   @param  onSelect  function - the function(dateText) to call when a date is selected
	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
	                     event - with x/y coordinates or
	                     leave empty for default (screen centre)
	   @return the manager object */
    _dialogDatepicker: function (input, dateText, onSelect, settings, pos) {
      var inst = this._dialogInst; // internal instance
      if (!inst) {
        var id = "dp" + ++this.uuid;
        this._dialogInput = $(
          '<input type="text" id="' +
            id +
            '" size="1" style="position: absolute; top: -100px;"/>'
        );
        this._dialogInput.keydown(this._doKeyDown);
        $("body").append(this._dialogInput);
        inst = this._dialogInst = this._newInst(this._dialogInput, false);
        inst.settings = {};
        $.data(this._dialogInput[0], PROP_NAME, inst);
      }
      extendRemove(inst.settings, settings || {});
      this._dialogInput.val(dateText);

      this._pos = pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null;
      if (!this._pos) {
        var browserWidth =
          window.innerWidth ||
          document.documentElement.clientWidth ||
          document.body.clientWidth;
        var browserHeight =
          window.innerHeight ||
          document.documentElement.clientHeight ||
          document.body.clientHeight;
        var scrollX =
          document.documentElement.scrollLeft || document.body.scrollLeft;
        var scrollY =
          document.documentElement.scrollTop || document.body.scrollTop;
        this._pos =
          // should use actual width/height below
          [browserWidth / 2 - 100 + scrollX, browserHeight / 2 - 150 + scrollY];
      }

      // move input on screen for focus, but hidden behind dialog
      this._dialogInput
        .css("left", this._pos[0] + "px")
        .css("top", this._pos[1] + "px");
      inst.settings.onSelect = onSelect;
      this._inDialog = true;
      this.dpDiv.addClass(this._dialogClass);
      this._showDatepicker(this._dialogInput[0]);
      if ($.blockUI) $.blockUI(this.dpDiv);
      $.data(this._dialogInput[0], PROP_NAME, inst);
      return this;
    },

    /* Detach a datepicker from its control.
	   @param  target    element - the target input field or division or span */
    _destroyDatepicker: function (target) {
      var $target = $(target);
      var inst = $.data(target, PROP_NAME);
      if (!$target.hasClass(this.markerClassName)) {
        return;
      }
      var nodeName = target.nodeName.toLowerCase();
      $.removeData(target, PROP_NAME);
      if (nodeName == "input") {
        inst.append.remove();
        inst.trigger.remove();
        $target
          .removeClass(this.markerClassName)
          .unbind("focus", this._showDatepicker)
          .unbind("keydown", this._doKeyDown)
          .unbind("keypress", this._doKeyPress);
      } else if (nodeName == "div" || nodeName == "span")
        $target.removeClass(this.markerClassName).empty();
    },

    /* Enable the date picker to a jQuery selection.
	   @param  target    element - the target input field or division or span */
    _enableDatepicker: function (target) {
      var $target = $(target);
      var inst = $.data(target, PROP_NAME);
      if (!$target.hasClass(this.markerClassName)) {
        return;
      }
      var nodeName = target.nodeName.toLowerCase();
      if (nodeName == "input") {
        target.disabled = false;
        inst.trigger
          .filter("button")
          .each(function () {
            this.disabled = false;
          })
          .end()
          .filter("img")
          .css({ opacity: "1.0", cursor: "" });
      } else if (nodeName == "div" || nodeName == "span") {
        var inline = $target.children("." + this._inlineClass);
        inline.children().removeClass("ui-state-disabled");
      }
      this._disabledInputs = $.map(this._disabledInputs, function (value) {
        return value == target ? null : value;
      }); // delete entry
    },

    /* Disable the date picker to a jQuery selection.
	   @param  target    element - the target input field or division or span */
    _disableDatepicker: function (target) {
      var $target = $(target);
      var inst = $.data(target, PROP_NAME);
      if (!$target.hasClass(this.markerClassName)) {
        return;
      }
      var nodeName = target.nodeName.toLowerCase();
      if (nodeName == "input") {
        target.disabled = true;
        inst.trigger
          .filter("button")
          .each(function () {
            this.disabled = true;
          })
          .end()
          .filter("img")
          .css({ opacity: "0.5", cursor: "default" });
      } else if (nodeName == "div" || nodeName == "span") {
        var inline = $target.children("." + this._inlineClass);
        inline.children().addClass("ui-state-disabled");
      }
      this._disabledInputs = $.map(this._disabledInputs, function (value) {
        return value == target ? null : value;
      }); // delete entry
      this._disabledInputs[this._disabledInputs.length] = target;
    },

    /* Is the first field in a jQuery collection disabled as a datepicker?
	   @param  target    element - the target input field or division or span
	   @return boolean - true if disabled, false if enabled */
    _isDisabledDatepicker: function (target) {
      if (!target) {
        return false;
      }
      for (var i = 0; i < this._disabledInputs.length; i++) {
        if (this._disabledInputs[i] == target) return true;
      }
      return false;
    },

    /* Retrieve the instance data for the target control.
	   @param  target  element - the target input field or division or span
	   @return  object - the associated instance data
	   @throws  error if a jQuery problem getting data */
    _getInst: function (target) {
      try {
        return $.data(target, PROP_NAME);
      } catch (err) {
        throw "Missing instance data for this datepicker";
      }
    },

    /* Update or retrieve the settings for a date picker attached to an input field or division.
	   @param  target  element - the target input field or division or span
	   @param  name    object - the new settings to update or
	                   string - the name of the setting to change or retrieve,
	                   when retrieving also 'all' for all instance settings or
	                   'defaults' for all global defaults
	   @param  value   any - the new value for the setting
	                   (omit if above is an object or to retrieve a value) */
    _optionDatepicker: function (target, name, value) {
      var inst = this._getInst(target);
      if (arguments.length == 2 && typeof name == "string") {
        return name == "defaults"
          ? $.extend({}, $.Monthpicker._defaults)
          : inst
          ? name == "all"
            ? $.extend({}, inst.settings)
            : this._get(inst, name)
          : null;
      }
      var settings = name || {};
      if (typeof name == "string") {
        settings = {};
        settings[name] = value;
      }
      if (inst) {
        if (this._curInst == inst) {
          this._hideDatepicker(null);
        }
        var date = this._getDateDatepicker(target);
        extendRemove(inst.settings, settings);
        this._setDateDatepicker(target, date);
        this._updateDatepicker(inst);
      }
    },

    // change method deprecated
    _changeDatepicker: function (target, name, value) {
      this._optionDatepicker(target, name, value);
    },

    /* Redraw the date picker attached to an input field or division.
	   @param  target  element - the target input field or division or span */
    _refreshDatepicker: function (target) {
      var inst = this._getInst(target);
      if (inst) {
        this._updateDatepicker(inst);
      }
    },

    /* Set the dates for a jQuery selection.
	   @param  target   element - the target input field or division or span
	   @param  date     Date - the new date
	   @param  endDate  Date - the new end date for a range (optional) */
    _setDateDatepicker: function (target, date, endDate) {
      var inst = this._getInst(target);
      if (inst) {
        this._setDate(inst, date, endDate);
        this._updateDatepicker(inst);
        this._updateAlternate(inst);
      }
    },

    /* Get the date(s) for the first entry in a jQuery selection.
	   @param  target  element - the target input field or division or span
	   @return Date - the current date or
	           Date[2] - the current dates for a range */
    _getDateDatepicker: function (target) {
      var inst = this._getInst(target);
      if (inst && !inst.inline) this._setDateFromField(inst);
      return inst ? this._getDate(inst) : null;
    },

    /* Filter entered characters - based on date format. */
    _doKeyPress: function (event) {
      var inst = $.Monthpicker._getInst(event.target);
      if ($.Monthpicker._get(inst, "constrainInput")) {
        var chars = $.Monthpicker._possibleChars(
          $.Monthpicker._get(inst, "dateFormat")
        );
        var chr = String.fromCharCode(
          event.charCode == undefined ? event.keyCode : event.charCode
        );
        return event.ctrlKey || chr < " " || !chars || chars.indexOf(chr) > -1;
      }
    },

    /* Pop-up the date picker for a given input field.
	   @param  input  element - the input field attached to the date picker or
	                  event - if triggered by focus */
    _showDatepicker: function (input) {
      input = input.target || input;
      if (input.nodeName.toLowerCase() != "input")
        // find from button/image trigger
        input = $("input", input.parentNode)[0];
      if (
        $.Monthpicker._isDisabledDatepicker(input) ||
        $.Monthpicker._lastInput == input
      )
        // already here
        return;
      var inst = $.Monthpicker._getInst(input);
      var beforeShow = $.Monthpicker._get(inst, "beforeShow");
      extendRemove(
        inst.settings,
        beforeShow ? beforeShow.apply(input, [input, inst]) : {}
      );
      $.Monthpicker._hideDatepicker(null, "");
      $.Monthpicker._lastInput = input;
      $.Monthpicker._setDateFromField(inst);
      if ($.Monthpicker._inDialog)
        // hide cursor
        input.value = "";
      if (!$.Monthpicker._pos) {
        // position below input
        $.Monthpicker._pos = $.Monthpicker._findPos(input);
        $.Monthpicker._pos[1] += input.offsetHeight; // add the height
      }
      var isFixed = false;
      $(input)
        .parents()
        .each(function () {
          isFixed |= $(this).css("position") == "fixed";
          return !isFixed;
        });
      if (isFixed && $.browser.opera) {
        // correction for Opera when fixed and scrolled
        $.Monthpicker._pos[0] -= document.documentElement.scrollLeft;
        $.Monthpicker._pos[1] -= document.documentElement.scrollTop;
      }
      var offset = { left: $.Monthpicker._pos[0], top: $.Monthpicker._pos[1] };
      $.Monthpicker._pos = null;
      inst.rangeStart = null;
      // determine sizing offscreen
      inst.dpDiv.css({
        position: "absolute",
        display: "block",
        top: "-1000px",
      });
      $.Monthpicker._updateDatepicker(inst);
      // fix width for dynamic number of date pickers
      // and adjust position before showing
      offset = $.Monthpicker._checkOffset(inst, offset, isFixed);
      inst.dpDiv.css({
        position:
          $.Monthpicker._inDialog && $.blockUI
            ? "static"
            : isFixed
            ? "fixed"
            : "absolute",
        display: "none",
        left: offset.left + "px",
        top: offset.top + "px",
      });
      if (!inst.inline) {
        var showAnim = $.Monthpicker._get(inst, "showAnim") || "show";
        var duration = $.Monthpicker._get(inst, "duration");
        var postProcess = function () {
          $.Monthpicker._datepickerShowing = true;
          if ($.browser.msie && parseInt($.browser.version, 10) < 7)
            // fix IE < 7 select problems
            $("iframe.ui-datepicker-cover").css({
              width: inst.dpDiv.width() + 4,
              height: inst.dpDiv.height() + 4,
            });
        };
        if ($.effects && $.effects[showAnim])
          inst.dpDiv.show(
            showAnim,
            $.Monthpicker._get(inst, "showOptions"),
            duration,
            postProcess
          );
        else inst.dpDiv[showAnim](duration, postProcess);
        if (duration == "") postProcess();
        if (inst.input[0].type != "hidden") inst.input[0].focus();
        $.Monthpicker._curInst = inst;
      }
    },

    /* Generate the date picker content. */
    _updateDatepicker: function (inst) {
      var dims = {
        width: inst.dpDiv.width() + 4,
        height: inst.dpDiv.height() + 4,
      };
      var self = this;
      inst.dpDiv
        .empty()
        .append(this._generateHTML(inst))
        .find("iframe.ui-datepicker-cover")
        .css({ width: dims.width, height: dims.height })
        .end()
        .find(
          "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"
        )
        .bind("mouseout", function () {
          $(this).removeClass("ui-state-hover");
          if (this.className.indexOf("ui-datepicker-prev") != -1)
            $(this).removeClass("ui-datepicker-prev-hover");
          if (this.className.indexOf("ui-datepicker-next") != -1)
            $(this).removeClass("ui-datepicker-next-hover");
        })
        .bind("mouseover", function () {
          if (
            !self._isDisabledDatepicker(
              inst.inline ? inst.dpDiv.parent()[0] : inst.input[0]
            )
          ) {
            $(this)
              .parents(".ui-datepicker-calendar")
              .find("a")
              .removeClass("ui-state-hover");
            $(this).addClass("ui-state-hover");
            if (this.className.indexOf("ui-datepicker-prev") != -1)
              $(this).addClass("ui-datepicker-prev-hover");
            if (this.className.indexOf("ui-datepicker-next") != -1)
              $(this).addClass("ui-datepicker-next-hover");
          }
        })
        .end()
        .find("." + this._dayOverClass + " a")
        .trigger("mouseover")
        .end();
      var numMonths = this._getNumberOfMonths(inst);
      var cols = numMonths[1];
      var width = 17;
      if (cols > 1) {
        inst.dpDiv
          .addClass("ui-datepicker-multi-" + cols)
          .css("width", width * cols + "em");
      } else {
        inst.dpDiv
          .removeClass(
            "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4"
          )
          .width("");
      }
      inst.dpDiv[
        (numMonths[0] != 1 || numMonths[1] != 1 ? "add" : "remove") + "Class"
      ]("ui-datepicker-multi");
      inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + "Class"](
        "ui-datepicker-rtl"
      );
      if (
        inst.input &&
        inst.input[0].type != "hidden" &&
        inst == $.Monthpicker._curInst
      )
        $(inst.input[0]).focus();
    },

    /* Check positioning to remain on screen. */
    _checkOffset: function (inst, offset, isFixed) {
      var dpWidth = inst.dpDiv.outerWidth();
      var dpHeight = inst.dpDiv.outerHeight();
      var inputWidth = inst.input ? inst.input.outerWidth() : 0;
      var inputHeight = inst.input ? inst.input.outerHeight() : 0;
      var viewWidth =
        (window.innerWidth ||
          document.documentElement.clientWidth ||
          document.body.clientWidth) + $(document).scrollLeft();
      var viewHeight =
        (window.innerHeight ||
          document.documentElement.clientHeight ||
          document.body.clientHeight) + $(document).scrollTop();

      offset.left -= this._get(inst, "isRTL") ? dpWidth - inputWidth : 0;
      offset.left -=
        isFixed && offset.left == inst.input.offset().left
          ? $(document).scrollLeft()
          : 0;
      offset.top -=
        isFixed && offset.top == inst.input.offset().top + inputHeight
          ? $(document).scrollTop()
          : 0;

      // now check if datepicker is showing outside window viewport - move to a better place if so.
      offset.left -=
        offset.left + dpWidth > viewWidth && viewWidth > dpWidth
          ? Math.abs(offset.left + dpWidth - viewWidth)
          : 0;
      offset.top -=
        offset.top + dpHeight > viewHeight && viewHeight > dpHeight
          ? Math.abs(offset.top + dpHeight + inputHeight * 2 - viewHeight)
          : 0;

      return offset;
    },

    /* Find an object's position on the screen. */
    _findPos: function (obj) {
      while (obj && (obj.type == "hidden" || obj.nodeType != 1)) {
        obj = obj.nextSibling;
      }
      var position = $(obj).offset();
      return [position.left, position.top];
    },

    /* Hide the date picker from view.
	   @param  input  element - the input field attached to the date picker
	   @param  duration  string - the duration over which to close the date picker */
    _hideDatepicker: function (input, duration) {
      var inst = this._curInst;
      if (!inst || (input && inst != $.data(input, PROP_NAME))) return;
      if (inst.stayOpen)
        this._selectDate(
          "#" + inst.id,
          this._formatDate(
            inst,
            inst.currentDay,
            inst.currentMonth,
            inst.currentYear
          )
        );
      inst.stayOpen = false;
      if (this._datepickerShowing) {
        duration = duration != null ? duration : this._get(inst, "duration");
        var showAnim = this._get(inst, "showAnim");
        var postProcess = function () {
          $.Monthpicker._tidyDialog(inst);
        };
        if (duration != "" && $.effects && $.effects[showAnim])
          inst.dpDiv.hide(
            showAnim,
            $.Monthpicker._get(inst, "showOptions"),
            duration,
            postProcess
          );
        else
          inst.dpDiv[
            duration == ""
              ? "hide"
              : showAnim == "slideDown"
              ? "slideUp"
              : showAnim == "fadeIn"
              ? "fadeOut"
              : "hide"
          ](duration, postProcess);
        if (duration == "") this._tidyDialog(inst);
        var onClose = this._get(inst, "onClose");
        if (onClose)
          onClose.apply(inst.input ? inst.input[0] : null, [
            inst.input ? inst.input.val() : "",
            inst,
          ]); // trigger custom callback
        this._datepickerShowing = false;
        this._lastInput = null;
        if (this._inDialog) {
          this._dialogInput.css({
            position: "absolute",
            left: "0",
            top: "-100px",
          });
          if ($.blockUI) {
            $.unblockUI();
            $("body").append(this.dpDiv);
          }
        }
        this._inDialog = false;
      }
      this._curInst = null;
    },

    /* Tidy up after a dialog display. */
    _tidyDialog: function (inst) {
      inst.dpDiv
        .removeClass(this._dialogClass)
        .unbind(".ui-datepicker-calendar");
    },

    /* Close date picker if clicked elsewhere. */
    _checkExternalClick: function (event) {
      if (!$.Monthpicker._curInst) return;
      var $target = $(event.target);
      if (
        $target.parents("#" + $.Monthpicker._mainDivId).length == 0 &&
        !$target.hasClass($.Monthpicker.markerClassName) &&
        !$target.hasClass($.Monthpicker._triggerClass) &&
        $.Monthpicker._datepickerShowing &&
        !($.Monthpicker._inDialog && $.blockUI)
      )
        $.Monthpicker._hideDatepicker(null, "");
    },

    /* Adjust one of the date sub-fields. */
    _adjustDate: function (id, offset, period) {
      var target = $(id);
      var inst = this._getInst(target[0]);
      if (this._isDisabledDatepicker(target[0])) {
        return;
      }
      this._adjustInstDate(
        inst,
        offset + (period == "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
        period
      );
      this._updateDatepicker(inst);
    },

    /* Action for current link. */
    _gotoToday: function (id) {
      var target = $(id);
      var inst = this._getInst(target[0]);
      if (this._get(inst, "gotoCurrent") && inst.currentDay) {
        inst.selectedDay = inst.currentDay;
        inst.drawMonth = inst.selectedMonth = inst.currentMonth;
        inst.drawYear = inst.selectedYear = inst.currentYear;
      } else {
        var date = new Date();
        inst.selectedDay = date.getDate();
        inst.drawMonth = inst.selectedMonth = date.getMonth();
        inst.drawYear = inst.selectedYear = date.getFullYear();
      }
      this._notifyChange(inst);
      this._adjustDate(target);
    },

    /* Action for selecting a new month/year. */
    _selectMonthYear: function (id, select, period) {
      var target = $(id);
      var inst = this._getInst(target[0]);
      inst._selectingMonthYear = false;
      inst["selected" + (period == "M" ? "Month" : "Year")] = inst[
        "draw" + (period == "M" ? "Month" : "Year")
      ] = parseInt(select.options[select.selectedIndex].value, 10);
      this._notifyChange(inst);
      this._adjustDate(target);
    },

    /* Restore input focus after not changing month/year. */
    _clickMonthYear: function (id) {
      var target = $(id);
      var inst = this._getInst(target[0]);
      if (inst.input && inst._selectingMonthYear && !$.browser.msie)
        inst.input[0].focus();
      inst._selectingMonthYear = !inst._selectingMonthYear;
    },

    /* Action for selecting a day. */
    _selectMonth: function (id, month, year, td) {
      var target = $(id);
      var year = parseInt($(".ui-month-datepicker-year").text());
      var dateStr = month + "-" + year;
      if (
        $(td).hasClass(this._unselectableClass) ||
        this._isDisabledDatepicker(target[0])
      ) {
        return;
      }
      var inst = this._getInst(target[0]);
      inst.selectedMonth = month;
      inst.selectedYear = year;
      if (inst.stayOpen) {
        inst.endDay = inst.endMonth = inst.endYear = null;
      }
      this._SetselectedMonth(id, dateStr);
      if (inst.stayOpen) {
        inst.rangeStart = this._daylightSavingAdjust(
          new Date(inst.currentYear, inst.currentMonth, inst.currentDay)
        );
        this._updateDatepicker(inst);
      }
    },

    /* Erase the input field and hide the date picker. */
    _clearDate: function (id) {
      var target = $(id);
      var inst = this._getInst(target[0]);
      inst.stayOpen = false;
      inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
      this._SetselectedMonth(target, "");
    },

    /* Update the input field with the selected date. */
    _SetselectedMonth: function (id, dateStr) {
      var target = $(id);
      var inst = this._getInst(target[0]);
      if (inst.input) inst.input.val(dateStr);

      this._updateAlternate(inst);
      var onSelect = this._get(inst, "onSelect");
      if (onSelect)
        onSelect.apply(inst.input ? inst.input[0] : null, [
          dateStr,
          inst,
        ]); // trigger custom callback
      else if (inst.input) inst.input.trigger("change"); // fire the change event
      if (inst.inline) this._updateDatepicker(inst);
      else if (!inst.stayOpen) {
        this._hideDatepicker(null, this._get(inst, "duration"));
        this._lastInput = inst.input[0];
        if (typeof inst.input[0] != "object") inst.input[0].focus(); // restore focus
        this._lastInput = null;
      }
    },

    /* Update any alternate field to synchronise with the main field. */
    _updateAlternate: function (inst) {
      var altField = this._get(inst, "altField");
      if (altField) {
        // update alternate field too
        var altFormat =
          this._get(inst, "altFormat") || this._get(inst, "dateFormat");
        var date = this._getDate(inst);
        dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
        $(altField).each(function () {
          $(this).val(dateStr);
        });
      }
    },

    /* Set as beforeShowDay function to prevent selection of weekends.
	   @param  date  Date - the date to customise
	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
    noWeekends: function (date) {
      var day = date.getDay();
      return [day > 0 && day < 6, ""];
    },

    /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
	   @param  date  Date - the date to get the week for
	   @return  number - the number of the week within the year that contains this date */
    iso8601Week: function (date) {
      var checkDate = new Date(
        date.getFullYear(),
        date.getMonth(),
        date.getDate()
      );
      var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
      var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
      firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
      if (firstDay < 4 && checkDate < firstMon) {
        // Adjust first three days in year if necessary
        checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
        return $.Monthpicker.iso8601Week(checkDate);
      } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) {
        // Check last three days in year
        firstDay =
          new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
        if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) {
          // Adjust if necessary
          return 1;
        }
      }
      return Math.floor((checkDate - firstMon) / 86400000 / 7) + 1; // Weeks to given date
    },

    /* Parse a string value into a date object.
	   See formatDate below for the possible formats.

	   @param  format    string - the expected format of the date
	   @param  value     string - the date in the above format
	   @param  settings  Object - attributes include:
	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
	                     dayNames         string[7] - names of the days from Sunday (optional)
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
	                     monthNames       string[12] - names of the months (optional)
	   @return  Date - the extracted date value or null if value is blank */
    parseDate: function (format, value, settings) {
      if (format == null || value == null) throw "Invalid arguments";
      value = typeof value == "object" ? value.toString() : value + "";
      if (value == "") return null;
      var shortYearCutoff =
        (settings ? settings.shortYearCutoff : null) ||
        this._defaults.shortYearCutoff;
      var dayNamesShort =
        (settings ? settings.dayNamesShort : null) ||
        this._defaults.dayNamesShort;
      var dayNames =
        (settings ? settings.dayNames : null) || this._defaults.dayNames;
      var monthNamesShort =
        (settings ? settings.monthNamesShort : null) ||
        this._defaults.monthNamesShort;
      var monthNames =
        (settings ? settings.monthNames : null) || this._defaults.monthNames;
      var year = -1;
      var month = -1;
      var day = -1;
      var doy = -1;
      var literal = false;
      // Check whether a format character is doubled
      var lookAhead = function (match) {
        var matches =
          iFormat + 1 < format.length && format.charAt(iFormat + 1) == match;
        if (matches) iFormat++;
        return matches;
      };
      // Extract a number from the string value
      var getNumber = function (match) {
        lookAhead(match);
        var origSize =
          match == "@" ? 14 : match == "y" ? 4 : match == "o" ? 3 : 2;
        var size = origSize;
        var num = 0;
        while (
          size > 0 &&
          iValue < value.length &&
          value.charAt(iValue) >= "0" &&
          value.charAt(iValue) <= "9"
        ) {
          num = num * 10 + parseInt(value.charAt(iValue++), 10);
          size--;
        }
        if (size == origSize) throw "Missing number at position " + iValue;
        return num;
      };
      // Extract a name from the string value and convert to an index
      var getName = function (match, shortNames, longNames) {
        var names = lookAhead(match) ? longNames : shortNames;
        var size = 0;
        for (var j = 0; j < names.length; j++)
          size = Math.max(size, names[j].length);
        var name = "";
        var iInit = iValue;
        while (size > 0 && iValue < value.length) {
          name += value.charAt(iValue++);
          for (var i = 0; i < names.length; i++)
            if (name == names[i]) return i + 1;
          size--;
        }
        throw "Unknown name at position " + iInit;
      };
      // Confirm that a literal character matches the string value
      var checkLiteral = function () {
        if (value.charAt(iValue) != format.charAt(iFormat))
          throw "Unexpected literal at position " + iValue;
        iValue++;
      };
      var iValue = 0;
      for (var iFormat = 0; iFormat < format.length; iFormat++) {
        if (literal)
          if (format.charAt(iFormat) == "'" && !lookAhead("'")) literal = false;
          else checkLiteral();
        else
          switch (format.charAt(iFormat)) {
            case "d":
              day = getNumber("d");
              break;
            case "D":
              getName("D", dayNamesShort, dayNames);
              break;
            case "o":
              doy = getNumber("o");
              break;
            case "m":
              month = getNumber("m");
              break;
            case "M":
              month = getName("M", monthNamesShort, monthNames);
              break;
            case "y":
              year = getNumber("y");
              break;
            case "@":
              var date = new Date(getNumber("@"));
              year = date.getFullYear();
              month = date.getMonth() + 1;
              day = date.getDate();
              break;
            case "'":
              if (lookAhead("'")) checkLiteral();
              else literal = true;
              break;
            default:
              checkLiteral();
          }
      }
      if (year == -1) year = new Date().getFullYear();
      else if (year < 100)
        year +=
          new Date().getFullYear() -
          (new Date().getFullYear() % 100) +
          (year <= shortYearCutoff ? 0 : -100);
      if (doy > -1) {
        month = 1;
        day = doy;
        do {
          var dim = this._getDaysInMonth(year, month - 1);
          if (day <= dim) break;
          month++;
          day -= dim;
        } while (true);
      }
      var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
      if (
        date.getFullYear() != year ||
        date.getMonth() + 1 != month ||
        date.getDate() != day
      )
        throw "Invalid date"; // E.g. 31/02/*
      return date;
    },

    /* Standard date formats. */
    ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
    COOKIE: "D, dd M yy",
    ISO_8601: "yy-mm-dd",
    RFC_822: "D, d M y",
    RFC_850: "DD, dd-M-y",
    RFC_1036: "D, d M y",
    RFC_1123: "D, d M yy",
    RFC_2822: "D, d M yy",
    RSS: "D, d M y", // RFC 822
    TIMESTAMP: "@",
    W3C: "yy-mm-dd", // ISO 8601

    /* Format a date object into a string value.
	   The format can be combinations of the following:
	   d  - day of month (no leading zero)
	   dd - day of month (two digit)
	   o  - day of year (no leading zeros)
	   oo - day of year (three digit)
	   D  - day name short
	   DD - day name long
	   m  - month of year (no leading zero)
	   mm - month of year (two digit)
	   M  - month name short
	   MM - month name long
	   y  - year (two digit)
	   yy - year (four digit)
	   @ - Unix timestamp (ms since 01/01/1970)
	   '...' - literal text
	   '' - single quote

	   @param  format    string - the desired format of the date
	   @param  date      Date - the date value to format
	   @param  settings  Object - attributes include:
	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
	                     dayNames         string[7] - names of the days from Sunday (optional)
	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
	                     monthNames       string[12] - names of the months (optional)
	   @return  string - the date in the above format */
    formatDate: function (format, date, settings) {
      if (!date) return "";
      var dayNamesShort =
        (settings ? settings.dayNamesShort : null) ||
        this._defaults.dayNamesShort;
      var dayNames =
        (settings ? settings.dayNames : null) || this._defaults.dayNames;
      var monthNamesShort =
        (settings ? settings.monthNamesShort : null) ||
        this._defaults.monthNamesShort;
      var monthNames =
        (settings ? settings.monthNames : null) || this._defaults.monthNames;
      // Check whether a format character is doubled
      var lookAhead = function (match) {
        var matches =
          iFormat + 1 < format.length && format.charAt(iFormat + 1) == match;
        if (matches) iFormat++;
        return matches;
      };
      // Format a number, with leading zero if necessary
      var formatNumber = function (match, value, len) {
        var num = "" + value;
        if (lookAhead(match)) while (num.length < len) num = "0" + num;
        return num;
      };
      // Format a name, short or long as requested
      var formatName = function (match, value, shortNames, longNames) {
        return lookAhead(match) ? longNames[value] : shortNames[value];
      };
      var output = "";
      var literal = false;
      if (date)
        for (var iFormat = 0; iFormat < format.length; iFormat++) {
          if (literal)
            if (format.charAt(iFormat) == "'" && !lookAhead("'"))
              literal = false;
            else output += format.charAt(iFormat);
          else
            switch (format.charAt(iFormat)) {
              case "d":
                output += formatNumber("d", date.getDate(), 2);
                break;
              case "D":
                output += formatName(
                  "D",
                  date.getDay(),
                  dayNamesShort,
                  dayNames
                );
                break;
              case "o":
                var doy = date.getDate();
                for (var m = date.getMonth() - 1; m >= 0; m--)
                  doy += this._getDaysInMonth(date.getFullYear(), m);
                output += formatNumber("o", doy, 3);
                break;
              case "m":
                output += formatNumber("m", date.getMonth() + 1, 2);
                break;
              case "M":
                output += formatName(
                  "M",
                  date.getMonth(),
                  monthNamesShort,
                  monthNames
                );
                break;
              case "y":
                output += lookAhead("y")
                  ? date.getFullYear()
                  : (date.getYear() % 100 < 10 ? "0" : "") +
                    (date.getYear() % 100);
                break;
              case "@":
                output += date.getTime();
                break;
              case "'":
                if (lookAhead("'")) output += "'";
                else literal = true;
                break;
              default:
                output += format.charAt(iFormat);
            }
        }
      return output;
    },

    /* Extract all possible characters from the date format. */
    _possibleChars: function (format) {
      var chars = "";
      var literal = false;
      for (var iFormat = 0; iFormat < format.length; iFormat++)
        if (literal)
          if (format.charAt(iFormat) == "'" && !lookAhead("'")) literal = false;
          else chars += format.charAt(iFormat);
        else
          switch (format.charAt(iFormat)) {
            case "d":
            case "m":
            case "y":
            case "@":
              chars += "0123456789";
              break;
            case "D":
            case "M":
              return null; // Accept anything
            case "'":
              if (lookAhead("'")) chars += "'";
              else literal = true;
              break;
            default:
              chars += format.charAt(iFormat);
          }
      return chars;
    },

    /* Get a setting value, defaulting if necessary. */
    _get: function (inst, name) {
      return inst.settings[name] !== undefined
        ? inst.settings[name]
        : this._defaults[name];
    },

    /* Parse existing date and initialise date picker. */
    _setDateFromField: function (inst) {
      var dateFormat = this._get(inst, "dateFormat");
      var dates = inst.input ? inst.input.val() : null;
      inst.endDay = inst.endMonth = inst.endYear = null;
      var date = (defaultDate = this._getDefaultDate(inst));
      var settings = this._getFormatConfig(inst);
      try {
        date = this.parseDate(dateFormat, dates, settings) || defaultDate;
      } catch (event) {
        this.log(event);
        date = defaultDate;
      }
      inst.selectedDay = date.getDate();
      inst.drawMonth = inst.selectedMonth = date.getMonth();
      inst.drawYear = inst.selectedYear = date.getFullYear();
      inst.currentDay = dates ? date.getDate() : 0;
      inst.currentMonth = dates ? date.getMonth() : 0;
      inst.currentYear = dates ? date.getFullYear() : 0;
      this._adjustInstDate(inst);
    },

    /* Retrieve the default date shown on opening. */
    _getDefaultDate: function (inst) {
      var date = this._determineDate(
        this._get(inst, "defaultDate"),
        new Date()
      );
      var minDate = this._getMinMaxDate(inst, "min", true);
      var maxDate = this._getMinMaxDate(inst, "max");
      date = minDate && date < minDate ? minDate : date;
      date = maxDate && date > maxDate ? maxDate : date;
      return date;
    },

    /* A date may be specified as an exact value or a relative one. */
    _determineDate: function (date, defaultDate) {
      var offsetNumeric = function (offset) {
        var date = new Date();
        date.setDate(date.getDate() + offset);
        return date;
      };
      var offsetString = function (offset, getDaysInMonth) {
        var date = new Date();
        var year = date.getFullYear();
        var month = date.getMonth();
        var day = date.getDate();
        var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
        var matches = pattern.exec(offset);
        while (matches) {
          switch (matches[2] || "d") {
            case "d":
            case "D":
              day += parseInt(matches[1], 10);
              break;
            case "w":
            case "W":
              day += parseInt(matches[1], 10) * 7;
              break;
            case "m":
            case "M":
              month += parseInt(matches[1], 10);
              day = Math.min(day, getDaysInMonth(year, month));
              break;
            case "y":
            case "Y":
              year += parseInt(matches[1], 10);
              day = Math.min(day, getDaysInMonth(year, month));
              break;
          }
          matches = pattern.exec(offset);
        }
        return new Date(year, month, day);
      };
      date =
        date == null
          ? defaultDate
          : typeof date == "string"
          ? offsetString(date, this._getDaysInMonth)
          : typeof date == "number"
          ? isNaN(date)
            ? defaultDate
            : offsetNumeric(date)
          : date;
      date = date && date.toString() == "Invalid Date" ? defaultDate : date;
      if (date) {
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        date.setMilliseconds(0);
      }
      return this._daylightSavingAdjust(date);
    },

    /* Handle switch to/from daylight saving.
	   Hours may be non-zero on daylight saving cut-over:
	   > 12 when midnight changeover, but then cannot generate
	   midnight datetime, so jump to 1AM, otherwise reset.
	   @param  date  (Date) the date to check
	   @return  (Date) the corrected date */
    _daylightSavingAdjust: function (date) {
      if (!date) return null;
      date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
      return date;
    },

    /* Set the date(s) directly. */
    _setDate: function (inst, date, endDate) {
      var clear = !date;
      var origMonth = inst.selectedMonth;
      var origYear = inst.selectedYear;
      date = this._determineDate(date, new Date());
      inst.selectedDay = inst.currentDay = date.getDate();
      inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
      inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
      if (origMonth != inst.selectedMonth || origYear != inst.selectedYear)
        this._notifyChange(inst);
      this._adjustInstDate(inst);
      if (inst.input) {
        inst.input.val(clear ? "" : this._formatDate(inst));
      }
    },

    /* Retrieve the date(s) directly. */
    _getDate: function (inst) {
      var startDate =
        !inst.currentYear || (inst.input && inst.input.val() == "")
          ? null
          : this._daylightSavingAdjust(
              new Date(inst.currentYear, inst.currentMonth, inst.currentDay)
            );
      return startDate;
    },

    /* Generate the HTML for the current state of the date picker. */
    _generateHTML: function (inst) {
      var today = new Date();
      today = this._daylightSavingAdjust(
        new Date(today.getFullYear(), today.getMonth(), today.getDate())
      ); // clear time
      var isRTL = this._get(inst, "isRTL");
      var showButtonPanel = this._get(inst, "showButtonPanel");
      var hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext");
      var navigationAsDateFormat = this._get(inst, "navigationAsDateFormat");
      var numMonths = this._getNumberOfMonths(inst);
      var showCurrentAtPos = this._get(inst, "showCurrentAtPos");
      var stepMonths = this._get(inst, "stepMonths");
      var stepBigMonths = this._get(inst, "stepBigMonths");
      var isMultiMonth = numMonths[0] != 1 || numMonths[1] != 1;
      var currentDate = this._daylightSavingAdjust(
        !inst.currentDay
          ? new Date(9999, 9, 9)
          : new Date(inst.currentYear, inst.currentMonth, inst.currentDay)
      );
      var minDate = this._getMinMaxDate(inst, "min", true);
      var maxDate = this._getMinMaxDate(inst, "max");
      var drawMonth = inst.drawMonth - showCurrentAtPos;
      var drawYear = inst.drawYear;
      if (drawMonth < 0) {
        drawMonth += 12;
        drawYear--;
      }
      if (maxDate) {
        var maxDraw = this._daylightSavingAdjust(
          new Date(
            maxDate.getFullYear(),
            maxDate.getMonth() - numMonths[1] + 1,
            maxDate.getDate()
          )
        );
        maxDraw = minDate && maxDraw < minDate ? minDate : maxDraw;
        while (
          this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw
        ) {
          drawMonth--;
          if (drawMonth < 0) {
            drawMonth = 11;
            drawYear--;
          }
        }
      }
      inst.drawMonth = drawMonth;
      inst.drawYear = drawYear;
      var prevText = this._get(inst, "prevText");
      prevText = !navigationAsDateFormat
        ? prevText
        : this.formatDate(
            prevText,
            this._daylightSavingAdjust(
              new Date(drawYear, drawMonth - stepMonths, 1)
            ),
            this._getFormatConfig(inst)
          );
      var prev = this._canAdjustMonth(inst, -1, drawYear, drawMonth)
        ? '<a class="ui-datepicker-prev ui-corner-all" onclick="prevYear()"' +
          ' title="' +
          prevText +
          '"><span class="ui-icon ui-icon-circle-triangle-' +
          (isRTL ? "e" : "w") +
          '">' +
          prevText +
          "</span></a>"
        : hideIfNoPrevNext
        ? ""
        : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="' +
          prevText +
          '"><span class="ui-icon ui-icon-circle-triangle-' +
          (isRTL ? "e" : "w") +
          '">' +
          prevText +
          "</span></a>";
      var nextText = this._get(inst, "nextText");
      nextText = !navigationAsDateFormat
        ? nextText
        : this.formatDate(
            nextText,
            this._daylightSavingAdjust(
              new Date(drawYear, drawMonth + stepMonths, 1)
            ),
            this._getFormatConfig(inst)
          );
      var next = this._canAdjustMonth(inst, +1, drawYear, drawMonth)
        ? '<a class="ui-datepicker-next ui-corner-all" onclick="nextYear()"' +
          ' title="' +
          nextText +
          '"><span class="ui-icon ui-icon-circle-triangle-' +
          (isRTL ? "w" : "e") +
          '">' +
          nextText +
          "</span></a>"
        : hideIfNoPrevNext
        ? ""
        : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="' +
          nextText +
          '"><span class="ui-icon ui-icon-circle-triangle-' +
          (isRTL ? "w" : "e") +
          '">' +
          nextText +
          "</span></a>";
      var currentText = this._get(inst, "currentText");
      var gotoDate =
        this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today;
      currentText = !navigationAsDateFormat
        ? currentText
        : this.formatDate(currentText, gotoDate, this._getFormatConfig(inst));
      var controls = !inst.inline
        ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.Monthpicker._hideDatepicker();">' +
          this._get(inst, "closeText") +
          "</button>"
        : "";
      var buttonPanel = showButtonPanel
        ? '<div class="ui-datepicker-buttonpane ui-widget-content">' +
          (isRTL ? controls : "") +
          (this._isInRange(inst, gotoDate)
            ? '<button type="button"  style="display:none" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.Monthpicker._gotoToday(\'#' +
              inst.id +
              "');\"" +
              ">" +
              currentText +
              "</button>"
            : "") +
          (isRTL ? "" : controls) +
          "</div>"
        : "";
      var firstDay = parseInt(this._get(inst, "firstDay"), 10);
      firstDay = isNaN(firstDay) ? 0 : firstDay;
      var dayNames = this._get(inst, "dayNames");
      var dayNamesShort = this._get(inst, "dayNamesShort");
      var dayNamesMin = this._get(inst, "dayNamesMin");
      var monthNames = this._get(inst, "monthNames");
      var monthNamesShort = this._get(inst, "monthNamesShort");
      var beforeShowDay = this._get(inst, "beforeShowDay");
      var showOtherMonths = this._get(inst, "showOtherMonths");
      var calculateWeek = this._get(inst, "calculateWeek") || this.iso8601Week;
      var endDate = inst.endDay
        ? this._daylightSavingAdjust(
            new Date(inst.endYear, inst.endMonth, inst.endDay)
          )
        : currentDate;
      var defaultDate = this._getDefaultDate(inst);
      var html = "";
      for (var row = 0; row < numMonths[0]; row++) {
        var group = "";
        for (var col = 0; col < numMonths[1]; col++) {
          var selectedDate = this._daylightSavingAdjust(
            new Date(drawYear, drawMonth, inst.selectedDay)
          );
          var cornerClass = " ui-corner-all";
          var calender = "";
          if (isMultiMonth) {
            calender += '<div class="ui-datepicker-group ui-datepicker-group-';
            switch (col) {
              case 0:
                calender += "first";
                cornerClass = " ui-corner-" + (isRTL ? "right" : "left");
                break;
              case numMonths[1] - 1:
                calender += "last";
                cornerClass = " ui-corner-" + (isRTL ? "left" : "right");
                break;
              default:
                calender += "middle";
                cornerClass = "";
                break;
            }
            calender += '">';
          }
          calender +=
            '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' +
            cornerClass +
            '">' +
            (/all|left/.test(cornerClass) && row == 0
              ? isRTL
                ? next
                : prev
              : "") +
            (/all|right/.test(cornerClass) && row == 0
              ? isRTL
                ? prev
                : next
              : "") +
            this._generateMonthYearHeader(
              inst,
              drawMonth,
              drawYear,
              minDate,
              maxDate,
              selectedDate,
              row > 0 || col > 0,
              monthNames,
              monthNamesShort
            ) + // draw month headers
            '</div><table class="ui-datepicker-calendar"><tr>&nbsp;</tr>';

          var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
          if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
            inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
          var leadDays =
            (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
          var numRows = isMultiMonth
            ? 6
            : Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
          var printDate = this._daylightSavingAdjust(
            new Date(drawYear, drawMonth, 1 - leadDays)
          );
          var idow = 0;
          for (var dow = 0; dow < 4; dow++) {
            // create date picker rows
            calender += '<tr align="center" class="month-calendar-tr">';
            var tbody = "";
            for (var rdow = 0; rdow < 3; rdow++) {
              // create date picker days

              if (idow == drawMonth) {
                tbody +=
                  '<td class="ui-datepicker-today"   onclick="DP_jQuery.Monthpicker._selectMonth(\'#' +
                  inst.id +
                  "','" +
                  monthNamesShort[idow] +
                  "'," +
                  drawYear +
                  ', this);">' +
                  '<a class="ui-state-default ui-state-highlight" style="text-align:center" href="#">' +
                  monthNamesShort[idow] +
                  "</a></td>";
              } else
                tbody +=
                  '<td class="ui-datepicker-today" onclick="DP_jQuery.Monthpicker._selectMonth(\'#' +
                  inst.id +
                  "','" +
                  monthNamesShort[idow] +
                  "'," +
                  drawYear +
                  ', this);">' +
                  '<a class="ui-state-default"  style="text-align:center" href="#">' +
                  monthNamesShort[idow] +
                  "</a></td>";
              idow++;
            }
            calender += tbody + "</tr>";
          }
          drawMonth++;
          if (drawMonth > 11) {
            drawMonth = 0;
            drawYear++;
          }
          calender +=
            "</tbody></table>" +
            (isMultiMonth
              ? "</div>" +
                (numMonths[0] > 0 && col == numMonths[1] - 1
                  ? '<div class="ui-datepicker-row-break"></div>'
                  : "")
              : "");
          group += calender;
        }
        html += group;
      }
      html +=
        buttonPanel +
        ($.browser.msie && parseInt($.browser.version, 10) < 7 && !inst.inline
          ? '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>'
          : "");
      inst._keyEvent = false;
      return html;
    },

    /* Generate the month and year header. */
    _generateMonthYearHeader: function (
      inst,
      drawMonth,
      drawYear,
      minDate,
      maxDate,
      selectedDate,
      secondary,
      monthNames,
      monthNamesShort
    ) {
      minDate =
        inst.rangeStart && minDate && selectedDate < minDate
          ? selectedDate
          : minDate;
      var changeMonth = this._get(inst, "changeMonth");
      var changeYear = this._get(inst, "changeYear");
      var showMonthAfterYear = this._get(inst, "showMonthAfterYear");
      var html = '<div class="ui-datepicker-title">';
      var monthHtml = "";
      // month selection
      if (secondary || !changeMonth) monthHtml += "";
      else {
        var inMinYear = minDate && minDate.getFullYear() == drawYear;
        var inMaxYear = maxDate && maxDate.getFullYear() == drawYear;
        monthHtml +=
          '<select class="ui-datepicker-month" ' +
          "onchange=\"DP_jQuery.datepicker._selectMonthYear('#" +
          inst.id +
          "', this, 'M');\" " +
          "onclick=\"DP_jQuery.datepicker._clickMonthYear('#" +
          inst.id +
          "');\"" +
          ">";
        for (var month = 0; month < 12; month++) {
          if (
            (!inMinYear || month >= minDate.getMonth()) &&
            (!inMaxYear || month <= maxDate.getMonth())
          )
            monthHtml +=
              '<option value="' +
              month +
              '"' +
              (month == drawMonth ? ' selected="selected"' : "") +
              ">" +
              monthNamesShort[month] +
              "</option>";
        }
        monthHtml += "</select>";
      }
      if (!showMonthAfterYear)
        html +=
          monthHtml +
          ((secondary || changeMonth || changeYear) &&
          !(changeMonth && changeYear)
            ? "&#xa0;"
            : "");
      // year selection
      if (secondary || !changeYear)
        html +=
          '<span class="ui-month-datepicker-year">' + drawYear + "</span>";
      else {
        // determine range of years to display
        var years = this._get(inst, "yearRange").split(":");
        var year = 0;
        var endYear = 0;
        if (years.length != 2) {
          year = drawYear - 10;
          endYear = drawYear + 10;
        } else if (years[0].charAt(0) == "+" || years[0].charAt(0) == "-") {
          year = drawYear + parseInt(years[0], 10);
          endYear = drawYear + parseInt(years[1], 10);
        } else {
          year = parseInt(years[0], 10);
          endYear = parseInt(years[1], 10);
        }
        year = minDate ? Math.max(year, minDate.getFullYear()) : year;
        endYear = maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear;
        html +=
          '<select class="ui-month-datepicker-year" ' +
          "onchange=\"DP_jQuery.datepicker._selectMonthYear('#" +
          inst.id +
          "', this, 'Y');\" " +
          "onclick=\"DP_jQuery.datepicker._clickMonthYear('#" +
          inst.id +
          "');\"" +
          ">";
        for (; year <= endYear; year++) {
          html +=
            '<option value="' +
            year +
            '"' +
            (year == drawYear ? ' selected="selected"' : "") +
            ">" +
            year +
            "</option>";
        }
        html += "</select>";
      }
      if (showMonthAfterYear)
        html +=
          (secondary || changeMonth || changeYear ? "&#xa0;" : "") + monthHtml;
      html += "</div>"; // Close datepicker_header
      return html;
    },

    /* Adjust one of the date sub-fields. */
    _adjustInstDate: function (inst, offset, period) {
      var year = inst.drawYear + (period == "Y" ? offset : 0);
      var month = inst.drawMonth + (period == "M" ? offset : 0);
      var day =
        Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
        (period == "D" ? offset : 0);
      var date = this._daylightSavingAdjust(new Date(year, month, day));
      // ensure it is within the bounds set
      var minDate = this._getMinMaxDate(inst, "min", true);
      var maxDate = this._getMinMaxDate(inst, "max");
      date = minDate && date < minDate ? minDate : date;
      date = maxDate && date > maxDate ? maxDate : date;
      inst.selectedDay = date.getDate();
      inst.drawMonth = inst.selectedMonth = date.getMonth();
      inst.drawYear = inst.selectedYear = date.getFullYear();
      if (period == "M" || period == "Y") this._notifyChange(inst);
    },

    /* Notify change of month/year. */
    _notifyChange: function (inst) {
      var onChange = this._get(inst, "onChangeMonthYear");
      if (onChange)
        onChange.apply(inst.input ? inst.input[0] : null, [
          inst.selectedYear,
          inst.selectedMonth + 1,
          inst,
        ]);
    },

    /* Determine the number of months to show. */
    _getNumberOfMonths: function (inst) {
      var numMonths = this._get(inst, "numberOfMonths");
      return numMonths == null
        ? [1, 1]
        : typeof numMonths == "number"
        ? [1, numMonths]
        : numMonths;
    },

    /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
    _getMinMaxDate: function (inst, minMax, checkRange) {
      var date = this._determineDate(this._get(inst, minMax + "Date"), null);
      return !checkRange || !inst.rangeStart
        ? date
        : !date || inst.rangeStart > date
        ? inst.rangeStart
        : date;
    },

    /* Find the number of days in a given month. */
    _getDaysInMonth: function (year, month) {
      return 32 - new Date(year, month, 32).getDate();
    },

    /* Find the day of the week of the first of a month. */
    _getFirstDayOfMonth: function (year, month) {
      return new Date(year, month, 1).getDay();
    },

    /* Determines if we should allow a "next/prev" month display change. */
    _canAdjustMonth: function (inst, offset, curYear, curMonth) {
      var numMonths = this._getNumberOfMonths(inst);
      var date = this._daylightSavingAdjust(
        new Date(curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1)
      );
      if (offset < 0)
        date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
      return this._isInRange(inst, date);
    },

    /* Is the given date in the accepted range? */
    _isInRange: function (inst, date) {
      // during range selection, use minimum of selected date and range start
      var newMinDate = !inst.rangeStart
        ? null
        : this._daylightSavingAdjust(
            new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay)
          );
      newMinDate =
        newMinDate && inst.rangeStart < newMinDate
          ? inst.rangeStart
          : newMinDate;
      var minDate = newMinDate || this._getMinMaxDate(inst, "min");
      var maxDate = this._getMinMaxDate(inst, "max");
      return (!minDate || date >= minDate) && (!maxDate || date <= maxDate);
    },

    /* Provide the configuration settings for formatting/parsing. */
    _getFormatConfig: function (inst) {
      var shortYearCutoff = this._get(inst, "shortYearCutoff");
      shortYearCutoff =
        typeof shortYearCutoff != "string"
          ? shortYearCutoff
          : (new Date().getFullYear() % 100) + parseInt(shortYearCutoff, 10);
      return {
        shortYearCutoff: shortYearCutoff,
        dayNamesShort: this._get(inst, "dayNamesShort"),
        dayNames: this._get(inst, "dayNames"),
        monthNamesShort: this._get(inst, "monthNamesShort"),
        monthNames: this._get(inst, "monthNames"),
      };
    },

    /* Format the given date for display. */
    _formatDate: function (inst, day, month, year) {
      if (!day) {
        inst.currentDay = inst.selectedDay;
        inst.currentMonth = inst.selectedMonth;
        inst.currentYear = inst.selectedYear;
      }
      var date = day
        ? typeof day == "object"
          ? day
          : this._daylightSavingAdjust(new Date(year, month, day))
        : this._daylightSavingAdjust(
            new Date(inst.currentYear, inst.currentMonth, inst.currentDay)
          );
      return this.formatDate(
        this._get(inst, "dateFormat"),
        date,
        this._getFormatConfig(inst)
      );
    },
  });

  /* jQuery extend now ignores nulls! */
  function extendRemove(target, props) {
    $.extend(target, props);
    for (var name in props)
      if (props[name] == null || props[name] == undefined)
        target[name] = props[name];
    return target;
  }

  /* Determine whether an object is an array. */
  function isArray(a) {
    return (
      a &&
      (($.browser.safari && typeof a == "object" && a.length) ||
        (a.constructor && a.constructor.toString().match(/\Array\(\)/)))
    );
  }

  /* Invoke the datepicker functionality.
   @param  options  string - a command, optionally followed by additional parameters or
                    Object - settings for attaching new datepicker functionality
   @return  jQuery object */
  $.fn.Monthpicker = function (options) {
    /* Initialise the date picker. */
    if (!$.Monthpicker.initialized) {
      $(document)
        .mousedown($.Monthpicker._checkExternalClick)
        .find("body")
        .append($.Monthpicker.dpDiv);
      $.Monthpicker.initialized = true;
    }

    var otherArgs = Array.prototype.slice.call(arguments, 1);
    if (
      typeof options == "string" &&
      (options == "isDisabled" || options == "getDate")
    )
      return $.Monthpicker["_" + options + "Datepicker"].apply(
        $.Monthpicker,
        [this[0]].concat(otherArgs)
      );
    if (
      options == "option" &&
      arguments.length == 2 &&
      typeof arguments[1] == "string"
    )
      return $.Monthpicker["_" + options + "Datepicker"].apply(
        $.Monthpicker,
        [this[0]].concat(otherArgs)
      );
    return this.each(function () {
      typeof options == "string"
        ? $.Monthpicker["_" + options + "Datepicker"].apply(
            $.Monthpicker,
            [this].concat(otherArgs)
          )
        : $.Monthpicker._attachDatepicker(this, options);
    });
  };

  $.Monthpicker = new Monthpicker(); // singleton instance
  $.Monthpicker.initialized = false;
  $.Monthpicker.uuid = new Date().getTime();
  $.Monthpicker.version = "1.7.2";

  // Workaround for #4055
  // Add another global to avoid noConflict issues with inline event handlers
  window.DP_jQuery = $;
})(jQuery);

function prevYear() {
  $(".ui-month-datepicker-year").text(
    parseInt($(".ui-month-datepicker-year").text()) - 1
  );
}
function nextYear() {
  $(".ui-month-datepicker-year").text(
    parseInt($(".ui-month-datepicker-year").text()) + 1
  );
}